Take in the engine zone's report of its own pack as the zone wrote it

This commit is contained in:
heaven 2026-09-07 04:53:43 +03:00
parent 5092ae3f0e
commit 0ae9e8a6ea

View file

@ -1,6 +1,6 @@
# Журнал прогресса
> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-09-07, голова D39.221КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и P7 его НЕ размораживает (D39.147). **ОЧЕРЕДЬ №23** (единственный носитель — здесь; роль передана 06.09, №22 закрыт нотой передачи D39.217; ⚠ испр. 06.09: коммит передачи `c992ee5` бампнул голову и НЕ тронул номер — гейта на номер очереди нет вовсе, `counts.py` сверяет только голову, поэтому носитель разошёлся молча). ⚠ **ЗАКАЗ ВЛАДЕЛЬЦА 01.09 — ПЕРВЫМ:** (0а) **ревизия документации на ПРОТУХШЕЕ** — по всем зонам, не только тронутым; (0б) **планы доработок в БЭКЕНД и ПЛАТФОРМУ** по остатку бэклога и регистра; (0в) **вынос неактуального в АРХИВ** (`docs/archive/`, `platform/docs/archive/`) — за сутки 31.08 закрыто много, и часть носителей стала историей. ⚠ Трезвость по масштабу (пере-считано 02.09): **90** живых дока в `docs/` (пере-счёт 04.09: `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`), 8 в `platform/docs`, 9 в `backend/docs` — ⚠ из 94 ВРЕМЕННЫЙ остался ОДИН (`DOC_CLEANUP_PLAN`, живой до закрытия батчей Б14/Б15/Б17); два прежних временных уехали в `archive/reports/` 02.09; счёт бэклога — бюллетенем ниже, открытых рядов регистра платформы — 112 (major 3), всего рядов 465 (пере-счёт `python3 docs/scripts/counts.py`; с 04.09 оба числа под гардом `--check`, прежние 95/3 разошлись молча) ⚠ (ревизией 02.09 ряды **154** и **157** переведены из «скоро» в «когда-нибудь»: их гейтом стоял первый холодный прогон, он ОТРАБОТАЛ 31.08 и оба предусловия оказались другими — разбор в самих ячейках, ни одна НЕ закрыта). ⚠ Числа доков `counts.py` НЕ сторожит — при переносе файлов пере-считывать руками командой `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`. ⚠ И предупреждение о МЕТОДЕ, купленное сменой №21: «выглядит протухшим» ≠ «протухло». Три факта оркестратора опровергнуты ЗАМЕРОМ сессий, а якоря `15-money-path.md` в девяти случаях из двенадцати РОДИЛИСЬ верными и сгнили дрейфом — то есть ревизия обязана быть исполнением, а не чтением. ⚠ **ОЧЕРЕДЬ, унаследованная от №21** (три лендинга 31.08 — секция «СОСТОЯНИЕ ПАКОВ» ниже): **(1) ~~РАЗРЫВ ЦИКЛА~~ ЗАМКНУТ ЖИВЬЁМ 04.09** — пользователь получил EPUB настоящего ПЛАТНОГО перевода ЧЕРЕЗ API, `epubcheck` 5.3.0 на СКАЧАННОМ файле 0/0/0/0 (книга `bk_SS5VES2JELESJSTR`, потрачено $0.278319 из гранта $0.60 при потолке пака $1.5, санкция D39.189). Дверь выдачи построена и проверена исполнением: `202`+`Location`, поллинг с `Retry-After`, Range 206 · второй клиент 200 · аноним 401 · чужая книга 404, TTL с GC, идемпотентность третьего создающего вызова. Все ТРИ сценария строки 216 предъявлены живьём (подпись банка · halt на потолке с exit 4 · `409 run_not_resumable/ceiling_reached` и лечение новым прогоном).
> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-09-07, голова D39.222КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и P7 его НЕ размораживает (D39.147). **ОЧЕРЕДЬ №23** (единственный носитель — здесь; роль передана 06.09, №22 закрыт нотой передачи D39.217; ⚠ испр. 06.09: коммит передачи `c992ee5` бампнул голову и НЕ тронул номер — гейта на номер очереди нет вовсе, `counts.py` сверяет только голову, поэтому носитель разошёлся молча). ⚠ **ЗАКАЗ ВЛАДЕЛЬЦА 01.09 — ПЕРВЫМ:** (0а) **ревизия документации на ПРОТУХШЕЕ** — по всем зонам, не только тронутым; (0б) **планы доработок в БЭКЕНД и ПЛАТФОРМУ** по остатку бэклога и регистра; (0в) **вынос неактуального в АРХИВ** (`docs/archive/`, `platform/docs/archive/`) — за сутки 31.08 закрыто много, и часть носителей стала историей. ⚠ Трезвость по масштабу (пере-считано 02.09): **90** живых дока в `docs/` (пере-счёт 04.09: `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`), 8 в `platform/docs`, 9 в `backend/docs` — ⚠ из 94 ВРЕМЕННЫЙ остался ОДИН (`DOC_CLEANUP_PLAN`, живой до закрытия батчей Б14/Б15/Б17); два прежних временных уехали в `archive/reports/` 02.09; счёт бэклога — бюллетенем ниже, открытых рядов регистра платформы — 112 (major 3), всего рядов 465 (пере-счёт `python3 docs/scripts/counts.py`; с 04.09 оба числа под гардом `--check`, прежние 95/3 разошлись молча) ⚠ (ревизией 02.09 ряды **154** и **157** переведены из «скоро» в «когда-нибудь»: их гейтом стоял первый холодный прогон, он ОТРАБОТАЛ 31.08 и оба предусловия оказались другими — разбор в самих ячейках, ни одна НЕ закрыта). ⚠ Числа доков `counts.py` НЕ сторожит — при переносе файлов пере-считывать руками командой `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`. ⚠ И предупреждение о МЕТОДЕ, купленное сменой №21: «выглядит протухшим» ≠ «протухло». Три факта оркестратора опровергнуты ЗАМЕРОМ сессий, а якоря `15-money-path.md` в девяти случаях из двенадцати РОДИЛИСЬ верными и сгнили дрейфом — то есть ревизия обязана быть исполнением, а не чтением. ⚠ **ОЧЕРЕДЬ, унаследованная от №21** (три лендинга 31.08 — секция «СОСТОЯНИЕ ПАКОВ» ниже): **(1) ~~РАЗРЫВ ЦИКЛА~~ ЗАМКНУТ ЖИВЬЁМ 04.09** — пользователь получил EPUB настоящего ПЛАТНОГО перевода ЧЕРЕЗ API, `epubcheck` 5.3.0 на СКАЧАННОМ файле 0/0/0/0 (книга `bk_SS5VES2JELESJSTR`, потрачено $0.278319 из гранта $0.60 при потолке пака $1.5, санкция D39.189). Дверь выдачи построена и проверена исполнением: `202`+`Location`, поллинг с `Retry-After`, Range 206 · второй клиент 200 · аноним 401 · чужая книга 404, TTL с GC, идемпотентность третьего создающего вызова. Все ТРИ сценария строки 216 предъявлены живьём (подпись банка · halt на потолке с exit 4 · `409 run_not_resumable/ceiling_reached` и лечение новым прогоном).
> ⛔ **ЧЕТЫРЕ ПОТОКА РАБОТЫ И ИХ ЗАВИСИМОСТИ (заведено 06.09; до этого жило только в переписке с владельцем).**
> **(1) ПОЛИГОН — «ремонт прибора»** (`docs/POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md`, строки 319 · 300 · 265 · 143):
> блокирующая линза слепого чтения меряет верность ЧЕРНОВИКУ, а судимой руке предписано отходить от него по исходнику
@ -209,7 +209,7 @@ $0, мои руки, выброшенные пробы. Каждый ноль с
**(е) §4.4 — два ложных комментария сняты.** `waverun.go`: оправдание `nil`-переноса sticky заменено фактом — `assignEditUnits` закрывает единицу внутри главы, sticky сбрасывается на границе ГЛАВЫ, 1962 из 2283 глав многоединичны (замер строки 321, не мой, атрибутирован); перенос НЕ строю. `chunkstatus.go`: см. §5, там моя формулировка была неверна дважды.
**(ж) Попутно исправлена собственная ложь, созданная расширением:** `seeding.go:73` говорил «an UNSIGNED row contradicts an APPROVED term» — неправда для новой половины. На старый текст не стоял ни один тест (`grep` в `*.go` = 0): сообщение, по которому оператор действует, было без пина.
**(ж) Попутно исправлена собственная ложь, созданная расширением:** `seeding.go:73` говорил «an UNSIGNED row contradicts an APPROVED term» — неправда для новой половины. Текст приведён к правилу. ⛔ **Прежняя приписка «на старый текст не стоял ни один тест (`grep` = 0)» ОПРОВЕРГНУТА приёмкой и снята — и это мой собственный «прибор ответил на свой вопрос».** Я грепала ЦЕЛУЮ фразу, которая живёт только в самом `seeding.go`, поэтому ноль был предрешён. Правда обратная: сообщение БЫЛО запинено ПОДСТРОКОЙ (`pipeline.TestUnsignedConflictIsReportedByTheRun` утверждал `"contradicts an approved term"`), батарея от расширения ПОКРАСНЕЛА, и правку этого самого теста объявляет §9 п.2 того же отчёта. То есть отчёт противоречил сам себе через две секции.
#### 4. Что нашли ДВА круга самопроверки в моей же работе
@ -313,6 +313,9 @@ $0, мои руки, выброшенные пробы. Каждый ноль с
| прибор проходил на пустом обходе, `trimTo` резал байты (5) | пустой обход — `t.Fatalf`; срез рун-безопасен | `TM_CORPUS=/nonexistent` → FAIL «a walk that found nothing reports the same zeros as a clean corpus» |
| шесть `file:line` отчёта протухли (5) | пере-сняты грепом, каждый проверен | 23 адреса резолвятся на заявленное (круг 6) |
| два счётчика отчёта протухли снова (6) | ВСЕ числа сняты ОДНИМ проходом после последней правки | круги 4, 5, 6 ловили это трижды — причина была в порядке, а не в счёте |
| **обещание про `src` верно лишь для banknote-посадки (приёмка Д1)** | достроено до обеих посадок; свойство, на которое оно опирается, запинено | идемпотентность 10/10 при контроле «4 из 10 входов меняются»; `TestNormalizeSourceKeyIsIdempotent` |
| **гарантия `approvedNeighbours` только в комментарии (приёмка Д2)** | `TestApprovedNeighboursAdmitsOnlySignedRows` | обе мутации фильтра красны со списком пролезших строк |
| **отчёт противоречил сам себе через две секции (приёмка Д3)** | §3(ж) и §5а №8 исправлены, класс сужен до «пин узкий» | греп целой фразы был предрешён — она живёт только в `seeding.go` |
#### 4-септимус. КРУГ 6 — СОШЛИСЬ
@ -324,6 +327,18 @@ $0, мои руки, выброшенные пробы. Каждый ноль с
Круг 6 сам поймал у себя ошибку до сдачи: прочёл чужой лог батареи как свой и объявил красноту. Назвал это в отчёте — то же требование, что канон предъявляет к сессии.
#### 4-октавус. ДОФИКС ПО ПРИЁМКЕ — три пункта, все закрыты
Приёмка (три линзы, 14 находок, 0 блокеров, 3 major) подтвердила исполнением «репорт-онли», нетронутый снапшот и пере-посаженные мутации. Три пункта дофикса:
**Д1 — обещание про `src` было верно для ПОЛОВИНЫ популяции, и я выбрала не сужать его, а достроить.** Приёмка права: `reverseSectionTerms` эмитит `Term{Src: c.Key}` только для banknote-кандидата, а MINED-строка ложится с сырым `m.Src` (`miner_emit.go:251`). **Замер решил, что чинить:** `c.Key` — верный источник и там, и там, но по разным причинам. Мined-поверхность — подстрока УЖЕ нормализованного текста чанка (майнер везде читает `c.NSource`), поэтому её собственный ключ равен ей самой; проверено исполнением — `NormalizeSourceKey` идемпотентен на 10 из 10 проб, при КОНТРОЛЕ, что 4 из 10 входов он реально меняет (то есть ноль расхождений — свойство, а не молчание). ⇒ Комментарий достроен до обеих посадок, **и свойство, на которое он теперь опирается, ЗАПИНЕНО** (`text.TestNormalizeSourceKeyIsIdempotent`): без идемпотентности проверка сравнивала бы ложащуюся строку с источником, которого у неё нет, — молча, на mined-половине каждого банка.
**Д2 — гарантия `approvedNeighbours` жила только в комментарии; теперь у неё пин.** Мутация «убрать `e.Status == "approved"`» переживала три пакета. Траектория дорогая: это канон для промта ПЛАТНОЙ роли, и неподписанная строка, попав в «свидетельство», меняет байты, едущие к модели. Добавлен `TestApprovedNeighboursAdmitsOnlySignedRows` — краснеет от снятия ЛЮБОЙ из двух половин фильтра, с контролем, что четыре подписанных и отрендеренных строки дают четыре.
**Д3 — утверждение отчёта опровергнуто, и опровергается оно моим же §9 п.2.** Я объявила, что на текст варнинга S14 не стоял ни один тест, сославшись на `grep = 0`. **Ноль был предрешён: я грепала ЦЕЛУЮ фразу, которая живёт только в самом `seeding.go`** — прибор ответил на свой вопрос. Правда обратная: сообщение БЫЛО запинено подстрокой, батарея от расширения ПОКРАСНЕЛА, и правку того самого теста объявляет §9 п.2 двумя секциями ниже. Оба места исправлены; класс позиции §5а сузился с «пина нет» до «пин узкий»: подстрока стерегла одно словосочетание, а локализующая половина сообщения не была закрыта ничем.
**Д3 — седьмой случай моего собственного класса за пак, и первый, который нашли не мои круги, а приёмка.** Шесть кругов искали расхождение описания с кодом и не заметили расхождения отчёта с самим собой через две секции.
#### 5. Таблица мутаций — правая колонка это ТЕКСТ падения, а не факт красноты
| мутация | текст падения | восстановлено |
@ -361,7 +376,7 @@ $0, мои руки, выброшенные пробы. Каждый ноль с
#### 6. Чем предъявлено — команды и вывод
- **Батарея после последней правки:** `make battery`**`MAKE_EXIT=0`**, `ok` пакетов **19** (+4 без тестов), строк `FAIL` **0**, линтер **`0 issues.`**; скипов **4**, все названы батареей: `TestMinerFullBookParity`, `TestCorpusBankKeyConflicts` (мой opt-in прибор — батарея его видит и называет), `TestHelperEventsRun`, `TestHelperKillLoop`.
- **Дифф тестов исполнением** (`git diff -- 'backend/*_test.go' | grep '^[-+]func Test'`): в отслеживаемых файлах добавлено **7**, удалено **0**; `func Fuzz` 0/0. Плюс по **1** в двух новых файлах (`bankconflict_corpus_test.go`, `resume_updatedat_test.go`) → итого **+9 / 0**.
- **Дифф тестов исполнением** (`git diff -- 'backend/*_test.go' | grep '^[-+]func Test'`): в отслеживаемых файлах добавлено **9**, удалено **0**; `func Fuzz` 0/0. Плюс по **1** в двух новых файлах (`bankconflict_corpus_test.go`, `resume_updatedat_test.go`) → итого **+11 / 0**.
- **Детерминизм:** 200 прогонов на одном входе — различных выводов `UnverifiedKeyConflicts` **1**, `ConsolidationKeyConflicts` **1**; КОНТРОЛЬ — заведомо map-упорядоченная склейка на тех же данных даёт **8** различных (само число зависит от фикстуры; значимо только «больше одного»). Плюс `-count=5 -race` по новым тестам.
- **Корпус** (`TM_CORPUS=<репо>/books go test ./internal/pipeline/ -run TestCorpusBankKeyConflicts -v`): `.db walked=162, with a glossary table=161, without one=1, read-failed=0; books with a glossary=142, rows read=13350; ПОПУЛЯЦИЯ: книг хотя бы с одной неподписанной строкой=142, approved=1093 draft=11399 auto=858; книг с ЛЮБЫМ конфликтом=0; только approved×unsigned=0; с парой unsigned×unsigned=0; КОНТРОЛЬ: подсадка ловится на 142 из 142.`
**0 книг из 142, и это «не встречается», а не «не смотрели»:** 12 257 из 13 350 строк корпуса неподписанные, а форма столкновения не возникает потому, что все существующие двери роняют дубль по ПОЛНОМУ ключу `(src,sense,since_ch,until_ch)`, а разные окна через них проходят. ⚠ **Старое правило на корпусе тоже даёт 0** — S14 живёт в дереве без единого наблюдённого срабатывания; без этого числа «0» прочтётся как «новая половина бесполезна».
@ -386,7 +401,7 @@ $0, мои руки, выброшенные пробы. Каждый ноль с
5. **`mempostcheck.go:91` против `:122` и `:130`** — дока `Shown` говорит «how many unsigned rows were actually PUT IN FRONT of the model here», а sticky-перенос `continue`-ится ДО счётчика. Имя метрики шире её смысла.
6. **`internal/pipeline/bankmaterialize.go:132`** — remark оператору «auto-bank rows dropped: their key is already held by a **signed** term (the signed term wins)». Та же ложь, что в `loadAutoBank`: держателем ключа может быть неподписанная строка, и оператор увидит её названной подписанной.
7. **`internal/membank/memseed.go`, пропуск по UNIQUE-кортежу** — сид-строка с окном ПО УМОЛЧАНИЮ и без sense делит кортеж с banknote-предложением (у обоих `since_ch 0`), поэтому самая частая форма рукописной сид-строки против выработки роли **молчит**, каким бы ни был её статус. Замер круга 2: та же фикстура без `until_ch: 20``BankConflicts=0` и при `draft`, и при `approved`; с `until_ch: 20` → 1. На провод это не влияет (предложение отбрасывается, двух форм там нет) — теряется строка на ЛИСТЕ ПОДПИСИ. Закрытие требует правила «заменённая строка движка против отброшенного предложения», а колонка `Source` его не даёт: дельта владельца и авто-банк движка обе читаются `mined`.
8. **Сообщения без пинов** — конкретный носитель `internal/pipeline/seeding.go:73` (текст варнинга S14). Ни один тест его не закрывал (`grep` по прежнему тексту в `*.go` = 0), поэтому расширение правила сделало операторское сообщение ложным при полностью зелёной батарее. Класс шире одного места: пины на ТЕКСТЫ операторских сообщений в зоне не ставятся системно.
8. **Пины на операторские сообщения есть, но узкие и несистемные** — носитель `internal/pipeline/seeding.go:73`. Текст варнинга S14 был закрыт ПОДСТРОКОЙ в `pipeline.TestUnsignedConflictIsReportedByTheRun`, и расширение правила его честно покраснило; но подстрока стерегла одно словосочетание из всего сообщения, поэтому локализующая половина (обе строки, оба окна, firing-ключ) не была закрыта ничем и появилась только этим паком. ⚠ **Прежняя формулировка этой позиции («не был закрыт ни одним тестом, `grep` = 0») была НЕВЕРНА и снята приёмкой:** греп искал целую фразу, живущую только в самом `seeding.go`. Класс остаётся, но он про ПОЛНОТУ пина на текст, а не про его отсутствие.
9. **`internal/terminology/terminology.go:993` и `internal/pipeline/mining.go:451` — ШОВ-БЛИЗНЕЦ того, что бил меня три круга, живёт рядом и НЕ ЗАПИНЕН.** Поля `Contradictions` и `Conf` пересекают границу файла тем же способом: ключ выбирается по разу с каждой стороны (`Contradictions` — по `c.Src` у писателя и читателя, `Conf` — по `c.Key` у обоих). Сегодня стороны согласованы, но ни одна фикстура не имеет кандидата с `Key != Src`, поэтому мутация любого из трёх ключей переживает ПОЛНЫЕ пакеты `pipeline`, `terminology` и `tmctl` (замер круга 6). На проводе не меняется ничего — теряются метка `⚠ contradicts` и порядок «least sure first» на листе подписи у banknote-кандидатов с традиционным/кана-написанием. ⚠ **Строки паком не тронуты, это не регресс**; свой шов я убрала целиком (§4-секстус п.1), а этот выношу, потому что он того же класса и чинится десятью строками рядом с существующим тестом.
10. **`internal/store/chunkstatus.go` вместе с `internal/pipeline/waverun.go` — ПУТЬ ЗАПИСИ СТАТУСА НЕ ЧИТАЕТСЯ ПО КОДУ, и это свойство места, а не невнимательность автора.** Писателей скипнутой строки ДВА, и какой сработает, решает раскладка волны: `recordSkippedStages` (`waverun.go`) — для флагнутой РЕДАКТОРСКОЙ единицы, флагнутая ветка `runStageSequence` (там же) — когда в ОДНОЙ волне две и более стадии. Читающий `chunkstatus.go` не видит ни того, ни другого. Замер: три формулировки механизма подряд оказались неверными (в дереве до пака, в моей первой правке, в моей второй), и каждую поймала только мутация — прочитанная по тексту, а не по цвету.
@ -422,7 +437,7 @@ $0, мои руки, выброшенные пробы. Каждый ноль с
#### 11-бис. Дерево на момент сдачи
`git status --short -- backend/ docs/PROGRESS.md` (позиций по `backend/`**17**: 15 M + 2 новых):
`git status --short -- backend/ docs/PROGRESS.md` (позиций по `backend/`**18**: 16 M + 2 новых):
```
M backend/cmd/tmctl/render.go
@ -440,6 +455,7 @@ $0, мои руки, выброшенные пробы. Каждый ноль с
M backend/internal/pipeline/terminologist.go
M backend/internal/pipeline/waverun.go
M backend/internal/store/chunkstatus.go
M backend/internal/text/norm_test.go
M docs/PROGRESS.md
?? backend/internal/pipeline/bankconflict_corpus_test.go
?? backend/internal/pipeline/resume_updatedat_test.go
@ -454,8 +470,8 @@ $0, мои руки, выброшенные пробы. Каждый ноль с
**Работа завершена, править больше не планирую.** Критерий проверяется механически:
1. **Исход у каждого пункта заказа** — таблица §0, пунктов без исхода нет.
2. **Круги сошлись** — круг 6 дал «сошлись», новых находок в коде пака нет; всё найденное кругами 16 закрыто поимённо таблицей §4-тер. Два остатка круга 6 не в коде пака: пред-существующий шов-близнец вынесен §5а №10, счётчики пере-сняты.
3. **Числа сняты после последней правки, каждое командой.** Батарея `MAKE_EXIT=0` (19 пакетов `ok`, 0 красных, линтер `0 issues.`, 4 названных скипа); что она позже последнего касания кода — предъявлено: `find backend -name '*.go' -newer <лог>`**0** при контроле **7**, и с тех пор изменён только `docs/PROGRESS.md`.
2. **Круги сошлись, и приёмка добавила три пункта дофикса — все закрыты** (§4-октавус). Круг 6 дал «сошлись»; всё найденное кругами 16 и приёмкой закрыто поимённо таблицей §4-тер. Два остатка круга 6 не в коде пака: пред-существующий шов-близнец вынесен §5а №10, счётчики пере-сняты.
3. **Числа сняты после последней правки, каждое командой.** Батарея `MAKE_EXIT=0` (19 пакетов `ok`, 0 красных, линтер `0 issues.`, 4 названных скипа); что она позже последнего касания кода — предъявлено: `find backend -name '*.go' -newer <лог>`**0** при контроле **3**, и с тех пор изменён только `docs/PROGRESS.md`.
4. **Мутации** — таблица §5 полна (**23** строк), выжившие названы отдельной таблицей «зелено ДО → красно ПОСЛЕ», отброшенная названа с причиной.
5. **Обещаний в отчёте нет** — всё, что «надо бы», стоит секцией предложений ниже и решается оркестратором.
6. **Всё живое в дереве** — отчёт, таблицы, замеры, ограничения; письма носителем не считаю.