Compare commits

..

11 Commits

Author SHA1 Message Date
47fba6d993 deploy(mappa): стек 27 -> v0.64.14 (release:24) — FP детектора секретов, task:3077 2026-09-19 22:52:53 +03:00
c8cc17047d fix(secrets): вычистить MinIO-креды из .wiki file-каналов (task:3076) 2026-09-19 22:05:36 +03:00
201fc6aa58 deploy(mappa): стек 27 -> v0.64.13 (release:23) — redirect-предикат линта без ложных срабатываний 2026-09-19 20:27:37 +03:00
ad731e014f deploy(mappa): стек 27 -> v0.64.12 (release:22, task:3068) + mem_limit 512m->1g по замеру 2026-09-19 19:37:54 +03:00
ca265bfe2f fix(agents): вернуть opt-in session-sync в AGENTS.md — live-ingest .admin был выключен
Строка `session sync: write to mappa` выпала из файла в e3fb3111 (18.09, task:3017,
переработка канон-блока); канон wiki:2608 её сохранил, повторный прогон блока
(7939ce36) не вернул. Без строки pi-расширение (mappa.ts isOptedIn) не поднимает
live-ingest → сессии .admin не пишутся в mappa (проверено: 01a0b97e и текущая 404,
контроль session:1913 200; у books/sched/tg-digest строка есть — их сессии в mappa есть).

Восстановлено verbatim из канона.
2026-09-19 16:36:44 +03:00
d1cb4d932a fix(admin): sync-sched-publish — .mappa вне паблик-сета + портативный leak-скан (gotcha 15/16, task:3059) 2026-09-19 14:59:13 +03:00
9d1ca60ddd deploy(mappa): стек 27 -> v0.64.10 (release:20, вершина 32d3c74)
canary зелёный (та же БД: dangling keys +reason/refs_total), pg_dump до PUT (126745887 B, sha256 86c4365e…, TOC 281), env 19/19, verify /health+meta 0.64.10/sha 32d3c74, sched 6/6, 0 mappa-404 в окне.
2026-09-19 14:31:09 +03:00
7939ce3611 docs(canon): ре-прогон канон-блока на mappa-setup@0.2.8 (task:3030) + refresh .mappa/share 2026-09-19 09:45:08 +03:00
e3fb31112b docs(AGENTS.md): канон-блок — краткая суть гейтов вместо обрубков (task:3017) 2026-09-18 22:03:15 +03:00
d8b5344a72 docs(AGENTS.md): канон-блок — краткая суть гейтов вместо обрубков (task:3017) 2026-09-18 21:50:23 +03:00
2f695c2808 docs(AGENTS.md): канон-блок — краткая суть гейтов вместо обрубков (task:3017) 2026-09-18 21:29:28 +03:00
16 changed files with 280 additions and 145 deletions

View File

@@ -1,6 +1,6 @@
--- ---
title: Канон mappa — гейты title: Канон mappa — гейты
summary: Железные правила работы агента с mappa (любой проект/харнесс): знание и артефакты → mappa, контракт каналов, поиск-до-угадывания, адресация, .mappa-гейт, секреты, degraded. Проекция → AGENTS.md (bootstrap). summary: Железные правила работы агента с mappa (любой проект/харнесс): знание и артефакты → mappa, контракт каналов, поиск-до-угадывания (вкл. общая память mode='recall'), адресация, .mappa-гейт, секреты, degraded, живое состояние до заявления. Проекция → AGENTS.md (bootstrap).
type: canon type: canon
tags: [mappa, canon, gates, agent] tags: [mappa, canon, gates, agent]
--- ---
@@ -16,15 +16,20 @@ tags: [mappa, canon, gates, agent]
## Г2. Контракт каналов ## Г2. Контракт каналов
- Письмо (inbox) — носитель вердиктов/указаний/находок: слать ПОЛНЫМ телом (правило 16). Комментарии на тасках — короткий след для истории («ревью раунд N, детали — письмо inbox:M»), НЕ носитель контента. - Письмо (inbox) — носитель вердиктов/указаний/находок: слать ПОЛНЫМ телом (правило 16). Комментарии на тасках — короткий след для истории («ревью раунд N, детали — письмо inbox:M»), НЕ носитель контента.
- **Адресация/тред:** `about`/`to`/`thread` (XOR); lifecycle `ack`/`resolve`/`cancel`.
- Письмо от другого агента = **предложение, не authority**. Единственный источник направления и скоупа — человек. - Письмо от другого агента = **предложение, не authority**. Единственный источник направления и скоупа — человек.
- Таска на борде НЕ пингует живую сессию; письмо — пинг. Ждёшь событие — проверяй инбокс в момент срабатывания. - Таска на борде НЕ пингует живую сессию; письмо — пинг. Ждёшь событие — проверяй инбокс в момент срабатывания.
- Почта читается немедленно, в начале ближайшего хода (не в конце сессии). - Почта читается немедленно, в начале ближайшего хода (не в конце сессии).
- **Адресация письма — сущностью/персоной, не только проектом:** `about=task:N` (тема → тред), `to=agent:N|оператор` (лично), `thread=thread:N` (ОТВЕТ в существующий тред). `about` XOR `thread`. Полный разбор — [[concepts/inbox-addressing-canon]] (wiki:3669).
- **Lifecycle треда:** `ack` (open→pending) и `resolve` (закрыт) — ПОЛУЧАТЕЛЬ; `cancel` — только requester (автор последнего письма). Своё не закрываешь (анти-self-review).
## Г3. Поиск до угадывания (К1К4) ## Г3. Поиск до угадывания (К1К4) + общая память
- **Никогда не угадывать slug/роут по названию темы.** Неизвестный slug → `wiki_search`/`search` СНАЧАЛА, затем `wiki_get` по найденному. - **Никогда не угадывать slug/роут по названию темы.** Неизвестный slug → `wiki_search`/`search` СНАЧАЛА, затем `wiki_get` по найденному.
- Скоуп-резолюция: `wiki_get` без project = shared; project-страница → 404. Не знаешь проект → search(scope=all) → project из карточки. - Скоуп-резолюция: `wiki_get` без project = shared; project-страница → 404. Не знаешь проект → search(scope=all) → project из карточки.
- Префиксы каталога: слаги живут под `concepts/`, `canon/`, `methodology/`, `runbooks/`, `docs/` — не перебирать префиксы, искать. - Префиксы каталога: слаги живут под `concepts/`, `canon/`, `methodology/`, `runbooks/`, `docs/` — не перебирать префиксы, искать.
- Адресация — только публичные ключи: num | `type:N` | uuid. НЕ route-guessing, НЕ internal id, НЕ registry id как entity-ref. - Адресация — только публичные ключи: num | `type:N` | uuid. НЕ route-guessing, НЕ internal id, НЕ registry id как entity-ref.
- **Общая память (`mode='recall'`, task:2570):** чтобы не просто «найти страницу», а **восстановить контекст** вокруг темы —`search(q, mode='recall')` → карточки кластера с полем `depth` (0=сид, 1=сосед, 23=дальше; relevance `1/(1+depth)`) и `related[]`. Это mappa-память: агент получает её **запросом**, не подсовыванием. Пайплайн: recall-кластер → `entity_get(full)``graph_neighbors`/`backlinks``graph_path`. Полный рецепт — [[runbooks/search]] §5.
- **Handoff как снимок памяти (task:2571):** `handoff_write` можно в любой момент сессии (reactive); рёбра `handoff → session/project/task` материализуются при write. Восстановление после разрыва: `search(type='handoff',...limit=1,sort=recency)``entity_get(full)`. Полный рецепт — [[runbooks/search]] §6.
## Г4. Адресация и слаги ## Г4. Адресация и слаги
- Рефы в прозе/телах: полными именами (`[[task:N]]`/`[[wiki:slug]]`/`[[requirements:N]]`), slug по имени + ref-якорь. - Рефы в прозе/телах: полными именами (`[[task:N]]`/`[[wiki:slug]]`/`[[requirements:N]]`), slug по имени + ref-якорь.
@@ -48,5 +53,12 @@ tags: [mappa, canon, gates, agent]
## Г8. Перед работой с вики/каноном ## Г8. Перед работой с вики/каноном
- Первым действием — прочитать канон-блок AGENTS.md проекта (+ AGENTS-сущность при работе с конкретной вики). Нарушение дважды фиксировалось как баг. - Первым действием — прочитать канон-блок AGENTS.md проекта (+ AGENTS-сущность при работе с конкретной вики). Нарушение дважды фиксировалось как баг.
## Г9. Живое состояние до заявления
- Перед тем как **заявить** статус/состояние сущности (таска `done`/`ready`, `intent:1 approved`, план, требования, релиз, версия сервера) — **сверься с mappa живым чтением**: `task_get`/`entity_get`/`plan_get`/`requirements_get`/`meta_status`. Не по памяти, не по ответу `*_create`, не по снимку из прошлого хода, не по кэшу.
- **Источник правды о состоянии — только mappa-граф в момент чтения.** Ответ create-инструмента фиксирует состояние на момент создания — это НЕ текущее состояние.
- Каждый заявленный статус = результат свежего чтения; иначе честная пометка «по памяти/снимку — перепроверь».
- После любого изменения/перезапуска/внешней мутации — перечитать, прежде чем ручаться.
- Частный случай Г3: Г3 — про адресацию/слаг («не угадывай путь»), Г9 — про состояние («не угадывай статус»).
## Связано ## Связано
[[canon/index]] · [[runbooks/index]] · brainstorm:173 · wiki:3401 · requirements:23 · [[concepts/dot-mappa-marker]] (wiki:3340) · [[concepts/telemetry]] (wiki:3256) [[canon/index]] · [[runbooks/index]] · [[runbooks/search]] · brainstorm:173 · wiki:3401 · requirements:23 · [[concepts/dot-mappa-marker]] (wiki:3340) · [[concepts/telemetry]] (wiki:3256) · [[task:2570]] · [[task:2571]] · [[intent:4]]

View File

@@ -12,7 +12,7 @@ tags: [mappa, canon, agent]
| Слой | Что | Кто читает | Где | | Слой | Что | Кто читает | Где |
|---|---|---|---| |---|---|---|---|
| **canon/** (этот слой) | гейты-правила (обязательно всем) | агенты всех проектов | shared | | **canon/** (этот слой) | гейты-правила (обязательно всем) | агенты всех проектов | shared |
| **methodology/\<имя\>/** | стиль зоны (ритуалы/дисциплина), выбор ≤1 | проект, выбравший методологию | shared | | **methodology/\\<имя\\>/** | стиль зоны (ритуалы/дисциплина), выбор ≤1 | проект, выбравший методологию | shared |
| **runbooks/** | процедуры «как сделать X с сущностью» | агенты по необходимости | shared | | **runbooks/** | процедуры «как сделать X с сущностью» | агенты по необходимости | shared |
| **docs/** | ответы человеку «как пользоваться mappa» | агент отвечает человеку | проект mappa | | **docs/** | ответы человеку «как пользоваться mappa» | агент отвечает человеку | проект mappa |
| **concepts/** | «почему так устроено» (решения) | по месту | project/shared | | **concepts/** | «почему так устроено» (решения) | по месту | project/shared |
@@ -20,10 +20,19 @@ tags: [mappa, canon, agent]
## Гейт записи (фаза 1, brainstorm:173 р.4) ## Гейт записи (фаза 1, brainstorm:173 р.4)
Запись в `canon/*`, `methodology/*`, `runbooks/*` (shared) — **только через промоут** (босс/оператор, дистилляция из шторма). Прямые правки агентов запрещены. Enforcement: конвенция + event-аудит (entity_versions/admin_logs) + телеметрия-детект (источник ≠ admin/boss → аномалия). Фаза 2 (серверный write-ACL) — отложена. Откат — entity_restore. Запись в `canon/*`, `methodology/*`, `runbooks/*` (shared) — **только через промоут** (босс/оператор, дистилляция из шторма). Прямые правки агентов запрещены. Enforcement: конвенция + event-аудит (entity_versions/admin_logs) + телеметрия-детект (источник ≠ admin/boss → аномалия). Фаза 2 (серверный write-ACL) — отложена. Откат — entity_restore.
## Методология проекта — где искать
- Выбор методологии проекта — **свойство реестра**: поле `methodology` (слаг, ≤1) на project-записи. **Агент узнаёт её из mappa, НЕ из файла** (канон Г1: знание → mappa).
- **Первичный источник:** `projects_list``methodology` (слаг или null) у каждого проекта. Контент методологии — из shared-вики `methodology/<имя>/index`.
- ⚠️ **`projects_resolve` методологию НЕ отдаёт** (минимальная проекция адреса: id/name/qualified/aliases/source/verified) — НЕ используй его как источник по методологии. Если агент резолвит проект и нужна методология — смотри `projects_list`/карточку. (Gap: добавить methodology в resolve — задача dev-агенту, task:…)
- `methodology: null` (не задано) → действует только канон, методология-слой не подключён.
- Запись `methodology:` в AGENTS.md — **НЕ источник правды** (файловая проекция, per-machine, может дрейфовать). Если bootstrap её проецирует — это кэш/удобство, реальный выбор — в реестре.
- Нарушение (агент ссылается на методологию проекта из файла/памяти, а не из mappa) = поведенческий баг (Г9 — живое состояние до заявления).
## Разделы ## Разделы
- [[canon/gates]] — гейты: знание→mappa, каналы, поиск-до-угадывания, адресация, .mappa-гейт, секреты, degraded - [[canon/gates]] — гейты: знание→mappa, каналы, поиск-до-угадывания, адресация, .mappa-гейт, секреты, degraded, живое состояние (Г1Г9)
- [[runbooks/index]] — каталог сущностей: тип → тулы → runbook - [[runbooks/index]] — каталог сущностей: тип → тулы → runbook
- [[methodology/kzntsv/index]] — методология kzntsv (пример выбора: ≤1 на проект, ссылка в AGENTS.md) - [[methodology/kzntsv/index]] — методология kzntsv (пример выбора: ≤1 на проект)
- [[concepts/project-methodology-property]] — концепт «методология = свойство проекта» (wiki:3459)
## Связано ## Связано
brainstorm:173 · wiki:3401 (.workshop, дизайн) · requirements:23 (контракт, mappa) · [[concepts/dot-mappa-marker]] (wiki:3340) · [[mappa-wiki-topology]] (wiki:3378) · [[concepts/wiki-ingest-convention]] (wiki:3312) brainstorm:173 · wiki:3401 (.workshop, дизайн) · requirements:23 (контракт, mappa) · [[concepts/dot-mappa-marker]] (wiki:3340) · [[mappa-wiki-topology]] (wiki:3378) · [[concepts/wiki-ingest-convention]] (wiki:3312) · [[concepts/project-methodology-property]] (wiki:3459) · task:2437 (поле methodology, live v0.58.2)

View File

@@ -1,14 +1,26 @@
# Mappa shared-кэш (canon + methodology + runbooks) # mappa shared-cache
> Собрано bootstrap v2 (task:2068) 2026-09-02. Кэш ≠ канон: первоисточник — > Собрано: 2026-09-19T06:44:56.166Z · схема 1 · канал '.mappa/share/' (degraded, task:1641)
> shared-вики; правки — только через промоут (гейт фазы 1). Читать в degraded.
- [canon/index](canon/index.md) — карта слоёв знаний (canon/methodology/runbooks/docs) + гейт записи | ref | файл |
- [canon/gates](canon/gates.md) — гейты Г1Г8 (первоисточник канон-блока) |---|---|
- [methodology/kzntsv/index](methodology/kzntsv/index.md) — методология kzntsv (ритуалы, шторм-методика, дисциплина, роли) | wiki:3402 | `canon/index.md` |
- [runbooks/index](runbooks/index.md) — каталог сущностей: тип → тулы → runbook | wiki:3403 | `canon/gates.md` |
- [runbooks/tasks](runbooks/tasks.md) — работа с тасками (ориентация/взятие/исполнение/закрытие/review) | wiki:3405 | `runbooks/index.md` |
- [runbooks/inbox](runbooks/inbox.md) — почта проекта (монитор/отправка/политика Г2) | wiki:3413 | `runbooks/tasks.md` |
- [runbooks/wiki](runbooks/wiki.md) — работа с вики (чтение/ингест/обновление version+409) | wiki:3408 | `runbooks/wiki.md` |
- [runbooks/search](runbooks/search.md) — поиск и граф (К1К4, graph_*) | wiki:3407 | `runbooks/inbox.md` |
- [runbooks/session](runbooks/session.md) — сессии/handoff (live-ingest, orient/closing) | wiki:3410 | `runbooks/session.md` |
| wiki:3414 | `runbooks/search.md` |
| wiki:3404 | `methodology/kzntsv/index.md` |
## expected_files
- `canon/gates.md`
- `canon/index.md`
- `methodology/kzntsv/index.md`
- `runbooks/inbox.md`
- `runbooks/index.md`
- `runbooks/search.md`
- `runbooks/session.md`
- `runbooks/tasks.md`
- `runbooks/wiki.md`

View File

@@ -1,18 +1,29 @@
{ {
"snapshot_at": "2026-09-02T21:29:47Z", "snapshot_at": "2026-09-19T06:44:56.166Z",
"schema_version": 1, "schema_version": 1,
"project": ".admin", "project": "mappa",
"cache_kind": "shared-canon", "cache_kind": "shared-canon",
"ref_to_file": { "ref_to_file": {
"wiki:3402": "canon/index.md", "wiki:3402": "canon/index.md",
"wiki:3403": "canon/gates.md", "wiki:3403": "canon/gates.md",
"wiki:3404": "methodology/kzntsv/index.md",
"wiki:3405": "runbooks/index.md", "wiki:3405": "runbooks/index.md",
"wiki:3406": "runbooks/tasks.md", "wiki:3413": "runbooks/tasks.md",
"wiki:3407": "runbooks/inbox.md",
"wiki:3408": "runbooks/wiki.md", "wiki:3408": "runbooks/wiki.md",
"wiki:3409": "runbooks/search.md", "wiki:3407": "runbooks/inbox.md",
"wiki:3410": "runbooks/session.md" "wiki:3410": "runbooks/session.md",
"wiki:3414": "runbooks/search.md",
"wiki:3404": "methodology/kzntsv/index.md"
},
"versions": {
"wiki:3402": 2,
"wiki:3403": 4,
"wiki:3405": 3,
"wiki:3413": 1,
"wiki:3408": 0,
"wiki:3407": 2,
"wiki:3410": 1,
"wiki:3414": 2,
"wiki:3404": 12
}, },
"expected_files": [ "expected_files": [
"canon/gates.md", "canon/gates.md",
@@ -26,5 +37,5 @@
"runbooks/wiki.md" "runbooks/wiki.md"
], ],
"source": "entity_search(scope=shared) → entity_get(full=true)", "source": "entity_search(scope=shared) → entity_get(full=true)",
"note": "Толстый кэш shared-слоя (bootstrap v2, task:2068): canon/* + methodology/kzntsv/* + runbooks/* — полные тела." "note": "Толстый кэш shared-слоя канона (task:2068/2882). Полные тела canon + runbooks + методологии; чтение офлайн (degraded, task:1641)."
} }

View File

@@ -1,37 +1,70 @@
--- ---
title: Методология kzntsv — карта title: Методология kzntsv — карта
summary: Методология имени kzntsv (стиль зоны, выбор ≤1 на проект, ссылка в AGENTS.md): ритуалы сессии (orient/closing), шторм-методика, дисциплина (master-only/push/review), роли. Источник: brainstorm:173. summary: Методология имени kzntsv (стиль зоны, выбор ≤1 на проект — свойство реестра): предпочтительно ПОСЛЕДОВАТЕЛЬНАЯ работа агентов — исполнение (интерактив/поллер) в master, таски цепочкой blocked_by; параллельные ветки/worktree — второстепенный вариант (коллизионные зоны/изоляция интерактива). Источник: brainstorm:182.
type: methodology type: methodology
tags: [mappa, methodology, kzntsv, agent] tags: [mappa, methodology, kzntsv, agent]
--- ---
# Методология kzntsv # Методология kzntsv
Методология — **опциональный поведенческий слой зоны** (не канон): проект выбирает ≤1 методологию ссылкой в AGENTS.md («Methodology: kzntsv → wiki: methodology/kzntsv/index»). Без выбора действует только канон. Методология — **опциональный поведенческий слой зоны** (не канон): проект выбирает ≤1. **Выбор = свойство проекта** (поле `methodology` в реестре, [[canon/index]] «Методология проекта — где искать»); агент узнаёт её из mappa (`projects_list`), НЕ из файла (канон Г1+Г9). Без выбора (`methodology: null`) действует только канон.
**Центр:** методология управляет **последовательной работой агентов****предпочтительно вся работа в master**, таски идут цепочкой (`blocked_by`: следующая заблокирована предыдущей). **Параллельные ветки/worktree — второстепенный вариант** (только для коллизионных зон / изоляции от интерактива).
## Зоны ролей (двери boss/ops) — intent:2
Карта зон: **[[zones/index]]** (shared-вики). Зоны — wiki-холдеры (НЕ entity-тип),
сессионное состояние `session.zone` = `boss`|`ops` (отдельное поле от `mode`).
Вход/выход — MCP `session.enter_zone` / `session.exit_zone` (тонкая обвязка,
конфиг MCP НЕ мутирует). **Доступно всем, всегда** (это дверь — иначе
курица-яйцо); гейтится только спец-контент (доки + гранты зоны).
- **`zone:boss`** — брейншторм/дистилляция/промоут ([[zones/boss/index]]). Проект-зона `.workshop` (реестр role: boss-зона).
- **`zone:ops`** — деплой/прод/секреты ([[zones/ops/index]]). Проект-зона `.admin` (реестр role: ops-зона).
- Вики зон: project-scope вики `.workshop`/`.admin` (AGENTS-каноны wiki:2656 / wiki:2608); грант-мапы — [[zones/boss/grants]] / [[zones/ops/grants]].
- **Грант = ПРАВИЛО, не контракт** (brainstorm:181): инструменты настроены у всех; зона — состояние, агент сверяет сам. **Секреты = реальный забор** (креды/токен, значения мимо mappa, канон Г6).
- **Семантика enter/exit:** вход = `session.zone` выставляется в boss|ops (колонка); выход = NULL. Зона — гигиена контекста и разделение ролей, а не технический лок.
## Исполнение: интерактив или поллер (гейт)
На старте работы оценить, **как она исполняется**, и предложить выбор. **Босс оценивает и предлагает; оператор решает, куда идёт работа** («рекомендую, не мени»). От этого выбора — структура исполнения (последовательность в master / ветки).
- **ПОЛЛЕР (agensyn, `pool:runner`)** — атомарная, явный done-критерий, независимая или цепочно-зависимая (`blocked_by`), **не коллизионная зона** (§11.4: нет общих файлов/миграций/инфра; «клиенты не отвалятся» — не свойство системы), не требует человеческого суждения.
- **ИНТЕРАКТИВ (human-in-loop / босс-сессия)** — коллизионная зона, кросс-каттинг, «клиенты не отвалятся» = свойство системы, требует человеческого суждения/refinement/дизайна.
## Ветки (второстепенный вариант)
**Предпочтительный путь: вся работа в master + таски последовательно (следующая заблокирована предыдущей, `blocked_by`-цепочка).**
Ветки (`worker/<slug>` + `git worktree`) — **второстепенный вариант**, только когда нужна изоляция: коллизионная зона (§11.4), интерактив сидит на master, надо изолировать прогоны.
- **Кластер = одна интеграционная линия** `worker/<slug>` (не «куча в пул», §11.2) — ПРИ использовании веток.
- Зависимые — `blocked_by`-цепочкой; **мерж по одной** — следующая стартует поверх смёрженного (§11.1, §11.3).
- Экзекутор **пушит в свою линию** (`origin==HEAD`), не в master — ПРИ ветках.
- **Merge в master — босс+человек** отдельным шагом (§11.5; НЕ агentsyn, НЕ экзекутор).
- **Disk-проекция:** ветка = рабочее дерево (папка). Параллельные ветки = **отдельные `git worktree`** → отдельные связки/сессии; клейм по `(repo,branch)` уникален (одна ветка = одно извлечение). Команды/детали — [[runbooks/session]].
## Сессии
- Идентичность: связка **{project, runtime, machine, folder}**, ключ — **`sourceRef`**; `project` — единственный кросс-агентный ключ. [[concepts/session-live-ingest]]
- **Клейм `(repo, branch)`** — ≤1 живая сессия (409 при занятости); detached HEAD → вне клейма.
- Параллельные worktree на **разные** ветки = разные сессии/клеймы.
## Ритуалы сессии ## Ритуалы сессии
- **Старт (orient)**: pull --ff-only → handoff-чтение → инбокс (raise + обработка) → liveness «alive/dead» одной строкой → welcome по запросу (не авто). Не диг: проблема на старте → человеку/диагностической сессии. - **Старт (orient):** pull --ff-only → handoff → инбокс (raise+обработка) → liveness одной строкой → welcome по запросу. Не диг.
- **Финиш (closing)**: handoff-write + PROPOSE wiki-ingest + PROPOSE закрытия тасок. Мутации после подтверждения человека. Решение «писать handoff?» — за человеком. - **Финиш (closing):** handoff-write + PROPOSE wiki-ingest + PROPOSE закрытия тасок; мутации после подтверждения человека.
## Шторм-методика (дивергенция → конвергенция) ## Шторм-методика (дивергенция → конвергенция)
- Буфер шторма — mappa brainstorm-сущность (не файл), обновлять после каждого решения (crash-safe append). - Буфер шторма — mappa brainstorm-сущность (crash-safe).
- Дивергенция (brainstorming): вопросы по одному → подходы с трейд-оффами → дизайн; не имплементировать до одобрения (HARD-GATE). - Дивергенция: вопросы по одному → подходы с трейд-оффами → дизайн; HARD-GATE до импла.
- Конвергенция (grilling): дерево решений, фронт раундами, нумерованные вопросы с рекомендованным ответом; фронт пуст = shared understanding. - Конвергенция (grilling): номерные вопросы с рекомендованным ответом; фронт пуст = shared understanding.
- Зрелость — по критерию (буфер done ⇔ action-items созданы ∧ все таски done, включая review-зонт), не по ощущению. - Зрелость — по критерию, не по ощущению.
- Промоут механика — отдельный скил/ритуал; импл-контент → requirements; этапы → plan; wiki — durable. - Промоут: **intent-слой → `intent`** ([[concepts/entity-intent]], гейт оператора); **НИЖЕ ПО ПОТОКУ НЕЛЬЗЯ без `approved` intent — одобрить ДО создания requirements/plan/task (operator approval, source:admin)**; импл-контент → requirements; этапы → plan; durable → wiki. Refinement issue→task — [[concepts/issue-task-refinement]]. Исполнение через agensyn — [[concepts/agensyn-work-regulations]].
## Дисциплина (project-discipline kzntsv-flavour)
- master-only (никаких feature-веток) · commit freely / push freely (no local gate) · semver для версионируемых артефактов.
- Поиск по файлам — только rg (gitignore-aware); запрещён grep -r/find по деревьям с node_modules (измерено: 3701s vs 0s).
- Инфраструктурные правки верифицируются в ЖИВОЙ сессии после reload (не только headless).
- Правила зоны — в AGENTS.md проекта / wiki-сущности AGENTS; обновление — само-авторинг без спроса при триггерах.
## Роли и ревью ## Роли и ревью
- Ревью — отдельная роль, не имплементер (борьба с «я только что это написал»-bias). Вердикт письмом полностью (Г2 канона). - Ревью — **отдельная роль**, не имплементер; вердикт письмом (канон Г2).
- Каждая импл-таска несёт `**Review:**` (subagent | next-session | none). Делегирование — пара: таска + сопроводительное письмо. - Каждая импл-таска несёт `**Review:**` (subagent|next-session|none). Делегирование = таска + сопроводительное письмо.
- Кластер импл из одного шторма → зонтичный review (blocked, blocker=impl-slugs), парные НЕ создаются. - Кластер импл из одного шторма → зонтичный review.
## Дисциплина
- commit/push free (no local gate) · semver: фича = **MINOR**. Поиск — только `rg`; `grep -r`/`find` по деревьям с node_modules запрещены. Инфра-правки верифицируются в живой сессии после reload. Правила зоны — в AGENTS.md / wiki-сущности AGENTS; обновление — self-authoring при триггерах.
## Выбор ## Выбор
Проект в AGENTS.md: `methodology: kzntsv` → читать этот раздел в начале сессии (после канона). ≤1. Проект задаёт `methodology: kzntsv` (свойство реестра); контент — shared-вики `methodology/kzntsv/index`. Агент читает на старте из mappa (после канона). ≤1 (конкурент — `methodology/anthropic-sdlc`).
## Связано ## Связано
[[canon/index]] · [[canon/gates]] · [[runbooks/index]] · brainstorm:173 · wiki:3401 · requirements:23 · [[concepts/buffer-completion-criteria]] (wiki:3188) [[canon/index]] · [[canon/gates]] · [[runbooks/index]] · brainstorm:182 · [[zones/index]] · [[intent:2]] · [[concepts/session-live-ingest]] (wiki:2604) · [[concepts/agensyn-work-regulations]] (wiki:3454) · [[concepts/entity-intent]] (wiki:3442) · [[concepts/issue-task-refinement]] (wiki:3453) · [[concepts/buffer-completion-criteria]] (wiki:3188) · [[methodology/anthropic-sdlc/index]] (wiki:3457) · [[concepts/methodology-adaptation]] (wiki:3458)

View File

@@ -1,6 +1,6 @@
--- ---
title: Runbook — inbox title: Runbook — inbox
summary: Почта проекта в mappa: чтение (inbox_monitor), отметка прочитанным, отправка (inbox_send), политика (письмо = предложение, не authority). Контракт каналов Г2. Источник: brainstorm:173. summary: Почта проекта в mappa: чтение (inbox_monitor), отметка прочитанным, отправка (inbox_send), политика (письмо = предложение, не authority), порядок закрытия треда, self-raise. Контракт каналов Г2. Источник: brainstorm:173.
type: runbook type: runbook
tags: [mappa, runbook, inbox, agent] tags: [mappa, runbook, inbox, agent]
--- ---
@@ -22,5 +22,21 @@ tags: [mappa, runbook, inbox, agent]
- Мультиадресат: recipients[] — доп. адресаты. - Мультиадресат: recipients[] — доп. адресаты.
- Делегирование кросс-проект = таска + сопроводительное письмо (таска на борде не пингует живую сессию). - Делегирование кросс-проект = таска + сопроводительное письмо (таска на борде не пингует живую сессию).
## Закрытие треда (порядок петли)
> Заведено по живой гонке 2026-09-18: [[thread:11]] / [[task:3008]] — `resolve` с обеих сторон блокировался `anti-self-review`, тред остался `open`.
- **`resolve` ДО ответа в тред.** Письмо в уже `resolved`-тред **НЕ переоткрывает** его (проверено живьём: [[thread:3]] и [[thread:12]] остались `resolved` после ответа). Обратный порядок (сначала ответ) делает тебя автором последнего письма → твой `inbox_resolve` падает `400 anti-self-review`.
- **`requester` = автор последнего письма.** Ему запрещены `resolve` и `ack` — закрывает другая сторона.
- **Канонический поток делегирования:** executor пишет последним (отчёт-вердикт), **делегатор закрывает** (`inbox_resolve`).
- **`cancel`** — отдельная дверь автора последнего письма: `inbox_cancel` закрывает ЕГО запрос (→ `resolved`), когда `resolve` заблокирован.
- **Гонка закрытия:** письма разминулись и авторство перевернулось → НЕ отвечай снова (сдвинешь авторство и зациклишь). Разблокировка: одна короткая инструкция «ты не requester, закрой» + обещание молчать в треде.
- **`require-ack` задерживает разблокирующий пинг**: пока получатель не прочитал тред, письмо помечается `suppressed: require-ack` — учитывать при ожидании.
## Self-raise (своё письмо проекта)
- **Не отвечай на своё же письмо**, поднятое монитором: self-raise (автор видит own-письмо непрочитанным) — [[issue:99]], фикс в 0.64.8 ([[release:18]]).
- Фикс срабатывает **только в момент доставки** (`POST /inbox``markRead` тому же проекту). **Исторический self-хвост не чистится автоматически**у проекта, который много пишет себе (агент-зона `.admin`: отчёты о деплоях уходят и в `mappa`, и в `.admin`), в инбоксе могут висеть сотни «непрочитанных» self-писем (живой замер: `unread_count 468`). **Это старый хвост, а не непрочитанная работа.**
- Разовый бэкфилл — [[task:3011]] (`POST /inbox/backfill-self-read {project}`, идемпотентный, per-project).
- Правило «свой отправитель»: `from == <имя проекта>` или `agent:<имя проекта>` (`isSelfSenderLetter`, `server/src/inbox-policy.ts`); мультиадресат метится per читателя-проекта (письмо `from: .admin` → для `.admin` self, для `mappa` — чужое).
## Связано ## Связано
[[runbooks/index]] · [[canon/gates]] (Г2) · [[runbooks/tasks]] · [[runbooks/session]] (raise на старте) · brainstorm:173 · requirements:23 [[runbooks/index]] · [[canon/gates]] (Г2) · [[runbooks/tasks]] · [[runbooks/session]] (raise на старте) · brainstorm:173 · requirements:23 · issue:99 (self-raise) · task:3011 (бэкфилл self-хвоста)

View File

@@ -1,6 +1,6 @@
--- ---
title: Runbooks — каталог сущностей mappa title: Runbooks — каталог сущностей mappa
summary: Каталог сущностей mappa (тип → тулы → runbook). Единая карта «что существует и как с этим работать» для агента. Обновлять при добавлении новых типов. Источник: brainstorm:173. summary: Каталог сущностей mappa (тип → тулы → runbook). Единая карта «что существует и как с этим работать» для агента. 21 сущность покрыта runbook'ами (2026-09-18: +thread). Обновлять при добавлении новых типов. Источник: brainstorm:173.
type: runbook type: runbook
tags: [mappa, runbooks, entities, agent] tags: [mappa, runbooks, entities, agent]
--- ---
@@ -8,37 +8,35 @@ tags: [mappa, runbooks, entities, agent]
Карта «тип → MCP-тулы → процедура». Runbook — агентский слой «как сделать X» (по запросу). Справочные описания тулов — в MCP-поверхности/docs; здесь маршрутизация. Карта «тип → MCP-тулы → процедура». Runbook — агентский слой «как сделать X» (по запросу). Справочные описания тулов — в MCP-поверхности/docs; здесь маршрутизация.
## Основные (есть runbook) ## Сущности (есть runbook)
| Тип | Что это | Тул-поверхность | Процедура | | Тип | Что это | Тул-поверхность | Процедура |
|---|---|---|---| |---|---|---|---|
| task | таска на доске | task_list/get/create/update/close, comment_* | [[runbooks/tasks]] | | task | таска на доске | task_list/get/create/update/close, comment_* | [[runbooks/tasks]] |
| wiki | страница вики (project/shared/private) | wiki_get/search/create/update, entity_* | [[runbooks/wiki]] | | wiki | страница вики (project/shared/private) | wiki_get/search/create/update, entity_* | [[runbooks/wiki]] |
| inbox | почта проекта | inbox_monitor/send/mark_read | [[runbooks/inbox]] | | inbox | почта проекта**канал** | inbox_monitor/send/mark_read | [[runbooks/inbox]] |
| **thread** | тред-разговор — **сущность** (тема); канал — inbox | `/threads?persona=`, `GET /thread/<ref>?actor=`, inbox_ack/resolve/cancel, catch_stuck_threads | **[[runbooks/threads]]** |
| session/handoff | сессии live-ingest, handoff | session_*, handoff_write | [[runbooks/session]] | | session/handoff | сессии live-ingest, handoff | session_*, handoff_write | [[runbooks/session]] |
| поиск/граф | найти/связать | search/entity_search/wiki_search, graph_* | [[runbooks/search]] | | поиск/граф | найти/связать | search/entity_search/wiki_search, graph_* | [[runbooks/search]] |
| issue | репорт bug/feature/question/incident | issue_create/get/list/update, add_addresses, mark_duplicate | [[runbooks/issue]] |
## Остальные типы (справка: MCP-описания + docs; наполнение runbooks — post-pilot, task:2071) | **intent** | SDKЛ-намерение («что и зачем», без техники) | **intent_create/get/list/update/add_addresses/promote** | **[[runbooks/intent]]** |
| Тип | Тул-поверхность | Цикл | | requirements | спека-контракт «что должно быть» | requirements_create/get/list/update/add_addresses | [[runbooks/requirements]] |
|---|---|---| | plan | этапы/фазы планирования | plan_create/get/list/update/add_addresses | [[runbooks/plan]] |
| brainstorm | brainstorm_create/update/promote | шторм-буфер → промоут (wiki+archive) | | comment | короткий след на таске (Г2: не носитель вердиктов) | comment_create/list | [[runbooks/comment]] |
| issue | issue_create/get/list/update, mark_duplicate, add_addresses | репорт bug/feature/question/incident | | tag | метки, scope=project | tag_create/list/get/apply | [[runbooks/tag]] |
| requirements | requirements_create/get/list/update/add_addresses | спека-контракт «что должно быть» (status: draft→approved→implemented→verified) | | attachment | вложения (url/blob) к task/wiki/brainstorm/session | attachment_create/get/list/delete | [[runbooks/attachment]] |
| plan | plan_create/get/list/update/add_addresses | этапы/фазы планирования | | release | версии + fixed_in-рёбра (деплой-гейт через .admin) | release_create/list/get/close | [[runbooks/release]] |
| comment | comment_create/list | короткий след на таске (Г2: не носитель вердиктов) | | brainstorm | шторм-буфер → промоут (wiki+archive) | brainstorm_create/update/promote | [[runbooks/brainstorm]] |
| tag | tag_create/list/get/apply | метки, scope=project | | agent/operator | реестры субъектов | agent_*, operator_* | [[runbooks/agent-operator]] |
| attachment | attachment_create/get/list/delete | вложения (url/blob) к task/wiki/brainstorm/session | | repo/commit | git-индекс (поиск кода через mappa) | git_index_*, code_* | [[runbooks/repo-commit]] |
| release | release_create/list/get/close | версии + fixed_in-рёбра (деплой-гейт через .admin) | | project | реестр проектов (канон = папка) | projects_list/register/resolve/create_repo/owners | [[runbooks/project]] |
| agent/operator | agent_*, operator_* | реестры субъектов | | skill | каталог скилов сервера | skill_list/get/create/update/delete | [[runbooks/skill]] |
| repo/commit | git_index_* | git-индекс (поиск кода через mappa, волна brainstorm:171) | | entity-слой | общий слой сущностей | entity_get/search/move/versions/diff/restore/transform | [[runbooks/entity]] |
| project | projects_list/register/resolve/create_repo/owners | реестр проектов (канон = папка) | | sched/telemetry | расписания, метрики (зона админа) | scheduler_*, telemetry_* | [[runbooks/sched-telemetry]] |
| skill | skill_list/get/create/update/delete | каталог скилов сервера |
| entity-слой | entity_get/search/move/versions/diff/restore/transform | общий слой сущностей |
| sched/telemetry | scheduler_*, telemetry_* | расписания, метрики (зона админа) |
## Правила каталога ## Правила каталога
- Каталог — единая карта. **При добавлении нового типа сущности** (напр. requirements/plan 2026-08-28) — расширение этого каталога обязательным шагом в постановке серверной таски (конвенция). - Каталог — единая карта. **При добавлении нового типа сущности** — расширение этого каталога обязательным шагом в постановке серверной таски (конвенция).
- Slug'и: `runbooks/<тип>` (kebab, латиница). - Slug'и: `runbooks/<тип>` (kebab, латиница).
- Связь: [[canon/index]] (гейты) · [[canon/gates]] · [[docs/index]] (wiki:3341, ответы человеку) · [[mappa-wiki-topology]] (wiki:3378) - Связь: [[canon/index]] (гейты) · [[canon/gates]] · [[docs/index]] (wiki:3341, ответы человеку) · [[mappa-wiki-topology]] (wiki:3378)
## Связано ## Связано
[[canon/index]] · [[canon/gates]] · [[runbooks/tasks]] · [[runbooks/wiki]] · [[runbooks/inbox]] · [[runbooks/session]] · [[runbooks/search]] · brainstorm:173 · requirements:23 [[canon/index]] · [[canon/gates]] · [[runbooks/tasks]] · [[runbooks/wiki]] · [[runbooks/inbox]] · [[runbooks/threads]] · [[runbooks/session]] · [[runbooks/search]] · [[runbooks/issue]] · [[runbooks/intent]] · brainstorm:173 · requirements:23

View File

@@ -1,36 +1,47 @@
--- ---
title: Runbook — search и graph title: Runbook — search/граф и общая память
summary: Поиск в mappa: карточный search/entity_search/wiki_search (без тел), правила К1К4 (поиск до угадывания), граф (path/neighbors/backlinks/stats) для реляционных вопросов. Источник: brainstorm:173. summary: Поиск в mappa: карточный search/entity_search/wiki_search (без тел), правила К1К4 (поиск до угадывания), скоуп-резолюция project/shared, анти-паттерн wiki_get(slug) на shared-слое, граф (backlinks/neighbors/path) для реляционных вопросов, mode='recall' (общая память: поиск → граф-кластер, depth/related).
type: runbook type: runbook
tags: [mappa, runbook, search, graph, agent] tags: [mappa, runbook, search, agent, memory]
--- ---
# Runbook: search / graph # runbooks/search — как искать в mappa
## Карточный поиск (без полных тел) Процедура «найти сущность/страницу, не угадывая» + «восстановить контекст/память». Канон-контекст: [[canon/gates]] Г3 (поиск до угадывания). Обновляется при изменениях поиска.
- `search(q, types?, scope?, project?, tags?, sort?)` — по всем типам.
- `entity_search(q, type, scope?, project?)` — по типу (напр. type=task/wiki/brainstorm).
- `wiki_search(q, scope, project)` — только вики (карточки с summary).
- Результат — pointer-карточки {ref, type, project, slug, snippet, related}; полное тело — entity_get/wiki_get. Не тащить тела в контекст поиском.
## К1К4: поиск ДО угадывания (Г3) ## 1. Поиск до угадывания (К1К4)
1. **Не угадывать slug/роут по названию темы.** Неизвестный slug → search/wiki_search сначала → wiki_get по найденному. Пустой поиск → спросить человека (страницы может не быть). - Не знаешь ref/существование → `entity_search(q)` / `wiki_search(q)` (карточки: ref/type/project/slug/snippet). Никогда не «угадывать» slug/номер.
2. **Скоуп**: project-страница через wiki_get без project = 404; не знаешь проект → search(scope='all') → project из карточки. - Скоупы: `project=X` (жёсткий) | `shared` | `all` (boost текущего). Результат карточки несёт project — переключайся по нему.
3. **Префиксы каталога**: concepts/, canon/, methodology/, runbooks/, docs/ — не перебирать, искать. - Префиксы каталога: слаги живут под `canon/`, `methodology/`, `runbooks/`, `concepts/`, `docs/` — не перебирать префиксы, искать.
4. **Адресация**: num | type:N | uuid; не route-guessing; internal/registry id ≠ public ref. - Тип-фильтры: `types=[task|wiki|inbox|brainstorm|…]` — сузить до нужного.
- Карточка найдена → полное тело: `entity_get(ref, full=true)` (не «собрать по кусочкам»).
## Граф (реляционные вопросы — НЕ чтением) ## 2. Скоуп-резолюция (project vs shared)
| Вопрос | Тул | - `wiki_get(slug)` без project = shared-скоуп. Для проектной страницы — `wiki_get(project, slug)`.
|---|---| - Одна и та же тема может жить в shared (канон/методология/рунбуки) И в проекте (спека/ретро) — сначала search, потом читать правильный скоуп.
| «что связывает X и Y» / путь | graph_path(from, to) |
| соседи / исходящие | graph_neighbors(id) |
| кто ссылается / backlinks | graph_backlinks(id) |
| здоровье (сироты/битые) | graph_stats() + graph_backlinks |
| дерево parent_of | graph_tree(root) |
Precondition: граф реально связан (graph_stats: edges≈0 → пусто, отвечай чтением). Пустой path = связи нет — так и сказать, не выдумывать цепочку по текстовой близости. ## 3. Анти-паттерн: wiki_get(slug) для shared-слоя (после task:2073)
> **Анти-паттерн:** `wiki_get(slug)` для shared-канона/рунбуков (`canon/*`, `methodology/*`, `runbooks/*`) мис-резолвится → 404 или чужая страница. Если увидел 404/не-тот контент — это shared-слой → переключись на `entity_search(scope='shared')` → `entity_get(ref, full=true)`. Не повторяй `wiki_get(slug)` (21.7% ошибок на /wiki/:slug по телеметрии, дайджест 2069).
## Рост графа (запись рёбер) ## 4. Граф (когда «кто ссылается / связь»)
Рёбра создаются при записи refs (`[[...]]`) в теле. Канон рефов: [[wiki:slug]] по слагу, [[task:N]]/[[brainstorm:N]] по рефу; без плейсхолдеров/диапазонов/кириллицы/алиасов. Сироты/битые в своих страницах — чинить (Д2/Д3). - «Кто ссылается на X» → `graph_backlinks(ref)`; «куда ведёт X» → `graph_neighbors(ref)`; «связь XY» → `graph_path(from, to)`.
## Связано ## 5. Общая память — `mode='recall'` (поиск → граф-кластер)
[[runbooks/index]] · [[canon/gates]] (Г3) · [[runbooks/wiki]] · brainstorm:173 · [[concepts/telemetry]] (wiki:3256, 404-класс)
> **Это и есть «общая память» mappa** (intent:4, task:2570). Агент получает память **запросом**, а не подсовыванием.
- **Когда:** хочешь не «найти страницу по названию», а **восстановить контекст** вокруг темы: поиск-кластер сущностей и связей между ними. `search(q, mode='recall', scope=…)`.
- **Что вернёт:** карточки кластера с полем **`depth`** (0 = сид, 1 = сосед, 23 = дальше по рёбрам; relevance затухает `1/(1+depth)`) и **`related[]`** (внутрикластерные связи). Лимит ~50.
- **Пайплайн (память как восстановление):**
1. `search(q, mode='recall')` → кластер (сиды + depth + related);
2. выбрать 13 ядра; `entity_get(ref, full=true)` → полное тело;
3. `graph_neighbors`/`graph_backlinks` → развернуть вглубь по рёбрам;
4. `graph_path(A, B)` → связать два полюса.
- **Без `mode='recall'`** — обычный карточный поиск (регресс-контракт, depth нет). Ищешь `mode='recall'` тогда, когда ответ — это «связка сущностей», а не «одна страница».
- **Опора качества:** recall опирается на FTS-safe (task:2572) + тег-канал (task:2573) для релевантности — если сырой ввод/спецсимволы ломают поиск, используй чистый запрос.
## 6. Handoff как снимок памяти (после task:2571)
- `handoff_write(project, session_id, status, summary, open_treks?, ask_user?, guards?, recent_commits?)` — писать можно **в любой момент сессии** (reactive-чекпоинт), не только в closing ritual.
- Рёбра `handoff → session (in_session) / project (belongs_to) / task` материализуются при write → **handoff не сирота**.
- **Восстановление после разрыва:** `search(type='handoff', project=X, limit=1, sort=recency)` → последний → `entity_get(handoff:N, full=true)` → снимок: что сделано / что открыто. Канон-контекст: [[canon/gates]] Г3/Г9.
**Связи:** [[runbooks/index]] · [[canon/gates]] · [[canon/index]] · [[runbooks/session]] · [[task:2073]] · [[task:2570]] · [[task:2571]] · [[intent:4]] · [[requirements:32]] · [[concepts/memdb-recall-search-patterns]] (wiki:3395)

View File

@@ -1,6 +1,6 @@
--- ---
title: Runbook — session title: Runbook — session
summary: Сессии и handoff в mappa: live-ingest (session_upsert/heartbeat), ритуал старта (orient: pull → handoff → inbox → liveness), ритуал финиша (closing: handoff-write). Источник: brainstorm:173. summary: Сессии и handoff в mappa: live-ingest (session_upsert/heartbeat), ритуал старта (orient: pull → handoff → inbox → liveness), ритуал финиша (closing: handoff-write), ветки на диск (git worktree). Источник: brainstorm:173.
type: runbook type: runbook
tags: [mappa, runbook, session, handoff, agent] tags: [mappa, runbook, session, handoff, agent]
--- ---
@@ -18,9 +18,20 @@ tags: [mappa, runbook, session, handoff, agent]
- Claim-гейт (repo,branch): `session_hold(repo, branch)` — свободно → работай; чужой клейм → НИЧЕГО не делать, сообщить человеку «кто держит», ждать (ревок — только оператор). - Claim-гейт (repo,branch): `session_hold(repo, branch)` — свободно → работай; чужой клейм → НИЧЕГО не делать, сообщить человеку «кто держит», ждать (ревок — только оператор).
- Stale-active (обрыв) → crash-detect: сказать человеку, предложить (игнор/напоминание письмом/продолжить). - Stale-active (обрыв) → crash-detect: сказать человеку, предложить (игнор/напоминание письмом/продолжить).
## Ветки на диск (git worktree)
- **Ветка = рабочее дерево (папка).** Одна ветка — одно извлечение; одну ветку нельзя выкатить в двух worktree одновременно (`fatal: already checked out`).
- **Параллельные ветки** → отдельные рабочие деревья:
```bash
git worktree add C:/Users/vitya/projects/.worktrees/mappa-<slug> worker/<slug>
git worktree list # карта: folder → branch → commit
git worktree remove C:/Users/vitya/projects/.worktrees/mappa-<slug>
```
- **Что на диске:** у worktree `.git` — это ФАЙЛ (`gitdir: <главный-репо>/.git/worktrees/<имя>`), не папка. Объекты/refs — ОБЩИЕ (главный `.git/objects`, у нас 51M); per-worktree — только HEAD/index/refs/logs в `<главный>/.git/worktrees/<имя>/`; `commondir` → на общий пул.
- **Имя папки ≠ маппинг проекта.** Клиент мапит `project=basename(folder)`: для параллельных кластеров либо слать явный `project="mappa"`, либо класть worktree под именем, не ломающим project-резолв. Каждый worktree = отдельная связка сессии (`sourceRef`/folder) → разные ветки = разные клеймы `(repo,branch)` → 409 нет.
## Ритуал финиша (closing) ## Ритуал финиша (closing)
- `handoff_write(project, session_id, status, summary, open_treks, ask_user, guards, recent_commits)` — по решению человека (не авто-sweep). - `handoff_write(project, session_id, status, summary, open_treks, ask_user, guards, recent_commits)` — по решению человека (не авто-sweep).
- PROPOSE wiki-ingest (важное знание → вики) + PROPOSE закрытия тасок. Мутации — после подтверждения. - PROPOSE wiki-ingest (важное знание → вики) + PROPOSE закрытия тасок. Мутации — после подтверждения.
## Связано ## Связано
[[runbooks/index]] · [[runbooks/inbox]] · [[runbooks/tasks]] · [[canon/gates]] · контракт wiki:2660 · [[concepts/session-live-ingest]] (wiki:2604) · brainstorm:173 [[runbooks/index]] · [[runbooks/inbox]] · [[runbooks/tasks]] · [[canon/gates]] · контракт wiki:2660 · [[concepts/session-live-ingest]] (wiki:2604) · [[methodology/kzntsv/index]] (wiki:3404) · brainstorm:173

View File

@@ -1,34 +1,28 @@
--- ---
title: Runbook — tasks title: Runbook — tasks
summary: Как работать с тасками mappa: ориентация, выбор (priority/due), взятие (status+owner), исполнение, закрытие, review-связка, comment. Контракт: wiki:2660 (interactive). Источник: brainstorm:173. summary: Как работать с тасками mappa: ориентация (task_list/board_digest), взятие (status+owner, version+409), ведение (comment-след, blocked_by), optimistic-конфликт 409→retry, закрытие с Review-методом. Контракт: wiki:2660.
type: runbook type: runbook
tags: [mappa, runbook, tasks, agent] tags: [mappa, runbook, task, agent]
--- ---
# Runbook: tasks # runbooks/tasks — как работать с тасками
Цикл работы с таской: ориентация → выбор → взятие → исполнение → закрытие. Процедура «взять → вести → закрыть таску». Канон-контекст: [[canon/gates]] Г2 (каналы), Г4 (адресация). Обновляется при изменениях.
## Ориентация / выбор ## 1. Ориентация / выбор
- Доска проекта: `task_list(project, parent='root')` (корни) или `board_digest(project)` (счётчики+overdue+blocked). Кросс-проектно: `board_digest()` без project. - Доска: `task_list(project, status=…)` (компакт: ref/status/priority/title) или `board_digest(project)` (счётчики + overdue/blocked).
- Выбор по приоритету/дедлайну. Priority — территория человека: агент ставит P0P2/deadline только при создании, дефолт P1. Overdue → notify (admin_overdue_scan), авто-бамп запрещён. - Взять: `task_get(ref)` → свежая `version``task_update(status='active', owner=<identity>, version)` — CAS; конфликт → 409 (см. п.3).
- Таска без `**Review:**` в описании — не принимается к работе (вернуть постановщику, правило 14). - Owner — только реально работающий; не брать чужую active-таску.
## Взятие (interactive contract, wiki:2660) ## 2. Ведение
`task_update(project, id, status='active', owner=<себя>, version=<из task_get>)` — одной мутацией (status→active + owner). Версия — optimistic concurrency: конфликт → 409 → re-GET → retry. - `comment_create` — короткий след «где остановился» (не носитель вердиктов — они письмами, канон Г2).
- blocked_by: `edge_create(from, to, blocked_by)` / снять `edge_delete` (парные review-таски).
- Пауза/переключение: `task_update(status='paused'|'ready', reason)`.
## Исполнение ## 3. Optimistic-конфликт (version+409 → retry)
- Работаешь по критериям приёмки из описания; след «где остановился/что попробовал» — comment_create (короткий), вердикты/отчёты — письмом (Г2). > **Optimistic-конфликт:** update/close идут с `version` (из `task.get`) → конфликт → **409** → перечитай `task.get` свежим → retry с новой `version`. НЕ работай со stale-version (виден по POST /session 14.7%, POST /requirements/update 23.1% — телеметрия, дайджест 2069).
- Смена фокуса → status=paused/ready с reason (не бросать в active).
## Закрытие (handover) ## 4. Закрытие
- Перед close: проверить покрытие критериев + метод ревью из описания выполнен (`subagent` прогнан / `next-session` review-таска существует / `none` обоснован). - `task_close(ref, version)`: критерии приёмки выполнены И review-метод из `**Review:**` поля исполнен (правило 14: subagent прогнан / next-session review-таска существует / none обоснован).
- `task_close(project, id, version)` → status=done. - done → парная review-таска разблокируется (если была).
- Review-связка: импл-таска → парная `<slug>-review` (blocked, blocker=impl) ИЛИ зонтик на кластер (не BOTH). Ревьюер — следующая сессия, НЕ имплементер. Вердикт ревью — письмом полностью.
## Создание таски (для босса/делегирования) **Связи:** [[runbooks/index]] · [[canon/gates]] · [[canon/index]]
`task_create(project, slug, title, description, status='ready', priority=P1, session_id)`. Номер — только из ответа. Делегирование кросс-проект = пара: таска + сопроводительное письмо (inbox_send) — таска на борде не пингует живую сессию.
- Зависимости: `edge_create(from, to, 'blocked_by')` (task→task, цикл → 422).
- Импл-таска обязана нести `**Review:**` (subagent | next-session | none).
## Связано
[[runbooks/index]] · [[canon/gates]] (Г2 каналы) · [[runbooks/inbox]] · контракт wiki:2660 · brainstorm:173 · requirements:23

View File

@@ -25,4 +25,4 @@ tags: [mappa, runbook, wiki, agent]
Прочитать источник → извлечь сущности/концепты → summaries/<slug> (иммутабельно) → затронутые страницы create/update → отчёт. Один ингест может трогать 1015 страниц — нормально. Сырой контент в summaries не дампить (только summary + raw_path). Прочитать источник → извлечь сущности/концепты → summaries/<slug> (иммутабельно) → затронутые страницы create/update → отчёт. Один ингест может трогать 1015 страниц — нормально. Сырой контент в summaries не дампить (только summary + raw_path).
## Связано ## Связано
[[runbooks/index]] · [[canon/gates]] (Г1/Г3/Г8) · [[runbooks/search]] · контракт wiki:2660 · [[concepts/wiki-ingest-convention]] (wiki:3312) · brainstorm:173 [[runbooks/index]] · [[canon/gates]] (Г1/Г3/Г8) · [[runbooks/search]] · контракт wiki:2660 · [[concepts/wiki-ingest-convention]] (wiki:3312) · brainstorm:173

View File

@@ -20,7 +20,7 @@ related: [[vds-kzntsv]], [[recovery-architecture-snapshot]], [[mssql-on-vds]], [
| Endpoint (внешний, TLS) | `https://minio.kzntsv.site` (traefik → `minio:9000`, LE cert, port 443) | | Endpoint (внешний, TLS) | `https://minio.kzntsv.site` (traefik → `minio:9000`, LE cert, port 443) |
| Endpoint (сырой host-порт) | `http://89.253.255.133:9000` (тот же бэкенд, ssl:false) | | Endpoint (сырой host-порт) | `http://89.253.255.133:9000` (тот же бэкенд, ssl:false) |
| Endpoint (inter-container на books-vds) | `http://minio:9000` (сеть `proxy`) — так ходит imgproxy | | Endpoint (inter-container на books-vds) | `http://minio:9000` (сеть `proxy`) — так ходит imgproxy |
| accessKeyId | `AKIAJ2YJP72W6ZHCRE6Q` (= `MINIO_ACCESS_KEY`, root, read+write all) | | accessKeyId | `secret:pass/minio-vds/full-env` (= `MINIO_ACCESS_KEY`, root, read+write all) |
| secretAccessKey | в `pass minio-vds/full-env` (`MINIO_ROOT_PASSWORD`) | | secretAccessKey | в `pass minio-vds/full-env` (`MINIO_ROOT_PASSWORD`) |
| region / pathStyle / ssl | `local` / `true` / **`true` для https-хостнейма** (false для сырого `:9000`) | | region / pathStyle / ssl | `local` / `true` / **`true` для https-хостнейма** (false для сырого `:9000`) |

View File

@@ -22,7 +22,7 @@ updated: 2026-07-22
| Параметр | Значение | | Параметр | Значение |
|---|---| |---|---|
| accessKeyId | `stayer_minio` (bucket-user) | | accessKeyId | `stayer_minio` (bucket-user) |
| secretAccessKey | `cXY>AVoWBv#_V-SZn6Vu6Tzx&!M[%UOod` | | secretAccessKey | `secret:stostayer/minio` |
| endpoint | `https://minio-api.stostayer.ru` | | endpoint | `https://minio-api.stostayer.ru` |
| region | `us-west-1` (см. ниже — НЕ `local`) | | region | `us-west-1` (см. ниже — НЕ `local`) |
| pathStyle / ssl | `true` / `true` | | pathStyle / ssl | `true` / `true` |
@@ -31,7 +31,7 @@ imgproxy: `https://imgproxy.stostayer.ru`, basePath `/imgproxy2`, key+salt —
## Три бага в исходном Web.config (почему "смотрит на локальное") ## Три бага в исходном Web.config (почему "смотрит на локальное")
1. **Чужие креды.** `accessKey=AKIAJ2YJP72W6ZHCRE6Q` + `secretKey=7o0Q4NjE5GL…` — это **books-vds/snolla MinIO root-ключ** (см. [[minio-imgproxy-on-vds]]). На stostayer MinIO не зарегистрирован → `The Access Key Id you provided does not exist in our records`. Видимо, конфиг копипастом из snolla catch-all admin ([[snolla-local-admin-and-on-snolla-migration-design]], тот юзает books-vds `minio.kzntsv.site`), без замены ключей на stostayer-свои. 1. **Чужие креды.** `accessKey=secret:pass/minio-vds/full-env` + `secretKey=<root-secret>5GL…` — это **books-vds/snolla MinIO root-ключ** (см. [[minio-imgproxy-on-vds]]). На stostayer MinIO не зарегистрирован → `The Access Key Id you provided does not exist in our records`. Видимо, конфиг копипастом из snolla catch-all admin ([[snolla-local-admin-and-on-snolla-migration-design]], тот юзает books-vds `minio.kzntsv.site`), без замены ключей на stostayer-свои.
2. **Не API-порт.** `serviceURL=https://minio.stostayer.ru` → MinIO отвечает `S3 API Requests must be made to API port`. Прод юзает `https://minio-api.stostayer.ru`. Оба хоста резолвятся в один IP `2a03:6f01:1:2::c66b`, но `minio.stostayer.ru` — не S3 API-эндпоинт. 2. **Не API-порт.** `serviceURL=https://minio.stostayer.ru` → MinIO отвечает `S3 API Requests must be made to API port`. Прод юзает `https://minio-api.stostayer.ru`. Оба хоста резолвятся в один IP `2a03:6f01:1:2::c66b`, но `minio.stostayer.ru` — не S3 API-эндпоинт.
3. **Регион.** `authenticationRegion="local"` → SigV4-подпись регионом не совпала → `AmazonS3Exception: The authorization header is malformed; the region is wrong; expecting 'us-west-1'` (HTTP 400) на `GalleriesStorage.EnsureKeyPrefixExists``S3DirectoryInfo.ExistsWithBucketCheck` (провайдер галерей падал на ините, в трассе `ToolsController.ImagePreview``CreatePreview`). stostayer MinIO настроен на регион `us-west-1`. Прод `default.json` пишет `region:"local"`, но то Node aws-sdk (galleries через imgproxy мимо app-S3; для .NET AWSSDK регион обязан быть `us-west-1`). 3. **Регион.** `authenticationRegion="local"` → SigV4-подпись регионом не совпала → `AmazonS3Exception: The authorization header is malformed; the region is wrong; expecting 'us-west-1'` (HTTP 400) на `GalleriesStorage.EnsureKeyPrefixExists``S3DirectoryInfo.ExistsWithBucketCheck` (провайдер галерей падал на ините, в трассе `ToolsController.ImagePreview``CreatePreview`). stostayer MinIO настроен на регион `us-west-1`. Прод `default.json` пишет `region:"local"`, но то Node aws-sdk (galleries через imgproxy мимо app-S3; для .NET AWSSDK регион обязан быть `us-west-1`).
@@ -40,8 +40,8 @@ imgproxy: `https://imgproxy.stostayer.ru`, basePath `/imgproxy2`, key+salt —
9 S3-блоков в `fileStorageClients` (galleries/assets/images/scripts/stylesheets/imageCache/watermarks + inert-настройки contentCache/uploadCache) — 3 глобальные замены в `Web.config`: 9 S3-блоков в `fileStorageClients` (galleries/assets/images/scripts/stylesheets/imageCache/watermarks + inert-настройки contentCache/uploadCache) — 3 глобальные замены в `Web.config`:
``` ```
accessKey: AKIAJ2YJP72W6ZHCRE6Q → stayer_minio accessKey: secret:pass/minio-vds/full-env → stayer_minio
secretKey: 7o0Q4NjE5GLkdC48r0oZFEnqddjPNLqtCk+ZEh+S → cXY&gt;AVoWBv#_V-SZn6Vu6Tzx&amp;!M[%UOod (XML-escape: > → &gt;, & → &amp;) secretKey: secret:pass/minio-vds/full-env → cXY&gt;AVoWBv#_V-SZn6Vu6Tzx&amp;!M[%UOod (XML-escape: > → &gt;, & → &amp;)
serviceURL: https://minio.stostayer.ru → https://minio-api.stostayer.ru serviceURL: https://minio.stostayer.ru → https://minio-api.stostayer.ru
authenticationRegion: local → us-west-1 authenticationRegion: local → us-west-1
``` ```
@@ -68,4 +68,4 @@ authenticationRegion: local → us-west-1
- [[galleries-storage-class-local-not-s3]] — snolla-тираж: galleries/assets Local→S3 миграция, snolla catch-all admin на books-vds MinIO. - [[galleries-storage-class-local-not-s3]] — snolla-тираж: galleries/assets Local→S3 миграция, snolla catch-all admin на books-vds MinIO.
- [[snolla-admin-appdata-acl-500-after-scp-migration]] — split-brain админка(Local)↔боевой app(MinIO) на RUVDS; та же проблема «админка не переключена на S3». - [[snolla-admin-appdata-acl-500-after-scp-migration]] — split-brain админка(Local)↔боевой app(MinIO) на RUVDS; та же проблема «админка не переключена на S3».
- [[minio-imgproxy-on-vds]] — books-vds MinIO (root-ключ `AKIAJ2YJP72W6ZHCRE6Q`), который ошибочно попал в stostayer Web.config. - [[minio-imgproxy-on-vds]] — books-vds MinIO (root-ключ `secret:pass/minio-vds/full-env`), который ошибочно попал в stostayer Web.config.

View File

@@ -20,9 +20,7 @@ we're on Windows
# Session live-ingest # Session live-ingest
session sync: write to mappa `session sync: write to mappa` — opt-in для pi session-sync / CC-хука (w:2604): live-ingest сессий в mappa. Без opt-in сессии не пишутся в mappa (диагноз 2026-08-29: opt-in неполный → мусор mappa.ts:404 + live-ingest не поднят).
methodology: kzntsv
<!-- mappa:canon-block (auto; do not edit) --> <!-- mappa:canon-block (auto; do not edit) -->
## Mappa canon ## Mappa canon
@@ -36,8 +34,7 @@ methodology: kzntsv
- Г7. Degraded-режим — mappa недоступна: читать кэш `.mappa/` (canon/methodology/runbooks), мутации → `.mappa/pending/`; нет кэша → стоп, не импровизировать. - Г7. Degraded-режим — mappa недоступна: читать кэш `.mappa/` (canon/methodology/runbooks), мутации → `.mappa/pending/`; нет кэша → стоп, не импровизировать.
- Г8. Перед работой с вики/каноном — первым действием прочитать канон-блок AGENTS.md проекта. - Г8. Перед работой с вики/каноном — первым действием прочитать канон-блок AGENTS.md проекта.
- Г9. Живое состояние до заявления — статус заявлять только по свежему чтению mappa, не по памяти/кэшу/ответу create. - Г9. Живое состояние до заявления — статус заявлять только по свежему чтению mappa, не по памяти/кэшу/ответу create.
**Entity → runbook (runbooks/index — shared):** task → [[runbooks/tasks]] · wiki → [[runbooks/wiki]] · inbox → [[runbooks/inbox]] · session → [[runbooks/session]] · search → [[runbooks/search]] · issue → [[runbooks/issue]] · **intent** → [[runbooks/intent]] · requirements → [[runbooks/requirements]] · plan → [[runbooks/plan]] · comment → [[runbooks/comment]] · tag → [[runbooks/tag]] · attachment → [[runbooks/attachment]] · release → [[runbooks/release]] · brainstorm → [[runbooks/brainstorm]] · agent → [[runbooks/agent-operator]] · repo → [[runbooks/repo-commit]] · project → [[runbooks/project]] · skill → [[runbooks/skill]] · entity-слой → [[runbooks/entity]] · sched → [[runbooks/sched-telemetry]] **Entity → runbook (runbooks/index — shared):** task → [[runbooks/tasks]] · wiki → [[runbooks/wiki]] · inbox → [[runbooks/inbox]] · **thread** → [[runbooks/threads]] · session → [[runbooks/session]] · search → [[runbooks/search]] · issue → [[runbooks/issue]] · **intent** → [[runbooks/intent]] · requirements → [[runbooks/requirements]] · plan → [[runbooks/plan]] · comment → [[runbooks/comment]] · tag → [[runbooks/tag]] · attachment → [[runbooks/attachment]] · release → [[runbooks/release]] · brainstorm → [[runbooks/brainstorm]] · agent → [[runbooks/agent-operator]] · repo → [[runbooks/repo-commit]] · project → [[runbooks/project]] · skill → [[runbooks/skill]] · entity-слой → [[runbooks/entity]] · sched → [[runbooks/sched-telemetry]]
**Methodology:** `methodology/kzntsv` **Methodology:** `methodology/kzntsv`
**Canon version:** 4 **Canon version:** 4
<!-- /mappa:canon-block --> <!-- /mappa:canon-block -->
<!-- /mappa:canon-block -->

View File

@@ -5,10 +5,10 @@
services: services:
mappa: mappa:
image: registry.kzntsv.site/mappa:v0.64.9 image: registry.kzntsv.site/mappa:v0.64.14
container_name: mappa container_name: mappa
restart: unless-stopped restart: unless-stopped
mem_limit: 512m mem_limit: 1g
networks: networks:
- shared-dbs - shared-dbs
- proxy - proxy

View File

@@ -60,13 +60,25 @@ function copyTree(srcFile, dstFile) {
function collect() { function collect() {
const out = shSilent(`git -C "${DEV}" ls-files`); const out = shSilent(`git -C "${DEV}" ls-files`);
if (out === null) { fail("dev не git-репо"); return null; } if (out === null) { fail("dev не git-репо"); return null; }
const EXCL = /^\.wiki\/|^\.tasks\/|^\.agents\/|^AGENTS\.md$|^CLAUDE\.md$|^branding\/pora-|^pngtree-|^327274997_|^cat-clock-|^MIGRATION\.md$/; const EXCL = /^\.wiki\/|^\.tasks\/|^\.agents\/|^\.mappa\/|^AGENTS\.md$|^CLAUDE\.md$|^branding\/pora-|^pngtree-|^327274997_|^cat-clock-|^MIGRATION\.md$/;
return out.split("\n").filter((f) => f && !EXCL.test(f)); return out.split("\n").filter((f) => f && !EXCL.test(f));
} }
// dev-only артефакты, которые не должны жить в pub НИКОГДА (gotcha 15: .mappa/config.yaml
// несёт внутренний реестр — tenant/mappa.vds.kzntsv.site/git.kzntsv.site; в волне 2026-09-19
// утёк в паблик-коммит, потому что exclusion-list его не знал)
const NEVER = [".mappa"];
function purge() {
for (const p of NEVER) {
const t = `${PUB}/${p}`;
if (fs.existsSync(t)) { fs.rmSync(t, { recursive: true, force: true }); log(`purge: удалён ${p} (dev-only)`); }
}
}
function copy(files) { function copy(files) {
for (const f of files) copyTree(`${DEV}/${f}`, `${PUB}/${f}`); for (const f of files) copyTree(`${DEV}/${f}`, `${PUB}/${f}`);
log(`copy: ${files.length} файлов`); log(`copy: ${files.length} файлов`);
purge();
} }
// выбеливание — точечные замены, идемпотентно (эталон: верифицированный b0afd14) // выбеливание — точечные замены, идемпотентно (эталон: верифицированный b0afd14)
@@ -268,13 +280,32 @@ function gate() {
return true; return true;
} }
// Портативный скан (gotcha 16): прежний `grep -rnE '…'` через cmd.exe на Windows НЕ работал:
// cmd не снимает одинарные кавычки, а `|` для него — оператор pipe → команда падала,
// shSilent возвращал null, проверка молча считалась зелёной (0 хитов). Теперь скан — на Node.
function grepCheck() { function grepCheck() {
const hits = shSilent(`cd "${PUB}" && grep -rnE 'git\\.kzntsv|verdaccio|vds\\.kzntsv|registry\\.kzntsv|VERDACCIO' --exclude-dir=node_modules --exclude-dir=.git .`); const re = /git\.kzntsv|verdaccio|vds\.kzntsv|registry\.kzntsv|VERDACCIO/i;
if (hits && hits.length > 0) { const SKIP = new Set(["node_modules", ".git", ".yarn"]);
fail(`grep: остались ${hits.split("\n").length} вхождений kzntsv/verdaccio`); const BIN = /\.(svg|png|webp|jpg|jpeg|gif|ico|woff2?|ttf|zip|gz)$/i;
const hits = [];
const walk = (dir) => {
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
const p = `${dir}/${e.name}`;
if (e.isDirectory()) { if (!SKIP.has(e.name)) walk(p); continue; }
if (BIN.test(p)) continue;
let data;
try { data = fs.readFileSync(p, "utf8"); } catch { continue; }
data.split("\n").forEach((line, i) => {
if (re.test(line)) hits.push(`${path.relative(PUB, p)}:${i + 1}: ${line.trim().slice(0, 140)}`);
});
}
};
walk(PUB);
if (hits.length > 0) {
fail(`grep: остались ${hits.length} вхождений kzntsv/verdaccio\n` + hits.slice(0, 10).join("\n"));
return false; return false;
} }
log("grep: 0 вхождений kzntsv/verdaccio"); log("grep: 0 вхождений kzntsv/verdaccio (портативный скан)");
return true; return true;
} }