20 KiB
ДОФИКС платформенному паку P13 «шов возврата оплаченного прогона» — по приёмке оркестратора №22 (03.09.2026)
⚠⚠ АРХИВ. НАРЯД ОТРАБОТАН — ИНСТРУКЦИИ ОТСЮДА НЕ ИСПОЛНЯЮТСЯ. Выдан 03.09 по приёмке пака P13, отработан той же сессией, принят (
D39.188). Исход: П1–П3 и П6 исполнены и красны на двадцати посадках приёмки; П4 зона ОТКАЗАЛАСЬ исполнять — и отказ был ПРАВ, предпосылка наряда на её дереве была ложной (ряд стоялopen, гейт и база согласованно печатали 12). Остаток — П5, записка о предусловии хоста; он пунктом 4 выданного пакаPLATFORM_EXPORT_SESSION_PROMPT.md.
Роль: платформа, та же сессия, что отработала пак P13. Зона записи:
platform/. Чужие зоны читаешь, не правишь. Не коммитишь и не трогаешь индекс и историю — запреты и причина:CLAUDE.md, «Git-координация мультисессий». Норматив —platform/docs/ENGINEERING_STANDARDS.md. ⛔ В индексе сейчас лежит НЕЗАКОММИЧЕННАЯ работа двух смен (46 файлов). Ни одной пишущей git-команды: ниcheckout, ниrestore, ниstash, ниreset, ниclean, ниadd, ниcommit.
Что это и почему оно пришло
Пак принят с дофиксом. Приёмка шла исполнением: десять линз, каждая находка ушла опровергателю с мандатом её ОПРОВЕРГНУТЬ своей командой. По платформе 24 находки, 18 пережили опровержение.
⚠ Главное сначала: правку тейлера НЕ ревертировать. Заказанное свойство она даёт, и приёмка
подтвердила все три границы промта. Твой PD-438 — сильная работа: ты нашла, что заказанное мной
пере-упорядочивание расширяло класс, доказала это до и после правки и вылечила глубже. Дофикс не про
это.
Карта чтения — три позиции
- Этот файл. Прежний промт
docs/PLATFORM_P13_SESSION_PROMPT.mdперечитывать целиком не надо. - Свой журнал
platform/docs/platform-PROGRESS.md, запись 03.09 — по П5–П6 правится он сам. - Улики ниже. Каждая воспроизведена приёмкой; воспроизведи сама — не воспроизводится, значит находка, неси пингом.
П1 [важное] — обоснование парковки ОПРОВЕРГНУТО исполнением; сама парковка остаётся
tail.go:157-159 утверждает абсолютно: «Nothing of ours can follow: the engine writes events only
under the project's exclusive flock … so a foreign handshake in this journal means our process no
longer holds it». Из этого выведено «попытка вот-вот закрывается свипом, вред ограничен по времени» —
и это записано в PD-438.
Опровергнуто путём, который лежит в этом же дереве. При повторном запуске ТОЙ ЖЕ попытки платформа
отдаёт тот же id (internal/runs/spawn.go:171 → engineStreamID(l.RunID, l.AttemptNo)), а движок
отказывается переиспользовать уже писавший id и минтит свежий (backend/internal/pipeline/events.go:80
→ fresh := obs.NewTraceID()). То есть «чужой» hello в журнале пишет живой процесс нашей же
попытки. Приёмка воспроизвела это своим probe-тестом на копии бэкенда (двойной openEmitter с одним
и тем же id на одном store).
Последствие, которое надо назвать честно: прогон уходит в полную немоту на весь свой срок — курсор
припаркован, ошибки нет, карантина нет (значит колонка QUARANTINE пуста, гейдж
quarantined_attempts его не считает, run unquarantine отвечает ErrNotQuarantined), а maybeResync
такую попытку пропускает (internal/runs/reconcile.go:806 — l.Position.LastSeq > 0 && !l.Quarantined).
Пользователь весь прогон видит замерший прогресс. ⚠ Опровергатель сузил радиус: путь — конъюнкция двух
признанных сбоев (претензия на юнит, отчитавшаяся ошибкой + исчезновение юнита без exit-marker), а не
рядовой рестарт. Вес от этого падает, но обоснование остаётся ложным.
Делай РОВНО так: (1) снять абсолютное «Nothing of ours can follow» в tail.go:157-159 и
формулировку «вред ограничен по времени» в ряде PD-438 — заменить на то, что верно; (2) дать
припаркованной попытке наблюдаемость: сегодня у этого класса нет ни одного из трёх сигналов,
которые были у карантина.
Решаешь сама и аргументируешь: ЧЕМ именно её сделать видимой — счётчиком, отдельной причиной,
включением в maybeResync, колонкой или новым рядом регистра под отдельный пак. Дорогое решение
здесь не заказано: назвать проблему и предъявить минимум — законный исход.
П2 [важное] — гейт батареи заявляет покрытие, которого у него нет; PD-374 как КЛАСС не снят
Докблок обещает: «What it asserts is all three columns: the NAME appears, the STATE follows the host rather than a word». По факту состояние сверяется у одной строки из восьми:
platform/internal/gates/battery_test.go:60-66 — два регэкспа только на TM_PLATFORM_TEST_DSN
(UNSET / set); у systemd проверяется лишь, что строка есть в любом состоянии
Приёмка воспроизвела ТРИ независимые дыры, каждую своей мутацией на копии:
- состояния семи остальных условий можно заморозить литеральной ЛОЖЬЮ —
state=MISSINGна присутствующих бинарях иUNREACHABLEна живом systemd:make conditionsпечатает ложь про хост, гейт зелёный; - обратного направления нет: вставлены выдуманные
TM_PLATFORM_TEST_DEAD_KNOBи бинарьffmpeg«read by: internal/ghost» — печатаются, гейт зелёный (положительный контроль: грепа этих имён в дереве нет); - подсказка и гейт выводят из ОДНИХ И ТЕХ ЖЕ двух якорей: тест, читающий
os.LookupEnvвместоos.Getenv, реально скипается, вmake conditionsне появляется, гейт зелёный. В обратную сторону пакет, лишь УПОМЯНУВШИЙ вызов в комментарии, зачисляется в читатели — вопреки собственному докблоку.
⇒ Первый же новый тест, написанный другой идиомой, возвращает зону в состояние PD-374 при зелёной
батарее и зелёном гейте.
Делай РОВНО так: сверять состояние по хосту для КАЖДОЙ строки, а не для одной.
Решаешь сама: как закрыть обратное направление (строка перечня → исходники) и расширять ли набор
идиом; если считаешь, что «второй карьер факта» тут недостижим — скажи это аргументом.
⚠ До этого PD-374 не считать снятым как класс — экземпляр вылечен, класс нет.
П3 [важное] — три калитки нового гейта класса
- (а)
accepted-riskуводит ряд из класса молча. Приёмка заменила статусPD-162(open, minor, «деньги + холд + блокир») наaccepted-risk:go test -run TestOpenRowsвыходит нулём, счёт падает до 10, а единственная строка — «PD-162 has left the class legitimately» — идёт черезt.Logfи не начинается сALARM, поэтому лифтер целиcheck(grep -o 'ALARM PD-.*') её не поднимает. Это ровно та калитка, против которой гейт и построен. - (б) фильтр «ниже major» слеп к весу ВЫШЕ major.
strings.Contains(r.weight, "major"), а словарь реестра содержит**BLOCKER**. Открытая BLOCKER-строка читается как «below major» и краснитmake check, причём совет в самом сообщении («either its weight is major») предлагает понизить вес самой громкой строки. Воспроизведено вставкой| PD-997 | bug | **BLOCKER** | … | open |. Сегодня латентно — все три BLOCKER-строки закрыты, — но словарь живой. - (в) при прозаическом статусе сообщение называет неверную причину. Гейт печатает «is in
alarmBaseline and no longer a row of the register: … this is a gate reading the wrong document», хотя
документ верный и строка на месте — причина в прозе статуса. Соседняя ветка гейта такую строку уже
умеет отличать (она печатает её в списке
PD-439).
Делай РОВНО так: (а) и (в) закрываются. Решаешь сама: форма — поднимать ли уведомление об
уходе до ALARM, ужесточать ли словарь дверей, и что делать с (б) — чинить фильтр или объявить
BLOCKER частью класса.
⚠ Решение про PD-439 (семь рядов со статусом вне словаря) — на оркестраторе, и от него зависит,
какой из двух путей в (в) законен. Упрёшься — пинг, не догадка.
П4 [мелочь] — alarmBaseline и числительное протухли ПОСЛЕ сдачи
register_test.go:52-53 всё ещё несёт PD-168, который акт лендинга перевёл в fixed(e85295d); гейт
на каждом прогоне печатает ALARM PD-count: 11 … (baseline 12) и собственное поручение. Комментарий
:151 («the same twelve rows») и таблица живых проб в журнале зоны говорят «12».
⚠ На сданном тобой дереве 12 было ВЕРНО — число протухло от закрытия ряда актом лендинга, это не
твоя ошибка. Но правится в зоне: делай РОВНО так — снять PD-168 из базы, поправить числительное,
снять «12» из таблицы живых проб. По существу довод комментария жив: оба прочтения дают один и тот же
список.
П5 [мелочь] — записка о предусловии хоста неверна, и цена этого — потерянный старт следующей смены
Журнал зоны (platform-PROGRESS.md:39-40 и :357) заявляет «Postgres на 5432», «~/go/bin не
существует», «sqlc и golangci-lint в ~/.local/bin, уже в PATH, make tools-check → 0».
На этом хосте: ~/go/bin существует и держит sqlc (mtime 30.08, ДО смены), в ~/.local/bin
его нет, make tools-check на дефолтном PATH даёт «got: none», живой сокет — только
/tmp/.s.PGSQL.55433. Это ровно тот класс, что лечит твой же пункт 4: подсказка, отправляющая
читателя не к той ручке.
⚠ Записка ссылается на подтверждение владельца, что промт писан на другой машине. Делай РОВНО так: либо привести записку к замеру на ЭТОМ хосте, либо вписать явно, что условия хоста замерены на другом и здесь не проверялись. Молчаливое расхождение недопустимо — следующая смена теряет на нём заход.
П6 [мелочь, по желанию] — RunBudget без пина в своём пакете
Подмена «читать ПОСЛЕДНИЙ холд вместо холда первой попытки» оставляет go test ./internal/pgstore/
зелёным; ловит её только соседний пакет (internal/runs/sweep_test.go:1663). Соседний денежный
читатель того же файла, RunSpent, пин в своём пакете имеет — то есть это асимметрия, а не норма.
⚠ Опровергатель понизил вес: штатная батарея зоны — go test ./... -race, так что «зелёный пакет»
достижим только ручным прогоном одного пакета, и дыры в защите инварианта нет.
Решаешь сама: заводить ли пин; отказ аргументируй.
Границы — что НЕ делать
- ⛔ Правку тейлера не ревертировать и границы не двигать: отказ по декоду остаётся ВЫШЕ,
понижение только при известном
want, приwant == ""валидация ПОЛНАЯ. Приёмка все три проверила. - ⛔ Не трогать форму манифеста, схему хранилища движка, версию контракта,
docs/scripts/counts.py. - ⛔ Не решать за оркестратора
PD-439и не переносить ряды между секциями регистра — статус и переезд суть акт лендинга, он их и делает. - ⛔ Не трогать бэкенд-половину индекса,
.env, соседний worktree.
Что приёмка ПРОВЕРИЛА и признала — переделывать не нужно
make checkпод всеми четырьмя условиями хоста:0 issues, 18 пакетовok, три SKIP и все три отENGINE_BIN. ДефектPD-374предъявлен вылеченным вживую: при выставленном DSN рецепт больше не посылает к DSN.- Перечень условий выводится из исходников по ВЫЗОВУ, а не держится списком в прозе — это сильнее заказанного.
- Оба новых гейта посажены мутацией приёмкой и оба КРАСНЕЮТ (выброшенный цикл
LookPath; дописанные слова тревоги в открытый не-major ряд). - Тейлер: три границы соблюдены, зелёный пин
TestAnotherAttemptsStreamInTheSameJournalIsSkippedжив, два прохода подряд идемпотентны, чужие события на нашу попытку не ложатся. reopenчитает бюджет из холда в обеих точках, прогон без первого холда отвечается ошибкой.- Пин
heldв ветке чужого handshake'а: приёмка исполнила заявленную им мутацию — ловится, обвинение в фиктивном покрытии снято. - Строка рантбука исправлена верно;
PD-436заведён. - Число «55 посадок» против «60 строк таблицы» — расхождение снято: это ДВЕ таблицы, не одна.
Мандат самопроверки — исполнением
- Каждый пункт П1–П6 проверяется своей командой, выход — цитатой в отчёте.
- Мутации сажаются на копии (
cp -a platform /tmp/…), гейты предъявляются КРАСНЫМИ на своей мутации и зелёными после её снятия. - Отдельный проход по своей готовой работе свежим контекстом. Субагенты разрешены явно, модель ИМЕНЕМ, число знай.
- ⚠ «Прошла, находок нет» отчётом не является — ноль обосновывается тем, ЧТО искалось.
Отчёт
В platform/docs/platform-PROGRESS.md (в docs/PROGRESS.md платформа НЕ пишет). Пройди по каждому
пункту П1–П6 и отчитайся по каждому. Каждое число — с командой получения; приёмка пере-ранит.
⚠ Гейты и счёты гнать ПОСЛЕДНИМ действием, после того как текст дописан: на прошлом круге число
«12» протухло именно потому, что было снято до последней правки.
Обязательная секция «Что НЕ удалось и что НЕ проверено» — третий исход законен.
Прямой канал
Механизм — CLAUDE.md, «Связь между сессиями»: свой блок в /tmp/textmachine-channel, сверка с
ListAgents перед отправкой; канала нет — нормальный случай, сессии подряд не опрашивать.