Модель памяти: два пространства имён, две оси
Статус: реализовано для уровней пространства имён и предмета; уровень применимости (workplaces/, machines/) — это пока только каталоги, ни один глагол их не создаёт и не связывает, хотя statuses_personal пишет в machines/<name>/ с 0.18.0. Уровень пространства имён и projects/<key> вышли в 0.7.0; уровень предмета был реализован наполовину до 2026-09-08, когда подключили common/. До того эта строка говорила «реализовано» про область, которую ни один глагол не создавал, не связывал и не читал: шестнадцать заметок лежали в приватном хранилище, куда ни одна сессия не могла дотянуться, — и именно это утверждение мешало кому-нибудь заметить. Написано 2026-08-25 против 0.6.1, пересмотрено при реализации. Документ существует потому, что раскладку переименовали трижды за один день — projects/<key>, затем /memory и /local, затем /shared и /private, — и каждое переименование было поправкой к модели, которую никто не записал. Имена продолжали говорить неправду, потому что сама вещь ни разу не была названа.
Прочитайте это, прежде чем менять любой путь в memory-store.sh, memory-workplace.sh или в том, как шим разрешает пути.
На что должна отвечать заметка
Три вопроса, и они независимы. Всякая раскладка, смешавшая два из них в одном имени каталога, оказывалась неверной.
| вопрос | значения | чем решается |
|---|---|---|
| Кому можно её читать? | команде или одному человеку | git-репозиторием, в котором она лежит |
| О чём она? | об одном проекте или ни об одном конкретном | каталогом projects/<key>/ или common/ |
| Где это верно? | везде, на одном рабочем месте, на одной машине | каталогом применимости внутри предыдущего |
На первый вопрос отвечает граница репозитория, а не каталог и не поле во frontmatter. Каталог — подсказка человеку; репозиторий — контроль доступа. Заметка, которая не должна попасть к команде, обязана лежать в репозитории, который команда не может склонировать; всё, что слабее, — договорённость, а договорённость не переживает git add -A.
Остальные два вопроса — каталоги, потому что человек по ним ходит, а git их перемещает.
Грамматика
<namespace>/<subject>/[<validity>/]<note>.md
private/ один репозиторий на человека
projects/<key>/ об этом проекте, верно везде
workplaces/<place>/ об этом проекте, верно только на этом месте
machines/<machine>/ об этом проекте, верно только на этой машине
common/ ни об одном проекте, верно везде
workplaces/<place>/ ни об одном проекте, только это рабочее место
machines/<machine>/ ни об одном проекте, только эта машина
public/ собственный репозиторий проекта или общий
projects/<key>/ ... те же шесть ячеек
common/ ...
Внутри этой формы три решения, у каждого своя причина:
- Предмет выше применимости. Обратный порядок (
workplaces/<place>/projects/<key>/) заставляет сессию, работающую над одним проектом, обойти1 + N мест + N машинкаталогов — а это самое частое чтение. Он же разрезает заметки проекта, и передать проект — или удалить его — перестаёт быть однимgit mv. - У «верно везде» нет своего каталога. Такие заметки лежат прямо в
projects/<key>/илиcommon/. Это самый частый случай, и он не должен стоить уровня. Нынешняя раскладка так и делает. public/иprivate/— всегда каталоги. Первый черновик говорил, что репозиторий с единственным пространством имён может держать свои области прямо в корне; реализация показала, почему нет: плагин допускает один URL, играющий обе роли, и тогда обе области оказались быprojects/<key>и столкнулись. Сделать уровень условным — «равны ли два URL» — значило бы, что путь меняется от строки в конфиге. Уровень всегда один, без условий. Обычный случай не затронут: публичная половина проекта, способного держать свою память, — это.agent-memory/в репозитории проекта, а эта грамматика управляет только памятью, живущей в отдельном репозитории.
Шесть ячеек, с настоящими примерами
Взяты из живого корпуса, не выдуманы.
| ячейка | путь | пример |
|---|---|---|
| приватная · проект · везде | private/projects/effectssdk/ | какую ветку клиентского чекаута мы поменяли и как это откатить |
| приватная · проект · рабочее место | private/projects/effectssdk/workplaces/home/ | стенд офиса отсюда доступен, GitLab клиента — нет |
| приватная · проект · машина | private/projects/effectssdk/machines/mac/ | разбор «Missing package product» в Xcode, для которого нужен Xcode |
| приватная · общее · везде | private/common/ | оценка стороннего инструмента; ловушка shell |
| приватная · общее · рабочее место | private/common/workplaces/home/ | где лежит чекаут бэкенда звонков и на какой машине |
| приватная · общее · машина | private/common/machines/linux/ | GPU этой машины, что на ней установлено |
Третью строку нынешняя раскладка выразить не может. Сегодня такая заметка либо лежит в области проекта и теряет «верно только на маке», либо в области машины и теряет «об этом проекте». В одном и том же корпусе её заводили и так, и так.
Какой репозиторий что держит
Выбрано 2026-08-25: один приватный репозиторий на человека, рабочие места — каталогом. Собственные договорённости человека, оценки инструментов и ловушки shell остаются в одном месте, вместо того чтобы копироваться между репозиториями по рабочим местам.
Другой вариант — репозиторий на каждое рабочее место — не ошибочен, и грамматика поддерживает его без изменений (уровень workplaces/ просто остаётся неиспользованным). Выбирайте его, когда «рабочее место» — это работодатель, а не комната: тогда граница репозитория становится границей изоляции, и заметки о чекауте одного клиента не окажутся рядом с заметками о другом даже случайно.
Публичная память сохраняет нынешнее правило: она живёт в собственном репозитории проекта (.agent-memory/), если только проект не может её держать — тогда она уходит в общий репозиторий, под public/projects/<key>/.
Как это читает сессия
Сессия всегда знает три координаты: проект, рабочее место и машину. Читает она по порядку:
<namespace>/projects/<key>/— индекс, затем заметки, на которые он указывает.<namespace>/projects/<key>/workplaces/<это место>/иmachines/<эта машина>/— только те две, что совпали. Остальные не просто нерелевантны, они здесь ложны, а это хуже.-
<namespace>/common/и два его совпавших каталога применимости — когда задача не только про проект. До сессии область доходит как<memory_dir>/common/sharedи<memory_dir>/common/<private>— по одной ссылке на пространство имён, потому что это два разных репозитория и машина могла подключить лишь одно из них.Из
MEMORY.mdcommon/сознательно НЕ достижим. Указатель из закоммиченной памяти внутрь области был бы мёртвым для всякого, кто её не подключил, — то же правило, что приватная область несёт с 0.4.0 и чтоlintпроверяет для обеих. Маршрутизировать сюда — работа читателя (обрядstartназывает область), а не указателя.
Шесть ячеек — больше, чем сессии стоит открывать по одной, поэтому маршрутизацией занимается индекс: один индекс на каталог предмета (projects/<key>/INDEX.md, common/INDEX.md), перечисляющий все заметки под ним, включая лежащие в каталогах применимости, и у каждого указателя помечено, где заметка верна. Один файл на чтение, а указатель говорит, применима ли заметка здесь.
От common/ lint этого индекса пока не требует, и это осознанный пропуск, а не недоделка. Область приходит уже написанной — те корпуса, где она есть, наполняли её руками целый год, — а проверка, которая на первом же запуске объявит сиротой каждую существующую заметку, это проверка, которую владелец выключит вместе с проверками самих заметок. Их lint применяет, и они показали, что лежит в непроверенном корпусе: из первых пятнадцати заметок восемь были без metadata.evidence, а у одной name не совпадало с именем файла.
Что понадобилось от конфигурации
| ключ | в какой версии | зачем |
|---|---|---|
project_key | до этого документа | называет проект в каждом репозитории памяти |
machine_key | 0.7.0 | hostname непригоден как имя: на одной из этих машин он WIN-GVR0V5UPOD7. Каталоги названы руками (linux-wsl-alexander), и так и должно остаться |
workplace_key | 0.7.0 | нужен только когда один репозиторий обслуживает несколько рабочих мест — а это и есть выбранная схема |
public_repo | 0.7.0, вместо memory_repo | прежнее имя говорило «память», а это обе половины |
private_repo | 0.7.0, вместо workplace_repo | прежнее имя говорило «рабочее место», а это одно из трёх значений применимости, а не аудитория |
Те два переименования оказались важнее, чем выглядели. memory_repo и workplace_repo — та самая пара, из-за которой два разных вопроса выглядели одной осью, и ровно эту ошибку документ существует, чтобы прекратить. Их совместимые запасные имена убраны в 0.8.0, так что конфиг, написанный любым из старых имён, теперь читается так, будто ключа нет вовсе.
Эта таблица написана 2026-08-25 как план и простояла в будущем времени до 2026-09-09, когда ревизия нашла в ней четыре «новых» ключа, которые парсер несёт с 0.7.0, — тремя экранами ниже заголовка, где уже написано «реализовано». Проектный документ, держащий свой план в настоящем времени, переживает сам план; теперь заголовок и таблица датируют себя сами.
Намеренно здесь не решено
- Выживет ли листовой
shared/private. В этой грамматике аудиторию несёт каталог пространства имён, так что лист, повторяющий её, избыточен. Сегодня он существует только потому, что один репозиторий мог играть обе роли. - Как
machines/<machine>/подключается к проекту. Сегодня эту связь не создаёт ни один глагол; заметки пишутся прямо в чекаут. Добавить связь — это ещё одна сущность в каждом проекте ради редкого случая, а в самом случае пока три заметки. - Заслуживает ли
common/вида подagents_memory_dir. Он есть у всякой другой области и нет у этой: единственный<views>/common/имеет одно имя и — для публичного пространства имён — столько значений, сколько хранилищ: два проекта с двумя публичными хранилищами под однимagents_memory_dirоба хотят, чтобы он означал их собственное. Измерено 2026-09-08 на двуххранилищной фикстуре самого набора тестов. Ссылки вместо этого ведут прямо в каждый клон — там нет общего имени, из-за которого можно столкнуться. Имя вида, включающее хранилище, сработало бы и купило бы только удобство просмотра. - Миграция. Шесть ячеек — переезд крупнее трёх переименований, которые ему предшествовали, и ни одно из них не стоит начинать, пока этот документ не прочитан человеком и не оспорен.