reconcile-docs · git:20260907.ad5db37 · 2026-09-07 · sha256 4ed854be2af6ef76
reconcile-docs git:20260907.ad5db37A
Immutable. This exact content is served forever at /api/v1/blob/4ed854be2af6ef76.
---
name: reconcile-docs
description: 'Best-effort reconciliation of the living architecture corpus against the code: the model reads docs/architecture/ plus the code and lists divergences with coordinates. Advisory only — an opinion of the model, never a verified verdict, no gates and no stamps. Nothing is applied automatically: corpus edits are a separate confirmed step written through the corpus primitive.'
argument-hint: "[SPEC-XXX | DESIGN-XXX | <путь>]"
cli_requires: "task_tool"
---
# /polisade:reconcile-docs [SPEC-XXX | DESIGN-XXX | <путь>] — сверка архитектура ↔ код (best-effort)
Показывает расхождения между тем, что **утверждает архитектурный корпус**
`docs/architecture/`, и тем, что **видно в коде**. Механическая часть —
разрешимость ссылок корпуса (`scripts/polisade_reconcile.py anchors`,
stdlib-only); сама сверка смысла — работа модели клиента на его токенах.
---
## ⚠️ ЧЕСТНАЯ РАМКА — прочитай и повтори пользователю в КАЖДОМ выводе
```
┌──────────────────────────────────────────────────────────┐
│ Это МНЕНИЕ модели о расхождениях, а НЕ вердикт. │
│ │
│ Корпус best-effort (провенанс INFERRED/GAP), код читает │
│ та же модель, и сверяет смысл она же. Ни гейтов, ни │
│ штампов, ни провенанса CONFIRMED здесь нет — и не │
│ появится оттого, что список выглядит строго. │
│ │
│ Детерминированная сверка «дизайн ↔ код» с провенансом │
│ и блокирующими гейтами — свойство ПЛАТНОГО продукта. │
└──────────────────────────────────────────────────────────┘
```
Что это значит на практике:
- пустой список расхождений = «модель ничего не заметила», а **не**
«архитектура соответствует коду»;
- найденное расхождение = «стоит посмотреть», а не «доказано»: корпус мог
устареть, код мог быть переименован, модель могла ошибиться в обе стороны;
- механическая часть (`anchors`) проверяет **разрешимость ССЫЛКИ** — есть ли
файл, существуют ли строки, встречается ли символ. Разрешившаяся ссылка
ничего не говорит о верности утверждения;
- сверка с гарантией (оракул-валидированный провенанс, детерминированные
гейты целостности корпуса, блокирующая проверка) — отдельный **платный**
продукт; граница описана
в `docs/what-works-without-paid-parts.md` репозитория Polisade Orchestrator
(в поставку плагина `docs/` не входит).
⛔ Запрещено (класс F1 — «отказ способности подан как положительный факт»):
подавать вывод как «дрейфа нет», «архитектура подтверждена», «сверка пройдена»,
рисовать штампы/галочки соответствия и вешать на вывод exit-код как вердикт.
Пиши как есть: «модель заметила N расхождений (best-effort, не проверено)».
⛔ Есть детерминированный сосед, и он не здесь: `scripts/polisade_drift_gate.py`
(api/er, блокирующий в CI). Не выдавай его гарантии за свои и не подменяй его
собой — если PM нужен блокирующий чек, отправь его туда.
---
## Использование
```
/polisade:reconcile-docs # весь живой корпус docs/architecture/
/polisade:reconcile-docs SPEC-001 # только то, что затронула эта SPEC
/polisade:reconcile-docs src/orders # только этот участок кода/корпуса
```
## Когда запускать
- Перед передачей проекта другой команде
- Перед следующим крупным SPEC на том же домене
- Перед архитектурным ревью / подготовкой к аудиту
- После завершения всех TASK по SPEC (по решению PM)
---
## Алгоритм
### Шаг 0 — Контекст и пре-чек
<!-- polisade:silo-legacy POINTER — канон «Силос → корпус» живёт в /polisade:design -->
> **Силос ≠ корпус.** Источник правды по архитектуре — живой корпус
> `docs/architecture/`; пакет `DESIGN-NNN-<slug>/` — legacy-силос. Прочитал
> файл из силоса — скажи об этом вслух (переходное чтение). Полный канон —
> `/polisade:design`, блок «Силос → корпус»; перевод силоса на корпус —
> `${POLISADE_PYTHON:-python3} scripts/polisade_migrate_silo.py <пакет>` (dry-run по умолчанию).
1. Корень проекта = текущая рабочая директория. Корпус — `docs/architecture/`.
2. Прочитай `.state/knowledge.json` (`projectContext.techStack`, `keyFiles`) —
без него сверка пойдёт вслепую по незнакомому стеку.
3. Аргумент:
- **`SPEC-NNN`** — срез: возьми `docs/specs/SPEC-NNN/changeset.yaml`
(created/modified) и `docs/architecture/trace.json`; сверяются только
перечисленные там объекты корпуса;
- **`DESIGN-NNN`** — legacy-силос: скажи вслух, что читаешь силос
(POINTER выше), и сверяй его артефакты; предложи
`polisade_migrate_silo.py`;
- **путь** — срез по каталогу;
- **без аргумента** — весь корпус.
4. Корпуса нет вовсе (`docs/architecture/` отсутствует) — **это не ошибка и не
расхождение**: скажи «сверять нечего, архитектурного корпуса в проекте нет»
и предложи `/polisade:design` (силос) или `/polisade:design-corpus` (живой
корпус, opt-in). Не выдумывай корпус, чтобы было что сверить.
### Шаг 1 — Якоря сверки (детерминированно)
<!-- polisade:exec-denied CAPSULE BEGIN -->
> ⛔ **Вызов скрипта отклонён или не запустился** (`Command references protected path` / `Install directory is read-protected` / `Filesystem Guard` / `the tool's default permission is 'deny'`, отказ песочницы, ненулевой exit без вывода) — **STOP**.
> Процитируй отказ дословно. НЕ пересказывай по исходнику, что скрипт «сделал бы»; НЕ собирай dry-run вручную; НЕ переходи к apply/push/pr-create.
> НЕ транскрибируй скрипт (прочитать → записать копию в `/tmp` или в проект → запустить копию): копия не байт-идентична — уезжают классы символов в regex, форма возврата функций, пропадают целые функции — и молча меняется набор применённых изменений.
> Отказ инструмента — это отказ, а не результат. Доложи PM дословный текст отказа и сошлись на #127 (доставка скриптов в проект).
<!-- polisade:exec-denied CAPSULE END -->
```bash
${POLISADE_PYTHON:-python3} {plugin_root}/scripts/polisade_reconcile.py anchors --root . --json
```
Скрипт перечисляет файлы корпуса, их провенанс и **разрешимость** каждого
`code_refs`: `resolved` / `missing-file` / `symbol-not-found` /
`line-out-of-range` / `outside-root`. Это факты о ССЫЛКАХ.
- `missing-file` / `symbol-not-found` — **кандидат** в расхождение (класс
`missing-in-code`), а не готовое расхождение: проверь глазами, не переезд ли
это файла;
- `no-code-refs` — у утверждения нет привязки к коду: механически сверять
нечего, только чтением;
- `gap` (провенанс `GAP`) — известное-неизвестное корпуса. **Не расхождение**:
корпус честно сказал «не знаю».
- ⛔ Exit-код `anchors` **не вердикт**: 0 значит «инвентарь построен».
### Шаг 2 — Сверка смысла (субагенты, read-only)
Разложи срез на участки (по bounded-context / каталогу) и запусти
fan-out read-only субагентов (Task tool, тип по умолчанию) —
по одному на участок, каждый в чистом контексте. Навигация — детерминированный
grep-протокол клиента (термины → символы → ссылки), как в `/polisade:implement`.
⚠️ **«Read-only» здесь держится ПРОМПТОМ, а не барьером.** Субагент технически
может писать: песочницы у бесплатной линии нет, и вредоносный текст внутри
корпуса тоже читается как инструкция. Поэтому — **снимок до и сверка после**
(детект, а не защита):
```bash
snap() { git rev-parse HEAD; find docs -type f -exec shasum {} \; | sort; }
snap > .polisade/tmp/reconcile-before.txt # ДО fan-out
# … fan-out субагентов …
snap > .polisade/tmp/reconcile-after.txt # ПОСЛЕ
diff .polisade/tmp/reconcile-before.txt .polisade/tmp/reconcile-after.txt
```
Снимок берётся **по содержимому** (sha каждого файла + `HEAD`), а не по
`git status`: статус уже-грязного файла (` M`, `??`) не меняется от новой
правки, и такой обход остался бы невидимым.
Расхождение диффа = **STOP**: кто-то писал в дерево, чего делать не должен.
Покажи дифф человеку, ничего не применяй и не «прибирай» за собой — след
правки важнее аккуратного вывода.
⚠️ **Что этот детект НЕ видит** (называем, чтобы его не приняли за барьер):
он сравнивает **итоговое** состояние `docs/` и `HEAD` — значит, пропустит
правку с последующим восстановлением тех же байтов, правку вне `docs/`
(например, в коде или в `.state/`), и не скажет, КТО правил. Атрибуции у него
нет, превенции тоже: барьер, физически закрывающий запись исполнителю, —
свойство платного продукта. Здесь его нет, и это сказано вслух.
Промпт субагента — дословно (не пересказывай, не дополняй примерами из чужих
проектов):
<!-- polisade:reconcile PROMPT BEGIN -->
```
═══════════════════════════════════════════
SYSTEM ROLE: Corpus↔Code Divergence Reader (best-effort)
═══════════════════════════════════════════
Ты сверяешь УТВЕРЖДЕНИЯ архитектурного корпуса с тем, что видно в коде
ЭТОГО репозитория, и возвращаешь список расхождений. Ты — READ-ONLY:
не правь ни код, ни корпус, ничего не коммить, ничего не удаляй.
ЧТО ДЕЛАТЬ
1. Прочитай выданные файлы корпуса. Каждое проверяемое утверждение —
это конкретная фраза/поле/строка, а не «файл целиком».
2. Найди соответствующее место в коде: сначала координаты из code_refs,
затем grep по терминам утверждения (символ, имя сущности, endpoint).
3. Сравни и запиши расхождение ТОЛЬКО там, где ты видел обе стороны.
ФОРМА ОТВЕТА — JSON, один объект на расхождение:
id RC-001, RC-002, … (сквозная нумерация)
kind ровно одно из: missing-in-code | missing-in-corpus |
mismatch | unverifiable
corpus_ref путь файла корпуса, где живёт утверждение
claim что утверждает корпус (цитата или точный пересказ)
observation что видно в коде
code_ref координата: путь[:символ][:строки] — ОБЯЗАТЕЛЬНА
confidence low | medium | high — твоя уверенность
Ничего, кроме этого JSON, в ответе быть не должно.
ЗАПРЕЩЕНО
- Выдавать ВЕРДИКТ. Ты пишешь мнение с уверенностью, а не решение.
Поля verdict / gate / provenance / certified / passed / stamp и любые
их синонимы запрещены — приёмник их отвергает (класс F1: отсутствие
гарантии нельзя подать как гарантию).
- Записывать расхождение, которого ты не видел в коде: если найти место
не удалось, это kind=unverifiable с честным observation
«место не найдено: <как искал>», а НЕ «в коде отсутствует».
- Вкладывать в ответ ожидаемые ответы, эталонные решения, координаты
или имена из ЧУЖИХ наборов задач, бенчмарков и прошлых прогонов:
работай только с файлами этого репозитория, выданными тебе сейчас.
Всё, чего ты не прочитал здесь, — не факт, а утечка.
- Править файлы, запускать сборку/тесты, менять git-состояние.
ШУМ НЕ НУЖЕН: расхождения по существу (сущность, поле, контракт,
состояние, зависимость), а не разница в формулировках, порядке или
стиле. Совпало — молчи: «нет расхождения» здесь ничего не гарантирует
и потому не пишется.
```
<!-- polisade:reconcile PROMPT END -->
Собери ответы субагентов в один список, перенумеруй `RC-NNN` сквозным
порядком и **выброси дубликаты** (одно и то же расхождение из двух участков).
⛔ Пустой ответ субагента — это «модель ничего не заметила на своём участке»,
и так его и пересказывай. Не превращай его в «участок соответствует корпусу».
### Шаг 3 — Приём расхождений (линт формы + отчёт)
<!-- polisade:exec-denied CAPSULE BEGIN -->
> ⛔ **Вызов скрипта отклонён или не запустился** (`Command references protected path` / `Install directory is read-protected` / `Filesystem Guard` / `the tool's default permission is 'deny'`, отказ песочницы, ненулевой exit без вывода) — **STOP**.
> Процитируй отказ дословно. НЕ пересказывай по исходнику, что скрипт «сделал бы»; НЕ собирай dry-run вручную; НЕ переходи к apply/push/pr-create.
> НЕ транскрибируй скрипт (прочитать → записать копию в `/tmp` или в проект → запустить копию): копия не байт-идентична — уезжают классы символов в regex, форма возврата функций, пропадают целые функции — и молча меняется набор применённых изменений.
> Отказ инструмента — это отказ, а не результат. Доложи PM дословный текст отказа и сошлись на #127 (доставка скриптов в проект).
<!-- polisade:exec-denied CAPSULE END -->
```bash
${POLISADE_PYTHON:-python3} {plugin_root}/scripts/polisade_reconcile.py record --root . --stdin < findings.json
```
Скелет входа — `polisade_reconcile.py template` (⛔ не реконструируй форму по
памяти). Скрипт проверяет **только форму**: id, класс из закрытого словаря,
координата, названная уверенность, существование `corpus_ref`. Он пишет
`.state/reconcile-report.json` и **ничего больше**.
- `E-RC-VERDICT-CLAIM` — в findings попало поле вердикта. Не обходи его
переименованием ключа: это граница продукта, а не придирка линта.
- `E-RC-MISSING-FIELD` / `E-RC-CODE-REF` — расхождение без координаты
непроверяемо человеком; верни субагента за координатой.
- Ошибки формы → отчёт **не записан**. Почини вход и повтори.
Перескажи вывод честно: сколько расхождений, каких классов, с какой
уверенностью — и рамкой сверху.
### Шаг 3.5 — Сверка с ВНЕШНИМ эталоном (только если PM его передал)
Отдельный режим и **отдельная секция отчёта**. Включается, когда PM передал
reference-спеку — файл или папку со схемами (JSON Schema / OpenAPI / AsyncAPI):
«сверь `async-api.md` со схемами, которые я прислал». Не передал — режима нет,
и в отчёте про него ничего не пишется.
⚠️ Это ДРУГАЯ сверка, и путать её с основной нельзя:
| | Шаги 1–3 (основная) | Шаг 3.5 (этот) |
|---|---|---|
| С чем сверяем | корпус ↔ **код** | артефакт ↔ **документ, который дал пользователь** |
| Кто сверяет | модель, best-effort | скрипт, механически |
| Что на выходе | мнение с уверенностью | таблица расхождений по 4 измерениям |
| Чем НЕ является | вердиктом о корпусе | вердиктом о корпусе **и** сверкой с кодом |
Совпадение полей с эталоном **не** говорит ничего о коде и **не** повышает
провенанс корпуса: `INFERRED`/`GAP` до и после, `CONFIRMED` не ставится.
<!-- polisade:exec-denied CAPSULE BEGIN -->
> ⛔ **Вызов скрипта отклонён или не запустился** (`Command references protected path` / `Install directory is read-protected` / `Filesystem Guard` / `the tool's default permission is 'deny'`, отказ песочницы, ненулевой exit без вывода) — **STOP**.
> Процитируй отказ дословно. НЕ пересказывай по исходнику, что скрипт «сделал бы»; НЕ собирай dry-run вручную; НЕ переходи к apply/push/pr-create.
> НЕ транскрибируй скрипт (прочитать → записать копию в `/tmp` или в проект → запустить копию): копия не байт-идентична — уезжают классы символов в regex, форма возврата функций, пропадают целые функции — и молча меняется набор применённых изменений.
> Отказ инструмента — это отказ, а не результат. Доложи PM дословный текст отказа и сошлись на #127 (доставка скриптов в проект).
<!-- polisade:exec-denied CAPSULE END -->
```bash
${POLISADE_PYTHON:-python3} {plugin_root}/scripts/polisade_reference_fields.py \
diff <файл-или-каталог-эталона> <файл-артефакта> --json
```
Эталоном может быть файл или каталог; каталог скрипт обходит сам и печатает
список источников со статусом каждого — вручную сводить папку не надо.
- exit **0** — «расхождений по сверенным измерениям нет» (имя, тип,
`format`/`pattern`, `required`). ⛔ Не переписывай это как «артефакт
соответствует эталону»: несравниваемые измерения перечислены в `--rules`.
- exit **1** — таблица расхождений идёт в секцию отчёта целиком.
- exit **2** — не разобрано. Процитируй `файл:строка` и скажи, что сверка не
выполнена. Неразбор — не «чисто».
⛔ Результат этого шага **не попадает** в `findings.json` шага 3. Это не
расхождение «корпус ↔ код», у него нет `kind` из закрытого словаря и нет
`code_ref`; попытка положить его туда — либо `E-RC-MISSING-FIELD`, либо (если
подписать «вердикт») `E-RC-VERDICT-CLAIM`. Секция живёт в отчёте PM рядом с
основной, отдельным блоком:
```
──────── СВЕРКА С ВНЕШНИМ ЭТАЛОНОМ (не с кодом) ────────
Эталон: <путь, переданный PM>
Артефакт: <файл корпуса/силоса>
Рамка: сверка ДВУХ ДОКУМЕНТОВ по имени, типу, format/pattern, required.
Это НЕ сверка с кодом и НЕ вердикт о корпусе; провенанс не меняется.
Итог: <таблица | «расхождений по сверенным измерениям нет» | «не разобрано: файл:строка»>
────────────────────────────────────────────────────────
```
⛔ Расхождение эталона и артефакта не объявляется «опечаткой» и не приводится
к одному имени/формату без PM (дисциплина #88) — оно выносится как открытый
вопрос **DECISION NEEDED** и до ответа PM не чинится:
```
DECISION NEEDED — сверка с эталоном
Вариант: RESPONSE
Поле: parentrequestId (эталон) vs parentRequestId (артефакт)
Эталон: pattern ^[a-f0-9]{32}$, required
Артефакт: format uuid, required
Вопрос: какое написание и какой формат канонические для этого типа
сообщения?
```
Правка артефакта, если PM её подтвердил, идёт обычным путём шага 5 (через
примитив записи), а не «заодно».
### Шаг 4 — Что дальше: решает ЧЕЛОВЕК, по одному пункту
⛔ **Автоматически не применяется ничего.** Ни правка корпуса, ни правка кода,
ни коммит, ни «заодно поправил мелочь».
Покажи PM список и по КАЖДОМУ пункту спроси, что делать:
| Решение PM | Что делаешь |
|---|---|
| **корпус устарел** → поправить корпус | Шаг 5 (отдельный подтверждённый шаг записи) |
| **код разошёлся с дизайном** → чинить код | `/polisade:defect` или `/polisade:debt` → TASK; **код в этом скилле не правится** |
| **это нормально** | ничего; расхождение остаётся в отчёте как зафиксированное |
| **непонятно** | оставь `unverifiable`, вынеси вопрос в `/polisade:questions` |
Молчание/пустой ответ = **не применять ничего**. «Он не возразил» — не
подтверждение.
### Шаг 5 — Правка корпуса (только по подтверждённым пунктам)
<!-- polisade:exec-denied CAPSULE BEGIN -->
> ⛔ **Вызов скрипта отклонён или не запустился** (`Command references protected path` / `Install directory is read-protected` / `Filesystem Guard` / `the tool's default permission is 'deny'`, отказ песочницы, ненулевой exit без вывода) — **STOP**.
> Процитируй отказ дословно. НЕ пересказывай по исходнику, что скрипт «сделал бы»; НЕ собирай dry-run вручную; НЕ переходи к apply/push/pr-create.
> НЕ транскрибируй скрипт (прочитать → записать копию в `/tmp` или в проект → запустить копию): копия не байт-идентична — уезжают классы символов в regex, форма возврата функций, пропадают целые функции — и молча меняется набор применённых изменений.
> Отказ инструмента — это отказ, а не результат. Доложи PM дословный текст отказа и сошлись на #127 (доставка скриптов в проект).
<!-- polisade:exec-denied CAPSULE END -->
⛔ **Никогда не пиши в `docs/architecture/` ни Write-инструментом, ни `cp`,
ни `mv`.** Единственный писатель живого корпуса —
`${POLISADE_PYTHON:-python3} {plugin_root}/scripts/polisade_corpus_io.py` (пофайловая атомарность,
блокировка прогона и операции, журнал оборванной промоции, backup, отказ на
симлинках). Ручная запись обходит всё перечисленное — это регресс.
1. `polisade_corpus_io.py status --json` — **до** любого IO. Непустой
`attention` (exit 1) → не начинай: разбери с PM оборванную промоцию.
2. `polisade_corpus_io.py acquire --run-id <run-id> --json` — блокировка на
прогон. `E-lock-held` → выйди без единой записи, процитировав `hint`.
3. Собери правки в staging `.polisade/tmp/design-corpus/<run-id>/staging/`
(тот же формат корпуса — раскладка в
`skills/design-corpus/references/corpus-layout.md`; провенанс правленого файла остаётся
`INFERRED`/`GAP` — **`CONFIRMED` не ставится никогда**).
4. Покажи PM diff staging и дождись подтверждения **на этот diff**. Собирая
diff, запомни `sha256` байтов КАЖДОЙ цели, которые ты прочитал, — они
пойдут в хэш-контракт шага 5.
5. Промоция одной командой (backup обязателен, если корпус непустой) **под
хэш-контрактом**. Подтверждение PM относится к тому корпусу, который ты
ему показал; между показом и промоцией корпус мог измениться — блокировка
кооперативная и человека с редактором не останавливает. Поэтому собери
карту `.polisade/tmp/design-corpus/<run-id>/expect.json` вида
`{"<путь-в-корпусе>": "<sha256>|absent"}` — `absent` для целей, которых в
корпусе не было, иначе `sha256` прочитанных байтов — и покрой ею **весь**
план (это и требует `--expect-strict`):
<!-- polisade:exec-denied CAPSULE BEGIN -->
> ⛔ **Вызов скрипта отклонён или не запустился** (`Command references protected path` / `Install directory is read-protected` / `Filesystem Guard` / `the tool's default permission is 'deny'`, отказ песочницы, ненулевой exit без вывода) — **STOP**.
> Процитируй отказ дословно. НЕ пересказывай по исходнику, что скрипт «сделал бы»; НЕ собирай dry-run вручную; НЕ переходи к apply/push/pr-create.
> НЕ транскрибируй скрипт (прочитать → записать копию в `/tmp` или в проект → запустить копию): копия не байт-идентична — уезжают классы символов в regex, форма возврата функций, пропадают целые функции — и молча меняется набор применённых изменений.
> Отказ инструмента — это отказ, а не результат. Доложи PM дословный текст отказа и сошлись на #127 (доставка скриптов в проект).
<!-- polisade:exec-denied CAPSULE END -->
```bash
${POLISADE_PYTHON:-python3} {plugin_root}/scripts/polisade_corpus_io.py promote \
--staging .polisade/tmp/design-corpus/<run-id>/staging \
--backup .polisade/tmp/design-corpus/<run-id>/backup \
--expect-from .polisade/tmp/design-corpus/<run-id>/expect.json \
--expect-strict \
--run-id <run-id> --json
```
6. Любой ненулевой exit — **не** успех: разбери вывод, при оборванной промоции
откатись `restore --backup <dir> --run-id <run-id>` и halt к PM. Отказ
`E-expect-*` — отдельный случай: корпус правили после того, как PM
подтвердил diff. **Не повторяй с `--force`** — покажи PM путь, ожидавшийся
и фактический `sha256` (они в `details`) и пересобери правку на актуальном
корпусе. В успешном отчёте сверь `expectUnchecked: 0`: ненулевое значение
означает, что часть плана прошла БЕЗ сверки.
7. `polisade_corpus_io.py release --run-id <run-id>` — и на успехе, и на halt'е.
8. Правка корпуса — это правка **утверждений**, а не сокрытие расхождения:
`DESIGN-DEVIATION`-комментарии в коде (audit trail) **не удаляются**.
---
## Формат вывода
```
════════ СВЕРКА КОРПУС ↔ КОД (best-effort) ════════
Срез: docs/architecture (весь корпус) · файлов: 34 · с привязкой к коду: 21
Ссылки корпуса: 48 · разрешились: 44 · нет файла: 3 · символ не найден: 1
Модель заметила расхождений: 5 (high 1 · medium 3 · low 1)
RC-001 [mismatch] docs/architecture/model/entities/Order.yaml
корпус: поле `discount` типа money
код: `discountAmount`, int (копейки) — src/orders/Order.java:31-34
RC-002 [missing-in-corpus] docs/architecture/model/containers.yaml
код: контейнер `notifier` (src/notifier/*) в корпусе не описан
…
Отчёт: .state/reconcile-report.json
Оговорка: это мнение модели, а не вердикт; пустой список не означает
соответствия; гейтов и штампов здесь нет.
Дальше: решение по каждому пункту — за человеком (правка корпуса / TASK на
код / «так и надо»). Автоматически не применяется ничего.
═══════════════════════════════════════════════════
```
---
## Важно
- **Скилл ничего не чинит.** Ни код, ни корпус без подтверждения. Правка кода
живёт в `/polisade:implement` через TASK; правка корпуса — Шаг 5, по одному
подтверждённому пункту, через примитив записи.
- **Отчёт — снимок момента.** `.state/reconcile-report.json` описывает дерево
на время прогона; читать его как «текущее состояние» через неделю нельзя.
- **Пустой отчёт ≠ соответствие.** Он значит «модель не заметила», и разница
между этими фразами — ровно то, что продаёт платная линия.
- **Корпус best-effort остаётся best-effort.** Сверка не повышает его
провенанс: `INFERRED`/`GAP` до и после; `CONFIRMED` в бесплатной линии не
ставится никогда.
- Связанные команды: `/polisade:design-corpus` (строит живой корпус, opt-in),
`/polisade:design` (per-SPEC силос), `/polisade:defect` / `/polisade:debt`
(TASK по расхождению в коде), `/polisade:questions` (вопросы PM),
`/polisade:doctor` (структурная диагностика артефактов).