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` (структурная диагностика артефактов).