TASKPLAN PRO · ветка codex/v3-native-delivery

Контур строительства V3

Живой журнал переписывания исполнительного ядра. Каждая задача проходит три ворот — полный прогон, одно независимое ревью, автоматический коммит. Подпись владельца — только на финальном слиянии в main.

67 / 109
карточек плана закрыто M9‑021 закрыла scheduler/source authority после M9‑051 · FWD‑коммиты отдельно не считаются
M9‑035
в работе · 18.08 группа FINALIZED CONSUMERS: launcher, prepared-run и runtime-preparation получают dormant canonical TaskCommit pairs; старая ACC остаётся единственной выбранной authority
69
арбитражей / FWD‑поправок 30 из них — за сутки 16.08 · два последних — docs‑only amendment Package v3 (359e807, 122da80)
97
дефектов поймано 4 дыры в самой машине · 2 дыры в плане (закрыты) · 9 из ревью кода — исправлены
0
плохих байтов в истории

Фундамент — BOOT

исполнительная машина · 11 / 11 ✓
BOOT Постройка самого движка исполнения 11 / 11
BOOT‑001Герметичный прогонщик тестов изолированная среда, где всё проверяется начисто
BOOT‑002Контракты, проверяльщики и импорт записей нотариуса
BOOT‑003Реестры: план, контекст, привязка к Git, граница проекта
BOOT‑004Компиляция принятого плана в точный исполняемый вид
BOOT‑005Планировщик: выбор задачи, запуск, первый настоящий Run
BOOT‑006События, доказательства и единый снимок состояния то, чего не было в V2
BOOT‑007Снимок кандидата кода и перепривязка при дрейфе
BOOT‑008Раннер полного прогона
BOOT‑009Механизм единственного независимого ревью
BOOT‑010Точный коммит с привязкой к Git и записью продолжения
BOOT‑011Активация ядра — необратимое включение машины

Продукт — 10 срезов

56 / 98 карточек · срезы 1–8 закрыты · срез 9: 22 / 63
закоммичено выполняется впереди
Срез 1Идентичность1 / 1
M1‑001Точная идентичность на каждом маршруте конец «каши», где план=PF=scope путались
Срез 2Каталог планов2 / 2
M2‑001План рождается своей папкой уже на Discovery «planless lifecycle» + переезд владения durable-записями в реестр
M2‑002Реестры принятых версий плана и родословной
Срез 3SQLite‑миграция + живое исполнение16 / 16
FWD‑пакетПоправка документов: план расширен на SQLite‑задачи + 13 точечных FWD‑амендментов зон b3f3997 … a3e622a, все двухфайловые
M3‑003Ядро SQLite: транзакции, схема, миграции 26 типизированных отказов; убитый писатель не оставляет замка
M3‑004Реестр планов на SQLite монотонность истории enforced триггером базы; файловый писатель мёртв
M3‑005Run + резервация + outbox одной транзакцией окно «замок отпущен → запись позже» (дефект №8) мертво
M3‑006Launch‑claims: durable‑захваты «унесённый ключ» (№5/№9) невозможен; проб живости по PID — ноль
M3‑007События + доказательства исходный TOCTOU аудита мёртв; файлового замка больше нет вовсе
M3‑008Проекция / checkpoint из фактов дефект №11 мёртв: version из фактов, не из константы; CAS в схеме базы
M3‑009Candidate‑реестр на SQLite закрыт мой давний P1: PID‑lock мёртв; append‑only + atomicity
M3‑010Stage‑артефакты + crash‑safe публикация гонка одновременной публикации залечена (поймал командир, я пропустил в спешке)
M3‑011Идемпотентный импорт старых данных 16 путей, git‑сверено 16/16 байт; провенанс делегат‑WeakMap неподделываем, дефект №5 мёртв
M3‑012Cutover: физический запрет двойной записи git‑сверено 7/7 байт; оба legacy‑запуска→503 через drift‑gate, live‑команда dormant до M3‑001; старая файловая машина отрублена
M3‑001Живая вертикаль Run поверх SQLite git‑сверено 6/6 байт; настоящий HTTP + настоящий OS‑процесс, крах+повтор сходятся к одному Run; зона выросла 4→6 путей двумя ночными решениями
M3‑013Само‑обнаруживающий страж владения SQLite git‑сверено 2/2 байт (29a0d42) · 7 раундов, 1819→6089 строк, 30+ обходов закрыто; анализ по типизированным токенам вместо списка файлов
M3‑014Полная перепись legacy‑нагрузки git‑сверено 3/3 байт (e1c4d4e) · 53 обращения к 4 целям, из них 15 в рабочем коде · первый круг отклонён мной, второй принят с честным заголовком «перепись для переноса, не сторож безопасности»
M3‑015Точная перепись долга по лимитам файлов git‑сверено 3/3 (72b7908) · 24 файла‑должника, ровно как обещал план · эксперимент владельца: ту же задачу вслепую сделала внешняя модель — обе версии дали идентичные 24 записи
M3‑002Граф, Kanban, Pipeline из ОДНОГО состояния git‑сверено 8/8 (5e86eff) · таймеров нет вовсе, «последний» не выбирается, 17 состояний без ветки «прочее» · анимация: предикат из 7 условий, все 4 стоп‑случая закрыты явно
Срез 4Кокпит‑хаб4 / 4
M4‑001Каталог всех планов, которым владеет реестр источник правды — не UI · поправка: чекпоинт каталога — свой SQLite‑адаптер (catalog‑store) через единую композицию, карта владеет composition.mjs
M4‑002Кокпит выбирает источник без гадания по «последнему» поправка: выбранный CockpitReadModel — SQLite‑адаптер (cockpit‑store), проектор — только ограниченный фасад
M4‑003Запрос только по подтверждённому снимку + модульный HTTP поправка: HTTP получает только читателей‑фасады; зона включает композицию
M4‑004Overview‑хаб всех планов + сквозной браузерный E2E частично (ca1d29f) · экраны открываются, браузерный прогон впервые исполнился по‑настоящему · отложено решением: сквозной незасеянный путь — его сборки не существует
Срез 5Восстановление3 / 3
M5‑001Перепривязка кандидата при дрейфе + доказательство сохранности поправка: хранение уже поглощено M3 — карта теперь владеет rebind‑калькулятором и чинит несовпадение схемы task_commit
M5‑002Замена намерения, безопасное восстановление, 4 двери мутаций поправка: ровно 4 Git/CAS‑двери; файловые/PID‑восстановления не возвращаются; intent‑store в зоне
M5‑003Ограниченный retry адаптера с одним финальным наблюдением закоммичена 15.08 01:22 (a87ffad) · поправка: лишний новый файл снят — событие уже обрабатывает редьюсер; retry завершается одним terminal‑наблюдением через event→SQLite
Срез 6Дочерние контексты2 / 2
M6‑001Изолированная дочерняя ветка закоммичена 15.08 13:38 (d352703) после FWD‑M6‑001 и полного прогона: 66 наборов, отказов 0 · «ветвление мысли с любого этапа» · поправка: изменяемое состояние дочки — SQLite context‑store через композицию · исправлено 16.08 03:20 (7b212c2): боевой маршрут принимал самочинный флаг accepted_branch_need — теперь только решение классификатора M8‑002, связанное с точной командой/родителем/первым этапом; самочинное решение отсекается до записи
M6‑002Полная изоляция: свой Git, данные, UI — проверено E2E закоммичена 16.08 04:27 (6fc29ff) · ContextTree / Breadcrumbs / Route + настоящий Playwright‑путь на одном bounded snapshot; кандидат собран за 6 минут · ворота: два отказа среды E2E (esbuild вне герметичного checkout, harness не видел spec), ревью нашло реальный блокер — Route требовал четыре Git‑поля, а боевой снимок содержит только {head} — исправлено · по пути закрыта дыра плана: производитель branch‑evidence построен под FWD‑M8‑002 (2fb3fc6, 705 строк, 42 минуты, один HIGH ревью — authority верил заявленному типу изменения) · и вылечен сосед exact-plan.test.mjs (FWD‑M6‑002 9f35769): дефект теста — дети гнались за первой миграцией базы, а упавший peer держал процесс до 300 с; теперь схема инициализируется до spawn, peer завершается гарантированно; 12,3 с вместо 300
Срез 7Интеграция ветки2 / 2
M7‑001Чистое ядро слияния + автопроверка готовности контекста закоммичена 16.08 04:51 (c3a34c5) — 23 минуты, 849 строк, 7 путей · пять проходов до заморозки нашли два authority‑пробела (готовность не была связана с уже спланированной операцией; ссылка на доказательство хранилась, но не перечитывалась) · ревью нашло настоящий дефект слияния: merge‑base выбирался по минимальной сумме расстояний и в графе с shortcut‑рёбрами брал старого предка вместо более нового общего — исправлено на выбор по максимальной родословной, несравнимые кандидаты fail‑closed, два regression‑графа · полный прогон PASS дважды, без вопросов владельцу
M7‑002Атомарная сага: дочка вливается в родителя целиком или никак закоммичена 16.08 09:39 (bb58915) — 4 ч 47 мин и 9 FWD, самая тяжёлая карточка после SQLite: schema‑пины v14 (и сразу followers для шести оставшихся миграций — одним FWD), oracle владения не знал новый пакет parent-resume-target, соседский fixture без обязательного publisher, вторая дыра плана — нет production‑производителей planned operation / reviewed merge resolution / точного Git readback / перехода active → read_only_history (8 путей добавлено), пять внутренних API утекли через запечатанный публичный фасад plan-acceptance (убраны), inherited‑consumption ancestry. Из 4 ч 47 мин — 2 ч 09 мин ожидания решения владельца (06:38→08:47) · воркер сначала нашёл существующий шов — joinable root transaction из M8‑001 · поправка: состояние саги/outbox — SQLite integration‑store; неизменяемые записи и Git CAS — снаружи
Срез 8Ветвление с этапов5 / 5
M8‑001Живые схемы шести этапов + генерируемые диаграммы закоммичена 16.08 01:19 (4e5a75f) · 11 часов и 5 заморозок: зона выросла 25→31 путь пятью остановками «разрешаю», ревью нашло 4 настоящих HIGH (устаревший экран мог писать в базу; окно между проверкой и записью; формат Builder не читался компилятором планов; Feature Preparation не сверялась с Git), потом — самозаведённый аудит «ещё один край» · ~3 000 строк кода, 32/32 focused, полный прогон 66 наборов PASS · поправка: указатель принятого набора и его CAS — в SQLite
M8‑002Классификатор «дочерний контекст или новый план» + защита от подделки закоммичена 16.08 01:45 (fff2134) — 23 минуты от старта до коммита в новом режиме: 8 путей, 17/17, полный прогон PASS, ревью PASS; hardening‑находка («внутренний вызывающий код может подложить свой reader») правильно НЕ признана блокером — потребителей ноль · поправка: публичный index.mjs
M8‑003Материализация отпочкованного плана (originated) закоммичена 16.08 10:38 (25a4d1b) — 59 минут · один FWD: три физически обязательных шва жизненного цикла корня (root-context чеканил только discovery, lifecycle-records отвергал любой другой корень) · поправка: расширяем существующий реестр (сейчас принимает только originRef=null), а не строим параллельный писатель
M8‑004Издатель вердикта «продукт удался», независимый от исполнителя закоммичена 16.08 11:00 (a4e16f9) — 22 минуты · оркестратор поймал воркера на пропуске обязательной регрессии через настоящий production Build→Produce («счёт остался 5/5 — не засчитываю молча») и потребовал реальный evolved binding · поправка не требовалась — чистые вычисления
M8‑005Интеграция отпочкованного плана обратно в источник закоммичена 16.08 12:49 (b9e4447) — 1 ч 49 мин, 31 путь, ревью — 0 дефектов · три FWD (два — с «разрешаю»): корневой контекст не умел переходить в read_only_history — власть перевода была только у дочернего; originated‑корень оставался bootstrapping, а интеграции нужен настоящий принятый Plan; schema‑follower для observer‑теста · Goal 1 (весь M8) закрыт в 12:49 · поправка: состояние саги — SQLite origin‑integration‑store через композицию
Срез 9Живое знание + замыкание машины + снос legacy22 / 63
M9‑001Живая Wiki по scope + AS‑BUILT схемы на завершении закоммичена 16.08 15:48 (4b5929f) — 2 ч 07 мин · три FWD (ownership‑ценз хостов, live‑ценз, contract соседнего E2E) + fix(plan) парсера зоны · ревью нашло реальный HIGH: поздний replay старой Wiki‑команды не менял SQLite head, но повторно публиковал старый Cockpit‑checkpoint (визуальный откат) — исправлено сценарием A→B→late‑A · перед стартом блока — по просьбе владельца («посмотри весь M9, чтобы не было новых поверхностей и границ») предварительный аудит и один FWD‑M9 (8620239): production‑границы всего блока авторизованы заранее вместо десяти остановок · один воркер, запрет legacy mutable Wiki как production truth · поправка: неизменяемые ревизии Wiki — файлами, изменяемый указатель — SQLite wiki‑projection‑store
M9‑002Проверка готовности workspace + сборка release‑candidate закоммичена 16.08 23:31 (21bcd55) — 1 ч 05 · один FWD по делу: readCurrentPlan не отдавал канонический planBundleVersion (= длина transitionHistory), без него superseding Plan блокировался — одно поле у владельца, 1695/11 не выросли · поправка: версионируемый target — SQLite workspace‑target‑store; попытки RC — content‑addressed
M9‑003Слияние в main через CAS + издатель «product‑ready» закоммичена 17.08 00:55 (5bf7557) — 1 ч 24, 21 путь · спор двух ревью о guard’е target‑писателя решён в пользу атомарной проверки внутри единственного писателя — реализована инжекцией (bindWorkspaceTargetMainlineGuard), без чтения чужой таблицы, trigger удалён · ревью нашло два настоящих дефекта: reconciliation наблюдал Git до SQLite‑перехода (ложный conflict/refMutationObserved=0) — Git CAS и переход теперь в одном fence; replay сохранённого conflict шёл мимо state machine — исправлено · поправка: активный слот финализации — SQLite mainline‑integration‑store; сам Git CAS и решение владельца — снаружи
M9‑004Убрать остатки per‑task ACC + распил продуктового CLI снята 17.08: карта замыкания (23 звена, R01–R23) показала, что машина коммита BOOT‑эры никогда не собиралась в проде на канонических формах — карточка на 53 пути заменена пакетом из 53 карточек ниже; её незакоммиченный WIP (48 + 8 файлов) сохранён байт‑в‑байт как справочный, в код не применяется
M9‑011Бюджетный контракт владельца + перегенерация плана закоммичена 17.08 10:10 (e799f15) — 8,5/10 · tiered‑оракул ≤400 / 401–480 с причиной / >480 с доказательством, imports отдельно; манифест исключений; попутно закрыт класс «зашитый дайджест документа»: production stage‑acceptance и тесты читают SHA Feature Preparation из регистра §0 TASK‑PLAN того же коммита (pin был сломан с a91495e); починен формат карточки M9‑010 для парсера зоны · прогон упал на чужом лимите тела маршрута (256 КБ < TASK‑PLAN 365 КБ) — закрыто в M9‑012
M9‑012Принятие плана на новом языке закоммичена 14:22 (a0884d0) — 9/10, прогон PASS 85 · Builder производит каноническую PlanRevisionAcceptance через единственный писатель decide; холодный read‑only reader (O_NOFOLLOW, dev/ino до/после); диспетчер эры в машине коммита читает эру с самой записи; лимит тела авторинга 2 МиБ; правило импортов заставило улучшить композицию
M9‑013Нормальный CandidateSnapshot из точного дерева закоммичена 14:47 (0183569) — 9/10, PASS 87 · граница чтения репозитория с закрытым git‑env и перепроверкой после чтения; ширина OID из object‑format; ноль публикаций на отказах (счётчик‑шпион)
M9‑014FullRun в SHA‑1 и SHA‑256 закоммичена 15:16 (4d10229) — 8/10, PASS 88 · формат читается из репозитория, внешние репо в том же формате и перепроверяются; production‑обёртка возвращает свидетельство либо отдельную запись отказа · долг покрытия: нет сквозного успешного прогона в sha256 (фикстура fetch’ит из SHA‑1‑проекта)
M9‑015Ревью v2 с хранением свидетельства + холодное чтение закоммичена 15:39 (a93cf8c) — 9/10, PASS 89 · вся цепочка одной атомарной публикацией, подделка отвергается при открытии стора, фасад BOOT‑009 не тронут, v1 — история
M9‑016Один боевой порт коммита + подлинный источник для планировщика закоммичена 15:58 + 2 fix (e7c286d, 0b3c8fd, 02976ae) — 8/10, PASS 90 · порт принимает только ссылки, семь пар резолвит холодно до мутации; источник верифицирует каждую запись, версия append‑only · минус: воркер зашёл в работу M9‑021 (бренд в планировщике) — откат стоил двух прогонов
M9‑018Readiness интеграции контекста хранится и читается холодно закоммичена 16:48 (75dc0db) — 9/10, PASS 90 · общий примитив хранилища укреплён по существу (дайджест до пути, kind/version до диска, чтение через тот же дескриптор, корень как dev/ino), readiness‑store — единственный владелец с replay/conflict
M9‑055Восстановление и финализация саги контекста закоммичена 17:51 (ac60f6d) — 9,5/10, PASS 91 · Worker #2 прочитал черновик предшественника как ревьюер и нашёл настоящий дефект: recovery строил финальную запись иначе, чем сага (две разные неизменяемые записи одной интеграции, потеря провенанса) — сведено в один рантайм хвоста саги с единственным построителем записи; readiness теперь реально пишется в проде; composition ±0; импорты 14→12 без ужимания чужого
M9‑019Readiness отпочкования + канонический декодер маршрутов закоммичена 18:25 (96361f4) — 9,5/10, PASS 92 · закрыта настоящая дыра: роут отпочкования проверял саговый бренд, а получал production‑операцию — работал бы только с пустым портом; readiness в родном семействе идентичности с проверкой дрейфа; копия примитива заменена укреплённым общим с маппингом кодов (500 не протекает); декодер сегментов общий для обоих роутов, таблица негативов (%zz, %2F, не‑NFC, control, неканоническая перекодировка) · находки в M9‑034: роут строится до активации → 503; непокрытый отказ тела
M9‑056Восстановление и финализация саги отпочкования закоммичена 18:53 (26f3507) — 9/10, PASS 93 · форма M9‑055 без копипасты, единственный построитель финальной записи, provenance/resolution refs запечатаны в intent, второй писатель outbox удалён
M9‑017Спящий Production Foundation root закоммичена 1630e75 · один root удерживает bounded production‑семейства без внешней authority и без второго владельца состояния
M9‑020Протокол команд Foundation закоммичена 1cdf2ae · единый типизированный command contract вынесен из будущих transport‑дверей
M9‑031Reviewer runtime закоммичена двумя bounded‑частями cae899d, b237f96 · descriptor, phase‑failure recovery и runtime разделены по ответственности; write zone уточнена в ed58680
M9‑032Current-chat runtime закоммичена 6dc6172 · transport текущего чата извлечён в отдельный bounded runtime без нового root
M9‑033Workflow, тонкий CLI и post-submit gates закоммичена 064ad23, bbfe062, 38cf0d1 · workflow собран, Candidate/FullRun/Review проверяются после submit, незапечатанный FullRun‑failure не маскируется как нормальный verdict
M9‑034Реальные Vite/host/CLI двери Foundation закоммичена e53a8b4, faa216c, 4e49b70 · закрыты applicability и sealed‑failure, root зарегистрирован во внешних входах, foreign-root masquerade activation(A)+composition(B) отвергается
M9‑074Production TaskCommit port + единый accepted-plan source закоммичена 77dcc7a exact-parent от 4e49b70 · canonical full run PASS · ревью исправило shallow freeze, тавтологичный reopen proof и неполную persisted negative matrix; port/source делят один комплект stores, replay и cold reopen byte-stable
M9‑051Старая ACC как одна bounded capability корня закоммичена e3c6c1e exact-parent от 77dcc7a · branded/frozen capability удерживается production root и доступна только через одну taskplan-runtime-routes дверь; bridge-local writer/endpoint удалены · rollback ограничен opaque one-use WeakMap token, публикация temp→fsync→link · genuine Vite E2E доказал first commit, exact replay и zero-mutation CSRF/origin‑отказы · canonical full run PASS (6aeb665)
M9‑021Аутентифицировать finalized TaskCommit source планировщика закоммичена 7589ca3 exact-parent от e3c6c1e · scheduler и SQLite принимают только genuine branded source; source создаётся лишь над тремя owner-branded stores и холодно связывает canonical TaskCommitRecord с intent и resulting GitBinding · real-store matrix закрывает missing/mismatch, duplicate, dependency gap, nonlinear order, stale decision, plan-complete и foreign M9‑999 · migrated 9 legacy fixtures без structural masquerade · canonical full run PASS (c2c8aac)
M9‑035Подготовить consumers запуска и runtime‑публикации выполняется · launcher/prepared-run/publisher/runtime-preparation принимают canonical finalized TaskCommit pairs из dormant stable source; fake ACC‑shape, caller list, foreign task/plan и раннее включение нового режима обязаны отказать без Run/публикации
M9‑036Следующий consumer: bridge/completed/PF‑E2E получает canonical pairs после M9‑035; current authority всё ещё не переключается
M9‑037…041, 060…062 → 022Двурежимная подготовка доменов (reviewer‑PASS backend, ACC‑denial, OwnerInbox, web, Runtime UI, current‑chat, VS Code) и один атомарный флип авторитета в корне — M9‑022 после слияний владельца: 057→037, 058→038, 059→039
M9‑023, 047…050Уборка после флипа: презентация web/VS Code (023), governance/OwnerInbox (047), web‑модель/экраны (048), runtime‑ui/host/CLI/VS Code (049), коллапс корня к безусловной TaskCommit‑authority (050) 063–069 слиты владельцем в 023/047–049 — 9 карточек на удаление мёртвого кода признаны церемонией
M9‑024…029, 042…046, 052…054, 070…073Терминал: Completion хранится (024); участники и происхождение (025, 042–044, 052 backfill); ProductOutcome ± с наблюдениями (026, 053, 054), негативные переходы (070), человекочитаемый ProductOutcome и его показ владельцу (071–073); кандидат релиза (027) → решение владельца (028) → main + ProductReady (029) → кокпит (045, 046) → терминальный маршрут (030)
M9‑005Распил лаунчера текущего чата и prepared‑run поправка: новые файлы — только фасады над существующими портами, вторых владельцев нет; файловые Run‑локи убраны
M9‑006Распил точки входа VS Code поправка: файловый поиск Run удаляется полностью — чтение только через SQLite‑читателей
M9‑007Миграция старых потребителей + паритет маршрутов поправка: перепись покрывает все 4 цели удаления и их живых потребителей (по M3‑014), не 2
M9‑008Физически удалить runtime‑bridge 11 657 строк — главный монолит V2 · поправка: до удаления — ноль ссылок на ВСЕ сносимые файлы, не только bridge
M9‑009Физически удалить оркестратор 5 307 строк · поправка не требовалась
M9‑010Финальные бюджеты Cockpit + каждая production‑дверь на месте поправка: владеет всеми 24 файлами‑должниками по манифесту M3‑015 и 57 путями разбиения; транзакционные границы механически не режутся
Срез 10Финал0 / 1
M10‑001completion → product‑outcome → merge в main → product‑ready здесь единственная подпись владельца — продукт готов · поправка не требовалась; открытый вопрос: явная запись о спящем BOOT‑011 в финальной приёмке

Журнал прохождения

сложности · пачки фиксов · консилиумы
срез 918.08M9‑021 закрыта: scheduler доверяет только genuine finalized TaskCommit source

Коммит 7589ca3 создан exact-parent от e3c6c1e. Structural {readScope, version} больше не является authority: TaskCommit source собирается только над тремя owner-branded stores, на каждом чтении проверяет record, intent и resulting GitBinding как одну связанную canonical цепочку, а scheduler сохраняет двойной version/read fence и финальную revalidate‑границу.

Что потребовало FWD: старые тестовые consumers сами изображали stores/source объектами и потому закономерно сломались после hardening. Одним census‑проходом переведены identity, M3‑001, release/origin/product/mainline, event-store и projection fixtures на genuine empty triplets либо реальные public-writer TaskCommit tuples; exact public-surface oracles обновлены только новыми brand assertions. Ревью дополнительно нашло дубли ledger и отсутствующий genuine foreign-task case — исправлено M9‑999 отказом до decision. Доказательства: migrated combined 76/76, scheduler 9/9, target 26/26, BOOT/oracle 32/32; canonical full run PASS, candidate c2c8aac. Следующая ready‑карточка — M9‑035.
срез 918.08M9‑051 закрыта: одна bounded ACC‑capability корня, одна current‑дверь, настоящий browser E2E

Коммит e3c6c1e создан exact-parent от 77dcc7a. Production activation один раз собирает branded/frozen legacy ACC capability; composition удерживает её внутри root, а taskplan-runtime-routes остаётся единственной дверью мутации. Из runtime-bridge удалены writer, authority provider и локальный ACC endpoint — там остались только чистая проекция команды и browser session marker.

Что поймало ревью: отсутствующий CSRF на новой двери; исчезнувшая UI-команда; публичный rollback через caller-supplied Map, способный удалить чужой файл; canonical target, видимый до полного write/fsync; отсутствие настоящего route E2E. Исправление вернуло temp→fsync→link publication, service-minted opaque one-use transaction token с SHA/dev/ino, genuine request marker и persisted seven-phase browser fixture. Финальный oracle дополнительно закрыл Map‑masquerade и связал разрешение удаления с exact native WeakMap get → push(closure) → execute receiver. Доказательства: core/activation 30/30, app 34/34, ownership 10/10, census 4/4, ACC browser 1/1; canonical full run PASS, candidate 6aeb665. Следующая ready‑карточка — M9‑021.
срезы17.08 · 16:30–18:54Саги закрыты с обеих сторон: readiness и восстановление контекста и отпочкования — четыре карточки, две настоящие дыры

Первый воркер закрыл M9‑018 и на M9‑055 честно остановился: контекст исчерпан после семи карточек, «полусделанная сага в ядре дороже паузы». Владелец открыл «Worker v3 m9 #2»; передача — через файл заметок на диске и байт‑точный снимок черновика. Второй воркер прочитал черновик как ревьюер и нашёл дефект класса «дрейф финальной записи» (recovery писал не те байты, что сага) — вылечено структурно: один рантайм хвоста саги для продюсера и восстановления. В M9‑019 нашёл, что живой роут отпочкования проверял не тот бренд и мог работать только с пустым портом; заодно один канонический декодер сегментов на оба роута вместо копипасты и укреплённый общий примитив вместо неукреплённой копии.

Темп второй смены: три карточки за 1 ч 35 (055 — 25 мин с чтением черновика, 019 — 34 мин, 056 — 29 мин), все прогоны зелёные, ни одного расширения зоны по инициативе воркера. Правило пары уточнено: ход не завершать до коммита+отчёта, промежуточные статусы текстом не писать (первый воркер однажды закрыл ход на слове «Продолжаю» и три часа стоял); заметки по карточке — на диске, чтобы пережить сжатие контекста.
срезы17.08 · 09:12–16:26Новая пара закрыла шесть карточек фундамента за день: M9‑011…016, шесть зелёных полных прогонов

Пара «воркер Claude Opus 5 + диспетчер‑ревьюер Fable» пошла по Package v3 с чистого дерева. Первая карточка стоила час разбора чужой поломки: полный прогон падал на зашитом хэше документа Feature Preparation в production и в тесте (сломан ещё a91495e от Codex) — вылечено глобально: единый источник — регистр §0 TASK‑PLAN того же коммита. Дальше темп 20–30 минут на карточку: принятие плана на новом языке (012), кандидат из точного дерева (013), FullRun SHA‑1/SHA‑256 (014), ревью v2 (015), ядро — порт коммита + источник для планировщика (016).

Что дало правило бюджета владельца: сработало пять раз по‑настоящему — четыре файла оформлены в манифесте с содержательными причинами, один раз правило импортов (15 > 12) заставило вынести сборку в производителя вместо оправдания. Что мешало: раннер допускает ровно один полный прогон и только до коммита из грязного дерева (после коммита — candidate_has_no_final_byte_delta, по хэшу — только «taskplan prepared candidate»); агрегатор останавливается на первой упавшей сюите — чужие поломки вскрываются по одной; в M9‑016 воркер включил бренд источника в планировщике (это M9‑021) — семь чужих тестов, откат. Наблюдение: sqlite-candidate-concurrency.test падает 16/16 в этом worktree даже на чистом дереве, в герметичном прогоне зелёный — окружение, не карточки; в бою не чиним.
план17.08 · 01:38–08:52Карта замыкания → Package v2 → v3: хвост плана переписан на 53 карточки, M9‑004 снята, пара сменена

По просьбе владельца свежий агент прошёл 23 обязательных звена production‑цепочки (R01–R23) по чистому HEAD и получил CLOSED = ∅: машина коммита BOOT‑эры (010) ни разу не собиралась в проде на канонических формах, четыре потребителя без производителя (принятие плана, кандидат, свидетельство прогона, запись о коммите для планировщика), саги без холодных читателей и восстановления, терминал считает и не хранит. Из карты выросли Package v2 (20 карточек) и, после двух исправляющих проходов, Package v3 (59 → 63 карточки с четырьмя терминальными добавками). Порядок — производитель и хранилище раньше проводов, провода раньше переключения: двурежимная подготовка доменов + один флип авторитета в корне (M9‑022), уборка после, терминал в конце.

Что срезал владелец: Codex‑аудит ушёл в петлю «проверь фикс → под‑фикс → проверь» (8 FIX‑промптов + 02A/03A/03B/05A/06A/08A) и резал карточки по числовому потолку «12 путей» — 40 → 59; девять карточек на удаление мёртвого кода и три «wire»‑карточки признаны церемонией и слиты при переносе (057→037, 058→038, 059→039, 063–065→023, 066→047, 067→048, 068–069→049): 53 карточки, 108 задач в плане. Перенос в TASK‑PLAN сделан скриптом (формат раннера: write paths → acceptance, литеральные journey‑команды), проверен рендерером (108/107/1/116), парсером зоны по всем 61 M9‑карточке, 51 тестом плана и кросс‑проверкой «ни один путь/зависимость/тест не потерян» — 359e807, 122da80. Попутно найден дефект старой M9‑010: её - acceptance, architecture: не читается парсером зоны — чинится в M9‑011.
Пара исполнения сменена: воркер — свежий чат Claude Code «Worker v3 m9» (Opus 5), диспетчер‑ревьюер — эта сессия (Fable); пара Codex припаркована. Пакет №0: 56 WIP‑файлов M9‑004 сохранены байт‑в‑байт вне репозитория и в stash@{0}, дерево чистое, каждая карточка идёт с чистого exact‑parent. Правило пары: один пакет — одна карточка; отчёт → ревью с оценкой из 10, ниже 7,5 — доделка; вопросы вне зоны — диспетчеру, не владельцу.
среда17.08 · 01:14Воркер перелинковал node_modules воркtree — SQLite‑тесты в дереве больше не открываются

В ходе M9‑004 воркер запустил pnpm exec vitest через fallback‑pnpm рантайма Codex; тот переписал node_modules/.pnpm (01:14:58) без сборки нативных модулей — у better-sqlite3 исчез build/Release. Свои артефакты (pnpm-lock.yaml, pnpm-workspace.yaml) воркер заметил и удалил, зависимости — нет. С этого момента любой SQLite‑тест, запущенный в воркtree, падает с sqlite_state_open_failed: проверено на трёх наборах, которые в 22:34 были зелёными. Полный прогон в герметичном checkout не задет — там свой toolchain.

Что делать: восстановить зависимости (npm ci в корне воркtree или пересборка better‑sqlite3) до следующего targeted по SQLite. Попутная находка: connection.mjs глотает исходную ошибку — causeCode: "unknown" вместо «Could not locate the bindings file»; типизированный отказ без причины стоил 10 минут диагностики — DEFERRED.
срезы16.08 23:31 · 17.08 00:55M9‑002 и M9‑003 закрыты; в M9‑004 ревью поймало «похудевший» CLI

M9‑002 (release candidate) — 1 ч 05 с одним содержательным FWD; M9‑003 (mainline CAS + ProductReady) — 1 ч 24: guard target‑писателя сделан инжекцией по итогам спора двух ревью, а собственное ревью оркестратора нашло окно reconcile↔CAS и replay мимо state machine — оба закрыты до коммита. В M9‑004 (снос per‑task ACC, 53 пути) воркер сделал CLI «тонким», удалив рабочий runtime (review/review-phase/correct, protected current‑chat seam) вместо делегирования — ревью не приняло, runtime возвращён, thin CLI делегирует workflow; 29/29, 30/30, 86/86.

Темп M9: ~1 ч 15 на карточку, FWD только по делу (3 за три задачи), форков — 3 и все на сообщения владельца. Оценка сегмента 8/10: минус за сломанную среду воркtree, оставленную без внимания.
ремонт16.08 · 16:04–22:26Ремонт №2 закрыт: девять продуктовых дефектов ревью исправлены, код среза M7–M8 поднялся до 7 из 10

Группа A (aaec66e, 29 путей): promotion теперь реально продвигает accepted‑current родителя через новую bounded‑операцию promoteAcceptedRoot поверх CAS M8‑001, идемпотентно при replay, artifact_set_pointer_changed → context_promotion_stale; resume родителя стал действием — resumeParentContext переводит authoring‑stage родителя на целевой этап CAS‑переходом с записью reconciliation, а outbox‑consumer срабатывает только на недоставленных событиях; обе HTTP‑двери интеграции зарегистрированы в реестре (проверено реальным handleNodeRequest); trust‑check promotionPort восстановлен; finalizedAt резервируется в саге один раз (ReserveFinalization) до записи финала — replay детерминирован; таблица HTTP‑статусов явная, закрыта тестом. Группа B (bbfa64c, 7 путей): кэш чтения коммитов на время одной верификации — 402 вызова вместо 81 005 при 400 общих коммитах; резолюция удалением (resolvedEntry: null) с привязкой к acceptance‑evidence; вердикт продукта требует observed === expected, привязан к дереву и subject, обязателен хотя бы один product_outcome‑оракул. C1 (объединение саг) — DEFERRED в M9‑010, названо словом.

Как шло: пункты выдавались воркеру по одному и принимались по diff + RED→GREEN на старых байтах; ворота — на группу. Полный прогон A падал трижды по делу: парсер зоны (FWD), бюджет 425 > 400 (helper parent-resume.mjs), ownership‑оракул поймал DDL таблицы саги в чужом файле — миграция v17 была дописана в «последний» список миграций в wiki-projection-store.mjs; перенесена владельцу, id переименован. Далее цепочка бюджетных превышений (14 импортов, 13, 422 строки) — четыре механических разреза. B прошла с одного повтора (сосед‑тест создавал старые oracle‑записи без tree/subject — прямое следствие B3).
Цена: 6 ч 20 мин стены, из них ~1 ч 50 мин — ожидание «разрешаю» на helper (18:48→20:36) и ~1 ч — арифметика 400/12. Все тесты ремонта зелёные (41/41). Форков — ноль.
Остаток долга по коду: копия саг M7‑002/M8‑005 (~590 строк), 79 копий валидаторов, цепочка списков миграций через последний store‑файл, покрытие типизированных отказов origin — всё в M9‑010.
консилиумревью кода · 16.08 14:30 · 3 ревьюераКод M7–M8: 5,5 из 10 — дисциплина отказов есть, но обе саги интеграции не завершены как продуктовые сценарии

Прочитано: ядро слияния M7‑001, сага M7‑002, originated bundle M8‑003, product outcome M8‑004, сага M8‑005 (~9 500 строк production + 6 100 тестов за сутки). Оценки после сверки с четвёртым (соседним) ревьюером: M7‑001 — 6, M7‑002 — 5, M8‑003 — 6, M8‑004 — 6, M8‑005 — 4–5; срез — 5,5 (сосед дал 6,3 — разошлись на его мягкости к M7‑001 и моей — к M7‑002). Все новые тесты зелёные (33/33), но они бьют в композицию синтетическими запросами и не моделируют перечисленное ниже.

Блокирующее по правилу владельца (ломает продуктовый сценарий или даёт неверную запись): (0) сага M7‑002 не продвигает accepted‑current родителяpromote читает версию только для stale‑проверки и кладёт кандидата, тогда как спека (ArtifactSetPromotionPlan.expectedTargetArtifactSetVersion) требует CAS‑продвижения; девять resume‑handlers лишь ставят delivered=1, родителя никто не возобновляет; обе HTTP‑двери интеграции (M7‑002 и M8‑005) не зарегистрированы в реестре маршрутовrouteKind === null → next(), хотя taskplan-runtime-routes.mjs был в зоне M7‑002; (1) merge‑base в tree-merge.mjs квадратичен по общей истории, а боевой readCommitgit cat-file subprocess на коммит без кэша: замер 400 общих коммитов → 81 005 запусков git ≈ 11 минут, при истории этой ветки — больше часа на одну интеграцию; тесты не видят — графы по 5–10 узлов; (2) finalizedAt: new Date() внутри content‑addressed финальной записи, записанной до Finalize — крах в окне = вторая «неизменяемая» запись при replay; (3) resume родителя срабатывает на каждом реплее, флаг delivered write‑only, тест закрепляет resumes === 2; (4) наблюдения оракулов «продукт удался» не привязаны к дереву/subject — зелёное наблюдение чужого дерева даёт accept.
Долг (не размораживает): сага M8‑005 на 90 % — копия M7‑002 с заменой слов (intent‑store/outbox/ref‑cas — 100 %), при копировании потерян trust‑check promotionPort; из 37 типизированных отказов origin‑саги тестами покрыты 4; 79 production‑файлов держат собственные копии валидаторов, 258 проверок isProxy, 22 файла ровно на 395–400 строках, хабы‑реэкспорты ради счётчика импортов.
Что сделано хорошо: CAS по (state, version) в BEGIN IMMEDIATE; публикация wx → fsync → link; настоящие crash‑инъекции в SQLite+файлы с replay; трёхстороннее слияние и хэш дерева — по‑гитовски корректно; evidence‑authority считает первый изменённый этап по хэшам, а не верит заявке.
Решено предложить: ремонт вне плана на 30–60 минут по четырём пунктам; копипасту саг схлопнуть в M9‑010, раз она всё равно трогает эти файлы.
режим16.08 · 05:00–13:41Goal 1 закрыт: четыре задачи, 17 поправок плана и два часа простоя на одном решении

За день закоммичены M7‑002 (09:39), M8‑003 (10:38), M8‑004 (11:00), M8‑005 (12:49) — весь M8 и весь M7, граница первого goal достигнута. Дисциплина держится: на каждую задачу один полный прогон и одно ревью, WIP всегда сохраняется побайтно, поправки плана — отдельными двухфайловыми коммитами; оркестратор поймал воркера на пропущенной регрессии в M8‑004 и не засчитал молча. Но цена: 17 FWD за день (всего 54), из них девять — на одной M7‑002.

Куда ушло время M7‑002 (4 ч 47 мин): вторая за сутки дыра плана того же класса, что branch‑evidence — есть потребители planned operation / reviewed merge resolution / точного Git readback / перехода active → read_only_history, а производителей нет (восемь путей добавлено); oracle владения не знал новый пакет; пять внутренних API утекли через запечатанный фасад; и главное — 2 ч 09 мин (06:38→08:47) всё стояло на «НУЖНО РЕШЕНИЕ» по правилу второго FAIL, пока владелец отсутствовал; в 05:19–05:20 один и тот же вопрос был задан трижды за минуту.
Что сработало: одним FWD (59ec025) schema‑pin followers выданы сразу шести оставшимся миграционным карточкам — класс остановок закрыт; перед M9 владелец попросил предварительный аудит блока — один FWD‑M9 (8620239) вместо десяти остановок.
Что вернулось: пять форков (12:51 ×3, 13:28, 13:36) — на аудите M9; multi_agent по‑прежнему включён.
Оценка дня: 7 из 10 — качество и дисциплина на 8–9, пропускная способность на 6: правило «второй FAIL → к владельцу» не отличает мелкую in‑zone правку от настоящего тупика и не умеет ждать без остановки всей цепочки.
дефектM7‑001 · ревью 04:42Ядро слияния выбирало не того общего предка

Первая версия ядра брала merge‑base по минимальной сумме расстояний до двух голов. В графе с «короткими» рёбрами (shortcut‑parent) такой выбор возвращает старого предка, хотя существует более новый общий — а значит трёхстороннее слияние считало бы изменениями то, что обе ветки уже давно разделяют, и тихо давало неверный результат. Тесты самой задачи были зелёными: сценарии не содержали такого графа.

Поймало независимое ревью по diff, не прогон. Исправление — выбор по максимальной родословной (как это делает Git); несколько несравнимых лучших предков — типизированный отказ, а не «первый попавшийся»; добавлены два regression‑графа: shortcut и criss‑cross. Полный прогон и ревью — PASS повторно; коммит c3a34c5. Вопросов владельцу — ноль, форков — ноль.
режим16.08 · 02:05–04:28Дыра плана закрыта за 42 минуты, срез 6 закрыт, сосед вылечен за 11 минут

После «разрешаю» на FWD M8‑002 (с условиями: переиспользовать существующие immutable/acceptance, один коммит, без параллельных исполнителей) — цепочка без единой самозаведённой остановки: FWD зоны fe91f33 → производитель branch‑evidence 2fb3fc6 (705 строк; полный прогон FAIL — страж M3‑013 поймал публикацию через renameSync, переведено на wx → fsync → link; ревью — один настоящий HIGH: authority верил заявленному типу изменения и не вычислял первый изменённый этап) → M6‑001 correction 7b212c2 за 15 минут → M6‑002: кандидат за 6 минут, ревью нашло реальный блокер (Git‑поля, которых нет в боевом снимке) → FWD‑M6‑002 9f35769 + ремонт exact-plan.test.mjs → M6‑002 6fc29ff. В 04:28 — M7‑001.

Темп: с 01:19 закоммичены M8‑001, M8‑002, evidence‑подсистема, M6‑001 correction, M6‑002 — против одной задачи за предыдущие 11 часов. Форков — ноль после 02:00; входных токенов у оркестратора 35 M за два часа против 140 M за прошлые сутки.
Что ещё стоит времени: три обращения к владельцу за два часа, два из них — из‑за инфраструктуры (флейк соседа и harness E2E), а не кода; сам флейк exact-plan / SQLITE_BUSY до ремонта уронил четыре полных прогона по 7 минут. Правило «второй FAIL → к владельцу» пока не отличает флейк соседа от дефекта кандидата.
Отклонение от промпта ремонта: починка вошла в коммит M6‑002, а не отдельным коммитом, и проверена 3× подряд, а не 10× под нагрузкой — при этом полный gate (то же параллельное окружение) прошёл, а причина названа точно: дефект теста, не продукта.
дыра плана16.08 · 01:59Классификатору веток нечего читать — в плане нет производителя доказательств

Оркестратор подключал только что построенный классификатор M8‑002 к боевому маршруту создания дочернего контекста (там стоял самочинный флаг «это новая ветка», который спека прямо запрещает) — и упёрся: спецификация §4.2 подробно описывает, что классификатор потребляет (хэш‑привязанные доказательства смены проблемы/пользователя/результата, ссылки на scope/DAG/acceptance), но ни спека, ни план, ни FEATURE‑PREPARATION не называют, кто это производит. Все четыре вида доказательств сегодня создают только тестовые подкладки. В проде reader вернёт пустоту — дочерний контекст не создастся никогда.

Проверил сам по спеке, плану и коду — дыра настоящая. M6‑001 закоммичена «работающей» на тестовых подкладках; M6‑002 (сквозной E2E) без производителя была бы фикцией; от того же зависят M8‑003 и M8‑005.
Запрошено: FWD M8‑002 на 11 путей — immutable store/authority доказательств, API их принятия, reader в SQLite‑композиции, route, тест и journey. Оценка по темпу нового режима — 40–90 минут. Альтернатива — продуктовое решение упростить спеку («владелец сам объявляет тип ветки»), но это обнуляет только что построенный классификатор.
Стоп здесь — правильный: это единственная категория, где новый регламент велит ждать владельца (новая подсистема сверх карточки).
режим16.08 · 01:19–01:45Две задачи за 26 минут после ночи в одиннадцать часов

Владелец переписал регламент пары: оркестратор — диспетчер и единственный ревьюер с правилом «исправляю только находку, которая воспроизводимо ломает продуктовый сценарий, нарушает дословную приёмку или создаёт реальную возможность неверной записи; спекулятивное hardening не размораживает кандидата»; воркер — только пишет код; goal‑режим до конца M8. Первые результаты: M8‑001 закоммичена в 01:19 (полный прогон 66 наборов PASS + ревью PASS), M8‑002 — 23 минуты от старта до коммита; hardening‑находка ревьюера правильно оставлена без правки.

Что не сделано из рекомендованного: воркер — тот же чат с 13.08 (контекст 150–240 K на каждый вызов), multi_agent включён и усилие ultra («максимум рассуждений с автоматическим делегированием» — так его описывает сам Codex), поэтому за 40 минут родилось ещё 9 форков оркестратора по 13 МБ. Темп держится на правиле про находки, лимиты — жгутся.
Граница goal: M8‑001 → M8‑002 → M6‑002 → M7‑001 → M7‑002 → M8‑003 → M8‑004 → M8‑005, затем стоп; M9‑008/009 (физические удаления), M9‑010 и M10‑001 (mainline) — только с владельцем.
канал Совета15.08 · разбор 16.08Совет ломал не механизм доставки, а мой протокол — слоями с 04.08

Владелец: «Совет читает конверты, но не доставляет; если сказать ему "забудь всё и отправь" — доставляет». Поднял всю историю Совета с 04.08 (139 128 записей журнала). Подтверждаю: примитив доставки работает; ломает его то, что я в него закладывал: 66 прямых сообщений‑инструкций в чат («поправка протокола», «ужесточение», «почини надёжность», выдуманные статусы), 5 версий инструкции автоматизации — каждая тяжелее (FIFO строго, attempt_log started/terminal, 55‑секундный предел, «истина доставки — журнал адресата», duplicate_detected → failed), и 6 впрысков проектного AGENTS.md через headless‑вызовы из папки проекта.

Цепочка отказа: адресат занят → вызов не вернулся за 55 с → unknown → «проверь журнал адресата» → там пусто → pending → следующая минута то же → FIFO держит всё, что за ним. Совет‑2 не помог: он взял ту же автоматизацию v5.
Исправление: инструкция автоматизации — пять строк («прочитай, отправь, дождись возврата, поставь delivered»), никаких моих сообщений в чат Совета, конверты — только в файл с фиксированными полями, новый чат, чтобы отрезать историю; тест — два ping подряд при занятом оркестраторе.
режимночь 15→16.08 · M8‑001Одна задача, пять заморозок, одиннадцать часов и ~300 M входных токенов

M8‑001 стартовала 15.08 13:40 и заморозилась пять раз (19:02, 21:46, 22:08, 23:08, 00:34). Разморозки 1–4 — по делу: полный прогон и ревью нашли настоящие дыры (устаревший экран мог писать в базу; окно между проверкой и записью; Builder несовместим с компилятором планов; Feature Preparation не сверялась с Git). Пятая — самозаведённый аудит «ещё один край», который оркестратор сам назвал своей ошибкой. Пять остановок «разрешаю» на расширение зоны (25→31 путь), 2,5 часа простоя в ожидании Совета, в 00:40 — 403 от OpenAI (отвалился VPN).

Куда ушли токены — не в код. Оба потока живут с 13.08: медиана 155 K входных на каждый вызов, пики 240 K при окне 258 K, 56 авто‑сжатий у воркера; за окно M8‑001 — 935 вызовов оркестратора и 1 079 воркера, плюс 23 субагента‑форка, каждый — копия всего журнала родителя. Выходных токенов всего ~570 K.
Диагноз владельцу: план ограничивает что трогать, но не сколько живёт разговор; свежий поток на задачу, без форков, ревью — свежим процессом. Числовые потолки без допуска дали пять новых файлов ровно на 397–399 строках при лимите 400 — подгонка под цифру.
срезы15.08 · 01:22 и 13:38Восстановление закрыто целиком; первая дочерняя ветка закоммичена

M5‑003 (ограниченный retry адаптера с одним финальным наблюдением) — a87ffad, срез 5 закрыт 3/3. M6‑001 (изолированная дочерняя ветка) — d352703 после FWD‑M6‑001 (два соседских теста в зону, коммит 2711951) и полного прогона: 66 наборов, отказов ноль. Ворота держались на Совете: утром 15.08 после перезагрузки в 11:04 очередь Совета сгорела вместе с /tmp, полтора часа ушло на восстановление связи вручную.

Порядок исполнения после этого: M8‑001 (по DAG M6‑001 формально зависит от M8‑002, но уже закоммичена — «закоммичено = сделано»).
инструменты14.08 деньЧетыре инструмента признались в поломках за один день

M5‑001 была написана к полудню и простояла замороженной полтора часа — её держал не собственный дефект, а цепочка поломок в том, чем строят. Запускалка браузерных тестов искала конфиг не там. Ожидание процесса зависало вместо ошибки, потому что ранний выход отклонял не тот промис. Запись доказательств выбрасывала текст, оставляя только его размер и хэш. И сама эта запись оказалась перезаписываемой.

Все четыре молчали месяцами и вскрылись только потому, что кто‑то дошёл до конца одной задачи. Ни один ремонт не тронул байты задачи — четыре отдельных коммита.
Ключевое решение: ночью я записал потерю текста как наблюдение и запретил чинить в бою. Это стоило трёх слепых циклов, и решение было неверным: правило «механизм не чинят в бою» касается промежуточных механизмов, а не тех, без которых нельзя увидеть, что сломалось. Отменил своё же решение после третьего повторения — раньше следовало.
Страж M3‑013 поймал свою добычу: починка записи выбила файл из списка прощённых долгов, и он немедленно потребовал соответствия сегодняшним правилам. Задача, за раздутость которой досталось справедливо, окупилась ровно здесь — иначе доказательства остались бы перезаписываемыми навсегда.
дефектM5‑001 · правило эрыВалидатор перепроверял прошлое правилами настоящего

Новая проверка требовала канонический вид записи там, где речь о вытесненной — то есть об истории. Соседский тест подавал запись эпохи BOOT, и проверка её отвергала. Приёмка задачи говорит дословно: записи прошлой эпохи остаются пригодной для чтения историей, запрещено лишь выпускать их заново.

Поймало сопоставление кода с текстом приёмки, а не прогон тестов — все тесты самой задачи были зелёными.
И здесь сработала ловушка моего же правила. Пара применила выданное мной постоянное разрешение и начала править соседский тест — то есть готовилась узаконить дефект как «обновление устаревшего теста». Поймало только независимое ревью; они немедленно отозвали правку, тест остался без единого изменения.
Правило ужесточено: прежде чем трогать соседский тест, обязан процитировать фразу своей карточки, которая отменяет инвариант. Не можешь процитировать отмену — значит отмены не было.
решениевладелец · 14.08 утроЗамок снят поправкой на шесть минут, а не задачей на день

Владелец потребовал одну рекомендацию вместо трёх сменившихся за ночь. Перед ответом три независимые проверки по байтам плана дали факты, которых у меня не было: круга в плане нет (обратная стрелка нигде не записана), но механизма частичного закрытия тоже нет — пока M4‑004 числилась открытой, были заблокированы пять задач; и главное — отложенный кусок мог потеряться молча: тех двух файлов не требовал никто, ни один финализатор, ни терминальная задача.

Решение владельца: идти по утверждённому плану, новую задачу про аппрув не заводить. Одна документная поправка: два пути и два требования переехали из M4‑004 в M9‑010 дословно — тот же маршрут, тот же порог пяти секунд; M4‑004 закрыта уже сделанным коммитом без перепрогона.
Шесть минут от решения до коммита (d7bb27b), при опасении владельца, что это встанет на день. Содержание поправки было расписано до строки заранее — решать и исследовать не пришлось ничего.
Что это дало: сняты блокировки с пяти задач, и поставлен капкан — сквозное доказательство стало обязательным условием M9‑010. Плана без него теперь не закрыть; если боевого пути принятия плана к тому моменту не будет, задача честно упрётся вместо того, чтобы пройти с тихо отсутствующим доказательством.
Мой урок: три сменившиеся рекомендации — это доклад до завершения раскопок. Копать до дна, потом говорить.
дыра машины14.08 · 04:46Собрать машину умеет только тест. Запустить руками — некому

M4‑004 первой потребовала, чтобы настоящая команда прошла путь целиком — и упёрлась в пустоту. Функции, собирающие живой запуск, существуют, но вызовов в боевом коде ноль: только объявления и переэкспорты. Единственный, кто их вызывает, — тест M3‑001. Значения привязаны к личности объектов, из данных их не восстановить, поэтому «маленьким сборщиком» это не закрывается.

Найдено не потому, что искали — потому что впервые пошли до конца. Оркестратор остановился, я разрешил обходной путь, он возразил; я перепроверил и снял собственное разрешение как ошибочное. Проверка заняла три команды, но её нужно было сделать до разрешения, а не после.
Заглушек нет: отложенную часть можно было подпереть одной строкой, и никто бы не заметил. Не подперли — прямой запрет соблюдён.
Ждёт решения владельца: строить боевую сборку отдельной задачей, снизить приёмку или разделить M4‑004.
дыра машины14.08 · 05:50Браузерная часть обязательных ворот не исполнялась ни разу

Запускалка искала конфиг браузерных тестов в корне проекта, а он лежит в папке приложения. Файла по пути нет — набор молча не стартовал. Молчала дыра потому, что до M4‑004 ни одна задача не добавляла браузерных тестов: гейт нечем было запустить.

Причину доказали арифметикой: разница вывода 216 байт = путь длиннее на 24 байта × 9 вхождений в тексте ошибки. Плюс отделили посторонний след из старого каталога, чтобы не приписать его этому отказу.
Правило «механизм не чинят в бою» здесь не применено сознательно: оно про промежуточные механизмы, а полный прогон — одни из трёх обязательных ворот. Ворота, которые физически не могут исполниться, нельзя закрыть строкой в реестре: зелёный по недосмотру хуже красного.
Окупилось немедленно: после починки браузерный набор впервые отработал по‑настоящему — 11,7 с, настольный и мобильный вид, снимки экрана.
веханочь 14.08 · срез 4Восемь задач за смену: каталог, проектор, запрос, экраны

M3‑014, M3‑015, M4‑001, M4‑002, M4‑003, M3‑002, починка запускалки и частичная M4‑004. Пятнадцать коммитов подряд, ноль откатов, ноль плохих байтов, донор не сдвинулся ни разу. Каждый коммит сверен из git против ревьюированных байтов.

Дисциплина по размеру: центральный файл композиции прошёл через три задачи и не вырос — 933 → 933 → 931 → 931 строка, хотя принял в себя каталог, проектор и запрос. Файлы проводки веб‑приложения сократились. Ровно ради этого M3‑015 и замораживал долг.
Три задачи подряд без единого дефекта — я честно допустил, что притупились мои проверки, и назвал это паре. На следующей задаче те же направления дали пять находок: инструмент рабочий, те три были действительно чистыми.
экспериментM3‑015 · внешняя модельОдну задачу сделали двое вслепую — сошлись до последней цифры

По решению владельца ту же задачу параллельно получила внешняя модель. Основная пара о ней не знала. Ловушка задачи была в охвате: по всему репозиторию выходит 180 превышений, и только ограничение каталогами модулей даёт 24. Обе стороны догадались сами, и обе дали ровно 24 записи, совпавшие с моим независимым замером.

Ценность не в скорости, а в сходимости: две слепые реализации с идентичным результатом — доказательство сильнее любого одиночного ревью. Отдельно проверена калибровка на точечной правке: 11 проб из 11, включая три на ложные срабатывания — обычный join по массиву строк остался молчать, то есть проверка не была расширена наугад. Правка вошла в историю отдельным коммитом b312667.
дефектM4‑004 · вкладка GitТест утверждает дефект как правильное поведение

Вкладка Git объявлена доступной, но требует четыре поля разом. Нагрузок со всеми четырьмя нет во всём дереве — вкладка не откроется никогда, даже когда привязка проверена и система знает ответ.

Опаснее самой дыры: браузерный тест утверждает «git · unavailable» как ожидаемый результат. Тест не ловит дефект — он его узаконивает, и следующий человек поверит тесту. Третий случай этого класса за сутки.
Корень: контракт вкладки требует четыре поля, проектор не гарантирует ни одного, производителя не существует. Никто эти концы не сводил.
Коммит не заблокирован — отказ честный и типизированный, ничего не падает. Требование перенесено в продолжение задачи: либо чинить, либо прямо помечать как известную неполноту.
решениевладелец · 13.08 вечерЗапрет на растраты: «нужен код, а не дорогая коробка для кода»

Владелец остановил строительство и задал прямой вопрос: почему просьба «проверь, учитывает ли план изменения после M3‑012» породила две задачи, съевшие восемь часов при нуле строк товарного кода. Цифры подтвердились: аудит плана был нужен и занял пять часов, найдя пять настоящих дыр. А вот выросшие из него сторожевые задачи дали тест на 6089 строк и вторую перепись — чтобы описать 15 обращений в рабочем коде к четырём файлам.

Найденный корень — структурный, а не про лень. Обычная задача закончена, когда работает. Сторож «закончен», когда мимо него ничего не пройдёт, — а у этого нет дна: всегда можно придумать ещё один обход. Поэтому сторожевая задача растёт, пока кто‑то не скажет «хватит». Не сказал никто, включая меня: мои же круги ревью добавляли команде круги работы, и я ни разу не спросил, стал бы кто‑нибудь реально так писать.
Модель угрозы была неверной: я рецензировал защиту от злоумышленника, которого в проекте нет — код пишет своя команда в своём репозитории. Введено правило: сторож обязан назвать, кто реально совершит ошибку; если ответ «злоумышленник» — не строим. Сторож не может быть больше того, что охраняет. У каждой сторожевой задачи заранее объявляется предел кругов.
вехаM3‑015 · экспериментОдну задачу сделали двое вслепую — и сошлись до последней цифры

По решению владельца ту же задачу параллельно получила внешняя модель в отдельном окне, чтобы посмотреть, как справится. Основная пара работала своим порядком и о её работе не знала. Суть задачи — обмерить производственные файлы и заморозить список превышающих лимит.

Обе версии дали ровно 24 записи и полностью совпали с моим независимым замером — те же файлы, те же числа, ноль расхождений. Ловушка задачи была в охвате: по всему репозиторию выходит 180 превышений, и только ограничение каталогами модулей даёт 24. Обе стороны догадались сами.
Внешняя модель: 25 минут, тест 117 строк, песочницу соблюдала, в отчёте честно перечислила непокрытое. Пара: тест 133 строки, проходит 3 из 3, дополнительно проверяет ложные запреты — что обычная правка и уменьшение файла проходят, а рост строк и рост импортов падают с названными кодами.
Главная ценность не в скорости, а в сходимости: две слепые реализации с идентичным результатом — доказательство правильности сильнее любого одиночного ревью. К приёмке идёт версия пары; чужая работа сыграла роль независимой сверки.
вехаM3‑014 · e1c4d4eПерепись legacy‑нагрузки: отклонена, сокращена, принята

Первый круг я не принял: перепись молча теряла живые загрузки. Проверял тремя источниками — многолучевое ревью, собственный стенд из байтов файла, внешний аудитор вслепую. Все сошлись на одном корне: анализатор узнавал перечень известных форм вызова, а всё незнакомое пропускал молча. Это тот же дефект, ради которого задача и создавалась, — список просто переехал с путей на формы вызова.

Перед вторым кругом я снял половину собственных требований. Обёртки над require, процент‑кодирование пути, различие регистра — так пишут, когда прячут нарочно, а прятать некому. Снял и требование «любое неразрешимое обязано падать»: на живом дереве оно сработало бы больше трёх тысяч раз — такой запрет просто отключат, и он хуже дыры.
Чинили шесть обычных форм: запуск воркера (так пишет их же код), запуск процессом через node, ошибка с .join на массиве, вызов через метод объекта и класса, путь‑константа из соседнего модуля, и отдельная ветка разбора для деклараций — убрана, то есть кода стало меньше. Заодно исчезли ложные ссылки от закомментированных строк.
Два хвоста не закрылись и не заблокированы — предел был объявлен заранее. Важнее другое: файл перестал врать о себе. Заголовок теперь прямо говорит, что это перепись для переноса, а не сторож безопасности. Расхождение между обещанием и поведением опаснее самой дыры — следующий человек поверил бы обещанию.
вехаM3‑013 · 29a0d42Страж владения построен — семь раундов, четыре независимых проверяющих

Первая задача новой пары оркестратор+воркер. Страж вырос с 1819 до 6089 строк и превратился из «сверяльщика по замороженному списку файлов» в анализатор по типизированным токенам: он сам обходит 41 модуль, а любой будущий незаконный писатель, второе соединение, двойная запись или подмена исполняемого файла падают автоматически. Закоммичено побайтно то, что ревьюилось (2/2 файла по якорю).

Закрыто 30+ способов обхода за 7 кругов. Вклад: внешний аудитор (DeepSeek в tmux) — 8, включая ATTACH DATABASE и VACUUM INTO как обход через сам SQL; второй Codex‑аудит — блокер с «-- внутри строки», прятавший записи; мои лучи — 12, в том числе execFile(файл, {shell:true}, колбэк) и --exec-path в списке безобидных; остальное поймала самопроверка пары. Дважды всплывала моя собственная недоработка (я назвал git и core.fsmonitor безопасными — оба оказались трамплинами), обе исправлены.
Главный урок: «защита есть и тест есть» ≠ «пройти нельзя» — один аудитор дал «принимать» там, где двое других нашли блокер; рассудили по байтам. Остановлено вовремя: раунда 8 не было — остаток ушёл отдельной задачей по заранее объявленному правилу.
вехаплан v2 · 839d1faПост‑SQLite поправка плана: +3 задачи M3, перепрошиты M4–M10

Два независимых аудита (мой многолучевой и соло‑аудит Codex в POST‑SQLite AUDIT) сошлись на одном корне: карты будущих задач писались до миграции и не знали новых правил. По приказу владельца Codex расширил канонический план: M3‑013 (само‑обнаруживающий страж владения — замороженный список файлов убит как класс), M3‑014 (полная перепись legacy‑нагрузки: 4 цели + обходные маршруты task‑ACC), M3‑015 (перепись долга по лимитам: 24 файла, 57 путей разбиения). Все M4–M10 теперь потомки этой цепочки; DAG 56 задач / 116 финализаторов; полный прогон 31/31 зелёный; коммит documents‑only (+1019 строк), parent 3aa92fc.

Моя сверка «ничего не потеряно» (28 пунктов, каждый флаг перепроверен состязательно): 25 доехали полностью (9 — в улучшенной упаковке), 0 потеряно, 3 частично: ledger отстал от карт на 11 путях; нет обязательства доказывать 503‑подавление во время переписей M9; пробуждение спящего BOOT‑011 всё ещё без владельца. Все три чинятся одним documents‑only патчем — список строк передан владельцу. Сравнение аудитов: согласие 22/28; в 5 расхождениях по байтам прав оказался Codex (мои недофлаги), зато у меня — ноль ложных тревог и построчные правки.
вехаутро · merge + аудитSQLite‑работа слита в v3‑execution‑core; остаток плана проаудирован

По решению владельца ночная ветка слита fast‑forward в codex/v3-execution-core (HEAD 3aa92fc, 89 файлов, +28 277 строк) и помечена тегом v3-sqlite-migration-complete. Черновой прототип M3‑001, лежавший в доноре незакоммиченным, сохранён страховкой (stash + патч), не потерян.

Аудит 28 оставшихся задач (9 аудиторов + состязательная проверка каждого флага, 0 опровергнутых): 4 уже адаптированы · 8 ок как есть · 16 требуют FWD‑поправки до исполнения · 0 полностью устаревших. Главная системная находка: замороженная перепись файлов в оракуле «нет двойной записи» уронит любую будущую задачу, добавляющую production‑файл в корни состояния — лечится одной строкой в shared‑path ledger (цепочка передачи оракула через 10 задач). Второй класс: 5 карт создают новое изменяемое состояние, не называя SQLite‑субстрат. Полный отчёт: ~/REPORTS/taskplan-sqlite-audit_130826-1021.md.
вехаSQLite‑пакет · финалНочная кампания завершена — весь SQLite‑пакет закрыт, ветка чиста

Терминальное условие пакета достигнуто и сверено по документу: FWD‑поправки + M3‑003…M3‑012 + M3‑001, ветка codex/v3-sqlite-forward-amendment на 3aa92fc, дерево чистое. Каждый коммит прошёл полный прогон на финальных байтах, одно независимое ревью и мою побайтную сверку из git. 0 плохих байтов в истории.

Владельцу остаются два решения: (1) слияние root→main — единственная подпись владельца; (2) отдельный мандат на продуктовую M3‑002 (визуализация; заодно ждёт выбор из трёх направлений UI). За ночь: 6 owner‑proxy решений по делегации, 5 дефектов поймано до заморозки, все зонные поправки — документными коммитами с моими условиями дословно. Агенты остановлены штатно.
вехаSQLite · M3‑001Живой запуск работает — настоящий процесс от команды до чекпоинта

Финальная кодовая задача миграции закоммичена (3aa92fc, сверено 6/6 байт). API‑команда поднимает настоящий HTTP‑сервер и запускает настоящий отдельный процесс; каждый факт (Run, событие, доказательство, чекпоинт) перепроверяется чтением из базы, а не доверием ответу. Крах после резервации + повтор сходятся к тому же запуску — без дублей и потерь.

Две ночные развилки решены по делегации: зона задачи выросла с 4 до 6 путей (переходник активации в общем файле — без сырого доступа и второй базы; устаревший тест мигрирован с усилением — старый способ вызова отвергается навсегда). Оба условия закреплены в плане дословно. Моё 6‑лучевое ревью: 2 мелких сомнения, оба опровергнуты перекрёстной проверкой — PASS.
вехаSQLite · M3‑012Cutover завершён — старая файловая машина физически отрублена

Самая ответственная задача среза закоммичена (6479325) и сверена мной побайтно (7/7 файлов с якорем). Продакшн теперь открывает ОДНУ базу на роль (web/runner/outbox), двойная запись невозможна: оба старых способа запуска отвечают 503 через счётчик‑страж (не заблокировал ровно один раз → сборка падает), живая команда честно «пока недоступна» до M3‑001.

Три развилки за ночь — все решены по плану: спящий тест BOOT‑011 отложен отдельной задачей (не трогаем); каталог базы уведён из папки неизменяемых квитанций в отдельный корень с точечным .gitignore; граница с M3‑001 зафиксирована (живой запуск — следующая задача, не эта). Командир поймал каждую до заморозки, я подтвердил и решил как owner‑proxy; всё под моим именем, обратимо.
вехаSQLite · M3‑008…011Ещё четыре домена перенесены — импорт старых данных закрыт чисто

Закоммичены и независимо сверены из git: проекция/checkpoint из фактов (M3‑008, дефект №11 мёртв), candidate‑реестр (M3‑009, мой давний PID‑lock убит), stage‑артефакты с crash‑safe публикацией (M3‑010, гонку одновременной публикации поймал командир — я пропустил в спешке, потом перепроверил), и импорт старых данных (M3‑011).

M3‑011 — образцовое приземление: полный прогон 48/48, два независимых ревью PASS (командир + моё из 6 состязательных лучей + личные спот‑проверки), коммит 9dfaae4 сверен мной побайтно (16/16 файлов совпали с якорем, parent верный). Подделку «пропуска» закрыли неподделываемым делегат‑WeakMap; старый баг «мёртвый поток держит ключ» физически вырезан; в тестах ноль реальных данных, оракулы не ослаблены. Свою неточность формулировки командир поймал — исправил честно.
вехаSQLite · M3‑003…007Пять доменов перенесены — тяжёлые классы дефектов мертвы

Ядро SQLite и четыре домена закоммичены и независимо сверены из git. По построению убиты классы, из‑за которых горело время: гонки замков, «замок отпущен → запись позже», «унесённый ключ», исходный TOCTOU журнала событий.

Как теперь: история — таблицы под запретом update/delete; переходы — одна транзакция BEGIN IMMEDIATE; владелец записи проверяется соединением; проб живости по PID больше нет нигде. Файловые замки самодельной машины мертвы домен за доменом.
арбитражM3‑007 · 4 блокераМой PASS был отозван — и правильно

Я дал PASS на журнал событий; командир оспорил четырьмя доказанными дырами. Худшая: проверка при записи не сверяла хэш и схему — аккуратная подделка легла бы в неизменяемую историю навсегда.

Итог: перечитал сам — он прав по всем четырём, PASS отозвал, методику ревью ужесточил (import‑блоки целиком, покрытие полей валидаторов). Все четыре закрыты, коммит верный. Двухканальный контроль сработал: ошибка не дошла до истории.
урокканал СоветаПринял свой релей за «врага» — поправил себя

В Совете появились вердикты под моим именем, которых я не писал. Я сгоряча назвал это атакой. Оказалось — та же Codex‑автоматика доставки, что разносит мои конверты, иногда сама говорит от моего имени. Не взлом, а плумбинг под тем же аккаунтом.

Правило после этого: канал — advisory, истина — git. Байты каждого коммита читаю из git сам; каждый вердикт под моим именем сверяю со своим списком отправленного. За всю ночь в историю попало ноль плохих байтов.
консилиумвнешний аудитВладелец заподозрил стратегию — и был прав

«Если у вас кто‑то ключ с собой уносит — стратегия хреновая». Внешний аудит семи файлов подтвердил: проект руками переизобретал транзакционную базу — самодельные замки с проверкой живости по номеру процесса породили 12 дефектов одного класса за двое суток и замедлили работу в 4–5 раз.

Вердикт аудита: перейти сейчас на единую SQLite; файлы остаются для неизменяемых артефактов, Git — для кода. Честная оговорка: SQLite закрывает по построению гонки замков и двойной старт, но четыре дефекта остаются заботой логики. Удаляется ~1000 строк самописного слоя.
вехановая схема управленияКомандиром миграции назначен аудитор

Владелец перестроил контур: аудитор из AUDIT TPV3 единолично командует исполнителем до конца миграции; Claude — глаза (минутная вахта на обоих чатах) и консультант, пишет только командиру; прямые указания исполнителю запрещены.

Первый цикл дал результат: ревью Claude нашло в плане миграции два пропущенных изменяемых хранилища (candidate‑реестр с PID‑замком и stage‑artifact со своей lock‑машиной), ранний финализатор и двусмысленность про крах процесса. Командир проверил каждое по байтам и принял все — план вырос с 8 до 10 задач.
вехаFWD‑SQLITE‑001Первый коммит SQLite‑эры

Поправка четырёх принятых документов закоммичена (b3f3997): план теперь 53 задачи, история неизменяемости переезжает в базу, «унесённый ключ» становится невозможен по построению — ни один ключ не принадлежит потоку, любой процесс дозавершает подготовленную операцию.

Дисциплина цикла: независимое ревью Claude (PASS с одной обязательной правкой — перенос финализатора «крах не застревает ключом» на задачу, где умирает последний замок) вошло в байты ДО коммита. Донорский срез M3‑001 не тронут — 29 путей ждут переноса поверх SQLite.
дефектM2‑002 · ревьюМёртвый поток держал замок вечно

Рабочий поток мог умереть после захвата замка, но процесс оставался жив — замок навсегда считал владельцем текущий процесс. Тихий вечный тупик, который в тестах не падает.

Решено по существу, а не быстро: отвергнуто протухание по времени (иначе живой приостановленный поток «раскулачат» — вернётся потеря данных из M2‑001) и отвергнут просто идентификатор потока (без проверяемой живости ничего не гарантирует). Сделана наблюдаемая живость владельца, которая умирает вместе с конкретным потоком, при сохранении ограждения по точному токену.
дефектM2‑002Чужой экземпляр проходил как свой

Реестр принимал «подлинный» объект от любого экземпляра через глобальную проверку модуля: два реестра в одном процессе — и чужое становилось своим.

Решено: изменение жизненного цикла возможно только при паре точно связанных проверяльщиков; сценарий «плана ещё нет» при этом остаётся рабочим.
арбитражM2‑002 · 1 раундУстаревшее ожидание против правила эры

В запечатанном тесте лежали четыре ожидания «производителя не существует», а задача как раз создавала этих производителей — ожидание стало заведомо ложным.

Решение Claude: разрешена замена только кода отказа в четырёх местах, без правки логики; с двумя предохранителями — если ветка станет недостижимой, доложить, не удалять; иное устаревшее — списком. Агент выполнил не формально: нашёл, что при дрейфе указателя первым обязан срабатывать защитный отказ, и сделал точное ветвление вместо слепой замены.
вехаСрез 2Каталог планов закрыт целиком

M2‑002: финальный прогон 41/41, независимое ревью PASS без замечаний, все 12 файлов и дерево совпали с доказательствами.

Итог: коммит a21a2560 ровно на подготовленном дереве от точного родителя. План теперь рождается своей папкой с самого начала и имеет реестр принятых версий с родословной.
консилиумM2‑001 · 2 раундаФайлы разрослись вчетверо против бюджета

Пять новых модулей вышли на 400–1300 строк против архитектурного бюджета в 400. Варианты: сжать код в тех же файлах, отложить долг до среза 9, объявить бюджет неприменимым — или разложить по смыслу сейчас.

Решение Claude: разложить сейчас, разрешено ровно 14 путей. Отклонено: сжатие (убивает читаемость ради арифметики), отсрочка (к срезу 9 рефакторинг лёг бы на код с десятками потребителей), «бюджет не применим» (подмена понятий). Условия: запечатанный код не трогать ни байтом, новых циклов не создавать, наружу не выпускать ничего пишущего.
поправкавладелец · бюджет модулейПорог 400 строк — ориентир, а не приговор

Жёсткий порог сам оказался бюрократией: файл на 401 строку не хуже файла на 399, а дробление ради цифры вредит. Первая формулировка Claude ошибочно ввела и нижнюю границу.

Итог (двумя поправками владельца): шкала односторонняя — до 400 свободно и без нижнего порога (файл на 90 строк нормален, добирать объём запрещено); 400–460 зона внимания с короткой аргументацией; свыше 460 только с сильным аргументом неделимости. Симметрично запрещено дробление ради цифры — «часть 1 / часть 2» ловится автоматически по имени, связности экспортов и взаимному импорту.
дефектM2‑001 · ревьюУстаревший план мог быть допущен к исполнению

Второй живой реестр восстанавливал закешированное состояние уже после того, как первый атомарно сдвинул указатель на новое — и разрешал старый план. Окно между проверкой и использованием, которое кеш обходил сбоку.

Решено: любое восстановление начинается с перечитывания точных байтов владельца; ссылка без перечитанных байтов не принимается никогда.
дефектM2‑001 · ревьюПерехват замка мог стереть историю

Восстановление после зависшего замка не ограждалось токеном: замороженный сигналом старый писатель мог проснуться после перехвата аренды и перезаписать более новую историю; бесхозный писатель мог снести чужой замок. Это потеря неизменяемых данных, а не просто подвисание.

Решено: ограждённые замки для обоих пакетов + перечитывание актуального указателя владельца под тем же ограждением. Плюс закрыты две смежные дыры: прямой импорт выдавал право записи без brand; первая публикация писала в финальный файл (заменено на temp → fsync → link).
консилиумM2‑001 · раунд 2Агент опроверг решение Claude — и был прав

Claude в первом раунде решил, что цикл в архитектуре держится на паре мелких утилит. Агент проверил байты и возразил: нижний пакет-хранилище физически владел записями реестра планов — регистрациями и состоянием жизненного цикла. Это инверсия владения, а не утилиты.

Claude признал ошибку и переиграл: реестр забирает свои записи себе, хранилище остаётся нижним слоем, который умеет только положить файл и проверить его. Плюс жёсткий порядок при обрыве и главное — право на запись выдаётся заново после перечитывания байтов, а не восстанавливается из файла, поэтому подделать его нельзя. Разрешено ровно три дополнительных файла.
вехаM2‑001Самая тяжёлая задача проекта закрыта

Три часа, четыре цикла ревью, ни одного повтора дефекта. Внутри оказалось три сросшихся работы: жизненный цикл плана, архитектурный переезд владения данными и самые тонкие в проекте вещи — конкурентные писатели, ограждённые замки, поведение при обрыве между двумя записями.

Итог: continuation‑ревью PASS, все 27 хэшей совпали, автокоммит на проверенном дереве. Это ровно тот класс дефектов, что в старой версии всплывал бы через месяц как «интерфейс показывает не то».
вехаBOOT · весь блокИсполнительная машина построена и активирована

11 задач за ночь, каждая через полный цикл без единой ручной паузы. Автокоммиты сверены по git байт‑в‑байт: дерево и родитель всегда совпадали с проверенными.

дефектBOOT‑002Мок был зелёный, а прод отказал бы всегда

Ревью нашло: порт ждал поле artifactSha256, а реальный адаптер выдаёт adapterSha256. Юнит‑тест на моке проходил, но живая интеграция всегда бы падала — классический «мок врёт».

Решено: одной пачкой из трёх файлов (порт + оба мока), continuation того же ревьюера → PASS. Лучшая реклама независимого ревью.
пачкаBOOT‑005Три гонки планировщика — закрыты одним заходом

Ревью нашло три P1 по конкуренции: возврат claim на старый Run, повреждения записей, потеря при 32 одновременных записях из 4 процессов.

Решено: по правилу владельца «пачки вместо капельницы» — все три починены и проверены одним повторным прогоном, а не тремя. Durable claim до запуска host, общий файловый lock, 1:1‑замыкание reservation↔Run↔outbox.
консилиумBOOT‑011 · 2 раундаФикс требовал войти в уже запечатанную задачу

Дефект необратимой двери активации жил в модуле BOOT‑003 — вне зоны записи текущей задачи. Архитектор не полез туда тихо, а вынес вопрос на арбитраж.

Раунд 1: Claude отверг «второй producer» — это два писателя одной сущности, нарушение инварианта. Раунд 2, решение Claude: ограниченное расширение зоны на 2 файла — принято, но с тремя обязательными инвариантами: descendant только по явному recovery‑opt‑in; verifier фиксирует observedHeadOid, materializer обязан увидеть тот же HEAD; first‑parent доказывается цепочкой OID, не через merge‑base.
дефектBOOT‑011 · активацияМашина впервые применила собственную дверь восстановления — на себе

В момент активации всплыла реальная дыра: git diff-tree без NUL‑режима, из‑за чего Git закавычил не‑ASCII путь и валидатор принял кавычки за имя файла.

Решено: починка ушла repair‑descendant’ом — новым коммитом поверх, ровно тем механизмом «после CAS → reconcile», который BOOT‑011 и строит. История НЕ переписана, инвариант «проверили = закоммитили» цел.
консилиумревью кода · 5 ревьюеровНезависимая оценка всего кода BOOT

Пять ревьюеров прочитали весь закоммиченный код построчно. Итог ~8,0 / 10: инварианты 8,7, архитектура 8,3, корректность 8,1. Ни одной дыры уровня P1.

Решено: найденные P2 и пробел негативных тестов оформлены НЕ отдельным реестром, а листом долга — каждый пункт закрывается той M‑задачей, что поднимает модуль в production. Первый пункт (bundle-artifact) уже гасится в M2‑001.
дефектM1‑001Валидный intent назывался «повреждённым»

Crash‑window: Discovery‑intent записывался до регистрации в памяти, и холодный старт называл этот валидный intent «corrupt», делая восстановление невозможным.

Решено: resume по той же точной command/root‑идентичности; конфликтующая команда по‑прежнему отклоняется. Класс, который старый тест с повторным использованием объектов не видел.
Обновляется по ходу строительства · 67 / 109 карточек плана (счёт по карточкам; ремонты и FWD‑пакеты не считаются) · срезы 1–8 закрыты · текущая задача M9‑035 · 0 заглушек, 0 откатов, 0 плохих байтов · обновлено 18.08 · исходник: ~/REPORTS/v3-build-log/v3-build-log.html