Second cut pass in the backend zone: restore what the review found lost, and take the sediment the first pass left behind

This commit is contained in:
heaven 2026-09-02 11:49:08 +03:00
parent 4a1ecc3aa6
commit 1d84cff75e
5 changed files with 145 additions and 132 deletions

View file

@ -1,6 +1,6 @@
# backend/ — Go-бэкенд TextMachine # backend/ — Go-бэкенд TextMachine
Зона сессии «Бэкенд». Контракт — `docs/architecture/05-decisions-log.md` (свежая голова — с хвоста файла); целевая архитектура (7 слоёв, инвариант общности §0.1 — любая книга/пара/структура; статус стройки — шапка-таблица) — `docs/architecture/09-target-architecture.md`; норматив общности — `12-go-style-notes.md`; **актуальный сессионный промт — список «Активные хендофф-промты» в `docs/README.md`**; контракты Фазы 0 — `03-implementation-notes.md` (через баннер); квирки провайдеров — `docs/experiments/00-provider-quirks.md` (читать ПЕРЕД правкой адаптеров/вызовами). **Язык-данные майнера — вне пайплайна: `internal/lang`+`configs/langpacks/` (D39.16); пар-калибровки — `configs/pairs/<пара>.yaml`, промпты — `prompts/<пара>/<роль>.md` по конвенции (D39.23).** **Подсистемы (`chunk`/`miner`/`checks`/`membank`) не импортируют друг друга и не импортируют `pipeline` — драйвер является композит-корнем (D39.23; проверяется `go list -deps`).** **`.env` не читать.** Зона сессии «Бэкенд». Контракт — `docs/architecture/05-decisions-log.md` (свежая голова — с хвоста файла); целевая архитектура (7 слоёв, инвариант общности §0.1 — любая книга/пара/структура; статус стройки — шапка-таблица) — `docs/architecture/09-target-architecture.md`; норматив общности — `12-go-style-notes.md`; контракты Фазы 0 — `03-implementation-notes.md` (через баннер). **Язык-данные майнера — вне пайплайна: `internal/lang`+`configs/langpacks/` (D39.16); пар-калибровки — `configs/pairs/<пара>.yaml`, промпты — `prompts/<пара>/<роль>.md` по конвенции (D39.23).** **Подсистемы (`chunk`/`miner`/`checks`/`membank`) не импортируют друг друга и не импортируют `pipeline` — драйвер является композит-корнем (D39.23; проверяется `go list -deps`).** **`.env` не читать.**
*(Актуализировано оркестратором 01.08 по мандату владельца, факты сверены по коду.)* *(Актуализировано оркестратором 01.08 по мандату владельца, факты сверены по коду.)*
@ -8,10 +8,10 @@
| Пакет | Что делает | Ключевые файлы | | Пакет | Что делает | Ключевые файлы |
|---|---|---| |---|---|---|
| `cmd/tmctl` | CLI: `translate` / `status` (read-only N/M+паспорта глав+деньги, `--json`; работает ПРИ живом прогоне — store без flock) / `report` (request-log+леджер книги **+ per-run quality-report**: структурный KPI предл./нарратив-абзац, тире, cosmetic-strip/echo-rates, глоссарий-промахи, trust-gated — наблюдаемость, НЕ гейт; D39.2-T4) / `export` (**экспорт-поверхность для полигона**: final_hash→checkpoint→checks.ExportNormalize, manifest-join c pending/ghost-учётом, ConfigDrift-поле, `--plaintext`; D39.5) / `build` (**писатель книги**, строка 236: EPUB 3 + чистый txt из той же экспорт-проекции в `<project_db>.book.<fmt>` рядом с БД, пути — в `artifacts.book_files`; книга с ЛЮБОЙ дырой — pending/withheld/incomplete/ghost — по умолчанию отказ **exit 16** с перечнем, `--partial` пишет с пометкой на первой странице и маркером на каждой дыре; слова читателя — данные `configs/langpacks/<цель>/reader.txt`, вне снапшота; `--format epub,txt`, `--out`) / `redrive` (переатака флагнутых: `--chapter/--chunk/--reason/--dry-run`, D15.3) / `manifest` (**$0-производитель персиста манифеста глав/чанков**, строка 100: нужен ДО первого прогона — дерево глав разобранной, но не запущенной книги; `--json` печатает сам документ) / `migrate` (**$0-write-open без прогона** (D39.134): единственный путь, доводящий схему проекта до головы бинаря — read-only команды её НЕ мигрируют. Грузит ТОЛЬКО `book.yaml` — ни цен, ни ключей на $0-пути (строка 146); restore point берёт ПОД ЛОКОМ и только когда шаг реально применяется (имя `<метка>-pre-migrate.db` — вне секундного неймспейса платного пути, строка 173); несовпадение схемы у read-only путей — типизированный отказ **exit 13** с машинным токеном `schema_mismatch found=N expected=M`). **ДВА потолка прогона, и они ортогональны.** `--ceiling-usd` (строка 145) — ДЕНЬГИ: перекрывает книжный `ceilings.book_usd` ТОЛЬКО на этот прогон, в book.yaml не пишется, ноль/отрицательное = отказ запуска; каппит КУМУЛЯТИВНУЮ трату книги, а не приращение прогона. `--max-units` (D39.165 §1б) — ОБЪЁМ: не больше N ВЫХОДНЫХ ЮНИТОВ (гранулярность `units_total` манифеста, та самая, в которой платформа продаёт главы) будет ОПЛАЧЕНО этим прогоном. Юниты, которые прогон отдаёт за $0 (резюм, ре-пин), едут бесплатно и потолок не тратят; ретраи и эскалации — тоже нет, они внутри юнита. Принимает только `translate`. **Остановка по объёму — ЗАВЕРШЕНИЕ (exit 0), а не пауза:** словарь кодов выхода не расширялся, различение живёт в отчёте прогона и в логе. Отчёт различает ДОСТАВКУ (юнит, которого не было) и ПЕРЕ-ДЕЛКУ (уже доставленный юнит под сдвинутым снапшотом) — покупка, целиком ушедшая в переделку, обязана читаться как переделка.На книге, которая МАЙНИТ банк, вторая покупка требует `--resnapshot` (авто-банк растёт между покупками и двигает edit-снапшот) — прогон предупреждает об этом в логе. main — тонкая обвязка: разбор/exit-коды/.env/рендеры в тестируемых функциях | `main.go`, `invocation.go`, `render.go`, `dotenv.go` | | `cmd/tmctl` | CLI: `translate` / `status` (read-only N/M+паспорта глав+деньги, `--json`; работает ПРИ живом прогоне — store без flock) / `report` (request-log+леджер книги **+ per-run quality-report**: структурный KPI предл./нарратив-абзац, тире, cosmetic-strip/echo-rates, глоссарий-промахи, trust-gated — наблюдаемость, НЕ гейт; D39.2-T4) / `export` (**экспорт-поверхность для полигона**: final_hash→checkpoint→checks.ExportNormalize, manifest-join c pending/ghost-учётом, ConfigDrift-поле, `--plaintext`; D39.5) / `build` (**писатель книги**: EPUB 3 + чистый txt из той же экспорт-проекции в `<project_db>.book.<fmt>` рядом с БД, пути — в `artifacts.book_files`; книга с ЛЮБОЙ дырой — pending/withheld/incomplete/ghost — по умолчанию отказ **exit 16** с перечнем, `--partial` пишет с пометкой на первой странице и маркером на каждой дыре; слова читателя — данные `configs/langpacks/<цель>/reader.txt`, вне снапшота; `--format epub,txt`, `--out`) / `redrive` (переатака флагнутых: `--chapter/--chunk/--reason/--dry-run`, D15.3) / `manifest` (**$0-производитель персиста манифеста глав/чанков**: нужен ДО первого прогона — дерево глав разобранной, но не запущенной книги) / `migrate` (**$0-write-open без прогона** (D39.134): read-only команды схему НЕ мигрируют. Грузит ТОЛЬКО `book.yaml` — ни цен, ни ключей на $0-пути (строка 146); restore point берёт ПОД ЛОКОМ и только когда шаг реально применяется (имя `<метка>-pre-migrate.db` — вне секундного неймспейса платного пути, строка 173); несовпадение схемы у read-only путей — типизированный отказ **exit 13** с машинным токеном `schema_mismatch found=N expected=M`). **ДВА потолка прогона, и они ортогональны.** `--ceiling-usd` — ДЕНЬГИ: перекрывает книжный `ceilings.book_usd` ТОЛЬКО на этот прогон, в book.yaml не пишется, ноль/отрицательное = отказ запуска; каппит КУМУЛЯТИВНУЮ трату книги, а не приращение прогона. `--max-units` (D39.165 §1б; механика и денежный отчёт — D39.170) — ОБЪЁМ: не больше N ВЫХОДНЫХ ЮНИТОВ (гранулярность `units_total` манифеста, та самая, в которой платформа продаёт главы) будет ОПЛАЧЕНО этим прогоном. $0-юниты (резюм, ре-пин) потолок не тратят. Принимает только `translate`. **Остановка по объёму — ЗАВЕРШЕНИЕ (exit 0), а не пауза:** различение живёт в отчёте прогона и в логе. ⚠ На книге, которая МАЙНИТ банк, вторая покупка требует `--resnapshot` (авто-банк растёт между покупками и двигает edit-снапшот) — прогон предупреждает об этом в логе. main — тонкая обвязка: разбор/exit-коды/.env/рендеры в тестируемых функциях | `main.go`, `invocation.go`, `render.go`, `dotenv.go` |
| `internal/llm` | OpenAI-совместимый транспорт + retry/backoff, **capability-слой** (budget_field/temperature/reasoning per-модель), провайдеры openai/local (no-proxy)/anthropic (DEPRECATED-референс); `failover.go` удалён паком-17 — маршрутизация лейблами живёт в config/pipeline (канал B, один хоп `chain[0]`, fail-closed) | `httpllm.go`, `capability.go`, `provider_*.go` | | `internal/llm` | OpenAI-совместимый транспорт + retry/backoff, **capability-слой** (budget_field/temperature/reasoning per-модель), провайдеры openai/local (no-proxy)/anthropic (DEPRECATED-референс); маршрутизация лейблами живёт в config/pipeline (канал B, один хоп `chain[0]`, fail-closed; D4/D39.26) | `httpllm.go`, `capability.go`, `provider_*.go` |
| `internal/ledger` | Цены по usage (вкл. reasoning/cache-поля), `PriceForResponse` по фактической модели | `pricing.go` | | `internal/ledger` | Цены по usage (вкл. reasoning/cache-поля), `PriceForResponse` по фактической модели | `pricing.go` |
| `internal/store` | SQLite (modernc, CGO-free), цепочка миграций `schema_version`, reserve/settle+checkpoint, chunk_status, глоссарий (+подписной цикл терминолога), ruby, retrieval_state, request_log; `OpenReadOnly` — без flock/миграций/recovery для status/report/export (схема не совпала — типизированный `*store.SchemaMismatchError{Found,Expected}`, обе стороны); `Migrate` (+шов `beforeApply` под локом: restore point берётся там) — поверхность деплой-шага строки 174, `SchemaHead` — та самая `Expected`; write-open БД новее бинаря теперь ОТКАЗ, а не тихое открытие | `ledger.go`, `migrate.go`, `glossary.go`, `store.go` | | `internal/store` | SQLite (modernc, CGO-free), цепочка миграций `schema_version`, reserve/settle+checkpoint, chunk_status, глоссарий (+подписной цикл терминолога), ruby, retrieval_state, request_log; `OpenReadOnly` — без flock/миграций/recovery для status/report/export (схема не совпала — типизированный `*store.SchemaMismatchError{Found,Expected}`, обе стороны); `Migrate` (+шов `beforeApply` под локом), `SchemaHead` — та самая `Expected`; write-open БД новее бинаря ОТКАЗ (D39.134) | `ledger.go`, `migrate.go`, `glossary.go`, `store.go` |
| `internal/config` | fail-fast загрузка models/pipeline/book; **эхо-мина-гейт** `echoMineViolation`; `CheckRunnable` блокирует неисполнимое (C2/fanout/judge); **пар-слой** (D39.23): `configs/pairs/<пара>.yaml` — калибровка нарезки + коридор длины пары; **промпт-резолв КОНВЕНЦИЕЙ** `prompts/<пара>/<роль>.md` из `Book.LangPair()`+роли, **fail-loud на пару без пакета** (ja-книга не едет молча через zh-промпт), осознанное исключение — `prompt_override` на стадии | `models.go`, `pipeline.go`, `pair.go` | | `internal/config` | fail-fast загрузка models/pipeline/book; **эхо-мина-гейт** `echoMineViolation`; `CheckRunnable` блокирует неисполнимое (C2/fanout/judge); **пар-слой** (D39.23): `configs/pairs/<пара>.yaml` — калибровка нарезки + коридор длины пары; **промпт-резолв КОНВЕНЦИЕЙ** `prompts/<пара>/<роль>.md` из `Book.LangPair()`+роли, **fail-loud на пару без пакета** (ja-книга не едет молча через zh-промпт), осознанное исключение — `prompt_override` на стадии | `models.go`, `pipeline.go`, `pair.go` |
| `internal/text` | Нормализация и рун-примитивы, общие для банка/майнера/чекеров (script-agnostic слой, `lang` НЕ импортирует): `NormalizeSourceKey`/`NormalizeTargetForm` (версионированный артефакт `NormVersion()`, фолдится в снапшот), `NormalizeSource`, `TokenizeScript` (алфавит цели из данных, Mn-фолд U+0301; `TokenizeCyrillic` = ru-дефолт-обёртка), `DenseScript` — единый дом sizing-таксономии (D39.64) | `norm.go`, `runes.go`, `source.go` | | `internal/text` | Нормализация и рун-примитивы, общие для банка/майнера/чекеров (script-agnostic слой, `lang` НЕ импортирует): `NormalizeSourceKey`/`NormalizeTargetForm` (версионированный артефакт `NormVersion()`, фолдится в снапшот), `NormalizeSource`, `TokenizeScript` (алфавит цели из данных, Mn-фолд U+0301; `TokenizeCyrillic` = ru-дефолт-обёртка), `DenseScript` — единый дом sizing-таксономии (D39.64) | `norm.go`, `runes.go`, `source.go` |
| `internal/seed` | Схема сид-YAML книги (`File`/`Term`/`Decl`/`Alias`) — общий артефакт: майнер её ПИШЕТ (mined-дельта), банк ЧИТАЕТ (`LoadGlossarySeed`); тип общий, поэтому эмиссия не может разъехаться с загрузчиком | `seed.go` | | `internal/seed` | Схема сид-YAML книги (`File`/`Term`/`Decl`/`Alias`) — общий артефакт: майнер её ПИШЕТ (mined-дельта), банк ЧИТАЕТ (`LoadGlossarySeed`); тип общий, поэтому эмиссия не может разъехаться с загрузчиком | `seed.go` |
@ -33,7 +33,7 @@
5. **Эскалация:** ровно 1 хоп, результат РЕ-гейтится, retry-бюджет не сбрасывается, editor pinned, канал adult — только permissive (fail-closed). 5. **Эскалация:** ровно 1 хоп, результат РЕ-гейтится, retry-бюджет не сбрасывается, editor pinned, канал adult — только permissive (fail-closed).
6. **Детерминизм:** рендер — чистая функция snapshot; сортировки перед записью; никакого map-order в выводе; length-prefixed хэши; сорс-чанкер lossless (fuzz). 6. **Детерминизм:** рендер — чистая функция snapshot; сортировки перед записью; никакого map-order в выводе; length-prefixed хэши; сорс-чанкер lossless (fuzz).
7. **Нейтральность адаптера:** `internal/llm` не знает про перевод — контент-вердикты в раннере (disposition-слой, post-settle). 7. **Нейтральность адаптера:** `internal/llm` не знает про перевод — контент-вердикты в раннере (disposition-слой, post-settle).
8. **Экспорт-контракт (D39 слой 6, D39.5):** `checks.ExportNormalize` — эфемерная проекция (НЕ входит в request_hash/чекпоинты/деньги), применяется к КАЖДОМУ финальному тексту на всех выдающих поверхностях; **любая внешняя экстракция (полигон!) обязана читать `tmctl export`**, не сырые чекпоинты store — иначе видит ненормализованные байты и молча-неполную книгу (export делает manifest-join + drift-гард, сырое чтение — нет). 8. **Экспорт-контракт (D39 слой 6, D39.5):** `checks.ExportNormalize` — эфемерная проекция (НЕ входит в request_hash/чекпоинты/деньги), применяется к КАЖДОМУ финальному тексту на всех выдающих поверхностях; **любая внешняя экстракция (полигон!) обязана читать `tmctl export`**, не сырые чекпоинты store — иначе видит ненормализованные байты и молча-неполную книгу.
## Подготовка ja-книги (чек-лист сида) ## Подготовка ja-книги (чек-лист сида)
@ -44,9 +44,9 @@
## Как гонять ## Как гонять
Стенд: WSL2 (localhost из-под прокси = 403 — для local-вызовов no-proxy транспорт). Книга-стенд: `/home/ubuntu/books/gu-zhenren/` (GB18030; тексты и производные ВНЕ git; парити-тесты майнера читают отсюда под `TM_MINER_PARITY=1`). Стенд: WSL2 (localhost из-под прокси = 403 — для local-вызовов no-proxy транспорт). Книга-стенд: `/home/ubuntu/books/gu-zhenren/` (GB18030; тексты и производные ВНЕ git).
Батарея — ОДНА команда, `make` из `backend/` (Makefile; собирать её руками больше не нужно): Батарея — ОДНА команда, `make` из `backend/` (Makefile):
```bash ```bash
make battery # build · vet (оба тег-набора, + архитектурные анализаторы) · gofmt · lint · test -race make battery # build · vet (оба тег-набора, + архитектурные анализаторы) · gofmt · lint · test -race
@ -65,7 +65,7 @@ go run ./cmd/tmctl status --config example/book.yaml --json # $0, N/M+пасп
go run ./cmd/tmctl report --config example/book.yaml # $0, quality-report (KPI/rates) go run ./cmd/tmctl report --config example/book.yaml # $0, quality-report (KPI/rates)
go run ./cmd/tmctl export --config example/book.yaml # $0, экспорт-JSON для полигона (--plaintext для человека) go run ./cmd/tmctl export --config example/book.yaml # $0, экспорт-JSON для полигона (--plaintext для человека)
go run ./cmd/tmctl manifest --config example/book.yaml # $0, пере-строить персист манифеста глав/чанков (--json — сам документ) go run ./cmd/tmctl manifest --config example/book.yaml # $0, пере-строить персист манифеста глав/чанков (--json — сам документ)
go run ./cmd/tmctl migrate --config example/book.yaml # $0, довести схему проекта до головы бинаря (деплой-шаг: стоп прогонов → НОВЫЙ бинарь на место → migrate ИМ по каждой книге без открытых попыток → прогоны в работу) go run ./cmd/tmctl migrate --config example/book.yaml # $0, довести схему проекта до головы бинаря (деплой-порядок — D39.134 §3)
go run ./cmd/tmctl translate --config example/book.yaml --ceiling-usd 0.5 # ДЕНЕЖНЫЙ потолок ТОЛЬКО на этот прогон, book.yaml не пишется go run ./cmd/tmctl translate --config example/book.yaml --ceiling-usd 0.5 # ДЕНЕЖНЫЙ потолок ТОЛЬКО на этот прогон, book.yaml не пишется
go run ./cmd/tmctl translate --config example/book.yaml --max-units 10 # ОБЪЁМНЫЙ потолок: оплатить не больше 10 выходных юнитов; стоп = завершение (exit 0) go run ./cmd/tmctl translate --config example/book.yaml --max-units 10 # ОБЪЁМНЫЙ потолок: оплатить не больше 10 выходных юнитов; стоп = завершение (exit 0)
# live-conformance (реальные провайдеры, платно, вне CI): # live-conformance (реальные провайдеры, платно, вне CI):
@ -79,15 +79,15 @@ set -a; . ./.env; set +a; TM_LIVE=1 go test -tags live -run TestLive -v ./intern
| `TestMinerFullBookParity` — единственная сверка Go-порта против Python-эталона на полной книге | `TM_MINER_PARITY=1` | jieba-словарь по внутрирепозиторному ПУТИ `eval/exp16/data/`, но ВНЕ git (`eval/.gitignore:4`) — клон его не получает, регенерируется из jieba 0.42.1 (SHA в `experiments/16-bank-mining.md:183`); плюс `~/books/gu-zhenren/{rerun/records.json, guzhenren-seed-v2.yaml}` | | `TestMinerFullBookParity` — единственная сверка Go-порта против Python-эталона на полной книге | `TM_MINER_PARITY=1` | jieba-словарь по внутрирепозиторному ПУТИ `eval/exp16/data/`, но ВНЕ git (`eval/.gitignore:4`) — клон его не получает, регенерируется из jieba 0.42.1 (SHA в `experiments/16-bank-mining.md:183`); плюс `~/books/gu-zhenren/{rerun/records.json, guzhenren-seed-v2.yaml}` |
| `TestCheckerLabelsBaseline`, `TestCheckerLabelsCandidates`, `TestK6LabelsBaseline` — единственный замер precision/recall $0-гейтов | `TM_CHECKER_LABELS=1` | `~/books/gu-zhenren/labels/` | | `TestCheckerLabelsBaseline`, `TestCheckerLabelsCandidates`, `TestK6LabelsBaseline` — единственный замер precision/recall $0-гейтов | `TM_CHECKER_LABELS=1` | `~/books/gu-zhenren/labels/` |
Флаг переводит отсутствие данных из тихого скипа в громкий `Fatal` — то есть «я это гонял» становится проверяемым. Пути дефолтятся ОТ `$HOME` и от корня репозитория (не от `/home/ubuntu`), так что клон под любым пользователем и по любому пути находит то, что есть; точечные переопределения — `TM_CHECKER_LABELS_DIR`, `TM_MINER_PARITY_{CONTRAST,RECORDS,SEED}`. Пути дефолтятся ОТ `$HOME` и от корня репозитория (не от `/home/ubuntu`), так что клон под любым пользователем и по любому пути находит то, что есть; точечные переопределения — `TM_CHECKER_LABELS_DIR`, `TM_MINER_PARITY_{CONTRAST,RECORDS,SEED}`.
**Golden-гард детерминизма** (`golden_test.go` + `testdata/golden/`): пинит бит-в-бит snapshotID, request_hash, wire-тела, вердикты и resume-байты. Красный golden = wire/вердикты изменились = `--resnapshot` = переоплата. Обновлять ТОЛЬКО на ратифицированной смене поведения: `TM_UPDATE_GOLDEN=1 go test ./internal/pipeline/ -run TestGolden`; при re-capture — **маскированный структурный дифф** (хеши/версии → плейсхолдер) обязан быть пустым, если смена версий не меняла вердиктов. **Golden-гард детерминизма** (`golden_test.go` + `testdata/golden/`): пинит бит-в-бит snapshotID, request_hash, wire-тела, вердикты и resume-байты. Обновлять ТОЛЬКО на ратифицированной смене поведения: `TM_UPDATE_GOLDEN=1 go test ./internal/pipeline/ -run TestGolden`; при re-capture — **маскированный структурный дифф** (хеши/версии → плейсхолдер) обязан быть пустым, если смена версий не меняла вердиктов.
## Известный техдолг (не трогать молча; ЕДИНЫЙ трекер — таблица «Бэклог» в `docs/PROGRESS.md`, номера строк = она) ## Известный техдолг (не трогать молча; ЕДИНЫЙ трекер — таблица «Бэклог» в `docs/PROGRESS.md`, номера строк = она)
- **D15.2:** READ-половина `tmctl export` построена (D39.5); annotation/override-половина и content-addressed resume отложены (строка 49). F3 at-most-once — после D15.2 (строка 50). - **D15.2:** READ-половина `tmctl export` построена (D39.5); annotation/override-половина и content-addressed resume отложены (строка 49). F3 at-most-once — после D15.2 (строка 50).
- **`Retries` НЕ фолдится в снапшот** (pre-existing, D39.4-LOW; сознательно так же для ручки `RegenerateEchoBeforeEscalate`, D39.64 — дефолт 0 = текущее поведение): в крэш-окне пониженный ретрай-бюджет молча бросает оплаченные OK-чекпоинты. - **`Retries` НЕ фолдится в снапшот** (pre-existing, D39.4-LOW; сознательно так же для ручки `RegenerateEchoBeforeEscalate`, D39.64 — дефолт 0 = текущее поведение): в крэш-окне пониженный ретрай-бюджет молча бросает оплаченные OK-чекпоинты.
- ⚠ ALTER-шаги миграций v8+ НЕ идемпотентны вопреки шапке `migrate.go` — полу-применённая БД не сходится (строка 49а). - ⚠ ALTER-шаги миграций v8+ НЕ идемпотентны вопреки шапке `migrate.go` — полу-применённая БД не сходится (строка 49а).
- Открытый остаток строки 79 — граница ПЛОТНОСТИ письма Go-константой `cjkScriptNames` (`internal/lang/script.go`); Cyrillic-хардкоды словесной границы DC-чекеров ПОГАШЕНЫ — она берётся из данных цели (`isTargetWordLetter`/`c.wordScript`, D39.39/D39.78). - Открытый остаток строки 79 — граница ПЛОТНОСТИ письма Go-константой `cjkScriptNames` (`internal/lang/script.go`).
- `prompts/zh-ru/editor-mono.md` — DORMANT-референс D13.1 (не боевой, тестом закреплён); боевой = `prompts/zh-ru/editor.md` v3-discourse (БИЛИНГВ). Глосс-капы санитайзера (6 CJK / 24 лат-токен) — tunable-эвристики (D39.5). Флоры min_max_tokens = схема (D24.3). - `prompts/zh-ru/editor-mono.md` — DORMANT-референс D13.1 (не боевой, тестом закреплён); боевой = `prompts/zh-ru/editor.md` v3-discourse (БИЛИНГВ). Глосс-капы санитайзера (6 CJK / 24 лат-токен) — tunable-эвристики (D39.5). Флоры min_max_tokens = схема (D24.3).
- Хвост LOW/NOTE-находок адверсариала D39.4 — в ledger-очереди (строка 53). - Хвост LOW/NOTE-находок адверсариала D39.4 — в ledger-очереди (строка 53).

View file

@ -186,7 +186,7 @@ about work»*. Асимметрия уже узаконена, и аргумен
Совершив необратимое — потратив деньги, записав файл, удалив файл, — движок обязан **сначала** выдать Совершив необратимое — потратив деньги, записав файл, удалив файл, — движок обязан **сначала** выдать
отчёт об этом и **только потом** сообщать об ошибке, случившейся позже на том же пути. Ошибка ПОСЛЕ отчёт об этом и **только потом** сообщать об ошибке, случившейся позже на том же пути. Ошибка ПОСЛЕ
необратимого действия не смеет ехать маршрутом, который отчёт подавляет. необратимого действия не смеет ехать маршрутом, который отчёт подавляет.
*Экземпляры: A3а · A2.* *Экземпляры: A3а.*
### Ст. 3. Расширение каналов — ЧЕТЫРЕ класса, и они РАЗНОЙ цены ### Ст. 3. Расширение каналов — ЧЕТЫРЕ класса, и они РАЗНОЙ цены
@ -207,7 +207,7 @@ number up; a class this build has never heard of still lands inside the band and
фаза идёт после оплаченной черновой волны. фаза идёт после оплаченной черновой волны.
⛔ **ОГОВОРКА К ДЕШЕВИЗНЕ ПОЛОСЫ — она из находки A15 (§6), и без неё закон разрешает удешевлённо делать ⛔ **ОГОВОРКА К ДЕШЕВИЗНЕ ПОЛОСЫ — она из находки A15 (§6), и без неё закон разрешает удешевлённо делать
то, что сам же называет опасным.** Противоречие поймал оркестратор №21 при чтении дизайна; формулировка моя. то, что сам же называет опасным.**
Довод, которым полоса удешевлена, — «незнакомый номер поглощается ЧЛЕНСТВОМ и читается `refused`, а не Довод, которым полоса удешевлена, — «незнакомый номер поглощается ЧЛЕНСТВОМ и читается `refused`, а не
`failed`». Это верно **по оси НОМЕРА и только по ней.** A15 показала, что разошёлся не номер, а **ОБЕЩАНИЕ** `failed`». Это верно **по оси НОМЕРА и только по ней.** A15 показала, что разошёлся не номер, а **ОБЕЩАНИЕ**
@ -253,18 +253,15 @@ number up; a class this build has never heard of still lands inside the band and
* ⚠ **И собственная ловушка среза, замеренная мной на живых деньгах:** `ok=0 AND cost_usd>0` **НЕ ЕСТЬ * ⚠ **И собственная ловушка среза, замеренная мной на живых деньгах:** `ok=0 AND cost_usd>0` **НЕ ЕСТЬ
«оплачено впустую»**. На `coldrun-v16` в этих 11 строках ($0.12316089) лежат три РАЗНЫЕ вещи: «оплачено впустую»**. На `coldrun-v16` в этих 11 строках ($0.12316089) лежат три РАЗНЫЕ вещи:
`degraded=cjk_artifact` у роли **classifier** — 3 строки, $0.00918827, **мис-вердикт**, вызовы удались. `degraded=cjk_artifact` у роли **classifier** — 3 строки, $0.00918827, **мис-вердикт**, вызовы удались.
⚠ Это утверждение я пере-обосновала КОДОМ, а не строкой бэклога 105 (адверсариальный проход показал, ⚠ Обоснование — КОДОМ, а не строкой бэклога 105: её предпосылка «`classify_types` выключен во всех
что предпосылка строки — «`classify_types` выключен во всех шиппинг-конфигах» — для ЭТОГО прогона шиппинг-конфигах» для ЭТОГО прогона ЛОЖНА — он его включал. Механизм прямой: `internal/pipeline/chunkrun.go:40`=`SourceEchoExpected: role == roleTerminologist`
ложна: он его включал). Механизм прямой: `internal/pipeline/chunkrun.go:40`=`SourceEchoExpected: role == roleTerminologist`
— исключение из эхо-правила выдано ТОЛЬКО терминологу, хотя формат ответа классификатора — та же — исключение из эхо-правила выдано ТОЛЬКО терминологу, хотя формат ответа классификатора — та же
двуязычная таблица терминов, а докстринг самого поля объясняет, чем это кончается: *«Left on, every двуязычная таблица терминов, а докстринг самого поля объясняет, чем это кончается: *«Left on, every
healthy call of that role lands in request_log as ok=0/degraded=cjk_artifact — poisoning the one signal healthy call of that role lands in request_log as ok=0/degraded=cjk_artifact — poisoning the one signal
that says a provider is misbehaving»*. that says a provider is misbehaving»*.
**И ПРЯМАЯ улика на сами эти три строки, а не только форма кода** — их ответы лежат в **И ПРЯМАЯ улика на сами эти три строки, а не только форма кода:** их ответы лежат в
`checkpoints.response_text` и читаются read-only: три ответа `finish=stop`, длиной 163/101/150 знаков, `checkpoints.response_text`, читаются read-only и здоровы — разбор с числами и содержимым
и содержимое — здоровая таблица `<терм>\t<тип>`: `MONEY_HONESTY_REPORT.md` §5.4. ⇒ вызовы удались, вердикт ложен. ⛔ **Чинить это здесь НЕЛЬЗЯ:** правка применимости эхо-правила двигает
«三转蛊师\tterm / 丙等\ttitle / 元海\tterm / … / 方源\tname». Доля CJK в ней высока ПО СПЕЦИФИКАЦИИ формата.
⇒ вызовы удались, вердикт ложен. ⛔ **Чинить это здесь НЕЛЬЗЯ:** правка применимости эхо-правила двигает
`classifierVersion`, а он — поле снапшота (`snapshot.go`, греп `ClassifierVersion versions the intrinsic`) `classifierVersion`, а он — поле снапшота (`snapshot.go`, греп `ClassifierVersion versions the intrinsic`)
⇒ ярус B (и ровно это записано ценой в строке бэклога 105); `degraded=sanitizer_stripped` у редактора — 1 строка, $0.01865424, ⇒ ярус B (и ровно это записано ценой в строке бэклога 105); `degraded=sanitizer_stripped` у редактора — 1 строка, $0.01865424,
текст **ОТГРУЖЕН**; и лишь $0.09531838 действительно выброшено. **Наивная поверхность назвала бы оператору текст **ОТГРУЖЕН**; и лишь $0.09531838 действительно выброшено. **Наивная поверхность назвала бы оператору
@ -405,8 +402,7 @@ number up; a class this build has never heard of still lands inside the band and
**Что поднимать НЕЛЬЗЯ:** расхождение в свёртке банка между `status` и `export` объявлено **Что поднимать НЕЛЬЗЯ:** расхождение в свёртке банка между `status` и `export` объявлено
СОЗНАТЕЛЬНЫМ (`export.go`, греп `symmetry between two surfaces that answer different questions`). СОЗНАТЕЛЬНЫМ (`export.go`, греп `symmetry between two surfaces that answer different questions`).
Общим делается ТОЛЬКО правило осиротевшей стадии. Общим делается ТОЛЬКО правило осиротевшей стадии.
* ⛔ **ЛОВУШКА, из-за которой наивная правка A7 СОЗДАЁТ новый экземпляр §2.2** (снята адверсариальным * ⛔ **ЛОВУШКА, из-за которой наивная правка A7 СОЗДАЁТ новый экземпляр §2.2:** `projectRebill` пропускает ровно те строки, на которые сработает
проходом, проверена мной по коду): `projectRebill` пропускает ровно те строки, на которые сработает
новое правило — `default: continue // a stage the current pipeline does not run is never re-billed` новое правило — `default: continue // a stage the current pipeline does not run is never re-billed`
(`internal/pipeline/rebill.go`). ⇒ поставив `config_drift=true`, поверхность оставит `rebill_units=0`, а (`internal/pipeline/rebill.go`). ⇒ поставив `config_drift=true`, поверхность оставит `rebill_units=0`, а
человеческий рендер статуса превращает этот флаг в денежное утверждение о пере-оплате, которой не человеческий рендер статуса превращает этот флаг в денежное утверждение о пере-оплате, которой не
@ -422,7 +418,7 @@ number up; a class this build has never heard of still lands inside the band and
* **Нарушено:** §2.3 — метка есть базис без гарантии, и её равенство читается как равенство байтов. * **Нарушено:** §2.3 — метка есть базис без гарантии, и её равенство читается как равенство байтов.
* **Потребитель:** оператор/замер (сравнимость прогонов). Не платформа, не деньги (деньги защищены * **Потребитель:** оператор/замер (сравнимость прогонов). Не платформа, не деньги (деньги защищены
`PromptSHA256` в снапшоте). `PromptSHA256` в снапшоте).
* ⚠ **И решающий довод, которого у меня в первой редакции не было: НОРМА УЖЕ ОБЪЯВЛЕНА И УЖЕ НАРУШЕНА.** * ⚠ **И решающий довод: НОРМА УЖЕ ОБЪЯВЛЕНА И УЖЕ НАРУШЕНА.**
`backend/configs/pipeline-c2.yaml:56` дословно: «**лейбл обязан следовать за новым SHA файла**». Именно `backend/configs/pipeline-c2.yaml:56` дословно: «**лейбл обязан следовать за новым SHA файла**». Именно
это и произошло 01.08 с `prompts/zh-ru/editor.md` при неизменном `v3-discourse-reflow`. ⇒ гейт здесь — это и произошло 01.08 с `prompts/zh-ru/editor.md` при неизменном `v3-discourse-reflow`. ⇒ гейт здесь —
не новый закон, а МАШИНА под уже написанным правилом, которое проза удержать не смогла. Планка не новый закон, а МАШИНА под уже написанным правилом, которое проза удержать не смогла. Планка
@ -453,14 +449,11 @@ number up; a class this build has never heard of still lands inside the band and
`projected_book_usd`. `projected_book_usd`.
* **Класс правки:** новое число (сессия вправе). ⚠ Замер этого прогона: терминологический контур — * **Класс правки:** новое число (сессия вправе). ⚠ Замер этого прогона: терминологический контур —
$0.04980482 из $0.43610966 = **11.42% захода**, и ни цента из этого в проекцию не входило. $0.04980482 из $0.43610966 = **11.42% захода**, и ни цента из этого в проекцию не входило.
* ⛔ **ОСЬ, НАЗВАННАЯ В СТРОКЕ 194, ОПРОВЕРГНУТА ЖИВЫМИ ДАННЫМИ — и это самое важное здесь.** Строка * ⛔ **ОСЬ, НАЗВАННАЯ В СТРОКЕ 194 («на сдвиге снапшота они реально пере-покупаются»), ОПРОВЕРГНУТА
говорит: «на сдвиге снапшота они реально пере-покупаются». Пере-покупка наступает НЕ от сдвига ЖИВЫМИ ДАННЫМИ — и это самое важное здесь.** Ось пере-покупки — **БАЙТЫ БАТЧА**: батчи пере-собираются,
снапшота. Разложение прогона по покупкам (`request_log`, `read-only`): когда растёт множество кандидатов, а оно растёт от каждой новой дочерновленной главы; на оси
П1 `f6bb59d4` — терминология $0.02056340 (классификатор 2 батча + терминолог 2 батча, всё свежее); терминологии снапшот за весь прогон не двигался ни разу. Разложение покупок П1/П2/П3 и прямая улика из
П2 `ce5990b3`**$0.02924141, ВСЕ батчи свежие** (`tm_hit=0`), при том что черновой снапшот не таблицы `jobs``MONEY_HONESTY_REPORT.md` §5.1 (опровержение ратифицировано D39.181 §3).
двигался; П3 `a0958e53`**$0.00, ВСЕ батчи попали в чекпоинты** (`tm_hit=1`), при том что снапшот
как раз СДВИНУЛСЯ (в П3 сработал снапшот-гард). ⇒ ось пере-покупки — **БАЙТЫ БАТЧА**: батчи
пере-собираются, когда растёт множество кандидатов, а оно растёт от каждой новой дочерновленной главы.
Чинить по названной в строке оси значит чинить не то. Чинить по названной в строке оси значит чинить не то.
* ⇒ **A10 и A9 — ОДИН дефект с двух сторон**, и §5 A9 ниже несёт его вторую половину. * ⇒ **A10 и A9 — ОДИН дефект с двух сторон**, и §5 A9 ниже несёт его вторую половину.
@ -626,7 +619,7 @@ json-тегов его типа, и рефлексия читает его бе
исключений по образцу существующего `exempt` (по импорт-пути + базовому имени) и **последним по исключений по образцу существующего `exempt` (по импорт-пути + базовому имени) и **последним по
очереди**: сначала Г1Г3, он дороже и слабее. очереди**: сначала Г1Г3, он дороже и слабее.
### ⛔ ГЛАВНОЕ ОГРАНИЧЕНИЕ ГЕЙТА, и первая редакция его не назвала ### ⛔ ГЛАВНОЕ ОГРАНИЧЕНИЕ ГЕЙТА
**Гейты покрывают НЕ ТЕ каналы, в которые закон маршрутизирует большинство корпуса** (сверка §5 против **Гейты покрывают НЕ ТЕ каналы, в которые закон маршрутизирует большинство корпуса** (сверка §5 против
§7): шесть строк из десяти закон отправляет в §7): шесть строк из десяти закон отправляет в
@ -641,9 +634,9 @@ A3(а) → отчёт + WARN, A3(б) → строка сборки, A4 → те
Статус на 31.08: **Г1 не построен · Г2 не построен · Г3 построен точечно (A4, по снапшотной оси) · Статус на 31.08: **Г1 не построен · Г2 не построен · Г3 построен точечно (A4, по снапшотной оси) ·
репо-гейт A8 построен · Г4 не построен.** репо-гейт A8 построен · Г4 не построен.**
**машинная половина закона достаёт до четырёх строк из десяти.** Это не довод против закона — статьи **машинная половина закона достаёт до четырёх строк из десяти — закон загейчен на 40%.** Это не довод
§2.1§2.5 остаются ревью-вопросами и без машины, — но это ЧЕСТНАЯ цена, и приёмка обязана её знать: против закона: статьи §2.1§2.5 остаются ревью-вопросами и без машины, — но это ЧЕСТНАЯ цена, и приёмка
**закон, поданный как «спроектирован с гейтом», сегодня загейчен на 40%.** Дозакрыть прозаические каналы обязана её знать. Дозакрыть прозаические каналы
можно только гейтом на ТЕКСТ (посадка на сообщение с проверкой красноты при подмене строки, D39.171), и можно только гейтом на ТЕКСТ (посадка на сообщение с проверкой красноты при подмене строки, D39.171), и
это отдельная работа, которую я НЕ проектировала. это отдельная работа, которую я НЕ проектировала.
@ -660,13 +653,9 @@ A3(а) → отчёт + WARN, A3(б) → строка сборки, A4 → те
## 8. Что закон ТРЕБОВАЛ на ратификацию — и что с этим стало ## 8. Что закон ТРЕБОВАЛ на ратификацию — и что с этим стало
**ВСЕ ТРИ РАТИФИЦИРОВАНЫ 31.08 (D39.181) И ПОСТРОЕНЫ.** Список оставлен как он уехал, с исходом каждого: **Все три пункта ратифицированы 31.08 (D39.181) и построены** — перечень в шапке файла, разбор каждого
1. **A5 — поля леджера доставки в кадре `finished`** → ратифицировано, построено. Признак едет ЧИСЛАМИ, и экземпляра — `MONEY_HONESTY_REPORT.md` §9.
присутствие объекта `volume` и есть признак; ни нового кода выхода, ни нового значения `Outcome`. **A10 оркестратор НЕ отнёс к классу «новое поле»**: это исправление ДЕРИВАЦИИ существующей фигуры,
2. **A7/A12 — `config_drift_basis` в `status --json`** → ратифицировано, построено на ОБЕИХ поверхностях,
и `build` его слушает.
3. **Сам закон** → норма зоны.
**A10 оркестратор отнёс к пункту 1**, а не к новому полю: это исправление ДЕРИВАЦИИ существующей фигуры,
что закон и предписывает. Условие — «ни одна фигура, которую читает платформа, не смеет сменить смысл» — что закон и предписывает. Условие — «ни одна фигура, которую читает платформа, не смеет сменить смысл» —
выполнено и предъявлено тестом (`committed_usd` остаётся `SUM(checkpoints)` до микро-доллара). выполнено и предъявлено тестом (`committed_usd` остаётся `SUM(checkpoints)` до микро-доллара).
@ -674,6 +663,5 @@ A3(а) → отчёт + WARN, A3(б) → строка сборки, A4 → те
* **Не проверяла, согласится ли платформа** декодировать предложенные поля — чужая зона, вопрос уехал * **Не проверяла, согласится ли платформа** декодировать предложенные поля — чужая зона, вопрос уехал
пингом вместе с дизайном. пингом вместе с дизайном.
* **A13 и A14 помечены PLAUSIBLE**: они выведены из кода и комментариев, живьём не воспроизводились.
* Реестр Г1 оценён по составу документов, но **не написан**; цена «одна запись на поле» — оценка, а не * Реестр Г1 оценён по составу документов, но **не написан**; цена «одна запись на поле» — оценка, а не
замер. замер.

View file

@ -4,6 +4,15 @@
(оркестратор №21, 31.08). Написана **ДО первой правки** дерева; ниже — состояние на момент написания, (оркестратор №21, 31.08). Написана **ДО первой правки** дерева; ниже — состояние на момент написания,
она не переписывается задним числом (дополнения помечаются датой и словом «дописано»). она не переписывается задним числом (дополнения помечаются датой и словом «дописано»).
> ⚠ **Дописано 02.09 — указатели и исходы; тело записки НЕ переписывается (это пре-регистрация).**
> Промт переехал: `docs/archive/prompts/BACKEND_MONEY_HONESTY_SESSION_PROMPT.md`. Прожитый дамп пака из
> секции «Бэкенд» `docs/PROGRESS.md` снят 02.09 — исходы живут в `MONEY_HONESTY_REPORT.md`.
> Пак ЗАЛЕНДЖЕН `bb541a8` и принят **D39.182**; закон раскрытия ратифицирован **D39.181**.
> ⚠ Два места ниже опровергнуты собственной же работой пака, и оба разобраны в отчёте:
> «22.6%» (§4) — ответ на ДРУГОЙ вопрос, величина завышения = **29.2%** (отчёт §5.4); пред-регистрированная
> посадка A9 (§2, «воспроизведение перерасхода фикстурой + посадка») НЕ написана — долг назван прямо
> в отчёте §8 п.1.
**Личность старта.** HEAD `9d27c0b`, дерево ЧИСТО (`git status --short` → пусто). **Личность старта.** HEAD `9d27c0b`, дерево ЧИСТО (`git status --short` → пусто).
Go-модуль `backend/`. Пак **$0**: платных вызовов не содержит и не планирует. Go-модуль `backend/`. Пак **$0**: платных вызовов не содержит и не планирует.

View file

@ -131,6 +131,12 @@ A0, и свёртку трогать не нужно. Свёртку я не т
| `TestShippingPipelinesRegenerateEchoBeforeEscalating` | снять ключ из `pipeline-arm-glm.yaml` | `--- FAIL … pipeline-arm-glm.yaml: … = 0, want 1` | | `TestShippingPipelinesRegenerateEchoBeforeEscalating` | снять ключ из `pipeline-arm-glm.yaml` | `--- FAIL … pipeline-arm-glm.yaml: … = 0, want 1` |
| `TestEchoRegenFiresONLYForEcho` | снять проверку ПРИЧИНЫ, оставив `attempt < echoRegen` | `--- FAIL … primary calls = 2, want 1` | | `TestEchoRegenFiresONLYForEcho` | снять проверку ПРИЧИНЫ, оставив `attempt < echoRegen` | `--- FAIL … primary calls = 2, want 1` |
⚠ **Граница, которую §6 промта требует различать, а одна строка «проверены краснотой» стирает:**
буквально «красная на состоянии ДО правки» здесь ОДНА — `TestShippingPipelinesRegenerateEchoBeforeEscalating`
(правка A1 есть ДАННЫЕ, и он краснеет на конфигах HEAD пятью строками, по одной на файл). Остальные три
на состоянии ДО правки ЗЕЛЁНЫЕ: они держат МЕХАНИЗМ, которым правка пользуется, и краснеют на мутациях
кода. Это не подгонка, а разные предметы — но отчёт обязан их различать.
**Ручка была БЕЗ ЕДИНОГО ТЕСТА** до этого пака (`grep -rn RegenerateEchoBeforeEscalate --include=*_test.go` → пусто). **Ручка была БЕЗ ЕДИНОГО ТЕСТА** до этого пака (`grep -rn RegenerateEchoBeforeEscalate --include=*_test.go` → пусто).
Включать в шиппинг ручку на денежном пути, которую держит только чтение кода, я не стала. Включать в шиппинг ручку на денежном пути, которую держит только чтение кода, я не стала.
@ -293,6 +299,27 @@ WARN'а, процитированного промтом. Следующий б
* **Ярус B** — не тронут ничем: эффорт редактора, потолок вывода, свёртка ре-генов, метка-из-хеша. * **Ярус B** — не тронут ничем: эффорт редактора, потолок вывода, свёртка ре-генов, метка-из-хеша.
* **`platform/`** — только чтение. Найденное там (A15) уехало пингом, файл не тронут. * **`platform/`** — только чтение. Найденное там (A15) уехало пингом, файл не тронут.
## 6.2 Адверсариальный проход по СВОЕЙ ГОТОВОЙ работе (промт §7.5/§7.8) — обязательный артефакт
**Два веера, 29 агентов.** Веер 1 — грунтовка корпуса (22: два картографа каналов + десять читателей по
строке корпуса + десять адверсариальных верификаторов ПОВЕРХ отчёта каждого читателя; вход — код обеих
зон read-only, БД прогона `?mode=ro`, текст промта КАК ПРИОР). Веер 2 — проход по ГОТОВОЙ работе (7:
шесть линз — посадки · каждое число · закон против своего корпуса · код-дифф · заказ против выдачи ·
решение по A9 — плюс седьмая, механическая сверка с заказом по трёхисходной шкале §6, то есть
интервальная сверка субагенту с явными критериями). Мандат дословно: «найди, где она выдаёт
непроверенное за проверенное». Линзе посадок было велено мутировать КОПИЮ дерева в `/tmp`; реальное
дерево агенты не трогали (проверено ими же по md5).
**Вердикты шести линз:** 2 × `MATERIALLY_WRONG` (закон против корпуса; код-дифф), 4 ×
`SOUND_WITH_CORRECTIONS`; линз, не нашедших ничего, НОЛЬ. **25 находок, из них 7 блокеров** — они
переписали §3.3, добавили три посадки, которых без них не было (`TestAUnitWhoseEDITFlaggedIsStillNewBook`,
`TestEchoRegenFiresONLYForEcho`, `TestDeliveryIsReadFromTheSHIPPINGWaveOnADraftOnlyPipeline`) и сняли
мой же довод §5.3 п.3 как неверный.
Диспозиции вплетены в §3§9 по месту.
**Отступление, которое называю сама: модель агентам я ЯВНО НЕ ЗАДАВАЛА** — они унаследовали модель
сессии (Opus 5), тогда как промт §7 велит задавать её ИМЕНЕМ.
--- ---
## 7. ПИНГИ оркестратору №21 — доставлены; открытыми остались ДВА ## 7. ПИНГИ оркестратору №21 — доставлены; открытыми остались ДВА
@ -418,7 +445,7 @@ consolidated» — потому что `unanswered` в одиночку чита
а не `null`). а не `null`).
⚠ Новое поле кадра бампает МИНОР потока: `StreamVersion` = `1.2` (`internal/runevents/runevents.go`) — ⚠ Новое поле кадра бампает МИНОР потока: `StreamVersion` = `1.2` (`internal/runevents/runevents.go`) —
правило записано в комментарии над самой константой, и первая редакция правки его нарушила. Платформенное правило записано в комментарии над самой константой. Платформенное
зеркало не тронуто: мажор совпадает. зеркало не тронуто: мажор совпадает.
### 9.6 A6 — деньги слепы к правке исходника на месте ### 9.6 A6 — деньги слепы к правке исходника на месте
@ -494,11 +521,8 @@ was taken`). Посадка `TestTheContourDoesNotWeakenTheConsentGate`: мут
Я не стала печатать старую фразу рядом с новой ради совпадения грепа: это было бы вводить в заблуждение Я не стала печатать старую фразу рядом с новой ради совпадения грепа: это было бы вводить в заблуждение
ради зелени, то есть нарушать закон, который я же пишу. Предпосылка переведена с подстроки на ФАКТ ради зелени, то есть нарушать закон, который я же пишу. Предпосылка переведена с подстроки на ФАКТ
(`lastTerminology.BatchesDropped == 0`) — строго сильнее и ровно то, что предписывает D39.171. (`lastTerminology.BatchesDropped == 0`) — строго сильнее и ровно то, что предписывает D39.171.
Оркестратор правку ОСТАВИЛ, проверив дифф сам (удалены ровно две строки предпосылки, утверждение стоит Оркестратор правку ОСТАВИЛ, проверив дифф сам; условия и разбор всех трёх касаний — **D39.182 §2**.
контекстной строкой): запрет канона бьёт по УТВЕРЖДЕНИЮ теста, а сменён был МЕХАНИЗМ ПРЕДПОСЫЛКИ — с ⚠ Порядок был нарушен: правка, потом пинг, а правило говорит «пинг, НЕ правка».
механизма, который проект ратифицированно считает дефектным (D39.171), на структурный факт. ⚠ Общей нормы
«правка предпосылки ≠ правка утверждения» он НЕ устанавливает — она унесена владельцу вопросом (D39.182
§2). ⚠ Порядок был нарушен: правка, потом пинг, а правило говорит «пинг, НЕ правка».
⚠ **ВТОРАЯ ПОЛОВИНА ТОГО ЖЕ ТЕСТА ОСТАВЛЕНА НА ТОЙ ЖЕ БОЛЕЗНИ — СОЗНАТЕЛЬНО, и это строка для следующего.** ⚠ **ВТОРАЯ ПОЛОВИНА ТОГО ЖЕ ТЕСТА ОСТАВЛЕНА НА ТОЙ ЖЕ БОЛЕЗНИ — СОЗНАТЕЛЬНО, и это строка для следующего.**
Сохранённое утверждение `strings.Contains(out, "EMPTY completion")` стоит на ТОМ ЖЕ механизме, который я Сохранённое утверждение `strings.Contains(out, "EMPTY completion")` стоит на ТОМ ЖЕ механизме, который я
@ -542,8 +566,5 @@ D39.182 §2): ПРЕДПОСЫЛКА `bankfixpack_test.go` (§9.10) · УТВЕ
## 11. Состояние на закрытии пака ## 11. Состояние на закрытии пака
Обе фазы отработаны. Закон ратифицирован (D39.181) и применён к десяти экземплярам; корпус вырос до Обе фазы отработаны, пак принят и заленджен (§0, шапка). **Открытое оставлено НАЗВАННЫМ, а не
четырнадцати, и четыре лишних нашла мерка, а не заказ. Тридцать три посадки, каждая красная под своей закрытым:** долг по посадке A9 (§8 п.1) и вторая половина чужого теста на дефектном механизме (§9.10).
мутацией; батарея зелёная с кодом, снятым с самого `make`, и тремя названными скипами. Открытое оставлено
НАЗВАННЫМ, а не закрытым: долг по посадке A9 (§8 п.1) и вторая половина чужого теста на дефектном
механизме (§9.10). Пак принят и заленджен 31.08 — `bb541a8`, нота D39.182.

View file

@ -190,19 +190,17 @@ file or directory` — та же причина, по которой красе
«пак улучшает»**: на таком числе событий это шум (Фишер p≈0.5); решающее и достаточное — что флейк «пак улучшает»**: на таком числе событий это шум (Фишер p≈0.5); решающее и достаточное — что флейк
живёт на дереве, которого пак не касался. Окончательная атрибуция — 5-раундовый A/B в §31. живёт на дереве, которого пак не касался. Окончательная атрибуция — 5-раундовый A/B в §31.
## 11. Три правила протокола, вынесенные инцидентами сессии ## 11. Два правила протокола, вынесенные инцидентами сессии
1. **Харнесс мутаций обязан фингерпринтить цели.** Прогон `mutate.py` был убит таймаутом инструмента, 1. **Эталон самопроверки снимается ДО первого изменения, и харнесс мутаций обязан фингерпринтить цели.**
`finally` не отработал, и посадка M4 (снятый гейт байтового no-op) просидела в Незавершённый прогон `mutate.py` оставил посадку M4 в дереве ~40 минут, выглядящей продакшн-кодом, и
`internal/pipeline/bankdecisions.go` ~40 минут, выглядя продакшн-кодом; сторонний ревьюер снял с сторонний ревьюер снял с этого дерева замеры (он же собрал `tmctl` из незакоммиченного дерева, не
этого дерева замеры и доложил «дефект гейта идемпотентности». Поймал посадку пин сняв отпечаток, — на класс наступили обе стороны). Посадку поймал и правило теперь держит пин
`TestBankApplyRepeatIsAByteNoOp` на первом прогоне после. Харнесс починен (sha256 целей до и после). `TestBankApplyRepeatIsAByteNoOp`: он же документирует и форму инцидента, и довод (инод плюс
Пин усилен по следу: повтор проверяется над файлом с РУЧНЫМ комментарием в шапке — это то, что рукописный комментарий в шапке — то, что пере-рендер уничтожает, а проверка содержимого не заметила
пере-рендер уничтожает и чего не заметила бы проверка содержимого — плюс что `changed:false` не врёт. бы). ⚠ Класс повторился следующей сессией ВНУТРИ самого харнесса — §25; отпечаток целей и каталога у
2. **Снимай отпечаток дерева ПЕРЕД сборкой бинаря замера.** Симметричная половина того же класса: инструмента сегодня свой — §16.
ревьюер собрал `tmctl` из незакоммиченного дерева, не сняв отпечаток, и инструмент унаследовал 2. **Одиночный прогон — не замер.** Атрибуцию флейков я сперва вывел из одного прогона («зелено в
посадку. За сессию на это наступили обе стороны.
3. **Одиночный прогон — не замер.** Атрибуцию флейков я сперва вывел из одного прогона («зелено в
изоляции ⇒ нагрузка»), затем другой одиночный прогон дал ровно обратное. Решает только чередующийся изоляции ⇒ нагрузка»), затем другой одиночный прогон дал ровно обратное. Решает только чередующийся
A/B (§10 п.7). A/B (§10 п.7).
@ -227,10 +225,8 @@ file or directory` — та же причина, по которой красе
## 13. Дифф `^func Test` — исполнением ## 13. Дифф `^func Test` — исполнением
**Удалено: НОЛЬ.** Добавлено 59 тест-функций в шести НОВЫХ файлах + `TestTheRefusalTableIsTotal` в **Удалено: НОЛЬ** — сводный счёт по трём пакам и обе команды в §40. Новых тест-функций пака шесть файлов
существующем `cmd/tmctl/exitcontract_test.go` + 2 фаззера — снято командами несут в себе, плюс `TestTheRefusalTableIsTotal` в существующем `cmd/tmctl/exitcontract_test.go`.
`git diff -U0 -- backend | grep -E "^[+-]func Test"` и `git ls-files --others --exclude-standard --
backend | grep '_test.go$' | xargs grep -h '^func Test' | wc -l`.
**Тронуто в существующих файлах — шесть, ни у одной сигнатура не изменилась:** **Тронуто в существующих файлах — шесть, ни у одной сигнатура не изменилась:**
- `exitcontract_test.go` — в список полосы добавлены `exitSchemaMismatch` и `exitDecisionsRejected` - `exitcontract_test.go` — в список полосы добавлены `exitSchemaMismatch` и `exitDecisionsRejected`
@ -248,8 +244,7 @@ backend | grep '_test.go$' | xargs grep -h '^func Test' | wc -l`.
# Дофикс той же двери (сессия 25.08.2026) # Дофикс той же двери (сессия 25.08.2026)
Промт (16 пунктов §4) архивирован — `docs/archive/prompts/BACKEND_SEAM_FIX_SESSION_PROMPT_2026-08-27.md`; Промт (16 пунктов §4) архивирован — `docs/archive/prompts/BACKEND_SEAM_FIX_SESSION_PROMPT_2026-08-27.md`;
записка-план — `SEAM_FIX_PLAN.md`. Секции 013 выше — улика приёмки, не тронуты. **Каждое число ниже — с записка-план — `SEAM_FIX_PLAN.md`. Секции 013 выше — улика приёмки, не тронуты.
командой, которой получено;** команды из `backend/`.
## 14. Батареи ## 14. Батареи
@ -566,12 +561,12 @@ YAML не накладывает ничего. Новый гоняет прои
## 25. Правило протокола, вынесенное инцидентом ЭТОЙ сессии ## 25. Правило протокола, вынесенное инцидентом ЭТОЙ сессии
**Инструмент, который сторожит от подсадки, сам подсадил.** Первая версия `tmmutate` **Инструмент, который сторожит от подсадки, сам подсадил.** Первая версия `tmmutate`
читала-правила-писала файл ОДИН РАЗ НА ПРАВКУ. У мутации B две правки в ОДНОМ файле — и «нетронутая» читала-правила-писала файл ОДИН РАЗ НА ПРАВКУ: у мутации B две правки в ОДНОМ файле, «нетронутая» копия
копия второй правки была снята с уже пропатченного файла; восстановление вернуло пропатченное содержимое, второй снималась с уже пропатченного файла, и sha256-самопроверка сравнивала пропатченное с пропатченным
а sha256-самопроверка сравнила его с пропатченным же хешем и **прошла**. Дерево копии осталось же хешем — **проходила**. ⚠ Цена: дерево копии осталось мутированным, и **два полных раунда измерений
мутированным, и **два полных раунда измерений после этого шли по мутированному коду**: несколько пинов после этого шли по мутированному коду** — несколько пинов отчитались как поймавшие мутации, к которым не
отчитались как поймавшие мутации, к которым не имели отношения. Вскрыто ровно тем, чему учит §11 п.3: имели отношения. Вскрыто ровно тем, чему учит §11 п.2: один подозрительный «RED», пере-проверенный
один подозрительный «RED», пере-проверенный изолированным прогоном, не воспроизвёлся. изолированным прогоном, не воспроизвёлся.
**Починено дважды:** одно чтение и одна запись на файл (порядок объявлен контрактом в комментарии), плюс **Починено дважды:** одно чтение и одна запись на файл (порядок объявлен контрактом в комментарии), плюс
второй независимый рубеж — отпечаток ВСЕХ файлов каталога, снятый на заведомо чистом дереве и второй независимый рубеж — отпечаток ВСЕХ файлов каталога, снятый на заведомо чистом дереве и
@ -611,9 +606,8 @@ YAML не накладывает ничего. Новый гоняет прои
## 27. Дифф `^func Test` — исполнением ## 27. Дифф `^func Test` — исполнением
**Удалено: НОЛЬ** — `git diff -U0 -- backend | grep -cE "^-func (Test|Fuzz)"` → 0, и это проверено **Удалено: НОЛЬ** — сводный счёт и обе команды в §40; поимённая половина проверки прошла по семнадцати
дважды: грепом по диффу и поимённо по семнадцати пинам, которые отчёт пака называет по имени (каждый пинам, которые отчёт пака называет по имени (каждый существует ровно один раз).
существует ровно один раз). Дофикс добавил 38 тест-функций и 1 фаззер поверх 59 + 2 фаззера пака.
**Тронуто (тело изменено, сигнатура — нет), и вот почему это законно:** **Тронуто (тело изменено, сигнатура — нет), и вот почему это законно:**
- `cmd/tmctl/exitcontract_test.go``TestTheRefusalTableIsTotal` перестал держать ручной список и - `cmd/tmctl/exitcontract_test.go``TestTheRefusalTableIsTotal` перестал держать ручной список и
@ -630,7 +624,8 @@ YAML не накладывает ничего. Новый гоняет прои
## 28. Состав дофикса ## 28. Состав дофикса
**Новое:** `internal/seed/normalize.go` (канонический вид документа) · `internal/membank/problems.go` **Новое:** `internal/seed/normalize.go` (канонический вид документа) · `internal/membank/problems.go`
(вердикт загрузчика по субъектам) · `cmd/tmmutate/` (харнесс мутаций + каталог посадок, `python3 -c "import json;print(len(json.load(open('cmd/tmmutate/mutations.json'))))"`**36**) · (вердикт загрузчика по субъектам) · `cmd/tmmutate/` (харнесс мутаций + каталог посадок; счёт записей на
дату дофикса и команда актуального счёта — §16) ·
`internal/pipeline/bankchain_test.go`. `internal/pipeline/bankchain_test.go`.
**Тронуто:** `internal/membank/decisions.go` (доказывающий рендер, нормализация запроса, набор-осознанный **Тронуто:** `internal/membank/decisions.go` (доказывающий рендер, нормализация запроса, набор-осознанный
алиас, перевёрнутое окно, байты результата, `note` не стирается) · `memseed.go`, `memvoice.go` (вердикт алиас, перевёрнутое окно, байты результата, `note` не стирается) · `memseed.go`, `memvoice.go` (вердикт
@ -644,11 +639,9 @@ YAML не накладывает ничего. Новый гоняет прои
## 29. Ревью старшей моделью: три дефекта, каждый воспроизведён МНОЙ и починен ## 29. Ревью старшей моделью: три дефекта, каждый воспроизведён МНОЙ и починен
Ревью запрашивалось по семи решениям, где заказ оставлял форму на сессии. Оно согласилось с пятью, не Ревью запрашивалось по решениям, где заказ оставлял форму на сессии. **Каждую находку сессия
согласилось с одним и нашло три вещи, которых сессия не видела. **Каждую сессия воспроизвела сама воспроизвела сама прежде, чем чинить** — чужой результат, взятый на веру, ровно так же становится
прежде, чем чинить** — не потому что не доверяет, а потому что чужой результат, взятый на веру, ровно нормой. У двух подтверждённых решений ревью дало довод СИЛЬНЕЕ, и довод заменён в комментариях кода: у конверта путей на манифесте — что бамп версии выбросил бы все сохранённые сайдкары
так же становится нормой. У двух подтверждённых решений ревью дало довод СИЛЬНЕЕ, и довод заменён в
комментариях кода: у конверта путей на манифесте — что бамп версии выбросил бы все сохранённые сайдкары
и пере-нарезал каждую книгу ради аддитивного поля; у SIGTERM — атомарность и порядок записей вместо и пере-нарезал каждую книгу ради аддитивного поля; у SIGTERM — атомарность и порядок записей вместо
длины непрерываемого участка. длины непрерываемого участка.
@ -721,9 +714,9 @@ nil, …)` → true и **записала бы файл нулевой длин
## 30. Интервальная самоверификация субагентом: ещё пять дефектов, все воспроизведены и починены ## 30. Интервальная самоверификация субагентом: ещё пять дефектов, все воспроизведены и починены
Ревью гонялось В СЕРЕДИНЕ работы против семи ЯВНЫХ критериев, read-only, в копии. Дерево двигалось под Ревью гонялось В СЕРЕДИНЕ работы против явных критериев, read-only, в копии; дерево под ним двигалось,
ним трижды, поэтому его вердикты пере-исполнены на финальном снимке. Каждый дефект сессия воспроизвела поэтому его вердикты пере-исполнены на финальном снимке. Каждый дефект сессия воспроизвела своим
своим прогоном прежде, чем чинить; воспроизведение каждого теперь живёт в его пине, а не здесь. прогоном прежде, чем чинить; воспроизведение каждого теперь живёт в его пине, а не здесь.
### 1. ⛔ Правило маски проглатывало ливлок, который вносил САМ вызов ### 1. ⛔ Правило маски проглатывало ливлок, который вносил САМ вызов
@ -890,7 +883,10 @@ ApplyBankDecisions → openDecisionRequest · readBookState · decisionReport
**Считать длину функции надо по ТЕЛУ** (от `^func` до первой строки ровно `}`), а не от `^func` до **Считать длину функции надо по ТЕЛУ** (от `^func` до первой строки ровно `}`), а не от `^func` до
следующего `^func`: второе правило на методах даёт мусор, и именно им была получена несуществующая следующего `^func`: второе правило на методах даёт мусор, и именно им была получена несуществующая
«норма репозитория в 75 строк» — такой нормы в проекте НЕТ. «норма репозитория в 75 строк» — такой нормы в проекте НЕТ. **Замерено по ТЕЛУ:** две точки входа — **92**
и **90** строк против **42** у следующей по длине функции тех же двух файлов; максимумы пакетов совсем
другие — **218** (`Status`, `internal/pipeline`) и **105** (`loadVoiceSections`, `internal/membank`);
после разбора самая длинная функция обоих файлов — **44** (`signatureState`).
**И вот чем доказательство эквивалентности ОКАЗАЛОСЬ слабее, чем здесь было написано.** Первая **И вот чем доказательство эквивалентности ОКАЗАЛОСЬ слабее, чем здесь было написано.** Первая
редакция утверждала «весь каталог пере-прогнан, как записано». На деле рефакторинг сломал ДВЕ записи редакция утверждала «весь каталог пере-прогнан, как записано». На деле рефакторинг сломал ДВЕ записи
@ -898,32 +894,26 @@ ApplyBankDecisions → openDecisionRequest · readBookState · decisionReport
провал СБОРКИ красным, то есть две записи не проверяли ничего, а отчёт называл тесты, которые не могли провал СБОРКИ красным, то есть две записи не проверяли ничего, а отчёт называл тесты, которые не могли
отработать. Нашло воркфлоу-ревью; обе записи пере-выражены, у инструмента появился третий вердикт — §34. отработать. Нашло воркфлоу-ревью; обе записи пере-выражены, у инструмента появился третий вердикт — §34.
## 34. Воркфлоу-ревью: шесть осей, 50 находок, 26 переживших скептиков ## 34. Воркфлоу-ревью дофикса: шесть осей, все находки воспроизведены и закрыты
Третье и последнее ревью дофикса — **воркфлоу**, а не одиночный агент: шесть независимых полос читают Третье и последнее ревью дофикса — **воркфлоу**, а не одиночный агент (форма — §45). Полосы выбраны по
дерево параллельно, каждая находка отдаётся отдельному скептику с заданием ЕЁ ОПРОВЕРГНУТЬ, выживает тому, чего не касались два предыдущих ревью: гонка двух `bank-apply` · последствия новых полей для
только то, что он не смог. Полосы выбраны по тому, чего не касались два предыдущих ревью: гонка двух платформы (read-only) · эквивалентность только что сделанного рефакторинга · сам `cmd/tmmutate` (он
`bank-apply` · последствия новых полей для платформы (read-only) · эквивалентность только что сделанного теперь в репозитории, значит продакшн-код) · честность хендофф-документов · общность и безопасность
рефакторинга · сам `cmd/tmmutate` (он теперь в репозитории, значит продакшн-код) · честность данных. Каждая находка перепроверена своим прогоном прежде, чем чинить; правки доводов в комментариях и
хендофф-документов · общность и безопасность данных. **50 сырых находок, 26 пережили скептиков.** Каждая правки в самом этом документе живут по месту, здесь — только то, что осталось фактом.
перепроверена своим прогоном прежде, чем чинить; правки доводов в комментариях и семь правок в самом этом
документе живут по месту, здесь — только то, что осталось фактом.
### ⛔ Главное: две посадки каталога НЕ КОМПИЛИРОВАЛИСЬ — и это внёс мой же рефакторинг ### ⛔ Главное: две посадки каталога НЕ КОМПИЛИРОВАЛИСЬ — и это внёс мой же рефакторинг
`P-alias-judged-on-the-set` и `AB-alias-escape` патчат тело `refuseInertDeclines`, ссылаясь на `in.Delta`. `P-alias-judged-on-the-set` и `AB-alias-escape` патчат тело `refuseInertDeclines`, ссылаясь на `in.Delta`,
Рефакторинг §33 убрал `in` из области видимости этой функции. **Проверено:** прогон всех посадок с которое рефакторинг §33 убрал из области видимости, — а инструмент считал их КРАСНЫМИ, потому что `red`
`go build` после каждой — ровно эти две не собираются (`undefined: in`). А инструмент считал их КРАСНЫМИ, был буквально `terr != nil`, и провал СБОРКИ выглядел так же, как поймавший пин.
потому что `red` был буквально `terr != nil`, и провал СБОРКИ выглядел так же, как поймавший пин.
**Починено на двух уровнях, и это живое свойство инструмента.** **Починено на двух уровнях.** Обе записи пере-выражены под новую сигнатуру и краснеют на своих пинах
(1) Обе записи пере-выражены под новую сигнатуру и краснеют на своих пинах поимённо. поимённо; у инструмента появился ТРЕТИЙ вердикт (`NOTHING` — ни один тест не назвал себя, гейт падает)
(2) У инструмента появился ТРЕТИЙ вердикт. `RED` теперь требует, чтобы хоть один тест назвал себя плюс обязательная зелёная базовая линия пакета ДО первой посадки. ⚠ Оба механизма и провенанс инцидента
(`--- FAIL:`); прогон, в котором не отчитался ни один тест, — это `NOTHING`, и он **роняет гейт**. Плюс живут в самом инструменте — `cmd/tmmutate/main.go`, комментарии «THE PACKAGE MUST BE GREEN BEFORE
перед первой посадкой каждый пакет прогоняется НЕТРОНУТЫМ и обязан быть зелёным: без базовой линии «этот ANYTHING IS PLANTED» и «NOT a red …»; второй копии этот отчёт не держит.
пин ловит эту мутацию» опирается на код возврата, который выдают также сборка, флейк, таймаут и опечатка
в имени пакета. **Негативная проба:** посадка, которая заведомо не компилируется, даёт
`NOTHING … 1 unexpected outcome(s)` и exit 1.
### Продуктовые дефекты — все воспроизведены мной ### Продуктовые дефекты — все воспроизведены мной
@ -946,11 +936,11 @@ ApplyBankDecisions → openDecisionRequest · readBookState · decisionReport
## 35. Проверка ЗАКРЫТИЯ — отдельным воркфлоу, и она нашла, что закрыто не всё ## 35. Проверка ЗАКРЫТИЯ — отдельным воркфлоу, и она нашла, что закрыто не всё
На вопрос «все замечания исправлены?» сессия не отвечала по памяти: четыре независимых агента прошли по На вопрос «все замечания исправлены?» сессия не отвечала по памяти: независимые агенты прошли по всем
всем 26 пережившим находкам §34 и по живому дереву решали КАЖДУЮ — закрыта / не закрыта / частично / пережившим находкам §34 и по живому дереву решали КАЖДУЮ — закрыта / не закрыта / частично / отклонена
отклонена осознанно. **Из 28 проверенных пунктов закрытыми оказались 16, осознанно отклонёнными 2, осознанно. Закрыто оказалось не всё; все остатки доделаны, и их результат живёт не здесь, а в
частично 7 и НЕ закрытыми 3.** Все остатки доделаны, и их результат живёт не здесь, а в исправленных по исправленных по месту секциях (§15, §16, §18, §26, §27, §31, §33) — второй копии этот отчёт намеренно не
месту секциях (§15, §16, §18, §26, §27, §31, §33) — второй копии этот отчёт намеренно не держит. держит.
**Два остатка были признаны вне полномочий пака, и оба закрылись позже:** межкнижная гонка за один **Два остатка были признаны вне полномочий пака, и оба закрылись позже:** межкнижная гонка за один
`mined_delta` — снятием объявляемых ключей (D39.158 п.5; остаток «второй конфиг ТОЙ ЖЕ книги» заведён `mined_delta` — снятием объявляемых ключей (D39.158 п.5; остаток «второй конфиг ТОЙ ЖЕ книги» заведён
@ -958,9 +948,10 @@ ApplyBankDecisions → openDecisionRequest · readBookState · decisionReport
(§43 4.10). (§43 4.10).
**Вывод, который стоит унести дальше самого пака.** Это было ТРЕТЬЕ ревью подряд, и каждое находило **Вывод, который стоит унести дальше самого пака.** Это было ТРЕТЬЕ ревью подряд, и каждое находило
настоящие дефекты, которых не видели предыдущие: одиночный старший ревьюер — три, интервальное — пять, настоящие дефекты, которых не видели предыдущие: одиночный старший ревьюер — три (§29), интервальное —
воркфлоу — двадцать шесть, проверка закрытия — ещё десять остатков. **Ни одно «все замечания исправлены» пять (§30), воркфлоу — двадцать шесть, проверка закрытия — ещё десять остатков (из 28 её пунктов: 16
в этой сессии не оказалось верным при проверке.** Вывод не «ревью бесполезны», а обратный: закрытие надо закрыто, 2 отклонено осознанно, 7 частично, 3 не закрыто). **Ни одно «все замечания исправлены» в этой
сессии не оказалось верным при проверке.** Вывод не «ревью бесполезны», а обратный: закрытие надо
ПРОВЕРЯТЬ отдельно от починки, и не тем, кто чинил. ПРОВЕРЯТЬ отдельно от починки, и не тем, кто чинил.
--- ---
@ -1067,6 +1058,9 @@ $ git diff -U0 -- . | grep -cE "^-func (Test|Fuzz)" → 0
$ git ls-files --others --exclude-standard -- . | grep '_test.go$' \ $ git ls-files --others --exclude-standard -- . | grep '_test.go$' \
| xargs grep -h '^func Test' | wc -l → 117 # было 97: +20 тест-функций (фаззеров по-прежнему 3) | xargs grep -h '^func Test' | wc -l → 117 # было 97: +20 тест-функций (фаззеров по-прежнему 3)
``` ```
**Сводно по трём пакам:** пак оставил 59 тест-функций + 2 фаззера, дофикс добавил 38 + 1, фикс2 — ещё 20;
**удалено за все три пака НОЛЬ**, и это проверено дважды — грепом по диффу и поимённо по пинам, которые
отчёты паков называют по имени.
Переименовано (не удалено): `TestTheStopClearsWhenTheOwnerDecidesTheWholeSignatureMap` Переименовано (не удалено): `TestTheStopClearsWhenTheOwnerDecidesTheWholeSignatureMap`
`TestTheChainOwnerDecidesTheWholeMapAndTheRunGoesOn` (замена по заказу §4.12, новая семантика; вторая цепь — `TestTheChainOwnerDecidesTheWholeMapAndTheRunGoesOn` (замена по заказу §4.12, новая семантика; вторая цепь —
`TestTheStopIsAFlagNotAGateOnDecisions` — и есть пин старой формулы) · `TestDecisionPathsDefaultByConventionOnAnEmptyKey` `TestTheStopIsAFlagNotAGateOnDecisions` — и есть пин старой формулы) · `TestDecisionPathsDefaultByConventionOnAnEmptyKey`
@ -1102,12 +1096,15 @@ $ git ls-files --others --exclude-standard -- . | grep '_test.go$' \
- **Гипотеза §4.13 о пере-оплате терминолога при подписании** механизмом не подтверждена и выигрышем не - **Гипотеза §4.13 о пере-оплате терминолога при подписании** механизмом не подтверждена и выигрышем не
заявляется: память предъявленного не трогает ни состав кандидатов, ни ключ чекпоинта (хеш заявляется: память предъявленного не трогает ни состав кандидатов, ни ключ чекпоинта (хеш
отрендеренных сообщений); `TestTerminologistResumeIsFree` держит $0-резюм в обеих семантиках. отрендеренных сообщений); `TestTerminologistResumeIsFree` держит $0-резюм в обеих семантиках.
- **Поимённой разметки новизны в карте подписи НЕТ**: оператор видит РАЗМЕР карты, а не число новых
термов (баннер стопа больше не выдаёт одно за другое — `renderSignatureStop`, §45). Пер-термная
новизна — продуктовая поверхность, не этот пак.
## 42. Интервальная самоверификация субагентом (§5.1): четыре находки, все minor ## 42. Интервальная самоверификация субагентом (§5.1): четыре находки, все minor
Ревью шло против десяти явных критериев, адверсариально, с исполнением (точечные тесты + посадки в своей Ревью шло против явных критериев, адверсариально, с исполнением (точечные тесты + посадки в своей
копии). Код по всем десяти сошёлся; находки — класс «довод/покрытие», ровно тот, что предыдущая сессия копии). Код сошёлся по всем; находки — класс «довод/покрытие», ровно тот, что предыдущая сессия назвала
назвала своим худшим. Три из них — неверные доводы в докстроках при верном коде (отменённая механика своим худшим. Три из них — неверные доводы в докстроках при верном коде (отменённая механика
«промотируй/отклони, потом re-run» у `renderSignatureStop`; предикат v16 в `migrate.go`, читавшийся как «промотируй/отклони, потом re-run» у `renderSignatureStop`; предикат v16 в `migrate.go`, читавшийся как
«любая поверхность вне памяти», тогда как код стреляет только на кластере, чья ВСЯ поверхность вне; «любая поверхность вне памяти», тогда как код стреляет только на кластере, чья ВСЯ поверхность вне;
описание стоп-окна в `bankapply.go`), все переписаны по месту. ⚠ Третья правка сама внесла ложь про описание стоп-окна в `bankapply.go`), все переписаны по месту. ⚠ Третья правка сама внесла ложь про
@ -1153,11 +1150,10 @@ retired-ключи ловятся полями, а не голым strict-decode
Прогнана по презумпции «каждое заявленное закрытие ложно, пока не увидено исполнением»: все 13 строк §43 Прогнана по презумпции «каждое заявленное закрытие ложно, пока не увидено исполнением»: все 13 строк §43
и все 4 диспозиции §42 подтверждены в дереве (13 точечных тестовых прогонов + 3 полных пакета — зелёные; и все 4 диспозиции §42 подтверждены в дереве (13 точечных тестовых прогонов + 3 полных пакета — зелёные;
носители по file:line; реверс-пин признан невакуумным с названным механизмом падения). Найдено ПЯТЬ носители по file:line; реверс-пин признан невакуумным с названным механизмом падения). Расхождения нашлись
расхождений — традиция «ни одно "всё исправлено" не выдерживает проверки» держится и на этой сессии. и здесь (⚠-вывод §35 держится и на этой сессии), все закрыты по месту — правки видны в §38, §40 и §42.
Все пять закрыты по месту (правки видны в §38, §40 и §42), и одно стоит того, чтобы его запомнили: Одно стоит того, чтобы его запомнили: пере-замер §4.4 жил только в скратчпаде — то есть был «числом без
пере-замер §4.4 жил только в скратчпаде — то есть был «числом без первоисточника» ровно того класса, за первоисточника» ровно того класса, за который заказ корил чужие числа; первоисточник положен в дерево постоянным якорем-пином
который заказ корил чужие числа; первоисточник положен в дерево постоянным якорем-пином
`internal/miner/emissioncap_test.go`. `internal/miner/emissioncap_test.go`.
## 45. Воркфлоу-ревью фикс2: две кодовые находки и три остатка, которые оно сузило ## 45. Воркфлоу-ревью фикс2: две кодовые находки и три остатка, которые оно сузило
@ -1165,9 +1161,8 @@ retired-ключи ловятся полями, а не голым strict-decode
Форма: шесть параллельных полос-искателей под антипаттерны проекта (неверные доводы при верном коде · Форма: шесть параллельных полос-искателей под антипаттерны проекта (неверные доводы при верном коде ·
вакуумные пины · семантика флажка глубоким чтением · дверь/отчёт глубоким чтением · общность движка · вакуумные пины · семантика флажка глубоким чтением · дверь/отчёт глубоким чтением · общность движка ·
шов/контракт), каждая находка — через трёх адверсариальных скептиков с разными линзами (корректность шов/контракт), каждая находка — через трёх адверсариальных скептиков с разными линзами (корректность
трассой · достижимость · «не принятый ли уже остаток»), выживание — большинство. 23 сырых находки, трассой · достижимость · «не принятый ли уже остаток»), выживание — большинство. Все выжившие находки
20 выживших, 16 уникальных, все закрыты. Правки доводов в комментариях и документах живут по месту; закрыты; правки доводов в комментариях и документах живут по месту, здесь — то, что осталось фактом.
здесь — то, что осталось фактом.
**Кодовые (2), обе закрыты правкой + пином + посадкой:** **Кодовые (2), обе закрыты правкой + пином + посадкой:**