Поддержите проект, сделав пожертвование

~/.claude в Git — это половина задачи. Вторая половина — общая память Claude Code

Тут недавно был отличный пост про то, как вынести ~/.claude в git-репозиторий. Я делаю так же — но у git-подхода есть слепое пятно: он версионирует то, что Claude умеет, а не то, что он узнал про твои проекты. Вот как я закрыл это для команды.


Тот самый пост — про то, как превратить ~/.claude в git-репозиторий: скиллы, агенты, слэш-команды, MCP-конфиг, хуки под симлинками через make install, синк между машинами, не теряется при блокировке аккаунта. Подход правильный, сам так делаю.

Но за 2 года на нескольких проектах я упёрся в то, что git-конфиг не решает.

Статика vs динамика

Git версионирует статику — то, что Claude умеет: твои скиллы, агентов, команды, правила. Это здорово и переносимо.

Чего там нет — это динамики: того, что Claude узнал про конкретный проект за прошлые сессии. Например:

  • здесь миграции катятся не через migrate, а через свою обёртку над artisan;
  • вот этот «временный» модуль в платёжке трогать нельзя, на нём прод;
  • у этого юрлица специально задан невалидный БИК, через него работает интеграция с банком.

Это не скилл и не правило — это накопленный контекст по проекту. В Claude Code он копится через auto-memory, но живёт в отдельной базе, а не в ~/.claude/*.md. Поэтому в git он не попадает. А значит:

  • новая сессия на другом ноуте начинает с нуля;
  • новый человек в команде не наследует то, что Claude уже понял про проект — переоткрывает те же грабли;
  • даже у тебя одного контекст «вчерашнего дня» не переезжает между машинами, хотя конфиг — переехал.

Git-pull этого по своей природе не лечит: он пофайловый и point-in-time. А память по проекту нужна живой, общей и искомой по смыслу, а не «закоммить — запушь — подтяни».

Что я сделал

Вынес слой памяти на сервер. ruflo-hub — небольшая Docker-обёртка: берёт MCP-сервер памяти, оборачивает stdio в HTTP, и Claude Code у всех в команде ходит в одно общее хранилище памяти. Один человек разобрался в особенности проекта — и у остальных Claude это уже знает.

Сразу честно, иначе про этот проект нельзя. В основе — ruflo (форк claude-flow), и у него репутация. Я сам проверял: большая часть из «300+ MCP-инструментов» — нерабочие заглушки. swarm_init оставляет agentCount: 0, neural_train возвращает Math.random(), «агенты» — это markdown-файлы. Как swarm-оркестратор это в основном театр (об этом же — обсуждение на r/ClaudeAI).

Реально работает ровно одна часть — слой памяти: настоящая ONNX-модель (MiniLM) + HNSW-индекс, SQLite-персист и auto-memory-хук. ruflo-hub — тонкая обёртка, которая отдаёт по сети только этот слой и мостит его в Claude Code. Никакого swarm/neural и сотен заглушек в контексте — мы их просто не грузим. То есть это ровно тот рабочий ~1% от ruflo, без остального.

Как выглядит на практике

Поднять сервер:

docker compose up -d
curl http://localhost:3000/health

Память хранится в SQLite (memory.db, WAL-режим). PostgreSQL в комплекте опционален — он не основное хранилище, а нужен только под ruflo ruvector import/export.

Подключение проекта — самоконфигурирующийся скрипт с того же сервера:

curl http://<сервер>:3000/setup | bash

Да, это curl | bash со своего сервера — скрипт отдаётся в открытом виде, гляньте перед запуском. Он кладёт хелперы в .claude/helpers/ (auto-memory-хук + statusline) и правит .claude/settings.json (хуки SessionStart → import / Stop → sync). Дальше Claude Code пишет и читает память на сервере сам: memory_store на находки, memory_search — по смыслу (не grep: найдёт «паттерн JWT-авторизации» по запросу «token-based login flow»). В statusline видно число векторов и статус MCP.

Честно про эксплуатацию (раз уж про честность)

  • Была реальная утечка. WASM-ФС у sql.js копил по полному образу БД на каждое открытие — прод-инстанс дорос до ~36 ГБ RSS за 6 недель. Нашли heap-снимком (V8-heap плоский — течёт нативка), корень — в реестре контроллеров @claude-flow/memory. Зарепортили апстриму (#2432), и в ruflo 3.14.2 это уже исправлено; у себя держим ещё RSS-watchdog как страховку.
  • Про версию — без самообмана. Образ собирается на ruflo@latest и пересобирается еженедельно, так что :latest со временем уедет вперёд. Аудит и фиксы ниже я делал на 3.14.2. Хотите воспроизводимость — берите конкретный тег (:1.3.0 или :<sha>), а не :latest, и проверяйте docker exec … ruflo --version.
  • Security-история. В старых версиях ruflo (3.1.0-alpha.55 – 3.5.2) был #1375: вредоносный preinstall-скрипт и скрытая инъекция в описаниях инструментов. Раз хаб ставит пакет и раздаёт описания клиентам — перепроверил версию, которую шиплю (3.14.2): preinstall-хуков нет, все 305 описаний чистые. В этой версии вылечено — но фиксируйте версию и проверяйте сами.
  • Бэкап WAL-безопасныйmemory.db в WAL-режиме, бэкапим том целиком (memory.db + -wal + -shm); копия одного memory.db даёт database disk image is malformed.

Что обычно спрашивают первым

Когда я кидал это в один Laravel-чат, первым прилетело не «как», а «а как с безопасностью общей памяти» и «чем это лучше папки docs + claude.md». Отвечу честно.

«А если кто-то накидает в общую память инъекций? Джун насыплет своих инструкций? А если они нужны только в одном проекте, а в другом нет?»

Память разводится по namespace — Claude сам заводит их по проектам, плюс можно явно сказать «сохрани/прочитай в такой-то namespace». Если у проектов разные trust-зоны и утечки между ними недопустимы — это не «одна общая помойка»: поднимаешь отдельный ruflo-hub под бизнес-скоуп (один сервер = один периметр доверия), личное — на своём.

А вот честное ограничение: per-user ACL и автофильтра инъекций из коробки пока нет. Сейчас это организационно — общая память это общая граница доверия: подключаешь тех, кому доверяешь, ревью памяти на тимлиде. Технического «джун не может писать сюда» я ещё не сделал — и не буду делать вид, что сделал. Если у тебя в команде это критично — пока только разводка по отдельным серверам.

«Чем лучше папки docs/ и claude.md

Они никуда не деваются, и память их не заменяет. Разница в двух вещах. Первое — часть рабочих вещей в гит класть нельзя или не нужно, а память не в гите. Второе — память живая и сразу доступна агенту через хуки + поиск по смыслу. Часто в ней лежат как раз ссылки на эти доки: Claude, просматривая память, сам быстро находит «а, про это есть док вот тут» — даже если конкретный разработчик не знает, что кто-то положил эту доку сто лет назад. То есть docs/claude.md — статика для людей, а память — индекс по опыту для агента, который на эту статику ссылается.

Когда это НЕ нужно

Зеркалю мысль из того поста — не ради инфраструктуры:

  • соло-разработчику или на 1–2 проекта — оверкилл; git-конфига из того поста хватит за глаза;
  • если ты осознанно начинаешь каждую сессию с чистого листа — тоже мимо.

Нужно — когда команда и много проектов, и хочется, чтобы то, что Claude понял на одном проекте или у одного человека, доходило до всех без пересказа.

Итого

~/.claude в git и общая память — про разные половины одной задачи: статика (что Claude умеет) едет в git, динамика (что он узнал про твои проекты) — в общий сетевой слой памяти. У меня работает связка из обоих.

  • Код: jazz-max/ruflo-hub (образ на Docker Hub — jazzmax/ruflo-hub; да, ник на GitHub и в Docker Hub исторически разный)
  • Апстрим-следы: issue #2432 (утечка, уже зафикшена), discussion #2433
0

Партнёры и друзья

Помощь в разработке вашего проекта на Laravel

Независимо от сложности проекта эти кампании помогают сообществу и всем его участникам воплощать идеи в элегантные приложения.

Присоединиться

Инструменты для управления эмоциями, которые помогают людям контролировать свою жизнь и лучше понимать себя.

Перейти

Подкасты c зажигательными эпизодами, которые заставят задуматься и приведут к новым перспективам.

Перейти

Делятся опытом, находят друзей и обсуждают разработку и сопровождение любых бэкендов на PHP.

Перейти