Take in the engine zone's follow-up: two arm headers now say what the diff says, and the battery stops leaving its harvest log in the tree

This commit is contained in:
heaven 2026-09-08 00:51:46 +03:00
parent 2093107cc8
commit 15eb25df9d
6 changed files with 54 additions and 10 deletions

8
backend/.gitignore vendored
View file

@ -1,2 +1,8 @@
# build artifact of `go build ./cmd/tmctl/` run from this directory — never a deliverable
# Build artifacts of `go build ./cmd/<x>/` run from THIS directory. go build puts the binary where it is
# invoked, and a session probing that a package still compiles types exactly that — so the artifact lands
# here, untracked, and shows up as a position in `git status` that is not work. Measured 07.09: a stray
# `tmmutate` sat there as the 40th position of a hand-off. bin/ (what the Makefile writes) is covered by
# the repository .gitignore; these three are what an ad-hoc build drops, and no Makefile can prevent it.
/tmctl
/tmvet
/tmmutate

View file

@ -97,19 +97,30 @@ test:
MAKEFILE_DIR := $(patsubst %/,%,$(dir $(THIS_MAKEFILE)))
mutations:
@tmp=$$(mktemp -d) && trap 'rm -rf "$$tmp"' EXIT INT TERM && mkdir "$$tmp/backend" && \
@tmp=$$(mktemp -d) && trap 'rm -rf "$$tmp"' EXIT && trap 'rm -rf "$$tmp"; exit 130' INT TERM && \
mkdir "$$tmp/backend" && \
tar -C "$(MAKEFILE_DIR)" -cf "$$tmp/tree.tar" --exclude='./.env*' --exclude=./bin . && \
tar -C "$$tmp/backend" -xf "$$tmp/tree.tar" && rm -f "$$tmp/tree.tar" && \
$(GO) run ./cmd/tmmutate -root "$$tmp/backend" -battery
# The hermetic battery: everything that is green on a bare clone. It ends by NAMING the tests that did
# not run, because a skip is invisible in `ok` lines and a silent skip reads as coverage.
# The harvest log goes to a TEMP file, not to .skips.log in the tree. Both normal paths removed the
# in-tree file, but Ctrl-C during the harvest pass left it behind, and it is not gitignored: the next
# `git status` then shows a position that is not work, which is how untracked files get swept into a
# commit or, worse, make a session miss the ones that ARE work. Recorded as debt on 09.08
# (13-tech-debt-anchors.md, Б-122) and closed here. mktemp+trap is the same idiom as `mutations` above.
#
# The INT/TERM trap EXITS; it does not just clean up. A POSIX shell resumes the interrupted line after its
# handler returns, so a cleanup-only trap left the chain running with the log already deleted — and this
# recipe's last step then printed "(none)", i.e. NO SKIPS, off a harvest that never finished. A silent skip
# reading as coverage is the exact failure this pass exists to catch.
battery: build vet fmt lint test
@echo "--- did NOT run (no stand data; see battery-stand) ---"
@$(GO) test ./... -count=1 -v > .skips.log 2>&1 || { echo "the skip-harvest pass FAILED:"; \
grep -E '^(---|\s+---) FAIL|^FAIL' .skips.log; rm -f .skips.log; exit 1; }
@grep -- '--- SKIP' .skips.log || echo "(none)"
@rm -f .skips.log
@log=$$(mktemp) && trap 'rm -f "$$log"' EXIT && trap 'rm -f "$$log"; exit 130' INT TERM && \
{ $(GO) test ./... -count=1 -v > "$$log" 2>&1 || { echo "the skip-harvest pass FAILED:"; \
grep -E '^(---|\s+---) FAIL|^FAIL' "$$log"; exit 1; }; } && \
{ grep -- '--- SKIP' "$$log" || echo "(none)"; }
# The stand battery: adds the corpus-gated tests. With the flags set, MISSING data fails instead of
# skipping, so "the corpus is here" is asserted rather than assumed.

View file

@ -42,7 +42,10 @@ stages:
escalate_to: deepseek-v4-pro
- name: edit
role: editor
# ⛔ ЕДИНСТВЕННОЕ отличие арма от боевого — эти четыре строки. Редактор не эскалирует (D12).
# ⛔ ОТЛИЧИЙ ОТ БОЕВОГО pipeline-c1.yaml ровно ДВА, и оба здесь: `model` — другой редактор, и строки
# `few_shot: false` у арма НЕТ (умолчание намеренное, см. следующий комментарий). Остальные ключи
# блока по ЗНАЧЕНИЮ равны боевому — расходятся только хвостовые комментарии, которые по правилу
# шапки живут в c1 в одном экземпляре. Редактор не эскалирует (D12).
model: glm-5
prompt_version: v4-discourse-reflow-nogenre
temperature: 0.4

View file

@ -46,7 +46,10 @@ stages:
escalate_to: deepseek-v4-pro
- name: edit
role: editor
# ⛔ ЕДИНСТВЕННОЕ отличие арма от боевого — эти четыре строки. Редактор не эскалирует (D12).
# ⛔ ОТЛИЧИЙ ОТ БОЕВОГО pipeline-c1.yaml ровно ДВА, и оба здесь: `model` — другой редактор, и строки
# `few_shot: false` у арма НЕТ (умолчание намеренное, см. следующий комментарий). Остальные ключи
# блока по ЗНАЧЕНИЮ равны боевому — расходятся только хвостовые комментарии, которые по правилу
# шапки живут в c1 в одном экземпляре. Редактор не эскалирует (D12).
model: mistral-large-2512
prompt_version: v4-discourse-reflow-nogenre
temperature: 0.4

View file

@ -207,8 +207,9 @@ const (
// fixed-field-order content hash.
//
// ⚠ NO PRODUCTION CALLER: the run pins each job to its own WAVE's snapshot (snapshotIDForWave), and the
// sequential driver this fold was written for no longer exists. It is test-only, and its four callers pin
// payload INPUTS (a max-tokens floor, a few-shot flip, the banknote gate) rather than the fold itself —
// sequential driver this fold was written for no longer exists. It is test-only, and its five call sites in
// four test files pin payload INPUTS (a max-tokens floor, a few-shot flip, the banknote gate, the classifier
// version alongside the local backend tag) rather than the fold itself —
// nothing compares it against the per-wave folds, and the two do not sum: the draft wave folds the BASE bank
// version precisely so a mining stop cannot move it.
func (r *Runner) snapshotID() (id, payload string, err error) {

View file

@ -661,6 +661,26 @@
Новые файлы: `internal/chunk/headingparity_test.go`, `internal/config/armparity_test.go`, `internal/pipeline/classifiervocab_test.go`. Удалён: `configs/pipeline-arm-deepseek-pro.yaml`.
#### ДОФИКС ПОСЛЕ ЛЕНДИНГА — три находки третьего верификатора (08.09, к акту `D39.225`)
Верификатор шёл по операторской правде и вернулся уже после лендинга: девять находок, шесть я закрыла прежним дофиксом, три пережили коммит. Все три пере-мерены МОИМИ руками — это были его утверждения, не мои замеры, — и все три подтвердились.
**F7 — арм-шапка снова называла не то, чем отличается, и это ровно тот класс, ради которого пак существовал.** Комментарий обещал «ЕДИНСТВЕННОЕ отличие арма от боевого — эти четыре строки» и перечислял `model` · `prompt_version` · `temperature` · `reasoning`. Замер диффом против `pipeline-c1.yaml` (комментарии сняты, сравниваются ЗНАЧЕНИЯ): отличий **два**`model` несёт другого редактора, и строки `few_shot: false` у арма НЕТ. Три из четырёх названных ключей боевому по значению равны, а пятое, настоящее отличие шапка не считала — при том что его тут же объясняет следующий комментарий. Гейт равенства это поймать не мог и не должен: он сравнивает конфиги, а не прозу о них. Комментарий пере-написан по диффу в обоих армах; пере-замер после правки печатает ровно две строки расхождения, ровно те, что названы.
**F9 — `snapshot.go`: «its four callers» при трёх перечисленных.** Замер: вызовов `\.snapshotID()`**5**, в **4** файлах (контроль: вызовов `snapshotIDForWave` — 53). Четвёртый файл — `runner_test.go:1687`, тест `TestRunnerSnapshotFoldsClassifierAndLocalTag`, пинит версию классификатора и локальный бэкенд-тег. Теперь в комментарии стоят оба числа и назван четвёртый предмет.
**F10 — `make battery` писала `.skips.log` в РАБОЧЕЕ дерево.** Не новая находка: записана 09.08 в `docs/architecture/13-tech-debt-anchors.md`, Б-122, как не-блокер приёмки пака стандартов — месяц пролежала с носителем. Замер: `git check-ignore` → не игнорируется; убирается на обоих штатных путях, переживает Ctrl-C. Закрыто В ИСТОЧНИКЕ, а не `.gitignore`: харвест-лог уехал в `mktemp` с trap — файла в дереве больше нет вовсе, прятать нечего.
**И собственная проба этой же правки поймала в ней дефект — печатаю, потому что вердикт по цвету от вердикта по тексту отличается только этим.** Первая редакция ставила `trap 'rm -f "$log"' EXIT INT TERM`, как и соседняя цель `mutations`. Проба SIGINT-ом показала: POSIX-шелл ПРОДОЛЖАЕТ прерванную строку после возврата из обработчика, и цепочка доехала до последнего шага с уже удалённым логом — напечатав `(none)`, то есть «скипов нет», по несостоявшемуся сбору. Тихий скип, читающийся как покрытие, — ровно то, что этот проход и заведён ловить. Обработчик `INT`/`TERM` теперь ВЫХОДИТ (`exit 130`), а не только убирает; та же правка внесена в `mutations`, где форма была та же. Предъявлено исполнением: прерванный прогон — вывода нет, `RC=130`, остаточных `/tmp/tmp.*` 0, мусора в дереве 0; КОНТРОЛЬ на штатном пути — та же цепочка печатает строку `--- SKIP` и убирает за собой.
**Попутно закрыта соседняя дверь того же класса.** `backend/.gitignore` держал одну строку `/tmctl` — артефакт `go build ./cmd/tmctl/`, запущенного из корня зоны. Пакетов `cmd/` три, и вчерашний `tmmutate` висел в `git status` сороковой позицией сдачи. Внесены все три (`/tmctl` · `/tmvet` · `/tmmutate`); проверено `git check-ignore`: три игнорируются, `internal/pipeline/snapshot.go` — нет, то есть правило не слишком широкое.
**И ВТОРОЙ дефект в той же правке — его поймал уже гейт, а не проба.** Пере-набирая строку `mutations` под новую форму trap'а, я срезала из неё `mkdir "$tmp/backend"`. `make mutations` упал за 0,02 с текстом `tar: /tmp/tmp.…/backend: Cannot open: No such file or directory` — то есть копия не создавалась вовсе, и гейт отказал ДО первой посадки, а не сделал вид, что прошёл. Восстановлено; числа ниже сняты после восстановления. Две правки подряд в одном рецепте, два дефекта — обе поймало ИСПОЛНЕНИЕ, ни одну не поймало перечитывание.
**Якоря каталога после правок целы:** 225 записей проверено, битых якорей 0 (прибор — тот же счёт вхождений `find`, что делает посадка).
**Числа, снятые ПОСЛЕ восстановления рецепта, ничем после них дерево не тронуто.** `make mutations` → exit 0, **3m52.6s**, «14 mutation(s) run, 0 unexpected outcome(s)», 14 RED, `anchors swept: 0 of 225 entr(ies) rotten`. Затем `make battery` → exit 0, **3m40.0s**, `0 issues`, `ok` 19 / `FAIL` 0 / «no test files» 4, скипов 4 — те же. Мусора после обоих прогонов: `.skips.log` в дереве **0**, осиротевших `/tmp/tmp.*` **0** (контроль: файлов в корне зоны 17). Записи `ARM-…` в подмножестве это касается прямо — она сажается в `pipeline-arm-glm.yaml`, чью шапку правил F7, и краснеет тем же механизмом, что и до правки.
### Пак «ЗАКОН БАНКА — ЧЕСТНО» (06.09, промт `docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md`, вход HEAD `e4097cb`). НЕ КОММИЧУ — ждёт лендинга
**Итог: закон банка описан тем, что код делает, и найдена дыра ШИРЕ заказанной — стадия схлопывания не сверяла свою выработку со строкой банка на тот же ключ ни при какой подписи.** Закрыто в двух местах (схлопывание + страховка на слиянии), репортом, без смены поведения платного прогона. **ШЕСТЬ кругов самопроверки нашли 43 находки В МОЕЙ ЖЕ работе** (18 + 8 + 5 + 6 + 4 + 2); круг 6 сказал «сошлись» — новых находок в коде пака нет. Шесть находок — ложные утверждения в моих же комментариях, то есть ровно тот класс, который пак чинил; две внесены лечением предыдущего круга; один и тот же шов «писатель ↔ читатель» ловился ТРИ круга подряд, после чего был убран целиком, а не подпёрт четвёртой заплатой. Все разобраны, списки ниже.