textmachine/backend/docs/SEAM_FIX2_PLAN.md

9.5 KiB
Raw Blame History

План дофикса-2 входной двери шва (промт BACKEND_SEAM_FIX2_SESSION_PROMPT.md)

Записка-план по §7 промта. Комплектность против §4 сверена механически: grep -cE '^### 4\.' docs/BACKEND_SEAM_FIX2_SESSION_PROMPT.md13. Ответ на развилку §7 (один пак или два): один пак, довод промта принимаю и добавляю свой — §4.3 (авто-провод при поднятом флаге) меняет ту же ветку runBankMiningStop, чьё сообщение стопа переписывает §4.12, а отчёт двери (§4.5) обязан узнать класс §4.7 — раздельные паки резали бы одну функцию и один enum пополам.

Порядок работ (зависимость §4.2 соблюдена: атомарность карты — первой)

  1. §4.10 — карта подписи: writeFileAtomic вместо голого os.WriteFile; конверт seed.SignatureMap{map_version, map_id} с инлайн-телом прежней схемы; map_id = sha256 от отрендеренного тела (идентичность содержимого, не криптодоказательство). Легаси-карта без конверта читается (страховка апгрейда посреди подписи). Карта НЕ накопитель — слияния нет.
  2. §4.9 — (а) filepath.Clean в резолве абсолютных путей LoadBook (Join и так чистит); (б) ключи mined_delta/mined_rejects СНЯТЫ: retired-key отказ по прецеденту adult: (громкое имя лечения, а не голый strict-decode), пути — только конвенцией от каталога и book_id; *Declared умирает, decisionFilePresent упрощается.
  3. §4.1§4.3 — миграция v16: таблица bank_stop_presented (book_id, surface) — плоское множество нормализованных поверхностей всех предъявленных кластеров (Src + Aliases); рост — только вширь, обрезки нет. Предикат «есть ли новое» = существует терм ИТОГОВОЙ карты (обе секции, после потолков), чей кластер не пересекается с памятью. Стоп и авто-провод — ДВА решения: стоп = флаг ∧ editWave ∧ новое; авто-провод (авто-банк + пере-сид + экспорт) — на ЛЮБОМ неостановившемся прогоне, включая «флаг поднят, нового нет» (новая явная строка лога). Порядок записи: карта (атомарно, §4.10) → память, в момент СТОПА. Развилки, решённые здесь: отказ записи памяти НЕ валит состоявшийся стоп (громкая строка; повтор — доброкачественный лишний стоп); остановившийся прогон авто-банк НЕ пишет (граница владельца; возобновление без решений догонит на следующем прогоне — названное решение, не случайность); черновая волна без editWave: карта пишется, стопа и памяти нет (доброкачественно, названо).
  4. §4.5 + §4.7 + §4.8 — отчёт делится на вердикт (decisionVerdict) и исход; исходы — явный тип (projection · refused · noop · stopped · written · write-failed), ОДИН конструктор finishReport заполняет исходные поля свитчем; для «записано» пост-состояние — перечитанные файлы. Отчёт получает written_delta/written_rejects (пофайловая правда §4.7) и честные значения mode; версия отчёта → v2 (словарь mode расширился — конверт обязан двинуться). Полоса: пол переформулирован («нет работы на откат; повтор безопасен»), классы объявляют свои инварианты, новый класс write_incomplete (exit 15 — ратификация значения на оркестраторе при лендинге) на оба исхода записи; отказ по обоим капам печатает отчёт (сведение контракта к одному носителю). Запись: подготовить ОБА temp-файла (write+sync), потом два rename, потом fsync каталога; отказ каталожного синка — класс write_incomplete с оговоркой долговечности.
  5. §4.6SignatureState пере-документируется: undecided считает нерешённые поверхности последней карты (информация для экрана подписи) и БОЛЬШЕ НЕ отвечает на вопрос о стопе — ответ требовал бы намайненного набора СЛЕДУЮЩЕГО прогона, которого нет ни у двери, ни у памяти; память дверь не читает (и потому read-only контракт не трогается). Unreadable расширяется до «не измерено» (нужно кап-отчётам §4.7). Поле не удаляется.
  6. §4.12 — снос наследия СПИСКОМ: шапка mining.go · комментарий у loadMinedRejects · хвост unsignedEngineSurfaces · сообщение стопа · renderSignatureStop · doc WaveSignatureStop; цепной тест переписывается под новую семантику (премисс-проверки фикстуры сохраняются) + вторая цепь «владелец не решил ничего — стоп гаснет памятью»; пинги чужим зонам с ПОРЯДКОМ (сброс флага платформой умирает только ПОСЛЕ движкового лендинга §4.3) и миграционная нота (пустая память → один доброкачественный стоп; v16 → tmctl migrate).
  7. §4.11 + §4.4 + §4.13 — посадки и пины по таблице слепых пятен + пин семантики §4.1 (краснеет при возврате старой формулы); §4.4 не лечится — пере-замер своей командой (числа промта без первоисточника) и пинг; платных вызовов ноль — фейковый провайдер, харнесс miningstop_join, живая проба на копии стенда.

Пофайлово

  • internal/seed/seed.go|decode.goSignatureMap + DecodeSignatureMap + SignatureMapID.
  • internal/miner/miner_emit.goDeltaFile (структура), DeltaYAML = рендер её же.
  • internal/pipeline/mining.go — конверт+атомарная запись карты; предикат новизны; разделение стопа и авто-провода; запись памяти; новые строки лога; снос формул старой модели.
  • internal/store/migrate.go + новый stopmemory.go — v16, StopPresentedSurfaces, MarkStopPresented.
  • internal/pipeline/bankdecisions.go — вердикт/исход/конструктор; кап-отчёты; staged-запись; written_*; версия отчёта v2; пере-док SignatureState.
  • internal/pipeline/refusal.go + cmd/tmctl/main.go — ярусы полосы, write_incomplete/15.
  • internal/pipeline/artifact.go — staged-вариант атомарной записи + fsync каталога.
  • internal/config/book.go — Clean; retired-ключи; конвенция путей решений.
  • cmd/tmctl/render.go|bankapply.go — тексты и контракт печати отчёта.
  • Тесты: bankchain_test.go (переписать) · пины §4.11 · пин семантики §4.1 · cmd/tmmutate/mutations.json (+записи на каждую правку §4).

Развилки, которые вижу заранее

  • Конверт ломает жанр карты для внешних читателей (eval/bank_autonomy/parse_common.py) — пинг, не правка (чужая зона); движковые читатели переведены все (единственный — signatureState).
  • seed-lint карту с конвертом не примет (его предмет — сид и дельта владельца, не карта); названо, не чинится.
  • Числа §4.4 пере-меряю своей командой до пинга; если картина та же — пинг в прежней формулировке.