345 lines
38 KiB
Markdown
345 lines
38 KiB
Markdown
# Бэкенд-пак: КУПЛЕНО — ЗНАЧИТ ДОСТАВЛЕНО. Юнит, который не доделается НИКОГДА
|
||
|
||
> Выдан оркестратором №23 (сессия `textmachine-11`) 11.09. Пак **$0** — платных вызовов в нём нет.
|
||
> Предмет решён владельцем 05.09 (`D39.204`); ты строишь решённое, а не выбираешь между вариантами.
|
||
|
||
## 1. Какая проблема и что решит твой результат
|
||
|
||
Читатель заплатил за главу. Движок купил первую попытку, получил флагуемый результат, пошёл за второй — и
|
||
**вторую ему не продали**: потолок книги или дня не вмещает резерв регенерации. ⚠ **И тут точность несущая,
|
||
первая редакция промта её теряла:** `maxTokensForAttempt` удваивает **только ВЫХОДНОЙ** бюджет, а резерв
|
||
считается оценкой по цене, промпту, потолку и буферу размышления (`backend/internal/pipeline/stagerun.go`,
|
||
греп `EstimateUSD`) — промпт и аддитивный буфер НЕ удваиваются. Значит «попытка 1 стоит ×2» — неправда, и
|
||
окно, в котором отказ неизбежен на ≥1 и невозможен на 0, считается по РЕАЛЬНОЙ оценке.
|
||
|
||
Дальше происходит вот что, и это проверяется одной строкой: **`backend/internal/pipeline/stagerun.go:204`=`infra failure; the cancelled-position mark`** — ЛЮБАЯ ошибка попытки уходит наверх из цикла, **РАНЬШЕ `UpsertChunkStatus`**.
|
||
|
||
**Следствия два, и оба стоят денег читателя:**
|
||
|
||
1. **Юнит не доделается НИКОГДА.** Чекпойнт попытки 0 есть (реплей за $0), строки `chunk_status` НЕТ ⇒
|
||
читающие модели видят юнит как `pending`, экспорт не отдаёт ничего. Каждый резюм реплеит попытку 0 за
|
||
$0 и умирает на попытке 1. **Прогон уходит `exit 4` при ПОЛНОСТЬЮ доставленных купленных юнитах.**
|
||
2. **Волну нельзя продолжить без ДЫРЫ в непрерывном префиксе** — то есть за это платят и соседние юниты,
|
||
которые в бюджет влезали (разброс резервов внутри волны замерен ×2.976).
|
||
|
||
**Решение владельца (`D39.204`, и оно НЕ обсуждается):** отказ резервации на РЕТРАЕ **деградирует во ФЛАГ**,
|
||
причина которого ОТЛИЧНА от исчерпания регенераций; текст попытки 0 оплачен и **отгружается**; волна идёт
|
||
дальше. ⛔ Вариант «минимальная покупка ≥ `step_max_usd`» **СНЯТ** владельцем — он стоил бы покупателю
|
||
входного порога в пять глав. Не реализуй его и не предлагай.
|
||
|
||
⚠ **И канон здесь сильнее, чем кажется:** `D2` п.2 уже ТРЕБУЕТ тегировать `flag_reason`. Значит новая
|
||
причина — не добавка к контракту, а его ИСПОЛНЕНИЕ. (Ссылка «смена `D2.3`», гулявшая по бэклогу, **неверна
|
||
дважды**: `D2` и так кончается флагом, а `D2.3` — про детектор вырождения перед удвоением.)
|
||
|
||
## 2. Зона записи и git
|
||
|
||
- Зона — **`backend/`**, и только она. `platform/` не трогать: её половина едет ОТДЕЛЬНЫМ промтом, но
|
||
**ОДНИМ АКТОМ с твоим** (см. §4.3).
|
||
- **Ты не коммитишь.** Готовое дерево передаёшь мне, я лендлю. `git add -A` запрещён каноном.
|
||
- Свою секцию итогов пиши в `docs/PROGRESS.md` — это единственное исключение из «`docs/` — зона
|
||
оркестратора». Чужие незакоммиченные файлы в дереве не трогай.
|
||
|
||
## 3. Карта чтения — ЗАКОН, дальше только по её ссылкам
|
||
|
||
1. `CLAUDE.md` — целиком.
|
||
2. **Тело `D39.204`** в `docs/architecture/05-decisions-log.md` (решение владельца) и **`D2` п.2** — он в
|
||
закрытой эре, тело в `docs/archive/architecture/05-decisions-D1-D38.md`, греп `^## D2\.`. ⚠ Подномер
|
||
собственного тела не имеет: `D2.3` — это ПУНКТ 3 тела `D2`.
|
||
3. **Ряд 291** в `docs/BACKLOG.md` — там весь разбор, включая **опровергнутую посылку прошлого
|
||
оркестратора**: «ретрай оставляет ФЛАГОВАННЫЙ юнит» — ЛОЖЬ, зона опровергла по строкам. Не наступи
|
||
второй раз.
|
||
4. `backend/internal/pipeline/stagerun.go` (цикл попыток и `runAttempt`), `escalation.go` (`errReserveCeiling`
|
||
и кто на нём УЖЕ деградирует), `disposition.go` (словарь `FlagReason`).
|
||
5. `docs/architecture/12-go-style-notes.md` — нормативы стиля, только больные места.
|
||
|
||
Код-факты добывай сам; `file:line` выше — отправные точки. **Код первичен.**
|
||
|
||
## 4. Состав
|
||
|
||
### 4.1 ⛔ КОНСТРУКЦИЯ ПЕРЕ-РЕШЕНА ВЛАДЕЛЬЦЕМ 11.09 — читай это ПЕРЕД кодом
|
||
|
||
**Слово владельца дословно:** «Надо о таком просто сообщать в виде метаданты, которая сейчас и пишется
|
||
предупреждением, и иметь возможность поднять просто потолок и возобновить прогон, так как **это ситуация
|
||
всё же СТАНДАРТНАЯ СО СТОПОМ, просто он произошёл по какой-то другой причине**».
|
||
|
||
⛔ **Это отменяет обе половины прежнего заказа — и моего, и `D39.204` п.4.** Ни «деградировать во флаг», ни
|
||
«волна идёт дальше» больше НЕ строится. Прежний план заводил новый исход; новый — **возвращает ситуацию в
|
||
УЖЕ ПОСТРОЕННЫЙ штатный путь остановки**, из которого она сегодня выпадает.
|
||
|
||
**Что это значит механически (моё чтение; спорь, если код скажет иначе):**
|
||
|
||
1. **Прогон ОСТАНАВЛИВАЕТСЯ, как при любом отказе по потолку.** Не продолжается с флагом. ⭐ И это заодно
|
||
снимает то, чем ряд 291 пугал: «продолжить волну нельзя без ДЫРЫ в непрерывном префиксе» — при остановке
|
||
дыры не возникает вовсе.
|
||
2. **Отказ ретраю публикует ту же метадату, что и любая остановка по потолку** — кадр
|
||
`Ceiling{Halted, Scope, ShortfallMicroUSD}` (`backend/internal/runevents/runevents.go`, греп
|
||
`ShortfallMicroUSD`). ⭐ **Он уже несёт ровно то, что владелец просит:** «пополни хотя бы на столько, и
|
||
тот же вызов будет допущен» — и это **ратифицировано им же, `D39.203`**. Строить новый носитель не надо.
|
||
⚠ **И твоя находка №2 этим РАЗРЕШАЕТСЯ, а не отменяется:** ты была права, что `ceilingReached`
|
||
идемпотентен по прогонному флагу и съел бы событие настоящей остановки — но теперь съедать НЕЧЕГО: эта
|
||
остановка И ЕСТЬ настоящая. Публикуй через штатный путь.
|
||
3. ⛔ **НАСТОЯЩИЙ ДЕФЕКТ — УЖЕ, чем я написал, и он назван в самом дереве.** Механизм «отметить
|
||
остановленную позицию» построен ИМЕННО против невидимых дыр:
|
||
`backend/internal/pipeline/stagerun.go:142`=`THE MARK FOR A STOPPED POSITION IS ATTACHED TO EVERY EXIT`,
|
||
и его комментарий приводит замер прежнего инцидента — «прогон, остановленный на эскалационном хопе,
|
||
рассчитал деньги и не оставил строки вовсе: `committed=0.001176`, `chunk_status_rows=0`». **Но метка —
|
||
no-op для всего, что не «доставленный вызов, который остановил человек»** (`recordCancelledStage`).
|
||
Отказ по потолку под это не подпадает ⇒ юнит остаётся без строки. **Вот дыра, и вот что ты закрываешь.**
|
||
4. **Поднял потолок → резюм ДОДЕЛЫВАЕТ юнит.** Значит строка, которую ты пишешь, обязана быть
|
||
НЕ-ТЕРМИНАЛЬНОЙ для резюма — по образцу `FlagCancelled`, единственной причины, у которой
|
||
`resolvedForResume` ложен (`backend/internal/pipeline/cutcall.go:293`=`FlagReason(cs.FlagReason) != FlagCancelled`),
|
||
и ложен именно потому, что это «оплачено, но не сделано». Твой случай той же природы.
|
||
|
||
**Делай РОВНО так:** остановка штатная · метадата через уже построенный кадр с недостачей · **юнит получает
|
||
строку, а не пустоту** · строка НЕ терминальна для резюма · после пополнения резюм доделывает.
|
||
|
||
**Решаешь сам и аргументируешь:** как назвать причину в строке юнита (или взять существующую) · где ставится
|
||
метка · как отличить «остановлено на ретрае» от «остановлено на попытке 0» в носителе, и надо ли отличать.
|
||
|
||
⛔ **Попытку 0 не трогать:** её отказ и сегодня останавливает книгу штатно — ратифицировано.
|
||
|
||
⛔ **КТО ПЛАТИТ — НЕ ПРЕДМЕТ ЭТОГО ПАКА.** Слово владельца 11.09: «пока платит за всё ЮЗЕР, потом будем
|
||
решать эту проблему». Механизм «платит продукт» не строить; существующее биллинговое поведение не трогать
|
||
ни в какую сторону, даже где оно выглядит непоследовательным. ⚠ И отдельной строкой отчёта НАЗОВИ (не чини):
|
||
объёмный леджер сегодня считает флагованный юнит НЕ доставленным, то есть грант за него не съеден — это
|
||
расходится со словом владельца и существует ДО твоего пака. Он объявил вопрос отложенным.
|
||
|
||
⚠ **Отгрузка обрезанного текста не строится** — `D2` запрещает отгружать загрязнённое, и это не зависит от
|
||
того, кто платит.
|
||
|
||
### 4.2 Пин, ради которого пак существует
|
||
|
||
**«ОСТАНОВКА, КОТОРАЯ ЛЕЧИТСЯ ПОПОЛНЕНИЕМ».** Три утверждения, и они про разное:
|
||
|
||
1. **Юнит, на ретрае которого отказал потолок, ПОЛУЧАЕТ СТРОКУ.** Сегодня её нет — это и есть невидимая
|
||
дыра. Пин обязан печатать величину, доказывающую, что деньги были потрачены, а строка появилась: пустой
|
||
`chunk_status` рядом с ненулевым `committed` — ровно тот замер, которым дерево описывает прошлый
|
||
инцидент.
|
||
2. **Остановка несёт НЕДОСТАЧУ.** `ShortfallMicroUSD` ненулевой и таков, что пополнение на него допускает
|
||
тот же вызов. ⚠ Пин на «событие вообще есть» вырожден — утверждай ЧИСЛО.
|
||
3. **Пополнил потолок → резюм ДОДЕЛАЛ юнит.** ⛔ **И это ГАРД, а не доказательство лечения — поправка
|
||
исполняющей сессии, принята.** Моё «сегодня второй прогон умирает вечно» НЕВЕРНО: строки у юнита нет ⇒
|
||
гейт резюма не срабатывает ⇒ позиция ре-атакуется, попытка 0 реплеится из чекпойнта за $0, ретрай
|
||
покупается, и при поднятом потолке юнит доделывается **уже сегодня, без пака**. Вечно умирает только
|
||
резюм БЕЗ пополнения. ⇒ этот пин стережёт ратифицированное `D4`, чтобы пак его не сломал, и **на дефекте
|
||
он ЗЕЛЁН**. Так и напиши.
|
||
|
||
⛔ **И отсюда норма приёмки этого пака, которой у нас ещё не было ни в одном:** сними ЦВЕТ КАЖДОГО из трёх
|
||
пинов на дереве **ДО** фикса, числом, и положи замер в отчёт. На дефекте краснеет только первый. «Пин
|
||
зелен» и «пин стережёт» — разные утверждения, и без этого замера они сливаются.
|
||
|
||
⚠ **Про коды выхода.** Прежняя редакция промта требовала `exit 2` вместо `exit 4`. **Снято:** при штатной
|
||
остановке код остаётся тем, каким он и был для остановки по потолку. Предмет пака — не смена кода выхода, а
|
||
то, что за ним стоит: **строка вместо пустоты и лечимость пополнением.**
|
||
|
||
⚠ **Два гейта поймают тебя сами — назову, чтобы не терять круг:** `TestEveryFlagReasonIsRanked` потребует
|
||
завести новую причину в `flagSeverity` (`backend/internal/pipeline/status.go`), если ты её заводишь, а
|
||
`TestEveryOperatorMessageIsCatalogued` — внести новое сообщение в
|
||
`backend/internal/pipeline/testdata/operator-messages.txt` (сегодня в каталоге 134 строки, из них о потолке
|
||
уже говорят четыре — посмотри их прежде, чем писать пятую).
|
||
|
||
### 4.3 ⛔ ДЕФЕКТ, КОТОРЫЙ ТВОЙ ПАК НАКОРМИТ — и он НЕ латентный. Чинить ЗДЕСЬ
|
||
|
||
Нашла исполняющая сессия, посылку я пере-проверил и **она у неё неверна в СТОРОНУ МЯГКОСТИ**.
|
||
|
||
`backend/internal/pipeline/quality.go` (греп `draftEchoRecovered`) считает эхо ВОССТАНОВЛЕННЫМ по одному
|
||
признаку — `FirstFlagReason == cjk_artifact`, — **не спрашивая, флагована ли строка сейчас и чем**. Денежный
|
||
отказ эхо-рероллу даст ровно эту картину: первый флаг — эхо, итоговый — денежный, реролла не было, а отчёт
|
||
скажет «восстановлено».
|
||
|
||
⛔ **Сессия назвала это латентным «потому что ключ 0». Ключ НЕ ноль:** `regenerate_echo_before_escalate: 1`
|
||
стоит **во всех ЧЕТЫРЁХ боевых конфигах** (`backend/configs/pipeline-c1.yaml`, `-c2`, `-arm-glm`,
|
||
`-arm-mistral` — сверено мною по каждому). ⇒ дефект оживает **в день лендинга твоего пака**, а не когда-то
|
||
потом. **Чини его в этом паке и пинь** — «диспозиция в отчёте» здесь недостаточна.
|
||
|
||
### 4.4 Платформенная половина — **твоё дело назвать, не построить**
|
||
|
||
Карта заметок платформы **РУКОПИСНАЯ** (`platform/internal/ingest/notes.go`) и уезжает независимо от
|
||
словаря движка. Цена несделанного **замерена**: `PD-246` — минор 0.10.0 сутки жил ЛОЖНЫМ на проводе, причина
|
||
доезжала читателю как `unspecified`, и поймала это зона своей пере-проверкой ПОСЛЕ слов оркестратора
|
||
«приёмка закончена».
|
||
|
||
⇒ **отдельным пунктом отчёта** назови мне: точное значение новой причины на проводе · что платформа обязана
|
||
записать прогону, который кончился флагом вместо `exit 4` · какой её пин это стережёт. Я передам это
|
||
платформенной сессии, и **акт будет один на две половины**.
|
||
|
||
⚠ **И следствие, которое стоит назвать сразу, потому что оно про деньги читателя:** объёмный леджер считает
|
||
флагованный юнит НЕ доставленным (`backend/internal/pipeline/volume_test.go`, греп
|
||
`TestAFlaggedUnitIsNotReportedAsDelivered`). Значит грант за него не съеден, а книга честно короче — это
|
||
хорошая новость, но она обязана быть СКАЗАНА в отчёте, иначе следующая смена откроет её заново.
|
||
|
||
### 4.5 Приложение — ДВА пина, краснеющих по УДАЧЕ (ряд 379, ОБЕ половины)
|
||
|
||
Отдельная от §4.1 работа; делай её ПОСЛЕ основной. ⛔ **И мой диагноз здесь был НЕВЕРЕН — опровергнут
|
||
замером, а не мнением. Читай, чем именно, иначе повторишь мою ошибку.**
|
||
|
||
**Половина (б).** Запись каталога `CUTCALL-a-refusal-pays-when-the-reply-outruns-the-write` стережёт самую
|
||
дорогую половину денежного бита `delivered()`
|
||
(`backend/internal/llm/attemptcut.go:189`=`answered && t.firstByte.Load()`): провайдер ОТКАЗЫВАЕТ и рвёт
|
||
коннект, пока наше тело ещё пишется — байт ответа есть, статуса в руках нет, и чтение «байт = доставка»
|
||
оплачивает сметой каждый отказ (замер прежнего пака: 22 отказа из 25, один на $0.80).
|
||
|
||
**Два независимых замера на посадке (снятие `answered &&`), и они расходятся:** мой — **7 красных из 8**
|
||
(снят на нагруженной машине, рядом шла батарея); опровергателя на спокойной — **8 из 8**, а на сорока
|
||
процессах **39 FAIL / 1 PASS**. ⇒ пин краснеет по УДАЧЕ, это подтверждено обоими; частота зависит от
|
||
нагрузки, и поэтому «восемь красных подряд» **не является критерием приёмки**: сегодня, без единой правки,
|
||
восьмёрка выпадает примерно в 82 случаях из 100.
|
||
|
||
⛔ **А вот ПРИЧИНА не та, что я написал.** Я заказывал «сделать приход байта ответа НЕИЗБЕЖНЫМ до обрыва».
|
||
Зонд опровергателя (40 итераций, печать того, что реально получил клиент) дал **39 × обрыв с отказом
|
||
записи и 1 × ПОЛНЫЙ `401`**, и ни разу — «ни куска, ни статуса». То есть байт приходит практически всегда,
|
||
а мутант выживает в ДРУГОМ случае: клиент успевает вычитать `401` ЦЕЛИКОМ, `Do` возвращает не ошибку
|
||
записи, а ОТВЕТ, и `delivered()` не спрашивают вовсе — ошибка уходит статусной веткой. **Моё лекарство
|
||
било по половине, которая и так держится, и увеличивало вероятность ровно того исхода, в котором мутант
|
||
выживает.** (И «~6 МБ тела» тоже неверно: 11.0 МБ — Go не эскейпит кириллицу в JSON.)
|
||
|
||
**Задача — делай РОВНО так в части ЧТО, способ твой:**
|
||
1. **Тест утверждает СВОЮ ПОСЫЛКУ и печатает её:** что `Do` вернул ошибку ЗАПИСИ и что трасса видела
|
||
первый байт. **Сценарий не состоялся ⇒ тест КРАСНЫЙ**, а не зелёный «мимо предмета». Сегодня он зелен и
|
||
на полном `401`, то есть на другом предмете.
|
||
2. **Прямой табличный пин на сам `delivered()`** — он убивает посадку `answered &&` детерминированно, без
|
||
гонки вообще.
|
||
3. ⚠ У фикстуры `MaxAttempts: 3` — до трёх бросков кости на один `Complete`; **границу утверждай ПО
|
||
ПОПЫТКЕ**, а не по итогу вызова.
|
||
|
||
**Половина (а) — её первая редакция промта не заказывала вовсе.** Тот же ряд 379 несёт вторую половину:
|
||
две строки таблицы девяти в `backend/internal/pipeline/cutcall_test.go:402`=`time.Sleep(50 * time.Millisecond)`
|
||
разводятся ОКНОМ СТЕННЫХ ЧАСОВ, и по какую сторону границы заголовков сел `cancel()`, не утверждается
|
||
ничем — замер приёмки дал **2 красных из 8**. **Ряд закрывается ТОЛЬКО вместе с этой половиной.**
|
||
|
||
⛔ **Критерий приёмки берётся из самого ряда 379, он сильнее моего:** «каждый из двух пинов **ПЕЧАТАЕТ
|
||
величину, доказывающую пройденную границу, и ПАДАЕТ, когда сценарий не состоялся»**.
|
||
|
||
## 5. Где этот пак мягкий — четыре места, назвал я, веер и глубину выбираешь ты
|
||
|
||
Мандат самопроверки — **исполнением**; субагенты разрешены явно. Адверсариальный проход по СВОЕЙ ГОТОВОЙ
|
||
работе обязателен.
|
||
|
||
1. ⛔ **Пин, утверждающий только молчание, вакуумен ровно там, где сообщение ложно.** «Ошибка не вышла
|
||
наверх» — утверждение о молчании. Фикстура обязана быть такой, где новая причина ОБЯЗАНА прозвучать, и
|
||
тест утверждает её ИМЯ.
|
||
2. ⛔ **Фикстура обязана сделать отказ резервации НЕИЗБЕЖНЫМ на попытке ≥1 и НЕВОЗМОЖНЫМ на попытке 0** —
|
||
и окно считается по РЕАЛЬНОЙ оценке резерва, а не по «×2» (см. §1).
|
||
Денежный пин, флейковый на мутанте, измеряет пустой сценарий: у нас уже был пин, дававший 2 красных из
|
||
8, потому что деньги были ВЕРОЯТНЫ, а не неизбежны. Гоняй свой не один раз.
|
||
3. ⛔ **Посадка обязана бить в тот же слой, что стережёт пин.** За прошлый пак мутация трижды оказалась не
|
||
про то: недостижимое условие в фикстуре · не собирающаяся посадка (НЕизмеренная — хуже выжившей) · код
|
||
против гейта над данными.
|
||
4. ⛔ **Новая причина — факт ПРОВОДА, а не словаря.** Тест, проверяющий только, что константа добавлена в
|
||
`FlagReason`, не доказывает, что читатель её увидит. Скажи, чем предъявлена дорога от флага до
|
||
отчёта/экспорта.
|
||
|
||
⚠ И общее, стоившее трёх смен подряд: **зелёная батарея плюс полный мутационный каталог сходимостью НЕ
|
||
являются.** В последних трёх паках направленный второй читатель находил 6, 7 и 9 дефектов при полной зелени.
|
||
|
||
### ⭐ Адверсариальная стойка — способ смотреть, не правило пака
|
||
|
||
- ⛔ **Автор и ревьюер — разные роли, даже когда это один ты.** Перечтение своей работы рубежом не
|
||
считается: поднимай читателя, которому НАЗВАНО, где мягко.
|
||
- ⛔ **Спрашивай у аномалии, о ЧЁМ она — о предмете или о твоём приборе.**
|
||
- ⛔ **Верный результат при неверном методе не краснеет нигде.** «Сошлось» — не доказательство.
|
||
- ⛔ **Утверждение о молчании вакуумно** без фикстуры, где оно ОБЯЗАНО прозвучать.
|
||
- ⛔ **Заимствованное число проверяется не на существование, а на ТУ ЛИ КЛЕТКУ:** та же роль, та же модель,
|
||
та же стадия, тот же режим?
|
||
- ⭐ **Главный вопрос отчёта — не «что не получилось», а «что ты знаешь и не сказала».**
|
||
|
||
### ⭐ Находки ВНЕ заказа — отдельный заказ владельца
|
||
|
||
Слово владельца 11.09: **находить проблемы даже там, где мы не ждём.** Задавай себе в каждой фазе вопрос, у
|
||
которого нет заранее известного ответа: **что здесь стоит дороже, работает хуже или ведёт себя страннее,
|
||
чем должно бы, — и о чём никто не спрашивал?** Ради чего он заведён: удорожание из-за падающих запросов на
|
||
НАШИХ настройках никто не искал — просто кто-то посмотрел в леджер без гипотезы и увидел 25.4 % цены книги
|
||
в выброшенных попытках, при зелёных тестах и молчащих гейтах.
|
||
|
||
**Докладывай отдельной секцией: криты · мажоры · регрессии · баги · жёсткие точки улучшения** — каждое
|
||
аргументированно, с носителем (`file:line`, число, команда) и с ценой в деньгах, тексте или доверии
|
||
читателя. ⚠ Секция обязана быть непустой ИЛИ нести строку «искал вот так, не нашёл» с перечислением мест:
|
||
«находок нет» и «не смотрел» в отчёте выглядят одинаково.
|
||
|
||
## 6. Предметные оси ревью
|
||
|
||
Выбери 1–3 и назови какие. Мой приор: **деньги под гонкой** · **терминальное состояние прогона** (что
|
||
видит платформа и что видит человек) · **обратная совместимость словаря причин**.
|
||
|
||
## 7. Записка-план ДО работы
|
||
|
||
Перед первой правкой — записка: что меняешь, чем предъявишь, где ждёшь сопротивления. Комплектность против
|
||
заказа сверяй механически.
|
||
|
||
## 8. Заявление = команда
|
||
|
||
Каждое число и каждая категорика отчёта — **с командой, которой получены**. Дифф `^func Test` — **исполнением,
|
||
не памятью**. Приёмка пере-снимает.
|
||
|
||
⛔ **И три нормы кодового пака, каждая ловит свой класс:**
|
||
- **перед отчётом сверь КАЖДЫЙ клейм с результатом инструмента ЭТОЙ сессии** — не с памятью о прогоне;
|
||
- **последний абзац отчёта оказался планом или обещанием? Сделай его СЕЙЧАС** — обещание в отчёте не
|
||
переживает смены;
|
||
- **в длинной сессии — интервальная самоверификация субагентом против ЯВНЫХ критериев** (`D39.121`), а не
|
||
в конце: проверка, отложенная до сдачи, проверяет уставшую работу уставшим взглядом.
|
||
|
||
## 9. Эхо-протокол старта
|
||
|
||
**Порядок двух первых действий:** сперва впиши свой блок в `/tmp/textmachine-channel` (§12), потом отправь
|
||
эхо — эхо без блока некуда адресовать.
|
||
|
||
**Эхо** — ≤10 строк СВОИМИ словами: что понял · что считаешь опасным · что считаешь неверным.
|
||
Не пересказ: дословный пересказ подтверждает канал, но не понимание, и ошибку промта повторяет вместе с
|
||
ним.
|
||
|
||
**Адрес бери из `/tmp/textmachine-channel`** — блок с `role=оркестратор`, — а не из этого промта: имя сессии
|
||
не переживает рестарт окружения. Перед отправкой сверься с `ListAgents`: файл переживает смерть сессии, а
|
||
`ListAgents` — нет.
|
||
|
||
## 10. Что НЕ удалось — обязательная секция отчёта
|
||
|
||
И вторая её половина: **«где прибор слеп и я это знаю»** — что невидимо · почему не чинил · чем
|
||
закрывается. ⭐ Норма прошлой смены: **«в коде названо, в отчёте нет — значит для следующей смены НЕ
|
||
названо».**
|
||
|
||
## 11. Канал вопросов и право отказаться
|
||
|
||
Конфликт промта с кодом или доками — **пинг мне, не интерпретация**. Право сказать «этого делать не надо» с
|
||
аргументом у тебя есть и им пользовались: в двух случаях из трёх правы были сессии, а не я.
|
||
|
||
⛔ **Тесты и гейты под зелень не подгонять.** Правка, вызванная ЗАКАЗАННОЙ сменой поведения, — обслуживание,
|
||
и протухший тест держать не нужно; но она **ОБЪЯВЛЯЕТСЯ** в отчёте: что изменилось, какой тест это
|
||
описывал, куда уехала гарантия.
|
||
|
||
### ⭐ Старший коллега — Fable 5. **Разрешён ОДИН на сессию (слово владельца 11.09)**
|
||
|
||
У тебя есть право поднять **одного** агента на модели **`fable`** и держать его как СОВЕТЧИКА при сомнениях —
|
||
тем же способом, каким это делает оркестратор. Владелец разрешил ровно одного на сессию.
|
||
|
||
**Как с ним работать, и форма здесь важнее числа:**
|
||
|
||
- **Поднимаешь ОДНОГО и держишь его весь пак.** Ценность этого агента — в НАКОПЛЕННОМ контексте смены:
|
||
он помнит, что ты уже решил и почему. ⛔ **Второго не поднимай** — вопросы ДОСЫЛАЮТСЯ первому (`SendMessage`
|
||
по его id), а не адресуются свежему. Свежий агент вместо накопленного — потеря именно того, ради чего он
|
||
заведён.
|
||
- **Модель задавай ЯВНО** (`model: "fable"`), иначе она унаследуется и ты не будешь знать, что у тебя
|
||
работает.
|
||
- **О чём его спрашивать:** сомнение в решении · развилка, где оба пути выглядят законными · «не заказываю
|
||
ли я уже построенное» · «не противоречит ли это ратифицированному» · спорная формулировка в отчёте.
|
||
⚠ **Спрашивай С КОНТЕКСТОМ и со СВОЕЙ рекомендацией** — вопрос без твоего варианта ответа даёт совет ни
|
||
о чём.
|
||
- ⛔ **Он советчик, а не источник истины: его ответ проверяется деревом.** У оркестратора он за смену
|
||
ошибся дважды на фактах (называл платный прогон бесплатным, объявлял ряд новым предметом) — и оба раза
|
||
его ВЫВОД оставался верным. Проверяй посылки, принимай выводы по существу.
|
||
- **Что он дал оркестратору за эту смену** — для калибровки, чего от него ждать: поймал, что я собирался
|
||
завести новый ряд бэклога под предмет, у которого ряд уже был; развернул порядок паков доводом, который
|
||
я не назвал; и назвал условие, без которого два прогона стали бы несравнимы.
|
||
|
||
## 12. Прямой канал
|
||
|
||
Механизм — `CLAUDE.md` §«Связь между сессиями». Впиши свой блок в `/tmp/textmachine-channel` ПЕРВЫМ
|
||
действием. Нужной роли нет ⇒ канала нет, и это нормальный случай: НЕ опрашивай сессии подряд.
|
||
|
||
## 13. Критерий завершённости
|
||
|
||
У каждого пункта заказа — исход (сделано · не делаю с доводом · пинг) · круги СОШЛИСЬ (последний не дал
|
||
НОВЫХ находок; прежние закрыты таблицей «находка → что сделано → ЧЕМ ПРЕДЪЯВЛЕНО») · **таблица мутаций
|
||
полная, выжившие названы, и КАЖДАЯ новая запись помечена `battery`** (прошлый пак этого не сделал, и его
|
||
«21/21 RED» оказался разовым прогоном смены, а не гейтом проекта) · числа сняты ПОСЛЕ последней правки ·
|
||
всё живое в ДЕРЕВЕ, а не в письме · явное **«работа завершена, править не планирую»**. Без последнего пак
|
||
считается идущим.
|