Give the anchors this landing introduced their roots and expectation tokens, and record the bare anchors that pre-date it as a row

This commit is contained in:
heaven 2026-09-16 17:13:37 +03:00
parent 5490a8e442
commit 9db522d79e
2 changed files with 9 additions and 8 deletions

View file

@ -3,7 +3,7 @@
> **Единственный трекер проекта.** Здесь живут строки, на которые доки, промты и D-ноты ссылаются словами «строка N» / «строка бэклога N»: **ID строки стабилен навсегда**, не перенумеровывается и не переиспользуется (D39.80). Правки — только через оркестратора; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено.
> ⚠ **Это НЕ бэклог зоны `docs/`, а бэклог ПРОЕКТА.** У зон свои, с другими неймспейсами ID, и единый их строк не принимает (D39.84): платформа — [../platform/BACKLOG.md](../platform/BACKLOG.md) (`П-N`) и её регистр дефектов `platform/docs/DEFECT_REGISTER.md` (`PD-N`); фронт — [../frontend/docs/BACKLOG.md](../frontend/docs/BACKLOG.md) (`Ф-N`).
> ⚠ **Состояние проекта — не здесь.** Очередь, курс, CURRENT-STATE, состояние паков и живая хроника — шапка [PROGRESS.md](PROGRESS.md). Здесь только долг и его диспозиции.
> - **СЧЁТ ОЧЕРЕДИ на 16.09 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **338** строк · зона бэкенд **173** строго / **225** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0** (236 закрыта D39.175; **371** — актом D39.233, **360** — актом D39.232, обе 10.09), платные прогоны разблокированы · «скоро» **175** (перечень — грепом по таблице, рукописный список снят D39.126) · гейт-строка эксп-22: 153 (плюс 150 — руки владельца; ⚠ 55 из гейтов СНЯТА — D39.198 п.5); строка 5 — остаток гейчен ре-пробой 74, носитель события теперь строка 188 (аудит D39.140); остальное «когда-нибудь». ⚠ Счёт — НИЖНЯЯ граница долга, не потолок (разбор — легенда таблицы ниже).
> - **СЧЁТ ОЧЕРЕДИ на 16.09 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **339** строк · зона бэкенд **173** строго / **225** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0** (236 закрыта D39.175; **371** — актом D39.233, **360** — актом D39.232, обе 10.09), платные прогоны разблокированы · «скоро» **175** (перечень — грепом по таблице, рукописный список снят D39.126) · гейт-строка эксп-22: 153 (плюс 150 — руки владельца; ⚠ 55 из гейтов СНЯТА — D39.198 п.5); строка 5 — остаток гейчен ре-пробой 74, носитель события теперь строка 188 (аудит D39.140); остальное «когда-нибудь». ⚠ Счёт — НИЖНЯЯ граница долга, не потолок (разбор — легенда таблицы ниже).
> - ⚠ **Переезд 06.09 (D39.218):** таблица вынесена из `PROGRESS.md` ДОСЛОВНО и ни один ID не сдвинут — **с единственным исключением: две ячейки (строки 220 и 306) тронуты РОВНО в номере якоря `docs/scripts/counts.py:566`→`:569` и `:592`→`:595`**, потому что цель сдвинул этот же коммит; текст ячеек не менялся, длины равны. В `PROGRESS.md` на прежнем месте оставлен заголовок-указатель, поэтому ссылки «секция „Бэклог“» доезжают в один хоп.
## Бэклог (ЕДИНЫЙ, собран 26.07, актуализация 04.08 D39.99/D39.101; правки — только через оркестратора)
@ -370,7 +370,8 @@
| 451 | **«УМНЫЙ УЧАСТОК» В ТОЧКЕ БАНКА — дизайн по слову владельца 16.09** (`D39.254` п.2): у банк-ролей нет ни ретрая, ни фоллбека, и владелец считает это дырой, а не отсутствием улучшения. Собрать в один предмет: регенерация банк-роли той же ветвью, что у черновой стадии (ряд 438) · включение эскалации на другую модель (ряд 435) · отдельный переспрос нерешённой строки · детерминированный ансамбль признаков и рецензент другого семейства на спорных кластерах (остаток ряда 5). ⛔ Границы ратифицированного: равноправный совет моделей, кросс-модельные веса, self-consistency и селекция из вариантов закрыты D39.102 п.2 замером (`research/24`: потолок 17/45, у 22 промахов из 27 верного `dst` в вариантах нет вовсе) — либо проект живёт в этих границах, либо владелец снимает закрытие явно ⚠ **16.09, слово владельца: «В границах ратифицированного»** (`D39.254` п.6) — закрытие D39.102 п.2 НЕ пере-открывается, замер под него не заказывается.| бэкенд | скоро (слово владельца) | дизайн-пак, затем стройка | `D39.254` п.2, `research/35` |
| 452 | **ГОЛОС И ОБРАЩЕНИЯ ты↔вы — СТРОИТЬ (слово владельца 16.09,** `D39.254` п.5**).** Сегодня построена схема с окнами в трёх таблицах, детектор утечки есть, а записей нет: производителя нет вовсе («no miner emits them», `backend/internal/seed/seed.go:24`), подача выключена константой (`bankmaterialize.go:295`). Владелец просит алгоритмически продуманного производителя, а не ручной посев. Предусловие — размеченный набор переходов, которого нет; провод включать только в окне перекроя и только при непустом реестре, иначе включение купит ноль, неотличимый от чистоты | бэкенд | скоро (слово владельца) | производитель + данные + провод в окне перекроя | `D39.254` п.5, ряд 24 |
| 453 | **ПРИЧИНА ОТКАЗА НЕ ВЫХОДИТ НА ПРОВОД ВОВСЕ — предмет пере-определён приёмкой 16.09 (`D39.255`).** Прежняя формулировка долга («дописать в контракт 14 три причины: `retry_unaffordable`, `cancelled`, `attempt_timeout») невыполнима: дописывать некуда. На проводе у юнита стоит `enum: [translated, withheld, pending]` (`docs/architecture/14-api-contract/openapi.yaml`), `flag_reason` в спеке — 0 упоминаний, а компаньон прямо пишет, что `flag_reason` и `detail` на провод не выходят и `flagged` вычисляется на каждой эмиссии, а не хранится. ⇒ настоящий вопрос: показывать ли покупателю, ПОЧЕМУ глава не переведена, или он видит только «не переведено». Это решение владельца о продукте, а не дописка в спеку | контракт + платформа | скоро | вопрос владельцу, затем контрактный минор | `D39.255`, приёмка пака 291 |
| 454 | **Ложная атрибуция ноты в комментарии кода:** `backend/internal/pipeline/quality.go:51` — «Split echo by stage (D39.18 owner decision)», а в теле `D39.18` расщепления по стадиям нет вовсе (пере-снято: «split» 0, «стади» 0); носитель решения — `D39.19` п.4, где стоит `echo_draft_rate`. Пред-существует на HEAD, паком не заведено; форма «D39.18-follow-up» на `:404` корректна и правки не требует. Тот же класс, что чинил круг 8 у четырёх других носителей | бэкенд | когда-нибудь | правка комментария | `D39.255`, приёмка пака 291 |
| 454 | **Ложная атрибуция ноты в комментарии кода:** `backend/internal/pipeline/quality.go:51`=`Echo is SPLIT by stage` — «Split echo by stage (D39.18 owner decision)», а в теле `D39.18` расщепления по стадиям нет вовсе (пере-снято: «split» 0, «стади» 0); носитель решения — `D39.19` п.4, где стоит `echo_draft_rate`. Пред-существует на HEAD, паком не заведено; форма «D39.18-follow-up» на `:404` корректна и правки не требует. Тот же класс, что чинил круг 8 у четырёх других носителей | бэкенд | когда-нибудь | правка комментария | `D39.255`, приёмка пака 291 |
| 455 | ⛔ **ТРИ ОПУБЛИКОВАННЫХ КЛЮЧА КАЧЕСТВА СМЕНИЛИ СМЫСЛ ОДНИМ ПАКОМ, а его остаток называл два.** (а) `ProcessedUnits` / `processed_units` — знаменатель strip-rate теперь включает позиции со стоп-меткой, то есть юниты, не дошедшие до финальной стадии; код сам говорит «„REACHED THE FINAL STAGE“ … too strong now». (б) `EchoDraftRecovered` / `echo_draft_recovered` — числитель СУЖЕН условием `shippedText`; доккомментарий признаёт «measured before this change reads HIGHER … the two are not comparable across it». (в) эдит-числитель — снят гейт `DispFlagged` (ратифицировано `D39.255` как эррата к `D39.19` п.4). ⇒ нужен перечень «до / после» у каждого ключа и пин несопоставимости, иначе сравнение прогонов через эту границу молча врёт | бэкенд | скоро | перечень в носителе + пин | `D39.255`, приёмка пака 291 |
| 456 | **Пин читательской фразы отчитывается за КЛАСС, а меряет СРЕЗ.** `backend/internal/pipeline/readerholewords_test.go:47-64`: строки таблицы варьируют причину флага (`retry_unaffordable`, `cancelled`, `hard_refusal`, `sanitizer_defect`), но `DroppedReason` захардкожен `FlagHardRefusal` во ВСЕХ строках. Поэтому строка «a stop mark over a unit that lost a member for good» меряет защитимый случай — член потерян настоящим отказом — и молчит ровно о случае ряда 375, где выпавший член САМ есть метка стопа. Прогон: 5/5 PASS, то есть зелень ничего не говорит о предмете | бэкенд | скоро | варьировать `DroppedReason` по строкам | `D39.255`, приёмка пака 291 |
| 457 | **ТРИ ПРОТУХШИХ ЯКОРЯ В ДОКАХ ФРОНТ-ЗОНЫ, и две цели живы по известным адресам.** `frontend/docs/frontend-PROGRESS.md:187` целит в `docs/architecture/14-api-contract/README.md:1054`=`не различает две беды` — токен живёт на `:1138`; `frontend/docs/frontend-PROGRESS.md:190` целит в `docs/architecture/14-api-contract/openapi.yaml:1606`=`enum: [source_unreadable, not_configured, processing_failed, content_refused]` — живёт на `:1633`; `frontend/docs/STACK_DECISIONS.md:263` целит в `backend/internal/pipeline/export.go:176`=`pend.Source = u.sourceText()`. ⚠ Правит их ФРОНТ: доки чужой зоны оркестратор не переписывает, а обе уехавшие цели — В МОЕЙ зоне, поэтому адреса названы здесь готовыми. ⛔ Замер 16.09: цели контракта БАЙТ-ИДЕНТИЧНЫ дереву и HEAD (README 1608 строк в обеих, `openapi.yaml` 3497 в обеих) ⇒ якоря протухли НЕ лендингом приёмки, а раньше. ⚠ И они едва не уехали в находку: контрольный прогон на HEAD показал 25 строк из 27 — линтер капит список, и «эти два якоря новые» было артефактом прибора, снятым замером | фронт | когда-нибудь | три якоря зелёные в `python3 docs/scripts/counts.py --lint` | приёмка пака «КУПЛЕНО — ЗНАЧИТ ДОСТАВЛЕНО» 16.09 (`D39.255`) |
| 456 | **Пин читательской фразы отчитывается за КЛАСС, а меряет СРЕЗ.** `backend/internal/pipeline/readerholewords_test.go:47-64`=`DroppedReason: string(FlagHardRefusal)`: строки таблицы варьируют причину флага (`retry_unaffordable`, `cancelled`, `hard_refusal`, `sanitizer_defect`), но `DroppedReason` захардкожен `FlagHardRefusal` во ВСЕХ строках. Поэтому строка «a stop mark over a unit that lost a member for good» меряет защитимый случай — член потерян настоящим отказом — и молчит ровно о случае ряда 375, где выпавший член САМ есть метка стопа. Прогон: 5/5 PASS, то есть зелень ничего не говорит о предмете | бэкенд | скоро | варьировать `DroppedReason` по строкам | `D39.255`, приёмка пака 291 |
| 457 | **ТРИ ПРОТУХШИХ ЯКОРЯ В ДОКАХ ФРОНТ-ЗОНЫ, и две цели живы по известным адресам.** `frontend/docs/frontend-PROGRESS.md:187`=`Какое слово о состоянии книги стоит в дереве` целит в контракт по адресу 1054 — токен живёт на `docs/architecture/14-api-contract/README.md:1138`=`не различает две беды`; `frontend/docs/frontend-PROGRESS.md:190`=`Фразы отказа книги` целит в openapi по адресу 1606 — enum отказов живёт на `docs/architecture/14-api-contract/openapi.yaml:1633`=`enum: [source_unreadable, not_configured, processing_failed, content_refused]`; `frontend/docs/STACK_DECISIONS.md:263`=`pend.Source = u.sourceText()` целит в экспорт по адресу 176 — присваивание живёт на `backend/internal/pipeline/export.go:178`=`pend.Source = u.sourceText()` (замер 16.09: `sourceText()` в файле два, второе — `ce.Source` на 344, и оно про другое). ⛔ **Мёртвые адреса здесь НАЗВАНЫ СЛОВАМИ, а не якорями, и это существенно:** выписав их в форме `` `путь:строка`=`токен` ``, я воспроизвёл чужую поломку у себя — линтер прочитал их как МОИ живые якоря и дал три новых красных (8 → 11). **Документируя протухший якорь, не пиши его якорем.** ⚠ Правит их ФРОНТ: доки чужой зоны оркестратор не переписывает, а обе уехавшие цели — В МОЕЙ зоне, поэтому адреса названы здесь готовыми. ⛔ Замер 16.09: цели контракта БАЙТ-ИДЕНТИЧНЫ дереву и HEAD (README 1608 строк в обеих, `openapi.yaml` 3497 в обеих) ⇒ якоря протухли НЕ лендингом приёмки, а раньше. ⚠ И они едва не уехали в находку: контрольный прогон на HEAD показал 25 строк из 27 — линтер капит список, и «эти два якоря новые» было артефактом прибора, снятым замером | фронт | когда-нибудь | три якоря зелёные в `python3 docs/scripts/counts.py --lint` | приёмка пака «КУПЛЕНО — ЗНАЧИТ ДОСТАВЛЕНО» 16.09 (`D39.255`) |
| 458 | **ПЯТНАДЦАТЬ ГОЛЫХ ЯКОРЕЙ В ЖИВЫХ СТРОКАХ: путь и номер есть, ТОКЕНА ОЖИДАНИЯ нет — линтер такой якорь не читает, и «ноль жалоб» тут неотличимо от «не разобран».** Одиннадцать в `docs/BACKLOG.md` (`backend/internal/pipeline/export.go:307` · `stagerun.go:93` · `backend/internal/seed/seed.go:24` · `backend/internal/store/chunkstatus.go:92` · `bankmaterialize.go:214` · `bankmaterialize.go:295` · `export.go:174` · `export.go:320-322` · `quality.go:492` · `status.go:538-543` · `voicerun.go:46` — ⚠ у восьми нет и КОРНЯ пути, а такой якорь не ловится даже существованием файла) и четыре в `docs/experiments/00-provider-quirks.md` (`pipeline-c1.yaml:129` · `pipeline-arm-glm.yaml:61` · `pipeline-arm-deepseek-pro.yaml:62` · `pipeline-arm-mistral.yaml:61`). ⛔ **Чинить ОПТОМ нельзя:** токен, подобранный под то, что в цели ОКАЗАЛОСЬ, есть подгонка под зелень (`D39.121`) — каждый разбирается чтением прозы, которая его описывает, и половина таких разборов кончается тем, что уехала ЦЕЛЬ, а не номер. Замер 16.09 (`D39.255` п.10): пред-существуют — лендинг приёмки эти строки лишь дополнял, а ввёл он двенадцать своих, и они закрыты в тот же заход | оркестратор | когда-нибудь | у каждого якоря есть корень пути и токен; пред-коммитный хук на этих строках молчит | приёмка пака «КУПЛЕНО — ЗНАЧИТ ДОСТАВЛЕНО» 16.09 (`D39.255`) |

View file

@ -3855,12 +3855,12 @@ bought NOTHING». ⇒ **`tmctl manifest` есть НИЖНЯЯ граница,
- **Половина (б):** чистое дерево **8/8 PASS** (ровно 1.11 с); мутант — снят `answered &&` в `backend/internal/llm/attemptcut.go:189`=`return t.wrote.Load() || (answered && t.firstByte.Load())`**8/8 FAIL**. В ряду стояло **7 красных из 8**: пин мерил вероятность, теперь меряет гарантию. Текст падения про предмет: `backend/internal/llm/attemptcut_test.go:793`=`a call that bought nothing is retried to the end of the budget` (2 попытки вместо 3 — прямое следствие того, что отказ стал покупкой); рядом печатаются посылка (`:786`=`premise: the provider was connected to`) и контроль второго сабтеста (`:815`=`the control: delivered=`, снято `delivered=true after_headers=true billable=false cause=connection_lost`).
- ⚠ **Что этот мутант НЕ меряет, и это называется, а не умалчивается:** детерминизм даёт **гард посылки** (`:792`), а денежное утверждение (`:796`=`the provider REFUSED this request`) на нём не исполняется — гард падает раньше. Критерию ряда («печатает величину, доказывающую пройденную границу, и падает, когда сценарий не состоялся») это отвечает дословно, но денежная ветка стережётся другим мутантом.
- **Половина (а)** закрыта построением: `backend/internal/pipeline/cutcall_test.go:461`=`if row.assertBoundary` печатает `the boundary crossed: after_headers=… billable=… bytes_read=…` и падает текстом `this fixture did not build the situation the row asserts money about`; сторона границы утверждается сверкой `cut.AfterHeaders` с ожиданием строки, а не временем.
- ⛔ **Норма, которую этот разбор подтвердил своей ценой:** `time.Sleep(50 * time.Millisecond)` — токен, которым ряд описывал дефект, — **жив на прежнем месте**, и суди я по токену, ряд остался бы открытым. Разводит уже не он: для строки «after 2xx» фикстура ждёт `<-srv.flushed` с бесцветным потолком 4 с (`cutcall_test.go:446`), а сторона границы УТВЕРЖДАЕТСЯ. **Живой токен не значит живой дефект — ровно так же, как подобранный под цель токен не значит верного якоря.**
- ⛔ **Норма, которую этот разбор подтвердил своей ценой:** `time.Sleep(50 * time.Millisecond)` — токен, которым ряд описывал дефект, — **жив на прежнем месте**, и суди я по токену, ряд остался бы открытым. Разводит уже не он: для строки «after 2xx» фикстура ждёт `<-srv.flushed` с бесцветным потолком 4 с (`backend/internal/pipeline/cutcall_test.go:447`=`case <-srv.flushed:`), а сторона границы УТВЕРЖДАЕТСЯ. **Живой токен не значит живой дефект — ровно так же, как подобранный под цель токен не значит верного якоря.**
**10. ЯКОРНЫЙ ИТОГ ЛЕНДИНГА — СНЯТ КОНТРОЛЕМ, А НЕ ПАМЯТЬЮ.** На развёртке HEAD (`af88680`) линтер давал **27** протухших якорей, после лендинга — **8**, новых **ноль**. Разница разложена: четыре уехали вместе с промтом в `archive/**` (не проверяется), четырнадцать перенаведены по финальному дереву, один переписан здесь. Остаток назван поимённо, и каждый — с причиной, по которой НЕ тронут:
- `docs/architecture/05-decisions-log.md:43` — эррата 28.08-к в ШАПКЕ этого журнала; шапка сама объявляет форму якорей в телах не подлежащей правке и велит читать с поправкой. Цель «seed-FILE edit» жива на `backend/internal/pipeline/status.go:1042` и `:1201`.
- `docs/architecture/05-decisions-log.md:43`=`Эррата 28.08-к` — эррата 28.08-к в ШАПКЕ этого журнала; шапка сама объявляет форму якорей в телах не подлежащей правке и велит читать с поправкой. Цель «seed-FILE edit» жива на `backend/internal/pipeline/status.go:1042`=`a seed-FILE edit not yet re-run is NOT reflected here` и `:1201`.
- `docs/experiments/23-editor-tier.md` — четыре якоря ЗАМОРОЖЕННОГО отчёта эксперимента. Замороженному отчёту положен штамп коммита, а не перенаведённые якоря: иначе улику правят задним числом.
- Три якоря в доках фронта — ЧУЖАЯ зона. Заведён ряд **457**, и обе уехавшие цели названы в нём готовыми адресами (`14-api-contract/README.md:1138`, `openapi.yaml:1633`), потому что сами цели — в МОЕЙ зоне.
- `docs/experiments/00-provider-quirks.md:163` починен **не токеном**: там цель не «уехала», а описанное состояние ИСЧЕЗЛО — `toOpenAIMessages` перестроена 28.08 и склейку теперь делает. Подставить найденный в цели токен значило бы подгонку под зелень; адрес переведён в ИСТОРИЧЕСКИЙ, живой стоит строкой ниже (`httpllm.go:766`).
- Три якоря в доках фронта — ЧУЖАЯ зона. Заведён ряд **457**, и обе уехавшие цели названы в нём готовыми адресами (`docs/architecture/14-api-contract/README.md:1138`=`не различает две беды`, `docs/architecture/14-api-contract/openapi.yaml:1633`=`enum: [source_unreadable, not_configured, processing_failed, content_refused]`), потому что сами цели — в МОЕЙ зоне.
- `docs/experiments/00-provider-quirks.md:163`=`ТОТ ЖЕ ДЕФЕКТ ЖИВЁТ В ДВИЖКЕ` починен **не токеном**: там цель не «уехала», а описанное состояние ИСЧЕЗЛО — `toOpenAIMessages` перестроена 28.08 и склейку теперь делает. Подставить найденный в цели токен значило бы подгонку под зелень; адрес переведён в ИСТОРИЧЕСКИЙ, живой стоит строкой ниже (`backend/internal/llm/httpllm.go:766`=`func toOpenAIMessages`).
**МОЯ ОШИБКА ПРИБОРА, снятая замером (и она стоила бы ложной находки о чужой зоне).** Сверив свои восемь со списком HEAD, я насчитал ДВА новых якоря во фронте и готов был назвать их следствием лендинга. Замер сказал обратное: цели БАЙТ-ИДЕНТИЧНЫ дереву и HEAD — `14-api-contract/README.md` 1608 строк в обеих, `openapi.yaml` 3497 в обеих, токены на `:1138` и `:1633`. Новыми они не были: **линтер капит список, и контрольный прогон напечатал 25 строк из 27**. Класс — «список, из которого делаешь утверждение, не режь», с поворотом: резал не я, резал ПРИБОР, а выглядело это как факт о дереве. ⇒ у обрезанной выдачи спрашивай знаменатель даже тогда, когда обрезал её не ты.