623 lines
89 KiB
Markdown
623 lines
89 KiB
Markdown
# АРХИВ: секция «Бэкенд» журнала прогресса, эра 24–28.08.2026
|
||
|
||
> ⚠ **ИСТОРИЧЕСКОЕ. Инструкции отсюда НЕ ИСПОЛНЯЮТСЯ.** Это вынесенная 28.08 прожитая проза зонной
|
||
> секции `docs/PROGRESS.md` — пять итогов бэкенд-сессий и их записки-планы. **ВСЕ описанные здесь паки
|
||
> ЗАЛЕНДЖЕНЫ**, и каждый «дерево готово, НЕ закоммичено» относится к состоянию, которого больше нет.
|
||
>
|
||
> **Куда что уехало:** входная дверь шва (24–27.08, четыре сессии) — `D39.158`, лендинг `d1eb8a9`;
|
||
> пак «тихая порча» (28.08) — `D39.164`, лендинг `7d0c6f2`.
|
||
>
|
||
> ⚠ **Остатки, которые здесь названы, живут СТРОКАМИ единого бэклога, а не этим файлом:** **228**
|
||
> (алиас возвращает отклонённую поверхность), **229** (снапшот не фолдит модель внутренних гейтов),
|
||
> **230** (размен сходимости против поучения), **231** (смета пере-прохода), **141** (остаток
|
||
> детектора сносок), **131** (кап инъекции не считает маркер). Вендор-вердикт по Gemini живёт
|
||
> ПИНГОМ ПОЛИГОНУ в живом журнале — здесь его копия, не носитель.
|
||
>
|
||
> Вынесено аудитом документации 28.08 (D39.167) по слову владельца «пройденную прозу можно сносить».
|
||
|
||
|
||
**⟶ Состояние бэкенда — CURRENT-STATE (один носитель, D39.80); здесь только пинги живых сессий.**
|
||
|
||
**✅ ИТОГ БЭКЕНД-СЕССИИ 28.08 — ПАК «ТИХАЯ ПОРЧА» (`docs/BACKEND_SILENT_HARM_SESSION_PROMPT.md`), все три пункта. Дерево готово, НЕ закоммичено.**
|
||
|
||
**§6 КОМПЛЕКТНОСТЬ — пункт → что сделано → каким ИСПОЛНЕНИЕМ подтверждено.**
|
||
|
||
| Заказ | Что сделано | Чем подтверждено ИСПОЛНЕНИЕМ |
|
||
|---|---|---|
|
||
| **§3.1** инъекция банка доезжает на каждом провайдере либо громкий отказ | Новая ось `llm.Capability.SystemMessages` (`multi`\|`single`, `capability.go:87-127,158-165`); под `single` `toOpenAIMessages` СКЛЕИВАЕТ ведущий системный ряд в одно сообщение (`httpllm.go:513-559`) и падает громко на системном посреди диалога — зеркально Anthropic; YAML-ось `capabilities.system_messages` с валидацией enum (`config/models.go:101-106,566-578,646-650`); квирк объявлен у провайдера `gemini` с вендор-ссылкой и датой (`configs/models.yaml:120-137`) | 6 тестов `internal/llm/systemmessages_test.go` + сквозной на ОБОИХ волнах `internal/pipeline/systemmessages_wave_test.go`. Мутация «ось игнорируется» → падает `TestSingleSystemEndpointCarriesTheBankOnBothWaves` обеими под-ветками и `…CarriesTheInjection` с текстом `got 2 (roles [system system user])`. Мутация «ось теряется по дороге из YAML» → тот же тест. Каталог: `SH1`, `SH2` |
|
||
| **§3.2** дыра выдачи видна читателю файла | ⚠ **Заказ пере-формулирован по находке** (разрешено оркестратором 28.08): маркер уже существовал и ВРАЛ. `ChunkOutcome`/`ChunkExport` несут `DroppedMembers` (`bookrun.go:69-75`, `export.go:45-51`, `waverun.go:488`, `export.go:227-230`); `cmd/tmctl/render.go` печатает маркер В ПОТОКЕ ТЕКСТА (`gapMarker`, :26-63) в обоих рендерах и честные счётчики `withheld`/`incomplete` | Сквозной прогон БОЕВОГО бинаря `cmd/tmctl/exportgap_cli_test.go`: `tmctl translate` → `tmctl export --plaintext`, текст ДО и ПОСЛЕ на ОДНОМ состоянии (ниже). Матрица семи состояний. Мутации `SH3` (маркер пуст) и `SH4` (счёт выпавших не ведётся) |
|
||
| **§3.3** повтор принятого документа сходится | `refuseSeedConflicts` больше не срабатывает, когда отказ УЖЕ на записи (`membank/decisions.go:365-393`, новый `rejectsHoldSurface` :690-700); порядок записи в `writeDecisionFiles` изменён на REJECTS-FIRST с обоснованием (`bankdecisions.go:427-441,458-489`) | 5 тестов `membank/decisions_converge_test.go` + 3 дверных `pipeline/bankdecisions_converge_test.go` (реальные файлы, реальные классы отказа). Мутации `SH5` (сужение снято) и `SH6` (порядок возвращён) |
|
||
|
||
**РЕШЕНИЯ ПО ПРОПУСКАМ И РОДНЕ — строкой каждое, как просил оркестратор.**
|
||
- **Четвёртая дыра (строка 141) — ВЗЯТА БЕСПЛАТНО, работы не потребовала.** Проверено исполнением
|
||
(проба по `internal/checks`, файл удалён после замера): сноска `[1] 蛊真人 — название романа.`
|
||
мимо детектора примечаний идёт, но поднимает класс `CJKLeak`, а он `CosmeticOnly`
|
||
(`checks/sanitizer.go:161-163`) ⇒ `StripCosmetic` вырезает ханьцзы, юнит уходит
|
||
`sanitizer_stripped`, и баннер «leak cleaned, verify» для НЕГО правдив. Механизм этого же заказа
|
||
накрывает класс без правки детектора — граница промта соблюдена буквально.
|
||
⚠ Смежное, НЕ взятое и названное строкой: сноска БЕЗ ханьцзы (`[1] Название романа.`) не поднимает
|
||
ни одного класса (замер: `total=0`), едет как есть — но текста при этом НЕ теряет, это лишняя
|
||
добавка, а не дыра. Маркер на ней дезинформировал бы (⛔ анти-скоуп промта). Ловля таких сносок —
|
||
работа В ДЕТЕКТОРЕ, промт её прямо запретил.
|
||
- **Д1 — НЕ ВЗЯТ, отдельным предметом.** Право §9. Канон определяет decline ПОВЕРХНОСТНО
|
||
(«declining a surface removes EVERY window of that surface», `14-api-contract/openapi.yaml:2051`),
|
||
и расширять его до энтити значило бы менять ратифицированный контракт из бэкенд-сессии. Вторая
|
||
половина Д1 («память глушит стоп») — уже НАЗВАННЫЙ и принятый двусторонний остаток в комментарии
|
||
`mining.go:308-313`, а не необнаруженный дефект. ⚠ Но одна траектория Д1 реальна и требует
|
||
ЧУЖОГО решения: эмиссия майнера энтити-широка (`miner_emit.go` `clusterTouches`), а фильтр
|
||
авто-банка ключуется только по собственному src строки (`mining.go:662`), поэтому ОТКЛОНЁННАЯ
|
||
поверхность может вернуться алиасом уцелевшей строки. Это противоречит канону уже сегодня.
|
||
**Не чиню в этом паке** (правильная форма — снять алиас со строки, а не снести строку; это
|
||
предмет банковой онтологии, а не тихой порчи) — **но это заказ, который стоит выдать.**
|
||
- **Д3 — НЕ ВЗЯТ, вне моей зоны.** `LiftBankStop` в `backend/` не существует ни в каком написании;
|
||
символ живёт в `platform/internal/runs/spawn.go` и `reconcile.go`, то есть в зоне, запертой паком
|
||
P9. Движковая половина при этом здорова: порядок «карта → память» ратифицирован и исполнен
|
||
(`mining.go:191` пишет карту, `:274` метит память), отказ памяти оценён в комментарии `:275-276`
|
||
как «one extra stop, nothing lost». ⚠ Поправка к моему же раннему пингу: я сказал «гарда не
|
||
существует» — точнее «не существует В ДВИЖКЕ».
|
||
- **Сосед 131 — НАЗВАН, не чиню.** Кап инъекции считает только `src → dst`
|
||
(`membank/memory.go:517-521` `glossaryLineTokens`), а рендер дописывает к КАЖДОЙ строке
|
||
`tx.UnverifiedMarker` (`:706`) либо `genderConstraintNote(...)` (`:711`), а редакторский блок ещё и
|
||
префикс `- ` с кавычками-ёлочками (`:821`). То есть отгружаемая строка строго длиннее той, за
|
||
которую платит бюджет; на коротких именных строках перерасход велик. Тема денег и качества
|
||
инъекции — не тихий брак в тексте.
|
||
|
||
**НАХОДКИ, МЕНЯЮЩИЕ ПРОМТ (все три подписаны, ни одна не абсорбирована молча).**
|
||
1. **§3.2: маркер существовал и ВРАЛ.** Ветка `case ce.FinalText != ""` печатала «(leak cleaned,
|
||
verify)» ЛЮБОМУ флагнутому юниту с текстом, а c-lite member-drop (`export.go` ставит `DispFlagged`
|
||
при непустом тексте) попадал ровно в неё. Существующий тест не ловил: покрывал ветку только
|
||
причиной `sanitizer_stripped` (`export_cli_test.go:66`). Предмет заказа изменён с «завести маркер»
|
||
на «перестать врать и покрыть непокрытое» — разрешено оркестратором 28.08 при закрытом гейте.
|
||
2. **§3.2: подсказка промта про место правки была опасна.** Промт указывал `export.go:237` рядом с
|
||
`ApplyHeading`. Туда нельзя: `ChunkExport.FinalText` — поле артефактного контракта, а провод судит
|
||
`translated`/`withheld` предикатом «текст непуст» (`waverun.go:203-204` и `events.go:538-554`,
|
||
`runevents.go:130` `Shipped`). Маркер в пустом юните перевернул бы `withheld` → `translated` —
|
||
ровно ⛔(а) промта. `ApplyHeading` этого не делает лишь потому, что на пустом тексте он no-op.
|
||
Маркер живёт в РЕНДЕР-слое. Проверено: `FlagReason`-константы до и после ИДЕНТИЧНЫ, `exportVersion`
|
||
не двигался, `dropped_members` аддитивно и `omitempty`.
|
||
3. **§3.1: посылка «Gemini принимает ровно одно» отозвана автором** (оркестратор, 28.08) — вендор-
|
||
вердикт со ссылками и датами отправлен ему отдельно, для `00-provider-quirks.md`. Кратко:
|
||
структурная посылка ПОДТВЕРЖДЕНА (`systemInstruction` — один `object (Content)`, `Content.role` ∈
|
||
{user, model}), поведение шима вендором НЕ документировано нигде, наш замер даёт «не склеиваются»
|
||
и «инструкция первого не исполнена»; «выживает одно или ноль» остаётся ОТКРЫТЫМ и для решения
|
||
безразлично.
|
||
|
||
**ДЕФЕКТ, КОТОРЫЙ Я ВНЁС САМ И ЗАКРЫЛ (называю, потому что он показателен).** Первая редакция ветки
|
||
маркера срабатывала по `DroppedMembers > 0` БЕЗ проверки непустого текста. Юнит, у которого выпали ВСЕ
|
||
члены, ship-ит пустоту — и получил бы баннер «(INCOMPLETE)» с фразой «фрагмент отсутствует в тексте
|
||
НИЖЕ», указывающей на несуществующий текст. То есть я едва не заменил одну ложь читателю на другую.
|
||
Найдено собственным разбором ветвлений до опровергателей, закрыто гардом на обоих сайтах вызова,
|
||
покрыто состоянием «выпали все» в матрице и запинено мутацией (снятие гарда → тест падает).
|
||
|
||
**§5 ОСИ РЕВЮ.**
|
||
1. **Читатель книги.** Все четыре класса проверены на ОТГРУЖЕННОМ ТЕКСТЕ, не на структурах:
|
||
(а) c-lite — был помечен ложно, теперь помечен верно и в потоке текста; (б) юнит целиком withheld и
|
||
(в) `glossary_miss` — помечены верно и раньше, работы не требовали, теперь ещё и не попадают под
|
||
маркер по ошибке; (г) сноска с ханьцзы — накрыта существующим верным маркером.
|
||
2. **Пара, которой в репо нет.** Правка не ветвится по паре ни в одном месте: ось `system_messages` —
|
||
свойство ЭНДПОЙНТА, маркер — английский операторский словарь той же поверхности, что и соседние
|
||
баннеры, поэтому у книги с любым `target_lang` и БЕЗ langpack вывод байт-идентичен. Специально НЕ
|
||
стал класть маркер в langpack: `InjectionTextsFor` для незнакомой цели возвращает нулевое значение
|
||
молча (`lang/embedded.go:411-423`) — маркер бы исчез, и дыра снова стала бы тихой ровно для той
|
||
пары, ради которой мандат общности и написан.
|
||
3. **Детерминизм.** Голден зелёный (`go test ./internal/pipeline/ -run TestGolden -count=1`), и это
|
||
сильная улика: голден пинит ПОЛНОЕ тело запроса с обоими системными сообщениями
|
||
(`testdata/golden/capture.golden:110`), то есть глобальная свёртка сделала бы его красным, а
|
||
квирк-свёртка не трогает никого, кто квирк не объявил. `omitempty` на новом поле запинен тестом
|
||
(`TestCapabilityWithoutTheAxisMarshalsUnchanged` сверяет БАЙТЫ). Снапшот фолдит Capability только
|
||
праймари и `escalate_to` (`snapshot.go:316-340`), а в `pipeline-c1.yaml` это `deepseek-v4-pro`
|
||
(`:60`) — gemini там лишь третий в цепочке при `budget_usd: 0` и SINGLE-HOP раннере ⇒ снапшот
|
||
боевого конфига не двигается, перекупки нет.
|
||
|
||
**§8 OBSTACLE — что НЕ удалось и что НЕ проверено.**
|
||
- **Живого вызова к Gemini НЕ было** (пак платных вызовов не требует, и я их не делал). Что склейка
|
||
ПОМОГАЕТ, доказано структурно вендор-докой и логикой «при любом чтении, кроме склеивания, два
|
||
системных теряют текст» — но НЕ замерено на проводе. Решающая проба стоит денег и принадлежит
|
||
полигону: маркер на ПОСЛЕДНЕЕ системное + user-only контроль закрыли бы открытый вопрос
|
||
«выживает одно или ноль». Также: проба полигона гонялась на `gemini-3.1-flash-lite`, а в цепочке
|
||
стоит `gemini-3.1-pro-preview` — слой тот же, слаг другой, перенос не замерен.
|
||
- **Достижимость §3.1 сегодня НУЛЕВАЯ, и это не смягчение дефекта, а его честная рамка.** Раннер
|
||
исполняет SINGLE-HOP, `escalate_to` боевого конфига — `deepseek-v4-pro`, `budget_usd: 0`. Gemini не
|
||
достигается ни одним шиппинг-конфигом; дефект ждал первого конфига, который назовёт его в
|
||
`escalate_to` или в `chain[0]` лейбла. Кривая пост-чек-промахов на эскалационном хопе, которую §4.2
|
||
просил как второй замер, СНЯТА БЫТЬ НЕ МОЖЕТ по той же причине — мерить нечего.
|
||
- **Ловушка, которую я НЕ чинил и обязан назвать: `capabilities` у провайдера с `kind: anthropic`
|
||
принимается валидацией и молча игнорируется** — `clients.go` не передаёт `Cap` в Anthropic-клиент
|
||
вовсе. Это ПРЕД-СУЩЕСТВУЮЩИЙ класс (так ведут себя ВСЕ оси: `budget_field`, `temperature`,
|
||
`reasoning`, `min_max_tokens`), моя ось лишь наследует его. Чинить правильно — тащить `kind` в
|
||
`validateCapabilities`, что трогает каждую ось; в этом паке это чужой предмет. Практический риск
|
||
сегодня нулевой: провайдера `anthropic` в `models.yaml` нет.
|
||
- **Изменён СУЩЕСТВУЮЩИЙ тест — заявляю прямо, не прячу в дифе.**
|
||
`internal/pipeline/bankreport_test.go` `TestHalfLandedIsNamedPerFile` кодировал ПОРЯДОК переименований
|
||
в своей фикстуре (занимал путь rejects, чтобы упал второй rename). Порядок изменён заказом §3.3, и
|
||
фикстура пере-нацелена на путь delta. Утверждение НЕ ослаблено: по-прежнему требуется, что ровно
|
||
одна половина легла, что это ПРОВЕРЕННЫЕ байты и что отчёт называет какая. Сверх того добавлен
|
||
`TestTheRenameOrderIsWhatMakesADeclineRecover`, который пинит САМ порядок вместе с его причиной,
|
||
чтобы его нельзя было вернуть как «уборку». **Если оркестратор считает это подгонкой — я готов
|
||
откатить и вынести §3.3-половину с полусостоянием отдельным заказом.**
|
||
- **Каталог мутаций: запись `AJ-seed-alias-decline` пере-заякорена.** Моя правка сдвинула строку, на
|
||
которую она указывала, и инструмент падал жёсткой ошибкой «the source moved under the catalogue» —
|
||
это был бы хард-блокер для следующей сессии. Атакуемое свойство сохранено дословно (снять
|
||
дельта-оговорку, оставить остальное); плюс добавлены шесть СВОИХ посадок `SH1`…`SH6`, по две на
|
||
пункт, чтобы фикс был постоянным гейтом, а не разовым замером.
|
||
- **Не проверено:** поведение под реальным параллелизмом двух `bank-apply` (лок это исключает, но я
|
||
не гонял); поведение склейки на провайдере, который принимает одно системное И имеет префиксный кеш
|
||
(у gemini кеш иной) — довод «склейка кеш не портит» опирается на комментарий самого кода и на то,
|
||
что префикс сохраняет байты и позицию, живьём не мерен.
|
||
|
||
**§4 ОПРОВЕРГАТЕЛЬ — ЗАКАЗ ИСПОЛНЕН, И ОН ОКУПИЛСЯ. Шесть линз, мандат «опровергни».**
|
||
Веер шесть, а не «2–4» из §4: численный потолок снят словом владельца 28.08, соразмеряю предмету.
|
||
Линзы: Anthropic-путь и кеш · читатель книги · провод `withheld`/`translated` · безопасность банковых
|
||
решений · пара, которой в репо нет + детерминизм · вырожденность собственных тестов. **Пять из шести
|
||
вернули вердикт REFUTED или PARTIAL, и это правильный исход: они нашли ШЕСТЬ дефектов, из них ЧЕТЫРЕ
|
||
я внёс сам этим паком.** Все воспроизведены ИСПОЛНЕНИЕМ на копиях дерева, не чтением.
|
||
|
||
| Находка | Кто/чем доказано | Что сделано |
|
||
|---|---|---|
|
||
| **MAJOR: маркер называл ЧУЖУЮ причину.** Юнит, где редактура флагнулась САМА (косм. чистка) И выпал член, печатал причину ЧИСТКИ как причину дыры: «фрагмент не переведён: sanitizer_stripped». Та же ложь, что убирал пак, перенесённая в поток текста | 2 линзы независимо, боевой бинарь | **ИСПРАВЛЕНО:** заведены `DroppedReason` на `ChunkOutcome`/`ChunkExport`, маркер несёт причину ЧЛЕНА, баннер — вердикт ЮНИТА. Пин `SH7`, состояние в матрице обоих рендеров |
|
||
| **MAJOR: анти-скоуп.** В черновично-однофазном конвейере юнит — одиночный чанк, и его СОБСТВЕННЫЙ флаг читался как «выпавший член» ⇒ косметически почищенный чанк, у которого ВЕСЬ текст на месте, объявлялся неполным | боевой бинарь, `tmctl translate` и `tmctl export` расходились на одном юните | **ИСПРАВЛЕНО:** учёт выпадений только когда финальная волна — редакторская (`export.go`). Тест `TestADraftOnlyStrippedChunkIsNotCalledIncomplete`, пин `SH8` |
|
||
| **MAJOR: перестановка порядка записи купила сходимость ЦЕНОЙ второго тихого вреда.** Rejects-first оставляет строку дельты на диске, а `seedGlossary` дельту отказами НЕ фильтровал ⇒ в окне между падением и ре-сендом ОПЛАЧЕННЫЙ прогон вливал в глоссарий редактора терм, который владелец отклонил | 2 линзы, исполнение на реальных файлах | **ИСПРАВЛЕНО:** `loadMinedDelta` отбрасывает поверхность, стоящую в списке отказов, и говорит об этом WARN'ом. Тест на реальном полусостоянии, пин `SH12`. Заодно исправлено утверждение в шапке `writeDecisionFiles`, которое после перестановки стало ложным |
|
||
| **MAJOR: сходимость останавливалась на ОДНОЙ из двух дверей.** `refuseInertDeclines` я решил не трогать — и ошибся: траектория из ОДНИХ ПРИНЯТЫХ вызовов (decline терма-со-своей-строкой → approve терма, который несёт его алиасом) делала повтор стоячего реестра решений отказным навсегда, а всё-или-ничего уносило с ним законный approve | исполнение, полная трасса | **ИСПРАВЛЕНО:** та же оговорка на второй двери (по `in.Rejects`, не `res.Rejects` — фолд уже отработал). Тест `TestTheStandingLedgerConvergesThroughBothDoors` + направление-гард на живом алиасе, пин `SH13` |
|
||
| **MAJOR: у боевого объявления в `configs/models.yaml` не было ГЕЙТА вовсе.** Две строки — единственное, что доводит фикс до реального эндпойнта, а удаление их оставляло ВЕСЬ модуль зелёным | опровергатель посадил свою мутацию и получил SURVIVED | **ИСПРАВЛЕНО:** `TestShippedGeminiDeclaresOneSystemMessage` над боевым конфигом, пин `SH9` (проверено: удаление строк → тест краснеет) |
|
||
| **MINOR: гарды в `renderTranslate` не были запинены** (близнецы в `renderExport` были), `case "multi"` не покрыт, счётчики читались как разбиение целого | исполнение | **ИСПРАВЛЕНО:** матрица шести состояний для `renderTranslate`, тест `TestExplicitMultiCostsNothing`, счётчик переписан как `exported=N (of them incomplete=M)`. Пины `SH10`, `SH11` |
|
||
|
||
**ЧТО ОПРОВЕРГАТЕЛИ АТАКОВАЛИ И НЕ СЛОМАЛИ** (чтобы следующий читатель знал, что уже покрыто):
|
||
Anthropic-путь (склейка до него не доходит структурно — `Cap` в него не передаётся; два блока и живой
|
||
`cache_control` на месте) · префиксный кеш (стабильный префикс сохраняет байты и позицию) · провод
|
||
`translated`/`withheld` (`UnitDone.Shipped` считается по пустоте текста; ни `DroppedMembers`, ни
|
||
маркер её не трогают) · отсутствие новых причин флага (константы `FlagReason` до и после ИДЕНТИЧНЫ) ·
|
||
`exportVersion` не двигался · снапшоты боевых конфигов не двигались · арм-конфиги грузятся.
|
||
|
||
**ЧТО НАЙДЕНО, НО СОЗНАТЕЛЬНО НЕ ЧИНИТСЯ — с аргументом.**
|
||
1. **Ловушка `capabilities` на `kind: anthropic`** — оказалась чинибельной дёшево, и я её ВЗЯЛ: ось
|
||
теперь отказывается на этом виде по образцу `cache_ttl` (`models.go`), с тестом. Пред-существующий
|
||
класс для ОСТАЛЬНЫХ осей (`budget_field`, `temperature`, `reasoning`, `min_max_tokens`) остаётся —
|
||
его правильная форма тащит `kind` в `validateCapabilities` и трогает каждую ось; это чужой предмет.
|
||
2. **Снапшот не покрывает модель ГЕЙТА ТЕРМИНОЛОГИИ** (`config/pipeline.go` — не фолдится сознательно,
|
||
ратифицированно), а терминолог шлёт ДВА системных. ⇒ флип оси у провайдера, которым пользуется
|
||
только этот гейт, меняет байты под НЕИЗМЕННЫМ `RequestHash`, и чекпойнты ложно попадают. Дыра НЕ
|
||
моей оси — по ней ездят все оси `capabilities` с D3.1 — но моя первая, чей смысл именно в смене
|
||
этих байтов. **Утверждение в комментарии я ослабил до правды и дыру НАЗВАЛ прямо в коде**
|
||
(`capability.go`); закрытие — фолд модели гейта, как это делает `repairSnapshot`, и это правка
|
||
снапшот-контракта, принадлежащая владельцу решения «не фолдить», а не провайдерскому квирку.
|
||
3. **Сузив отказ по поверхности, я потерял поучение в одном углу:** decline, который И записан, И
|
||
по-прежнему инертен против подписанного сид-терма, теперь отвечает `already_applied` вместо
|
||
единственной работающей инструкции «убери из glossary_seed». Сходимость сочтена более тяжёлой
|
||
обязанностью (у вызывающего, который следует опубликованному ретраю, другого хода нет), но размен
|
||
реальный: **закрывается полем отчёта, несущим стоячий факт**, и это форма шва.
|
||
|
||
**ХАРД-БЛОКЕР, НАЙДЕННЫЙ И СНЯТЫЙ (требование владельца «после тебя не осталось хард-блокеров»).**
|
||
`go test ./cmd/tmctl/` строил боевой бинарь в `os.MkdirTemp` и НИКОГДА не убирал каталог — по 20 МБ за
|
||
прогон. За этот пак накопилось **249 брошенных каталогов `tmctl-bin*`, ~5 ГБ**, и `/tmp` заполнился до
|
||
99%: батарея под `-race` начала падать с `link: mapping output file failed: no space left on device`,
|
||
что читается как сломанная сборка, а не как кончившееся место. Я на это и купился на один прогон —
|
||
сообщать «батарея красная» было бы ложью. **Причина найдена, место освобождено, харнесс починен:**
|
||
добавлен `TestMain`, снимающий каталог (`cmd/tmctl/exitcontract_test.go`); проверено исполнением —
|
||
два прогона подряд, прирост каталогов 0. Дефект пред-существующий, пак его лишь довёл до отказа.
|
||
|
||
**ЧИСЛА, С КОМАНДАМИ (§4.1).**
|
||
- `go build ./...` · `gofmt -l .` (пусто) · `go vet ./...` · `go vet -tags live ./...` — **все 0**.
|
||
- `go test ./... -count=1 -timeout=20m` → **EXIT 0**.
|
||
- `go test ./... -race -count=1 -timeout=20m` (= строка `make test`) → **EXIT 0, real 2m09s**.
|
||
- `golangci-lint run --timeout=15m ./...` (= `make lint`) → **0 issues**.
|
||
- `go test ./internal/pipeline/ -run TestGolden -count=1` → **ok** (голден пинит ПОЛНОЕ тело запроса).
|
||
- `go run ./cmd/tmmutate -root <КОПИЯ>` → **73 посадки, 0 неожиданных исходов, EXIT 0** (72 RED + один каталогизированный выживший `G-byte-gate`; все 13 моих красны); каталог вырос 60 → 73 (13 новых посадок:
|
||
`SH1`…`SH13`), у каждой из трёх заказанных тем ≥2 своих.
|
||
⚠ **Каталог гонять ТОЛЬКО на копии** — сам инструмент это требует, а я один раз запустил его на рабочем
|
||
дереве и словил таймаут; дерево спас обработчик сигнала самого инструмента (проверено: мутационного
|
||
текста не осталось, батарея зелена). Записываю как урок, а не как мелочь.
|
||
|
||
**ФАЙЛЫ (19 правленых + 5 новых; всё в `backend/`, плюс эта запись в журнале).**
|
||
`cmd/tmctl/render.go` · `cmd/tmctl/exitcontract_test.go` · `cmd/tmmutate/mutations.json` ·
|
||
`configs/models.yaml` · `internal/config/models.go` · `internal/config/models_catalog_test.go` ·
|
||
`internal/llm/capability.go` · `internal/llm/httpllm.go` · `internal/llm/provider_openai.go` ·
|
||
`internal/llm/provider_local.go` · `internal/membank/decisions.go` ·
|
||
`internal/membank/decisions_fuzz_test.go` · `internal/pipeline/bankdecisions.go` ·
|
||
`internal/pipeline/bankreport_test.go` · `internal/pipeline/bookrun.go` ·
|
||
`internal/pipeline/export.go` · `internal/pipeline/mining.go` · `internal/pipeline/runner_test.go` ·
|
||
`internal/pipeline/waverun.go`.
|
||
Новые: `cmd/tmctl/exportgap_cli_test.go` · `internal/llm/systemmessages_test.go` ·
|
||
`internal/membank/decisions_converge_test.go` · `internal/pipeline/bankdecisions_converge_test.go` ·
|
||
`internal/pipeline/systemmessages_wave_test.go`.
|
||
|
||
**⛔ ВОПРОСЫ И ПИНГИ ОРКЕСТРАТОРУ — четыре, каждый требует ЧУЖОГО решения.**
|
||
1. **Изменён СУЩЕСТВУЮЩИЙ тест, и я это заявляю, а не прячу.** `bankreport_test.go`
|
||
`TestHalfLandedIsNamedPerFile` кодировал в фикстуре ПОРЯДОК переименований, который заказ §3.3
|
||
изменил; фикстура пере-нацелена на второй rename, утверждение сохранено дословно и усилено новым
|
||
`TestTheRenameOrderIsWhatMakesADeclineRecover`, пинящим сам порядок с его причиной. **Считаешь
|
||
подгонкой — откачу, и тогда половину §3.3 с полусостоянием надо выносить отдельным заказом.**
|
||
2. **Вендор-вердикт по Gemini** — прислан отдельным сообщением, с URL и датами; три поправки к
|
||
`00-provider-quirks.md:157` (структурная посылка ≠ поведенческий вывод · `Content.parts[]`
|
||
повторяемо · «форум Google» — это два не-сотрудника из 2025). Пишешь ты, зона твоя.
|
||
3. **Дыра снапшота у модели гейта терминологии** (см. выше, п.2 «не чинится»). Закрытие — правка
|
||
снапшот-контракта; принадлежит владельцу решения «гейт не фолдится», не мне.
|
||
4. **Д1 достоин собственного заказа.** Не «расширить decline до энтити» (это против канона), а узко:
|
||
эмиссия майнера энтити-широка (`miner_emit.go` `clusterTouches`), а фильтр авто-банка ключуется
|
||
только по собственному src строки (`mining.go:662`), поэтому ОТКЛОНЁННАЯ поверхность возвращается
|
||
алиасом уцелевшей строки. Канон уже сегодня обещает «declining a surface removes EVERY window of
|
||
that surface» — то есть движок не держит обещание. Правильная форма — снять алиас со строки, а не
|
||
снести строку; это банковая онтология, и в «тихую порчу» её тянуть не следует.
|
||
|
||
**ПРАВО §9 ПРИМЕНЕНО ТРИЖДЫ, каждый раз с грунтом:** Д3 отклонён (символ живёт в `platform/`, зона
|
||
заперта; движковая половина здорова и порядок «карта → память» исполнен) · Д1 отклонён как отдельный
|
||
предмет (выше) · подсказка промта про место маркера отклонена (она перевернула бы `withheld` →
|
||
`translated`). ⚠ И один раз право §9 я применил ОШИБОЧНО: решил не трогать вторую дверь
|
||
`refuseInertDeclines`, рассудив, что её случай — «устаревший документ, а не ретрай». Опровергатель
|
||
показал траекторию из ОДНИХ ПРИНЯТЫХ вызовов. Рассуждение было неверным, исполнение это доказало,
|
||
дверь починена.
|
||
|
||
|
||
**⚠ ЗАПИСКА НИЖЕ — ПЛАН ДО ПРАВОК (§6), она СОХРАНЕНА как след дисциплины, но её выводы местами ОПРОВЕРГНУТЫ итогом выше. Не наследовать из неё: «сломан только класс (а)» (сломан ещё и стык «редактура флагнулась сама + выпал член»), «фиксация порядка записи безопасна» (она купила второй тихий вред, закрытый фильтром дельты) и «Д3 не существует» (существует, в `platform/`).**
|
||
|
||
**📝 ЗАПИСКА-ПЛАН БЭКЕНД-СЕССИИ 28.08 — ПАК «ТИХАЯ ПОРЧА» (`docs/BACKEND_SILENT_HARM_SESSION_PROMPT.md`), §6. Правок кода на момент записи НЕТ.**
|
||
Три заказа: §3.1 инъекция банка не теряется · §3.2 дыра выдачи видна читателю файла · §3.3 повтор
|
||
принятого документа сходится. Ниже — что установлено ЧТЕНИЕМ до правок и как из этого следует план.
|
||
⚠ Всё, что помечено «проверить исполнением», в план входит как обязательство, а не как факт.
|
||
|
||
**Находка 1 (меняет §3.2). Маркер уже есть — и он ВРЁТ.** `cmd/tmctl/render.go:499` печатает для
|
||
флагнутого юнита с НЕПУСТЫМ текстом баннер «(leak cleaned, verify)», а `:38` — «[FLAG … — leak
|
||
cleaned, exported cleaned, verify]». Ветка выбирается по `ce.FinalText != ""`, и c-lite member-drop
|
||
(`export.go:226-230` ставит `DispFlagged` при непустом тексте) попадает ровно в неё. То есть юнит, у
|
||
которого ВЫПАЛ ЦЕЛЫЙ ЧЛЕН, объявляется читателю косметической чисткой санитайзера, которой не было.
|
||
Существующий тест это не ловит: `cmd/tmctl/export_cli_test.go:66` покрывает ветку только причиной
|
||
`sanitizer_stripped`. ⇒ Предмет §3.2 не «завести маркер», а «перестать врать и покрыть непокрытое»
|
||
(пере-формулировка разрешена оркестратором 28.08 при закрытом гейте «что читает человек»).
|
||
|
||
**Гейт §3.2 закрыт чтением: движок НЕ ПИШЕТ ФАЙЛОВ ВООБЩЕ.** Все команды рендерят в stdout
|
||
(`cmd/tmctl/main.go:227-228`, `:338-349`). Читаемых человеком поверхностей у движка две, обе
|
||
текстовые и обе уже несут пер-юнитный баннер: `tmctl translate` (`render.go:27-72`) и
|
||
`tmctl export --plaintext` (`render.go:478-511`). Дефолт `export` — JSON
|
||
(`export_cli_test.go:24-28`), и он же артефакт шва к платформе (`research/23` строка 76 —
|
||
«артефактный контракт (export-JSON · 101 · 100)»). Читательский файл (epub и пр.) собирает
|
||
ПЛАТФОРМА по `POST /books/{bookId}/exports` (`14-api-contract/openapi.yaml:824-870`) — чужая зона.
|
||
⇒ Адресат моего маркера — человек, читающий plaintext-выгрузку движка; платформенная половина
|
||
остаётся за платформой, и провод различение несёт (`14-api-contract/README.md:300`).
|
||
|
||
**Следствие для места правки, и оно расходится с подсказкой промта.** Промт указывал на
|
||
`export.go:237` (прецедент `ApplyHeading`). Туда маркер класть НЕЛЬЗЯ: `ChunkExport.FinalText` — это
|
||
поле `final_text` артефактного контракта, а `waverun.go:203-204` кормит провод предикатом
|
||
`oc.FinalText != ""` (`shipped`). Любой маркер, вклеенный в текст ПУСТОГО юнита, перевернул бы
|
||
`withheld` → `translated` — ровно ⛔(а) промта. `ApplyHeading` этого не делает только потому, что на
|
||
пустом тексте он no-op (`chunk/chunker.go:186-191`). Различение: титул — часть КНИГИ и обязан ехать
|
||
на провод; маркер дыры — метаданные О тексте, и в поле, по которому провод судит, ему нельзя. ⇒
|
||
маркер живёт в РЕНДЕР-слое (`cmd/tmctl/render.go`), на слой дальше проекции. Это ответ на требование
|
||
промта «либо тем же механизмом, либо объясни, почему другое».
|
||
|
||
**Классы дыр — ревизия по коду.** (а) c-lite member-drop — помечен, но ЛОЖНО (находка 1); (б) юнит
|
||
целиком withheld (`waverun.go:496-509`) и (в) gate-override `glossary_miss` (`export.go:319-323`)
|
||
дают пустой текст и попадают в ветку `render.go:502-504` «(not translated, flagged for a human)» —
|
||
помечены ВЕРНО, работы не требуют; (г) четвёртая, сноска «[1] …» мимо детектора примечаний: детектор
|
||
требует заголовочного слова (`lang/data/target-ru.txt`, `sanitizer_trailing_note`), но ханьцзы в
|
||
сноске поднимают класс `CJKLeak`, а он `CosmeticOnly` (`checks/sanitizer.go:161-163`) ⇒ юнит уходит
|
||
как `sanitizer_stripped`, и баннер «leak cleaned» для НЕГО правдив. То есть класс (г) накрыт
|
||
существующим механизмом БЕСПЛАТНО и работы в детекторе не требует — граница промта соблюдена.
|
||
**Проверить исполнением обязательно:** что сноска с ханьцзы действительно даёт `CosmeticOnly`, а не
|
||
подтягивает субстантивный класс.
|
||
|
||
**§3.1 — план и его цена.** Свёртки в `toOpenAIMessages` нет (`llm/httpllm.go:513-521`, копия
|
||
один-в-один); её комментарий `:511-513` говорит, что `CacheBoundary` на этом пути бессмысленна ⇒
|
||
свёртка кеш не портит. У Anthropic путь другой и трогать его нельзя
|
||
(`llm/provider_anthropic.go:169-179`: ведущий system-префикс → блоки, `CacheBoundary` → реальный
|
||
`cache_control`). Ось лечения — `llm.Capability` + блок `capabilities:` (провайдерный ИЛИ модельный,
|
||
`config/models.go:85`,`:146`,`:442-450`), прецедент безопасного расширения — `MinMaxTokens` с
|
||
`json:",omitempty"`. **Детерминизм:** снапшот фолдит РАЗРЕШЁННУЮ Capability только для праймари и
|
||
единственного `escalate_to` (`pipeline/snapshot.go:316-340`,`:479`,`:495`); в `pipeline-c1.yaml`
|
||
`escalate_to: deepseek-v4-pro` (`:60`), а gemini стоит лишь третьим в цепочке `default` (`:129`) при
|
||
`budget_usd: 0` (`:136`) и раннере SINGLE-HOP ⇒ объявление квирка у gemini снапшот боевого конфига
|
||
НЕ двигает. Проверить исполнением (голдены + снапшот-тесты).
|
||
⚠ **Честная граница достижимости:** при SINGLE-HOP и текущих конфигах gemini не достигается ВООБЩЕ;
|
||
дефект латентный и ждёт конфига, который назовёт gemini в `escalate_to` или в `chain[0]` лейбла.
|
||
⚠ **Развилка, которую выношу на опровергателя (§4 заказ):** дефолт оси. «Квирк объявляет тот, у кого
|
||
он есть» (нулевое значение = сегодняшнее поведение) не двигает ничего, но НОВЫЙ провайдер с той же
|
||
ловушкой снова теряет инъекцию молча — тот же класс тихого вреда. «Свёртка по умолчанию, исключение
|
||
объявляет проверенный» безопасна для незнакомого провайдера, но меняет провод боевому переводчику без
|
||
замера (запрет «эмпирика решает») и двигает снапшот. Решение — после опровергателя, с обоснованием.
|
||
⚠ **Посылка промта «Gemini принимает ровно одно системное» ОТОЗВАНА автором** (оркестратор, 28.08):
|
||
это было рассуждение; собственный замер полигона (`00-provider-quirks.md:157`) даёт 535 токенов ≈ не
|
||
выжило НИ ОДНО. Заказу это безразлично, тесту — нет: утверждается пост-фиксный инвариант «системное
|
||
РОВНО ОДНО и инъекция ВНУТРИ него», он верен при любом чтении. Вендор-вердикт со ссылкой уходит
|
||
оркестратору для `00-provider-quirks.md` (его зона).
|
||
|
||
**§3.3 — трасса контрактной сессии ПОДТВЕРЖДЕНА моим чтением, и подтверждено то, что она сама не
|
||
читала.** Отказ живёт в `membank/decisions.go:374-377`, бежит ДО фолда (`:296-300`), и
|
||
всё-или-ничего вытирает документ целиком (`:302-307`). **Порядок записи я прочитал сам:
|
||
`bankdecisions.go:458-473` коммитит ДЕЛЬТУ ПЕРВОЙ**, а собственный комментарий функции `:436-438`
|
||
говорит дословно: «delta-first is safe for an approve and NOT for a decline … convergence is what
|
||
actually carries both». ⇒ окно застревания реально, и код сам называет допущение, которое ложно.
|
||
Идемпотентная ветка уже есть (`already_applied`, `:221-224`,`:269-272`) — вводить понятие не надо.
|
||
План: сузить условие отказа так, чтобы оно не срабатывало, когда отказ УЖЕ записан в rejects, плюс
|
||
направление-гард (настояще-инертный decline обязан отказывать по-прежнему тем же текстом).
|
||
Идентичность документа НЕ вводить — сходимость по СОСТОЯНИЮ.
|
||
|
||
**Д1 и Д3 — беру право §9 и НЕ чиню, оба с грунтом.**
|
||
· **Д3 ОТКЛОНЁН как несуществующий:** гард `LiftBankStop` не найден в коде НИ В КАКОМ написании
|
||
(греп по всему `backend/`); реальный носитель — `mining.go:266-277`, и он уже реализует
|
||
ратифицированный порядок «карта → память»: `writeFileAtomic` карты на `:191`, `MarkStopPresented`
|
||
на `:274`, с комментарием `:270-273` «strictly after the map … the reverse order can mark surfaces
|
||
presented whose map never reached disk» и с явной оценкой отказа памяти как «one extra stop, nothing
|
||
lost» (`:275-276`). То есть механизм написан ВМЕСТЕ с памятью v16, а не до неё.
|
||
· **Д1 ОТКЛОНЁН как ратифицированное поведение + названный остаток:** канон определяет decline
|
||
ПОВЕРХНОСТНО («declining a surface removes EVERY window of that surface» —
|
||
`14-api-contract/openapi.yaml:2051`), и расширение до энтити противоречило бы контракту; а «память
|
||
глушит стоп» — уже НАЗВАННЫЙ и принятый двусторонний остаток в комментарии
|
||
`mining.go:308-313`. Оба — строка с причиной, не правка.
|
||
|
||
**Сосед 131 (называю, не чиню, как велит §3.4):** кап инъекции считает только «src → dst» и не
|
||
считает маркер `⟨проверить⟩` и родовые пометки (`lang/data/injection.txt` несёт их как отдельные
|
||
значения) ⇒ реальная инъекция шире бюджета. Проверю точный носитель при работе в этом коде и назову
|
||
`file:line` в итоге; чинить не буду — тема денег и качества инъекции, а не тихого брака в тексте.
|
||
|
||
**Порядок работы:** §3.1 → §3.2 → §3.3, каждый с тестом на ПОСТ-фиксный инвариант; батарея под
|
||
`-race` + линтер; посадки мутаций ≥1 на пункт с вердиктом по ДЕЛЬТЕ и ТОПИЧНОСТИ; опровергатель на
|
||
выбор места §3.1 (заказ §4). Веер агентов соразмеряю предмету: численный потолок «2–4» из §4 промта
|
||
снят словом владельца 28.08.
|
||
|
||
**✅ ИТОГ БЭКЕНД-СЕССИИ 27.08 (2) — ФИКС3 ПО ФИКС-ЛИСТУ ПРИЁМКИ (`docs/BACKEND_SEAM_FIX3_SESSION_PROMPT.md`), все 6 пунктов. Дерево готово, НЕ закоммичено; продолжает дерево трёх паков.**
|
||
Четыре пина, один снос, ноль новых механизмов: пин порядка «карта → память» (мутация приёмки
|
||
воспроизведена в трёх пакетах ДО пина; занятый путь карты → ошибка прогона + пустая память) · пин
|
||
«отчёт класса 15 мерит подпись по ДИСКУ, не по намерению» (утверждение панели воспроизведено) · оба
|
||
носителя старого пола полосы приведены к двух-ярусной букве · отменённая формула «стоп гаснет, когда
|
||
решён каждый терм» зачищена ГРЕПОМ — восемь носителей, включая два файла самого пака · снесена
|
||
машинная таблица `.bank-stop.json` вместе с писателем и четырьмя тестами (читателя нет ни в одной
|
||
зоне — свой греп; человеческая `.bank-stop.txt` не тронута) · банк-экспорт получил якорь свежести
|
||
`as_of`+`run_id` (аддитивно на `tm-bank-v1`; «может быть устаревшим» больше не живёт только в логе).
|
||
**Доказательная база — `FINDINGS` §46; каталог мутаций 58 → 60 (FX23, FX24).**
|
||
|
||
**⛔ Пинги:**
|
||
1. **Платформе/оркестратору:** `.bank-stop.json` СНЕСЁН (мёртвая публикация упразднённого D39.144
|
||
пер-термного экрана) — платформенные журналы (`platform-PROGRESS.md`, `STACK_DECISIONS.md`)
|
||
называют его атомарно-читаемым сайдкаром, упоминания устареют при лендинге.
|
||
2. **Потребителям банк-экспорта:** документ несёт `as_of` (граница прогона) и `run_id` (тот же id,
|
||
что стрим `events.jsonl`); аддитивно, старые читатели не ломаются; пустой `run_id` = «идентичности
|
||
нет», не «текущий».
|
||
|
||
**✅ ИТОГ БЭКЕНД-СЕССИИ 27.08 — ДОФИКС-2 «ФЛАЖОК СТАНОВИТСЯ ФЛАЖКОМ» (`docs/BACKEND_SEAM_FIX2_SESSION_PROMPT.md`). Дерево готово, НЕ закоммичено; продолжает дерево паков 24–25.08.**
|
||
Все 13 пунктов §4 закрыты: движок сам реализует модель D39.144 — стоп банка срабатывает только на
|
||
кластер, которого ни один прежний стоп не предъявлял (персистентная память `bank_stop_presented`,
|
||
схема v16); авто-провод неподписанных строк работает и при ПОДНЯТОМ флаге; отчёт двери собирается
|
||
ОДНИМ конструктором по явному исходу (проекция · отказ · no-op · прерывание · записано · запись не
|
||
удалась), версия отчёта → v2 (`written_delta`/`written_rejects`, mode `refused`/`write_incomplete`);
|
||
полоса отказов получила два яруса и класс `write_incomplete` (exit 15); оба файла решений готовятся
|
||
целиком до первого rename + fsync каталога; ключи `mined_delta`/`mined_rejects` СНЯТЫ (пути только
|
||
конвенцией — МЕЖКНИЖНАЯ гонка недостижима, ⛔-пинг прошлого пака закрыт; воркфлоу-ревью нашло остаток
|
||
той же оси: второй конфиг ТОЙ ЖЕ книги с другим объявленным project_db пишет те же файлы под другим
|
||
локом, мимо flock живого прогона — пинг ниже, решение не паку); карта подписи
|
||
пишется атомарно и несёт конверт `map_version`+`map_id`; шесть слепых пятен гейта закрыты пинами,
|
||
проверенными посадкой. Поверх — воркфлоу-ревью (шесть полос × три скептика, `FINDINGS` §45): его две
|
||
кодовые находки закрыты правками с пинами — `--dry-run` теперь отказ для всех глаголов без проекции
|
||
(раньше `translate --dry-run` МОЛЧА запускал платный прогон), а повтор после отказа синка каталога
|
||
держит класс 15, пока долговечность не пере-доказана. **Доказательная база —
|
||
`backend/docs/SEAM_PACK_FINDINGS.md` §§36–§45; каталог мутаций 36 → 58 записей, 0 неожиданных
|
||
исходов.** Здесь — только требующее действия.
|
||
|
||
**⛔ ПОРЯДОК ДЕПЛОЯ/ЛЕНДИНГА — зависимость НАПИСАНА, а не выведена (заказ §4.12):**
|
||
1. **Движок первым, платформа второй.** Сброс флага `--verify-bank` платформой (её персистентная
|
||
колонка + особый случай в спавне, `platform/internal/runs/spawn.go`) может умереть ТОЛЬКО ПОСЛЕ
|
||
лендинга этого пака: в обратном порядке каждая книга с поднятым флажком в день лендинга перестаёт
|
||
писать авто-банк и пере-сидироваться ровно в режиме, ради которого флажок существует.
|
||
2. **`tmctl migrate` до прогонов** (голова схемы v15 → v16): `OpenReadOnly` отказывает классом 13 всем
|
||
непере-мигрированным книгам — ратифицированный порядок D39.134 п.3 это покрывает, но назван явно.
|
||
3. **Миграционная нота:** после апгрейда память пуста → ОДИН доброкачественный стоп на первом
|
||
verify-прогоне каждой книги.
|
||
|
||
**⛔ ПИНГИ ЧУЖИМ ЗОНАМ (правок не делал):**
|
||
1. **Платформе:** у неё умирает сброс флага при resume (после лендинга движка — п.1 выше) · отчёт двери
|
||
теперь v2 (`tm-bank-decisions-report-v2`: mode `refused`/`stopped`/`write_incomplete`, пофайловые
|
||
`written_*`) — её `readEngine` выбрасывает stdout при ненулевых кодах, прежний пинг об этом стал
|
||
острее: класс 15 БЕЗ отчёта неотличим от «ничего не легло» · новый exit 15 в полосе 10–19 читается
|
||
её ридером как refused по построению полосы — ратификация значения на оркестраторе при лендинге.
|
||
2. **Полигону:** `eval/bank_autonomy/parse_common.py` парсит `mined-signature.yaml` — карта теперь
|
||
несёт верхние ключи `map_version`/`map_id` (лежащие артефакты coldrun не тронуты; новые прогоны
|
||
будут в новом жанре).
|
||
3. **Фронту:** экран подписи, читающий `signature.undecided` из отчёта двери, обязан перестать трактовать
|
||
его как «стоп не погаснет» — поле информационное (D39.144), контракт поля пере-описан в коде.
|
||
4. **Майнерский хвост за потолком структурно недостижим** (§4.4, НЕ чинилось по заказу): потолок эмиссии
|
||
(200) режет ранжированный пул ДО фильтров пригодности/сида/отказов (`miner_emit.go`,
|
||
`ranked[:emitRankCap]` до `emissionEligible`). Пере-замерено своей командой (числа прежнего
|
||
сплошного читателя в дерево не попали): 2354 ранжированных · 209 годных во всём алфавите · 11 в окне
|
||
потолка · 198 невидимы постоянно; отклонение всех годных окна не подняло ни одного из хвоста
|
||
(`FINDINGS` §38). Первоисточник замера — постоянный якорь-пин `internal/miner/emissioncap_test.go`:
|
||
он утверждает ТЕКУЩЕЕ поведение и покраснеет в день сдвига потолка или порядка фильтров, приведя
|
||
двигающего к этому пингу. Двигать потолок — трогать фрозен-паритет; отдельное решение.
|
||
5. **Гипотеза «подписание промахивается мимо чекпоинтов терминолога и пере-оплачивает роль» механизмом
|
||
НЕ подтверждена** (§4.13): память предъявленного входов чекпоинта не трогает; если перерасход
|
||
существует — он существовал и до пака, отдельный предмет.
|
||
6. **Остаток оси арбитра (нашло воркфлоу-ревью, воспроизведено живьём):** второй конфиг ТОЙ ЖЕ книги
|
||
(один каталог, один book_id, другой объявленный `project_db`) пишет ту же пару файлов решений под
|
||
ДРУГИМ локом — в т.ч. мимо flock живого прогона. Межкнижная версия снята конвенцией; эта — второй
|
||
конфиг одной книги, т.е. рукотворная конфигурация оператора. Выбор лечения (второй арбитр на
|
||
идентичности файлов решений или отказ при загрузке) трогает закон п.2 — решение не паку, пинг.
|
||
Довод в коде сужен честно (`bankdecisions.go`, THE ARBITER).
|
||
|
||
**✅ ИТОГ БЭКЕНД-СЕССИИ 25.08 — ДОФИКС ТОЙ ЖЕ ДВЕРИ по приёмке (`docs/BACKEND_SEAM_FIX_SESSION_PROMPT.md`). Дерево готово, НЕ закоммичено; продолжает дерево пака 24.08, а не заменяет его.**
|
||
Все 16 пунктов §4 закрыты: блокер формата (дверь писала байты, которых её же парсер не читает, и любой
|
||
следующий вызов по книге — включая проекцию — падал) · пред-существующие поломки чинятся по одной ·
|
||
два ключа на один путь · гарды флагов на ПРИСУТСТВИЕ (`--decisions=` уходил на ПЛАТНЫЙ путь) · кап
|
||
документа решений · конверт путей на `manifest --json` · алиасы судятся по НАБОРУ · перевёрнутое окно
|
||
глав · честность отчёта о стопе · SIGTERM · десять слепых пятен гейта · **цепь целиком в репозитории**.
|
||
**Доказательная база, замеры, попунктный чек и обе итерации ревью — `backend/docs/SEAM_PACK_FINDINGS.md`
|
||
§§14–30;** здесь только то, что требует ДЕЙСТВИЯ.
|
||
|
||
**✅ ⛔-ЗАКАЗ ПРИЁМКЕ ИЗ ПАКА СНЯТ.** Цепь «стоп → `bank-apply` → резюм → стоп ГАСНЕТ» теперь живёт в
|
||
репозитории как $0-тест на фейковом провайдере (`internal/pipeline/bankchain_test.go`), на ОДНОМ проекте
|
||
от стопа до погасшего стопа. Довод пака «своими силами невозможно, надо дойти оплаченной черновой волной»
|
||
был шире правды: харнесс для этого уже был в репозитории. Мина №1 строки **199** (ливлок на `status:
|
||
auto`) закрыта исполнением, а не рассуждением.
|
||
|
||
**⚠ РАТИФИКАЦИЯ КЛАССА 14 — прежнее требование в силе, объём немного шире.** Класс `decisions_rejected`
|
||
теперь несёт и отказ по КАПУ (документ больше, чем движок применяет за один акт): это факт о ЗАПРОСЕ, а
|
||
не о деплое, поэтому 10 был бы неверен. Носители полосы поднимает оркестратор при лендинге, как и
|
||
планировалось.
|
||
|
||
**⛔ ПИНГИ ДОФИКСА (правок не делал):**
|
||
1. **`exit 2` при OOM платформа читает как успех** — общедвижковый класс; кап удерживает `bank-apply` от
|
||
того, чтобы стать первым, кто до него доедет, но самого класса не снимает.
|
||
2. **Каталог книги без права записи даёт `exit 1`** (вне полосы). Класс движка корректен и одинаков у
|
||
всех глаголов — чинить надо чтение кода 1 на платформе, которая списывает проблему прав ХОСТА в
|
||
бюджет попыток КНИГИ.
|
||
3. **Проекция отвечает «что применится», а не «почём».** Рекомендация — НЕ строить: глагол $0 по
|
||
построению, поле «$0» было бы шумом. Решать оркестратору.
|
||
4. **Карта подписи не удаляется после погасшего стопа** — пред-существующее; зафиксировано тестом как
|
||
текущее поведение. Честный ответ на «есть ли что подписать» — новое поле отчёта `signature.undecided`.
|
||
5. **Цена глагола Θ(N²) по построению** — каждый пер-решенческий помощник сканирует весь документ.
|
||
Именно поэтому кап на КОЛИЧЕСТВЕ стоит на 5 000. Поднимать его без индексации этих сканов нельзя.
|
||
6. **Апстрим-дефект `gopkg.in/yaml.v3 v3.0.1`** (эмиттер пишет блочный скаляр, который его же парсер не
|
||
читает) вылечивается по-настоящему только скаляр-типом схемы с явным стилем или переездом на
|
||
`go.yaml.in/yaml/v4` (релиз-кандидат, смена module path в ДВУХ зонах). Мой обход несёт ссылку на
|
||
исходник библиотеки и характеризационный тест, который покраснеет в день починки апстрима.
|
||
7. **Фолд поверхностей Go-резидентный:** `internal/text/norm.go` держит `trad2simp` и катакана→хирагана
|
||
в Go, а не в langpack'е. Пара, которой в репо нет, деградирует до NFKC+lowercase — не блокирована, но
|
||
это ровно тот класс, о котором ревью-вопрос общности. Шире двери, поэтому пингом.
|
||
|
||
**⚠ ЧТО В ЗАПИСИ ПАКА 24.08 (ниже) УСТАРЕЛО — читать её через эту поправку.**
|
||
1. **Пинг 2, «таймаут: 1.6с на 5 000 термов, 9.1с на 20 000» — ЧИСЛА НЕВЕРНЫ, и это ровно тот датум,
|
||
которым платформенный пак будет мерить свой таймаут.** Мой замер той же командой: 5 000 `approve` →
|
||
**5.2 с**, 20 000 → **50 с**; на минимальных `decline` (самая дешёвая форма, и потому та, которой
|
||
байтовый кап пускает больше всего) 5 000 → **11.3 с**, 12 000 → **58 с**, 28 900 → **308 с**. Брать
|
||
надо `FINDINGS` §18 и §29 п.1, не эти.
|
||
2. **Пинг 6 «однострочник при лендинге: документ решений не капирован» — СДЕЛАН.** Капов теперь два
|
||
(1 МиБ на чтение + 5 000 решений на применение), потому что байтовый не ограничивает время.
|
||
3. **Пинг 3 про флейки** пере-снят сильнее: изолированный A/B против дерева HEAD даёт побайтно
|
||
одинаковое падение с обеих сторон — `FINDINGS` §31.
|
||
|
||
**⛔ ПИНГИ, КОТОРЫЕ ЖИЛИ ТОЛЬКО В `FINDINGS` И НЕ ДОЕЗЖАЛИ ДО ЖУРНАЛА** (найдено проверкой согласованности):
|
||
карта подписи пишется обычным `os.WriteFile` мимо атомарной конвенции сайдкаров того же пакета
|
||
(пред-существующее) · цена доказывающего рендера ≈5 % времени, плюс `notCanonical` теперь тоже разбирает
|
||
документ · опубликованные пути двух файлов решений не несут версионного конверта (пинг пака §10.5) ·
|
||
схема сида без `omitempty` (пинг пака §10.6).
|
||
|
||
**⚠ Два пред-существующих `-race`-флейка в `internal/store` не тронуты** (`TestKillMinus9LosesAtMostOneCall`,
|
||
`TestTheSeamIsNotChargedToTheStoreOperationBudget`). База ДО правок, снятая на нетронутом дереве пака,
|
||
уже была красной по первому — это моя собственная атрибуция, а не наследованная.
|
||
|
||
**⛔ ПИНГ, КОТОРЫЙ ТРОГАЕТ РАТИФИЦИРОВАННЫЙ ЗАКОН (п.2) — решать не паку.** Арбитр двери — flock на
|
||
`<project_db>.lock`, а пишутся `mined_delta`/`mined_rejects`, которые `book.yaml` может направить куда
|
||
угодно. **Две книги с РАЗНЫМИ `project_db` и ОДНИМ delta друг друга не исключают:** воркфлоу-ревью
|
||
продемонстрировало гонку на 1500 одобрений с каждой стороны — одна сторона потеряла всё, `exit 0`, отчёт
|
||
«применено». Внутрикнижную версию этого §4.3 уже запрещает; межкнижная законна сегодня. Выбор — второй
|
||
арбитр или отказ при загрузке на путь вне каталога книги. В корпусе нарушителей нет. В коде стоит явное
|
||
«арбитр покрывает проект, а не пути», а не молчаливое допущение.
|
||
|
||
**🔧 В репозиторий добавлен инструмент: `backend/cmd/tmmutate`** — харнесс мутаций с каталогом из 36
|
||
посадок, у каждой названо СВОЙСТВО, за которое она отвечает, и записан ожидаемый исход. Три сессии подряд
|
||
писали такой инструмент в скретчпад и теряли его; приёмка при этом нашла восемь мест, где гейт был слеп.
|
||
⚠ **Он дважды подводил и оба раза был починен по следу:** сначала подсадил мутацию и прошёл собственную
|
||
sha256-самопроверку (эталон второй правки снимался с уже пропатченного файла), затем считал КРАСНЫМ провал
|
||
СБОРКИ — из-за чего две записи каталога, сломанные рефакторингом, целую итерацию числились пойманными
|
||
тестами, которые не могли отработать. Теперь: одно чтение и запись на файл, отпечаток всего каталога перед
|
||
каждой посадкой, зелёная базовая линия пакета ДО первой посадки и третий вердикт `NOTHING`, роняющий гейт.
|
||
`FINDINGS` §25 и §34.
|
||
|
||
**✅ ИТОГ БЭКЕНД-СЕССИИ 24.08 — ПАК «ВХОДНАЯ ДВЕРЬ ШВА», движковая половина D39.156. Дерево готово, НЕ закоммичено, передаётся на лендинг.**
|
||
Заказ §4.1–§4.6 выполнен: конвенционные дефолты `mined_delta`/`mined_rejects` (ключей не объявляет и
|
||
файлов заранее не создаёт никто) · глагол `tmctl bank-apply --config <book.yaml> --decisions <doc.json>
|
||
[--dry-run]` ($0, идемпотентен побайтово, всё-или-ничего, занятый flock — ровно 12 неблокирующе, ответ
|
||
несёт версию и явное `depth: edit_wave`) · `--keys-file` у `translate` (строка **211**) · строгость
|
||
сид-загрузчика (**212**) · `status_version` + `artifacts{}` с абсолютными путями (**213**) · дефолт
|
||
стендового корпуса маркерным резолвом (**218**, критерий оркестратора выполнен буквально).
|
||
**Вся доказательная база, замеры и попунктный чек промта — `backend/docs/SEAM_PACK_FINDINGS.md`;**
|
||
здесь только то, что требует ДЕЙСТВИЯ.
|
||
|
||
**⚠ ТРЕБУЕТ РАТИФИКАЦИИ: заведён класс полосы отказов 14 `decisions_rejected.`** Отвергнутый по существу
|
||
набор решений ≠ сломанный деплой: `platform/internal/ingest/exit.go` `DeploymentFault` относит 10 к
|
||
«условию, общему для всех книг хоста», и по 10 набор решений одного пользователя списался бы на
|
||
оператора. Старый читатель деградирует безопасно (`Refused(14)` ⇒ `OutcomeRefused`). 10 сохранён для
|
||
документа, не прочитавшегося КАК документ решений. Гейт тотальности таблицы добавлен.
|
||
|
||
**⛔ ЗАКАЗ ПРИЁМКЕ — единственный незакрытый замер (согласован со сторонним архитектором).** Цепь целиком
|
||
не гонялась ни разу: стоп красный → `bank-apply` → резюм → **стоп гаснет**. Части доказаны порознь, но
|
||
мина №1 строки **199** — livelock уровня ЦЕПИ, которого частичные тесты по построению не видят. Снять не
|
||
могу, и это проверено: банк-стоп на машине не воспроизводится (`contrast_path` → отсутствующий
|
||
`eval/exp16/data/jieba_dict_general_zh.txt`, строка **123**), а до стопа надо дойти оплаченной черновой
|
||
волной. **Команда:** на КОПИИ книги на exit 3 скормить `bank-apply` документ на всю карту подписи, затем
|
||
`translate --verify-bank`. **ДЕФЕКТ** — стоп снова с ТЕМИ ЖЕ поверхностями; **не дефект** — свежая пачка
|
||
≤200 термов реверс-секции (мина №3 строки 199). До этого прогона вердикт по циклу — PLAUSIBLE.
|
||
|
||
**⛔ ПИНГИ ЗОНАМ И СЛЕДУЮЩИМ ПАКАМ:**
|
||
1. **`rubyToCandidates` мёртв в проде** — единственный вызов из теста (`memseed_test.go:204`);
|
||
`seeding.go:36-38` строит `manualSrcs` и никуда не передаёт (Go молчит: запись в map = использование).
|
||
Строк `Source:"ruby"` в банке не возникает, а платформа держит для них ветку словаря
|
||
(`ingest/bank.go` `termOrigin` → `OriginAnnotated`).
|
||
2. **Платформенному паку:** первый контакт с непере-мигрированной книгой даёт **exit 13** — воркер решений
|
||
обязан планировать `13 → migrate → повтор` · **проекция берёт тот же лок**, поэтому правка термина при
|
||
живом прогоне даёт 12 даже на превью, на всю длину прогона · **таймаут**: 1.6с на 5 000 термов банка,
|
||
9.1с на 20 000, бюджет платформы на вызов движка — 60с (`runs/reconcile.go:280`) · `bank-apply`
|
||
создаёт `<project_db>.lock` при первом касании никогда не запускавшегося проекта.
|
||
3. **⚠ БАТАРЕЯ НЕ ДЕТЕРМИНИРОВАННО ЗЕЛЕНА, и это НЕ пак — прочесть ДО пере-рана.** Два
|
||
пред-существующих `-race`-флейка в `internal/store` срабатывают примерно раз на 2–4 полных прогона
|
||
(`go test ./... -race -count=1` ×4 → 1 чист, 2-й красный). **Красное именно в этих двух тестах
|
||
ожидаемо; любое другое красное — регрессия.** Тесты НЕ трогал (D39.121).
|
||
`TestTheSeamIsNotChargedToTheStoreOperationBudget`, `TestKillMinus9LosesAtMostOneCall`. Чередующийся
|
||
A/B на `git worktree` HEAD: оба падают на HEAD **не реже** (`kill9` 2/30 против 0/30; `seam` 2/30
|
||
против 1/30; без `-race` 0/30). Покрытие: `LockProject`/`Release` этими тестами не исполняются вовсе.
|
||
⚠ 0/30 против 2/30 НЕ значит «пак улучшает» — на таком числе это шум (Фишер p≈0.5); достаточно того,
|
||
что флейк живёт на дереве, которого пак не касался.
|
||
4. **Гейт `TestDispatchCommandsCoversTheSwitch` слеп к `case` с константой** (считает только
|
||
`*ast.BasicLit`) — команда, объявленная константой, невидима гейту, чей смысл в дефекте строки **176**.
|
||
Я вернулся к литералу (конвенция файла), дыра не эксплуатируется.
|
||
5. **`redrive` — платный путь без канала ключей аргументом.** Промт: «флаг только у `translate`», сделано
|
||
ровно так; канал у него есть (конвенционный `.env`), платформа его не зовёт. Развилка следующему паку.
|
||
6. **Однострочник при лендинге (не блокер):** документ решений читается неограниченным `os.ReadFile`,
|
||
тогда как платформа свои чтения от движка капает. Документ на 10 000 решений ≈2МБ ⇒ кап 1–16МБ.
|
||
|
||
**⚠ ПРАВИЛА, ВЫНЕСЕННЫЕ ИНЦИДЕНТАМИ — для следующих сессий, не про этот пак.** Прогон харнесса мутаций
|
||
был убит таймаутом, `finally` не отработал, и посадка просидела в дереве ~40 минут, выглядя
|
||
продакшн-кодом; сторонний ревьюер снял с него замеры и доложил несуществующий дефект. Поймал посадку
|
||
собственный пин пака. Отсюда три правила: **харнесс мутаций обязан фингерпринтить цели** (починено) ·
|
||
**снимай отпечаток дерева перед сборкой бинаря замера** (на этом наступили обе стороны) · **одиночный
|
||
прогон — не замер** (атрибуцию флейков я дважды вывел неверно из одиночных прогонов).
|
||
|
||
**Что НЕ доказано:** рантайм-вердикт по платному пути — **PLAUSIBLE**. Доказано, что ключ из
|
||
`--keys-file` доезжает до заголовка и что без флага прогон отказывает конфигом; не доказано, что
|
||
реальный провайдер примет ключ и что SaaS положит файл по этому пути — платформенная половина строки
|
||
**211**, чужая зона. Живой `translate` не гонялся: санкции на платные вызовы у пака нет. (24.08)
|
||
|
||
**⛔ ПИНГ ОРКЕСТРАТОРА №19 — 23.08, ЗОНЕ БЭКЕНДА. Четыре движковых дефекта, все сверены моими командами.**
|
||
|
||
1. **ОТВЕТ НА ПИНГ ПОЛИГОНА: дефект ПОДТВЕРЖДЁН, он ваш.** Эскалация на Gemini теряет инъекцию
|
||
банка памяти (строка **208**). Механизм пере-проверен: `pipeline/render.go:256-258`=`Role: "system", Content: injection, CacheBoundary: false`
|
||
штатно строит ВТОРОЕ системное сообщение, а `llm/httpllm.go` (до-паковые строки 517-523, якорь ИСТОРИЧЕСКИЙ — сигнатура сменилась лендингом D39.164: функция приняла ось `mode SystemMessagesMode` и под квирком СКЛЕИВАЕТ системный ряд, так что описанного здесь «один-в-один» больше нет)
|
||
копирует сообщения дословно — склейки нет нигде. ⚠ Лекарство того же класса в проекте УЖЕ
|
||
написано и работает для другого провайдера: `llm/provider_anthropic.go:169-179`=`inSystemPrefix := true`
|
||
сворачивает ведущий system-префикс в одно поле. Не обобщено на Gemini — это и есть работа.
|
||
Полигон ждёт ответа с 22.08 и починил у себя по вендор-доке; их находка верна.
|
||
|
||
2. **Род не производится авто-путём вовсе** (строка **210**, дополнена 23.08): замка ДВА и они
|
||
независимы, а поле `Gender` в схеме сида УЖЕ есть — ось мертва в ПИСАТЕЛЯХ, не в формате.
|
||
|
||
3. **Выпавший член юнита исчезает из отгружаемых байт БЕЗ внутритекстового маркера** —
|
||
`pipeline/waverun.go:487-490`=`the flagged member is DROPPED from the edit`. Родня строки **193**;
|
||
для читателя это молчаливая дыра в тексте.
|
||
|
||
4. **Загрузчик сида НЕстрогий** (строка **212**): голый разбор YAML без проверки имён ключей, и
|
||
`seed-lint` этого не видит. Опечатка в имени поля молча теряется — в файлах, которые владелец
|
||
правит руками чаще всего.
|
||
|
||
⚠ Плюс строки **211** (движок на SaaS не получает провайдерских ключей — блокер живого прогона) и
|
||
**213** (платформа дублирует вашу конвенцию пути): обе половинные, движковая часть ваша.
|
||
|
||
**⛔ ПИНГ ОРКЕСТРАТОРА №20 — 22.08, ЗОНЕ БЭКЕНДА: три ваших дока разошлись с деревом (аудит доков, сверено кодом; рукой не лезу — ваша зона).**
|
||
1. **`backend/README.md`, карта пакетов** объявлена сверенной по коду, а в ней НЕТ `internal/runevents` — эмиттера журнала прогона, то есть ВСЕГО шва движок↔платформа (D39.131), — и нет второго бинаря `cmd/tmvet`. Греп: `runevents` и `tmvet` в файле по нулю вхождений, при том что оба каталога в дереве.
|
||
2. **`backend/README.md`, «Известный техдолг»** держит живыми Cyrillic-хардкоды DC-чекеров, которые сам код называет ПОГАШЕННЫМ долгом (фаза 2 общности, D39.64: `isRuTarget` удалён, `TargetActive`/`TargetScriptNonLatin`), и оба его `file:line`-якоря указывают мимо.
|
||
4. **(дописано 24.08) `backend/README.md:47`=`/home/ubuntu/books/gu-zhenren/` зовёт книгу-стенд по МЁРТВОМУ пути** `/home/ubuntu/books/gu-zhenren/` — каталога нет ни там, ни в `$HOME`: книги переехали в `<репозиторий>/books` и версионируются своим git (D39.157 п.2). Там же фраза «тексты и производные ВНЕ git» стала неточной: вне ЭТОГО git. Тем же касанием — три тест-хелпера, резолвящие корпус от `$HOME/books` (строка 218); они уже в заказе движкового пака шва §4.6, так что дублировать правку не надо, но док обязан сойтись с ними.
|
||
3. **`backend/docs/components.puml`** — диаграмма, которую карта доков продаёт как правимую «одним коммитом с кодом», отстала примерно на месяц: старый exit-контракт (без 4/5 и полосы 10–19), неполный список глаголов CLI, удалённый паком-17 `failover.go` и ни следа эмиттера. ⚠ Рендерить её в svg/png НЕ надо (гардрейл) — править исходник.
|
||
|
||
*(Пак «честные числа и статусы» — ИСПОЛНЕН, ПРИНЯТ С ФИКС-ЛИСТОМ и ЗАЛЕНДЕН `f840867` (17.08; D39.149, ФЧ-5 — D39.150). Отчёт, две волны адверсариального ревью, мутационная приёмка и тело фикс-листа ФЧ-1…ФЧ-8 — в [archive/PROGRESS-2026-08-17.md](archive/PROGRESS-2026-08-17.md); живой остаток — строка бэклога 197.)*
|
||
|
||
*(Пинги закрытых паков — фикс-пак банка D39.118, блокеры контракта D39.122 — в [archive/PROGRESS-2026-08-04-09.md](archive/PROGRESS-2026-08-04-09.md), D39.125.)*
|
||
|
||
*(Закрытые бэкенд-записи 01–02.08 — общность фаза 2 · качество банка (оба этапа) · фикс-пак банка · finding-1 · пакет-чекеров · мелкая пачка · coldrun-b · ручка эффорта — в [archive/PROGRESS-2026-08-01-02.md](archive/PROGRESS-2026-08-01-02.md).)*
|
||
|
||
|
||
*(Закрытые бэкенд-записи 14–15.08 — эмиттер шва (D39.131) · `tmctl migrate` (D39.134) · пере-пин цен DeepSeek (D39.137) — в [archive/PROGRESS-2026-08-14-15.md](archive/PROGRESS-2026-08-14-15.md); вынесено D39.139.)*
|
||
|
||
|
||
*(Закрытая хроника пакетов №0–№4 (04–10.07) перенесена в [archive/PROGRESS-2026-07-04-10.md](archive/PROGRESS-2026-07-04-10.md) — ревизия D31.)*
|
||
|
||
*(Хроника пакетов 11–12.07 (пакет-5, D15.2-этап-А, санитайзер-фикс D33) — в [archive/PROGRESS-2026-07-10-13.md](archive/PROGRESS-2026-07-10-13.md).)*
|
||
*(Трек-A пак-1/1.5 (D39.2/D39.5) — см. записи оркестратора №6 выше.)*
|
||
|
||
*(Хроника бэкенд-паков 11–16 (19–25.07, вкл. отчёт-запись пака-15) — в [archive/PROGRESS-2026-07-13-25.md](archive/PROGRESS-2026-07-13-25.md); отчёты паков — `archive/reports/`.)*
|
||
|
||
*(Закрытые записи 25–31.07 — пак-18 · мини-прогон · фикс-пак · сквозная проверка · хендофф 26.07 · ресёрч общности фаза 1 — в [archive/PROGRESS-2026-07-25-31.md](archive/PROGRESS-2026-07-25-31.md).)*
|
||
|