Этот документ покрывает то, что принципиально не берётся автотестами: живой TUI,
реальное развёртывание контейнера и онбординг на настоящем проекте. Пройти по
каждому пункту вживую и отметить результат: [ ] → [x].
Запуск: docker compose exec memory cms (без аргументов).
- Команда без аргументов открывает TUI — виден список «All notes».
-
↑/↓двигают курсор по списку. -
qвыходит из TUI, терминал не сломан (raw-mode восстановлен).
-
Enterна строке списка открывает detail-вид: тело заметки, карта якорей (сгруппирована по весам), блок упомянутых заметок[[id]]. -
Esc(илиBackspace) из detail возвращает в список, курсор на той же позиции.
- В detail встать на строку-упоминание (
[[id]]),Enter— открылась связанная заметка. - На stale-упоминании
Enterне переходит (заметка-цель удалена или id изменён).
- В detail встать на строку якоря
entity:…,Enter— список «Anchor: entity:…» с заметками, привязанными к этому якорю. - Аналогично для якоря
file:…. - Аналогично для якоря
symbol:….
-
/открывает строку вводаSearch. - Ввод символов — строка накапливается;
Backspace/Delete— стирает. -
Enterс непустым запросом — переход в список «Search: <запрос>». -
Enterс пустой строкой — поиск не выполняется, остаёмся на месте. -
Escв режиме ввода — отмена, возврат к предыдущему виду без поиска.
- В виде «Search: …» или «Anchor: …» по умолчанию
draft/outdatedскрыты; строка подсказок показываетd: drafts off a: archived off. -
d— в выдаче появляютсяdraft-заметки, подсказкаdrafts on; повторноеd— скрывает обратно. -
a— то же дляoutdated-заметок. - В списке «All notes»
draft/outdatedвидны всегда, toggle-подсказки нет,d/aничего не меняют.
- После цепочки переходов (список → заметка → якорь → заметка)
Esc/Backspaceпоследовательно возвращает по кадрам до стартового списка. - Forward-навигации нет — это нормально.
- В detail
eоткрывает.md-файл заметки в$EDITOR. - После выхода из редактора экран перерисован, правки видны (reconcile отработал автоматически).
- Если
$EDITORне найден (или не задан иviнедоступен) — красная строкаeditor "<name>" not found; set $EDITOR, TUI продолжает работу.
- В detail
dпереводит в режим подтверждения: подсказкаy: confirm n/Esc: cancel. -
y(илиY) — заметка удалена, TUI уходит на кадр назад, список обновлён. -
nилиEsc— отмена, заметка осталась.
- Собрать образ из
Dockerfile:docker build -t code-memory-service . # или через docker compose build memory
- Добавить блок
service: memoryвdocker-compose.ymlцелевого проекта:memory: build: ../code-memory-service # путь к клону этого репозитория environment: CMS_PROJECT_ROOT: /project CMS_PORT: 8765 volumes: - .:/project:ro - ./.memory:/project/.memory:rw restart: unless-stopped
-
docker compose up -d memory— контейнер поднялся. - В логах (
docker compose logs memory) видно, что на старте сервис сверил content hash файлов и переиндексировал расхождения. -
docker compose exec memory cms stats— CLI внутри контейнера отвечает, показывает статистику индекса.
- Добавить
.mcp.jsonв корень целевого проекта:(или командой{ "mcpServers": { "code-memory": { "type": "http", "url": "http://memory:8765/mcp" } } }claude mcp add --transport http --scope project code-memory http://memory:8765/mcp) - Убедиться, что Claude Code запущен в той же compose-сети, что и контейнер
memory— обращение идёт по имени сервиса.
-
create_noteиз Claude Code — заметка создалась (id возвращён). -
searchнаходит только что созданную заметку по тексту или якорю. -
get_notes([id])разворачивает заметку: тело, карта якорей, блок[[id]]. - Изменить файл кода в целевом проекте → повторить
search/docker compose exec memory cms verify→ индекс отражает свежее состояние (watcher переиндексировал изменение).
Флоу по specs/06-onboarding.md. Применяется при подключении сервиса к уже
существующему проекту.
- На пустом
.memory/reindexстроитsymbol_indexчерез tree-sitter. (Запускается автоматически на старте сервиса; можно явно:cms reindex --code.) -
cms statsпоказывает непустойsymbol_index.
- Объяснить Клоду логику преобразования: где лежат источники, как сырьё
отображается в заметки (пример: «спеки в
docs/, секция уровня##= одна заметка»). - Клод предлагает кандидатов доменных сущностей из структуры кода; человек прорежает список.
- Одобренные сущности зарегистрированы через
create_entity. -
list_entitiesвозвращает реестр с ожидаемыми сущностями.
- Документация скормлена частями; для каждого чанка Клод делает
searchсinclude_drafts: trueпередcreate_note—draft-заметки прошлых чанков находятся, дубликаты сливаются черезupdate_note, не дублируются. - Новые заметки создаются со
status: draft. - Сырой текст чанка сброшен перед переходом к следующему.
-
.memory/onboarding.mdведётся: план, правила преобразования, чек-лист источников (обработано / в очереди / пропущено).
- Онбординг прерван и возобновлён в новой сессии:
.memory/onboarding.mdпрочитан, прогресс восстановлен, работа продолжена с нужного места.
-
draft-заметки просмотрены; корректные промотированы вcurrentчерезupdate_note({status: "current"}). - Некорректные или лишние остаются
draftили удаляются. - По завершении
.memory/onboarding.mdудалён или помечен архивным.
- На источнике без явного намерения документировать (тесты, миграции, общая документация) заметка создаётся только при проверяемом артефакте-источнике (существование символа — по индексу, инвариант теста — по имени).
- «Почему так» без явного источника не реконструируется. При неуверенности
используется investigation-форма тела с явными метками
Подтверждено/Гипотезы.
Допущения, которые нельзя проверить автотестами. Для каждого — заполнить колонку Результат после вживого прогона.
| Допущение | Где в коде | Что замерить | Результат |
|---|---|---|---|
Parser.init() в Docker — WASM-движок tree-sitter и грамматики грузятся из tree-sitter-wasms/.../out/*.wasm; путь строится через createRequire |
structural-indexer.ts:108-126 |
Внутри образа node:24: запустить cms reindex --code и проверить, что символы проиндексированы. Если ошибка — вероятно, нужен locateFile для движкового web-tree-sitter.wasm |
|
BM25_FLOOR = 1e-9 — релевантность ниже порога = не матч; на маленьком корпусе порог не задействован |
search.ts:13, 130 |
На корпусе ≥50 заметок: ищет ли сервис по общим словам (не отсекает ли валидные слабые матчи); нет ли мусора в топе | |
UBIQUITY_RATIO = 0.7, MIN_CORPUS_FOR_IDF = 5 — якорь, встречающийся у ≥70% заметок при корпусе ≥5, не даёт IDF-вклада |
search.ts:8-9, 109 |
На реальном корпусе: есть ли «вездесущие» якоря, которые не должны быть вездесущими? Снизить UBIQUITY_RATIO до 0.5 если поиск по якорю даёт странные результаты |
|
$EDITOR в Docker-образе и в TUI — дефолт vi; TUI снимает raw-mode через setRawMode(false) и восстанавливает после |
editor.ts:6, app.tsx:186-193 |
Есть ли vi в node:24? (docker compose exec memory which vi). Не «зависает» ли терминал после выхода из редактора (raw-mode не вернулся) |
|
reconcileStructure на каждый CLI-вызов — структурный реиндекс на каждый холодный старт CLI |
context.ts (reconcile) |
Замерить time docker compose exec memory cms stats на репозитории с 1000+ файлами. Если >2s — задержка заметна |
Документ обновляется по результатам прогона. После полного прохода
пункты отмечены [x], колонка «Результат» заполнена.