Take the six objections both sessions raised before touching code: the estimate counter starts from the store, the operator line needs a registry that does not exist, and the sweep fails quietly rather than slowly.
This commit is contained in:
parent
186e229333
commit
ac9a24ddf2
5 changed files with 52 additions and 12 deletions
|
|
@ -194,7 +194,10 @@ a ratified dictionary»), и на 5 завязана логика платфор
|
|||
потолка, но и когда волн ещё не было (`backend/internal/pipeline/events.go`, греп `moneyLedger`):
|
||||
стоп до волн — ингест, сид — счётчиков не имеет, и это законная пустота, а не умолчание.
|
||||
- **Минор словаря потока `1.3 → 1.4`** (`backend/internal/runevents/runevents.go`, греп `StreamVersion`).
|
||||
⚠ Платформа поднимает СВОЮ константу сама — это её половина, не твоя.
|
||||
⛔ **И это ОСОЗНАННОЕ ИСКЛЮЧЕНИЕ из правила версий, ратифицированное `D39.236` п.2** — назови его в коде,
|
||||
чтобы правило не сгнило молча: расширение правила присутствия `Money` формально меняет СМЫСЛ поля, то есть
|
||||
по букве это МАЖОР. Везём минором, потому что мажор читателем ОТВЕРГАЕТСЯ ЦЕЛИКОМ и сломал бы платформу
|
||||
ради поля, на котором она не действует. ⚠ Платформа поднимает СВОЮ константу сама — это её половина.
|
||||
|
||||
### 4.8 Строка **377** — оплаченный обрыв, за которым ретрай УСПЕЛ, исчезает бесследно
|
||||
|
||||
|
|
@ -263,8 +266,12 @@ and sum of estimated-price rows beside committed_usd, which is what would let th
|
|||
Форма — та же `D39.235` п.1, что в §4.7: `estimated{rows, micro_usd}` на `spend` И в `Money`. Ничего не
|
||||
согласовывай отдельно: это один шов, и он уже описан нотой.
|
||||
|
||||
⛔ **ОДНО ОПРЕДЕЛЕНИЕ, ДВА ЧИТАТЕЛЯ — ЗАПИНЬ ИХ РАВЕНСТВО.** Величина «сколько из списанного — оценка»
|
||||
поедет двумя каналами: кадром (эмиттер копит на лету) и `status --json`, который считает её ИЗ СТРОК
|
||||
⛔ **ОДНО ОПРЕДЕЛЕНИЕ, ДВА ЧИТАТЕЛЯ — ЗАПИНЬ ИХ РАВЕНСТВО.** ⚠ **Скобка «эмиттер копит на лету» СНЯТА 10.09 по возражению сессии — она была моей ошибкой** (`D39.236` п.1):
|
||||
счётчик кадра **СИДИРУЕТСЯ ИЗ СТОРА** при старте и дальше инкрементится по тому же определению, что у
|
||||
`estimatedSpend`; прецедент — `waveCounters.counted` (`backend/internal/pipeline/events.go`, греп
|
||||
`counted` starts as the units ALREADY resolved`). Иначе на резюме и после редрайва каналы разойдутся, а пин
|
||||
будет зелен на пустом сценарии. Величина «сколько из списанного — оценка»
|
||||
поедет двумя каналами: кадром и `status --json`, который считает её ИЗ СТРОК
|
||||
`request_log` (`backend/internal/pipeline/status.go`, греп `estimatedSpend`). Платформа по `D39.235` п.1(г)
|
||||
обязана читать ОБА — и если на одном сторе они разойдутся, пользователю скажут два разных «не больше Y».
|
||||
⇒ тест: на одном и том же сторе `Money.estimated` терминального кадра РАВЕН паре `estimated_rows`/
|
||||
|
|
@ -293,8 +300,11 @@ the operator» и «before headers · cancelled by the operator») развод
|
|||
остановка по §4.4 результат ПРОИЗВОДИТ (`moneyStoppedResult`) — и до оператора он не доедет.
|
||||
|
||||
⇒ при первом сигнале печатается строка вида «остановка запрошена: N вызовов в полёте, самый долгий
|
||||
дедлайн Xs; ещё раз — оборвать их (спишется оценка)». Опора готова: хартбит «still waiting for the
|
||||
provider on a call in flight» (`stagerun.go:990`) уже знает и число, и дедлайн.
|
||||
дедлайн Xs; ещё раз — оборвать их (спишется оценка)». ⚠ **Испр. 10.09 по возражению сессии (`D39.236` п.3): опора готова НАПОЛОВИНУ.** Число летящих вызовов есть
|
||||
(`backend/internal/pipeline/reservegate.go`, греп `func (g *reserveGate) stateNow`), а ДЕДЛАЙН живёт только
|
||||
внутри горутины хартбита каждого вызова (`backend/internal/pipeline/stagerun.go`, греп `attempt_deadline`) —
|
||||
прогонного реестра «кто летит и до какого срока» НЕТ. ⇒ это РАБОТА, а не «уже есть»; реестр принят и он же
|
||||
нужен кадру, потому что `in_flight_finished`/`in_flight_cut` считаются по тем же объектам.
|
||||
|
||||
### 4.15 Пять мест, которые ревью назвало «без них не сойдётся» — **делай РОВНО так**
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,10 @@ so it can finish the chunk it is paying for». Сегодня это ЛОЖНО,
|
|||
который движок может попросить. Функция экспортирована ровно для такого вопроса — «сколько ждёт вызов
|
||||
такого размера у этого профиля», и её доккоммент это говорит. Сегодня наибольшая крышка — 1240 с
|
||||
(deepseek), у провайдеров без ключа значение выводится формулой. **Пере-считай своей рукой и назови
|
||||
число**; арифметика — в отчёт.
|
||||
число**; арифметика — в отчёт. ⛔ **И запиши его как ЗАВИСИМОСТЬ, а не как свою константу** (`D39.236` п.6):
|
||||
оно равно ожиданию после SIGTERM только если движковая половина посадит «мягкая остановка видна МЕЖДУ
|
||||
попытками и в бэкоффе» (`D39.235` п.2). Не сядет — ожидание снова становится цепочкой (~64 мин), и любой
|
||||
грейс, выведенный из одной попытки, снова окажется ниже неё.
|
||||
|
||||
⚠ Валидатор каталога держит лишь абсолютную границу (`backend/internal/config/models.go`, греп
|
||||
`maxAttemptSeconds`) — она в часах и вопроса не решает.
|
||||
|
|
@ -159,7 +162,10 @@ committed_usd, which is what would let this side say "at most Y"».
|
|||
`StreamVersion = "1.1"`, и его собственный комментарий объясняет, что это УТВЕРЖДЕНИЕ о том, что билд
|
||||
понимает, а не украшение («leaving it at 1.0 would have been a false one»). Читая поля минора `1.4`, ты
|
||||
обязан сказать об этом константой — иначе повторишь ровно ту ошибку, от которой предостерегает твой же
|
||||
комментарий. Зачем это нужно
|
||||
комментарий. ⛔ **И ТЕМ ЖЕ ДВИЖЕНИЕМ напиши у константы, каких полей миноров 1.2 и 1.3 ты НЕ читаешь и
|
||||
почему** (`D39.236` п.4): декодер несёт `Finished{Outcome}` без `Volume` и `Money` и `Ceiling{Halted, Scope}`
|
||||
без `ShortfallMicroUSD`. Из них `Money` пак и так заказывает; два оставшихся — решения зоны с записанным
|
||||
доводом, и они должны быть названы, иначе `1.4` лжёт по критерию, который сама константа себе задаёт. Зачем это нужно
|
||||
владельцу дословно: он разрешил списывать по ОЦЕНКЕ при УСЛОВИИ, что пометка стоит (`D39.230` п.1) —
|
||||
условие сегодня исполнено на одном канале из двух и потребителя не имеет. Пользователь должен видеть не
|
||||
только «списано X», но и «из них оценка Y».
|
||||
|
|
@ -187,8 +193,12 @@ catches SIGTERM and exits 1». Движок на пойманном сигнал
|
|||
- в HTTP-глаголе `/stop` при `WriteTimeout: 30 s` (`platform/cmd/tmplatformd/main.go`, греп `WriteTimeout`)
|
||||
пользователь НЕ получает `202`, который контракт обещает (`docs/architecture/14-api-contract/openapi.yaml`,
|
||||
греп `The `202` does not mean the run has stopped`);
|
||||
- свип реконсайлера (`platform/internal/runs/reconcile.go`, вызовы `Stop`) встанет до двадцати минут на
|
||||
одном прогоне.
|
||||
- ⚠ **испр. 10.09 по возражению сессии (`D39.236` п.5): свип НЕ встанет на двадцать минут** — `reconcileOne`
|
||||
заворачивает каждый прогон в СВОЙ бюджет (`platform/internal/runs/reconcile.go`, греп
|
||||
`context.WithTimeout(ctx, s.runBudget())`), и команда строится на нём. Ущерб тише и хуже: израсходованный
|
||||
бюджет САМ ПО СЕБЕ считается провалом реконсиляции (там же, греп `SPENDING the budget counts as a failure`)
|
||||
⇒ каждый мягко останавливающийся прогон получает `ReconcileFailures++`, отсрочку и через несколько проходов
|
||||
`StalledAfter` — ЛОЖНУЮ тревогу оператору; плюс фаза прохода съедается одним таким прогоном.
|
||||
|
||||
**Делай РОВНО так:** `--no-block`. Реконсайлер и так пере-выдаёт стоп на следующем проходе — это написано
|
||||
в комментарии над его `Stop`. ⚠ И пере-сними мой замер своей рукой, прежде чем опираться: он снят не на
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Журнал прогресса
|
||||
|
||||
> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-09-10, голова D39.235 — КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и P7 его НЕ размораживает (D39.147). **ОЧЕРЕДЬ №23** (единственный носитель — здесь; роль передана 06.09, №22 закрыт нотой передачи D39.217; ⚠ испр. 06.09: коммит передачи `c992ee5` бампнул голову и НЕ тронул номер — гейта на номер очереди нет вовсе, `counts.py` сверяет только голову, поэтому носитель разошёлся молча). ⚠ **ЗАКАЗ ВЛАДЕЛЬЦА 01.09 — ИСПОЛНЕН, испр. 08.09 (висел как «первым» неделю после исполнения):** (0а) ревизия документации на протухшее ОТРАБОТАНА 01.09 воркфлоу `docs-staleness-revision-A` (15 срезов), провенанс находок — `D39.185`; (0б) планы доработок в бэкенд и платформу — исполняются ПАКАМИ, за 07–08.09 закрыты два движковых (`D39.225`, `D39.226`); (0в) вынос неактуального в архив идёт батчами `DOC_CLEANUP_PLAN.md` (Б14/Б15/Б17 живы). ⇒ строка ниже — не заказ, а история: (0а) ревизия документации на ПРОТУХШЕЕ — по всем зонам; (0б) планы доработок в БЭКЕНД и ПЛАТФОРМУ; (0в) вынос неактуального в АРХИВ (`docs/archive/`, `platform/docs/archive/`) — за сутки 31.08 закрыто много, и часть носителей стала историей. ⚠ Трезвость по масштабу (пере-считано 02.09): **94** живых дока в `docs/` (пере-счёт 04.09: `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`), 8 в `platform/docs`, 9 в `backend/docs` — ⚠ из 94 ВРЕМЕННЫЙ остался ОДИН (`DOC_CLEANUP_PLAN`, живой до закрытия батчей Б14/Б15/Б17); два прежних временных уехали в `archive/reports/` 02.09; счёт бэклога — бюллетенем ниже, открытых рядов регистра платформы — 109 (major 1), всего рядов 465 (пере-счёт `python3 docs/scripts/counts.py`; с 04.09 оба числа под гардом `--check`, прежние 95/3 разошлись молча) ⚠ (ревизией 02.09 ряды **154** и **157** переведены из «скоро» в «когда-нибудь»: их гейтом стоял первый холодный прогон, он ОТРАБОТАЛ 31.08 и оба предусловия оказались другими — разбор в самих ячейках, ни одна НЕ закрыта). ⚠ Числа доков `counts.py` НЕ сторожит — при переносе файлов пере-считывать руками командой `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`. ⚠ И предупреждение о МЕТОДЕ, купленное сменой №21: «выглядит протухшим» ≠ «протухло». Три факта оркестратора опровергнуты ЗАМЕРОМ сессий, а якоря `15-money-path.md` в девяти случаях из двенадцати РОДИЛИСЬ верными и сгнили дрейфом — то есть ревизия обязана быть исполнением, а не чтением. ⚠ **ОЧЕРЕДЬ, унаследованная от №21** (три лендинга 31.08 — секция «СОСТОЯНИЕ ПАКОВ» ниже): **(1) ~~РАЗРЫВ ЦИКЛА~~ ЗАМКНУТ ЖИВЬЁМ 04.09** — пользователь получил EPUB настоящего ПЛАТНОГО перевода ЧЕРЕЗ API, `epubcheck` 5.3.0 на СКАЧАННОМ файле 0/0/0/0 (книга `bk_SS5VES2JELESJSTR`, потрачено $0.278319 из гранта $0.60 при потолке пака $1.5, санкция D39.189). Дверь выдачи построена и проверена исполнением: `202`+`Location`, поллинг с `Retry-After`, Range 206 · второй клиент 200 · аноним 401 · чужая книга 404, TTL с GC, идемпотентность третьего создающего вызова. Все ТРИ сценария строки 216 предъявлены живьём (подпись банка · halt на потолке с exit 4 · `409 run_not_resumable/ceiling_reached` и лечение новым прогоном).
|
||||
> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-09-10, голова D39.236 — КУРС: движок и платформа до «работает и отдаёт результат», фронт ЗАМОРОЖЕН и P7 его НЕ размораживает (D39.147). **ОЧЕРЕДЬ №23** (единственный носитель — здесь; роль передана 06.09, №22 закрыт нотой передачи D39.217; ⚠ испр. 06.09: коммит передачи `c992ee5` бампнул голову и НЕ тронул номер — гейта на номер очереди нет вовсе, `counts.py` сверяет только голову, поэтому носитель разошёлся молча). ⚠ **ЗАКАЗ ВЛАДЕЛЬЦА 01.09 — ИСПОЛНЕН, испр. 08.09 (висел как «первым» неделю после исполнения):** (0а) ревизия документации на протухшее ОТРАБОТАНА 01.09 воркфлоу `docs-staleness-revision-A` (15 срезов), провенанс находок — `D39.185`; (0б) планы доработок в бэкенд и платформу — исполняются ПАКАМИ, за 07–08.09 закрыты два движковых (`D39.225`, `D39.226`); (0в) вынос неактуального в архив идёт батчами `DOC_CLEANUP_PLAN.md` (Б14/Б15/Б17 живы). ⇒ строка ниже — не заказ, а история: (0а) ревизия документации на ПРОТУХШЕЕ — по всем зонам; (0б) планы доработок в БЭКЕНД и ПЛАТФОРМУ; (0в) вынос неактуального в АРХИВ (`docs/archive/`, `platform/docs/archive/`) — за сутки 31.08 закрыто много, и часть носителей стала историей. ⚠ Трезвость по масштабу (пере-считано 02.09): **94** живых дока в `docs/` (пере-счёт 04.09: `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`), 8 в `platform/docs`, 9 в `backend/docs` — ⚠ из 94 ВРЕМЕННЫЙ остался ОДИН (`DOC_CLEANUP_PLAN`, живой до закрытия батчей Б14/Б15/Б17); два прежних временных уехали в `archive/reports/` 02.09; счёт бэклога — бюллетенем ниже, открытых рядов регистра платформы — 109 (major 1), всего рядов 465 (пере-счёт `python3 docs/scripts/counts.py`; с 04.09 оба числа под гардом `--check`, прежние 95/3 разошлись молча) ⚠ (ревизией 02.09 ряды **154** и **157** переведены из «скоро» в «когда-нибудь»: их гейтом стоял первый холодный прогон, он ОТРАБОТАЛ 31.08 и оба предусловия оказались другими — разбор в самих ячейках, ни одна НЕ закрыта). ⚠ Числа доков `counts.py` НЕ сторожит — при переносе файлов пере-считывать руками командой `find docs -name '*.md' -not -path 'docs/archive/*' | wc -l`. ⚠ И предупреждение о МЕТОДЕ, купленное сменой №21: «выглядит протухшим» ≠ «протухло». Три факта оркестратора опровергнуты ЗАМЕРОМ сессий, а якоря `15-money-path.md` в девяти случаях из двенадцати РОДИЛИСЬ верными и сгнили дрейфом — то есть ревизия обязана быть исполнением, а не чтением. ⚠ **ОЧЕРЕДЬ, унаследованная от №21** (три лендинга 31.08 — секция «СОСТОЯНИЕ ПАКОВ» ниже): **(1) ~~РАЗРЫВ ЦИКЛА~~ ЗАМКНУТ ЖИВЬЁМ 04.09** — пользователь получил EPUB настоящего ПЛАТНОГО перевода ЧЕРЕЗ API, `epubcheck` 5.3.0 на СКАЧАННОМ файле 0/0/0/0 (книга `bk_SS5VES2JELESJSTR`, потрачено $0.278319 из гранта $0.60 при потолке пака $1.5, санкция D39.189). Дверь выдачи построена и проверена исполнением: `202`+`Location`, поллинг с `Retry-After`, Range 206 · второй клиент 200 · аноним 401 · чужая книга 404, TTL с GC, идемпотентность третьего создающего вызова. Все ТРИ сценария строки 216 предъявлены живьём (подпись банка · halt на потолке с exit 4 · `409 run_not_resumable/ceiling_reached` и лечение новым прогоном).
|
||||
> ⛔ **ПЯТЬ ПОТОКОВ РАБОТЫ — состояние на 07.09 (пере-снято лендингами смены №23).**
|
||||
> **(1) ПОЛИГОН — «ремонт прибора»** (`docs/POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md`, строки 319 · 300 · 265 · 143):
|
||||
> ⚠ **ЕДИНСТВЕННЫЙ ПОТОК, НЕ СДВИНУВШИЙСЯ ЗА СМЕНУ — сессия по промту так и не стартовала.** Блокирующая линза
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
> `3d90943`). Строки 285 · 305 · 325 закрыты. ⚠ **Синхронный разрез приёма принят ПОСТРОЕННЫМ, НО НЕ ГОТОВЫМ** —
|
||||
> сработало правило остановки (9 major из 11 в одном механизме), десять пунктов несёт строка **332**; ложный
|
||||
> инвариант бюджета заландён осознанно (окно лжи 8 секунд при дефолте в 16 минутах, ломается идемпотентность).
|
||||
> **(14) ОБЕ СЕССИИ ПАКА «ДВЕ ОСТАНОВКИ» ПРИНЯЛИ РАБОТУ И ОТВЕТИЛИ ЭХО-ПРОТОКОЛОМ; шесть возражений, шесть приняты — акт `D39.236`.** Три из них — ошибки В МОИХ ПАКАХ (счётчик оценки копился бы с нуля и пин равенства был бы вакуумен · «опора готова» для строки оператору · неверный механизм следствия у блокирующего `stop`), одно — правило версий, которое я нарушил бы молча. ⭐ Все шесть пришли ПОСЛЕ двух кругов ревью: эхо-протокол оказался третьим рубежом, а не формальностью входа.
|
||||
> **(13) ДВА ПАРНЫХ ПРОМТА «ДВЕ ОСТАНОВКИ» ВЫДАНЫ, акт `D39.235`** — движковый и платформенный, порознь не лендятся. Форма кадра остановки ЗАФИКСИРОВАНА нотой ДО старта работ (две зоны, один шов). ⛔ Эррата к `D39.234` п.1б: мой механизм «отказ на гейте» ратифицированных ~20 минут не даёт — резервация держит всю цепочку ретраев. ⛔ Замером исполнением найдено, что платформенный `Stop` без `--no-block` блокируется на весь грейс и сломал бы `202` контракта. **Сплошной инвентарь живых доков по слову владельца: 19 мест починено**, контракт исправлен минором `0.13.1` (схема требовала отставленный член ⇒ каждый ответ `Run` был невалиден).
|
||||
> **(12) СЛОВО ВЛАДЕЛЬЦА ПО ОСТАНОВКАМ ПОЛУЧЕНО И РАТИФИЦИРОВАНО, акт `D39.234`:** первое нажатие — мягкая, второе — жёсткая; ждём одну летящую попытку (~20 мин), не цепочку; пак мягкой остановки и строку **377** делаем ОДНИМ заходом; коды выхода не трогаем. Пак движка ПАРНЫЙ платформенному. ⛔ Тем же актом сверены носители, которых `D39.232` не тронул: закрыты и убраны строки **78** · **331** · **360** · **369**; блокеров очереди в трекере теперь **0**. Инвентарь живых доков прогнан (94 файла): `15-money-path.md` чинен в трёх местах.
|
||||
> **(11) ДВА СТОПА — СЛОВО ВЛАДЕЛЬЦА НАКОНЕЦ ЗАПИСАНО, акт `D39.233`.** У человека одна кнопка, и она рвёт всё в полёте; мягкий глагол в движке построен, но дёрнуть его может только денежный потолок. ⛔ Контракт и платформа УЖЕ обещают мягкий стоп, которого нет, а платформенный грейс (600 с) меньше законного ожидания вызова (1240 с). ⛔ Пометка «это оценка» — условие слова владельца — по шву НЕ едет и потребителя не имеет (строка **382**). ✅ Замером закрыты строки **374** (вердикт главы остановка уже не портит) и **371**. Пак не заказан: ждёт слова владельца по форме (рекомендация — «повтор ужесточает», коды выхода не трогать).
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Реестр D-нот — карта актуальности v2 (D1–D39.235; титул — носитель головы, бампать при каждом аппенде)
|
||||
# Реестр D-нот — карта актуальности v2 (D1–D39.236; титул — носитель головы, бампать при каждом аппенде)
|
||||
|
||||
> ⚠ **Колонку «тело» `counts.py --check` НЕ сторожит по устройству:** он сверяет полноту НОМЕРОВ, а не
|
||||
> место тела, поэтому колонка держится дисциплиной лендинга. Не нашёл тело по колонке — иди в слайсы,
|
||||
|
|
@ -294,3 +294,4 @@
|
|||
| D39.233 | 10.09 | **ДВА СТОПА получают носитель; две строки закрыты замером; условие слова владельца — без потребителя.** У человека одна кнопка и она ЖЁСТКАЯ (`cmd/tmctl/main.go:207`); мягкий глагол построен, но локален волне и дёргает его только потолок (`waverun.go:353`); второй Ctrl-C НЕ ДЕЛАЕТ НИЧЕГО. ⛔ Контракт (`openapi.yaml:762`) и платформа (`runner.go:56-58`) уже ОБЕЩАЮТ мягкий стоп, которого нет, а `stopGrace` 600 с меньше потолка ожидания 1240 с. ⛔ Пометка «оценка» по шву НЕ едет (0 хитов в кадрах, контроль 6) ⇒ `D39.230` п.1 без потребителя — строка **382**. ✅ Закрыты **374** (вердикт главы остановка уже не портит — пере-снято, пин зелён) и **371** (переплата невозможна: `Billable` требует 2xx). Рекомендована форма «повтор ужесточает», коды выхода не трогать | стоп · деньги · шов · метод |
|
||||
| D39.234 | 10.09 | **СЛОВО ВЛАДЕЛЬЦА по двум остановкам + сверка носителей, которую `D39.232` объявил и не сделал.** Ратифицировано: форма «повтор ужесточает» (первое нажатие — мягкая, второе — жёсткая), потолок ожидания ~20 мин (одна летящая попытка, не цепочка), пак мягкой остановки и строка **377** — одним заходом; коды выхода не трогать. Пак движка ПАРНЫЙ платформенному (грейс 600 с < 1240 с). ⛔ Эррата 10.09-б: три объявленные закрытыми строки сутки стояли в таблице — **78** · **369** · **360** закрыты и убраны, плюс незамеченная **331** (с названным сужением, остаток — **376**). Инвентарь живых доков: `15-money-path.md` чинен в трёх местах и получил новую денежную границу; реестр требований против брифа владельца сходится (V0–V6) | стоп · деньги · слово владельца · сверка |
|
||||
| D39.235 | 10.09 | **ФОРМА КАДРА ОСТАНОВКИ ЗАФИКСИРОВАНА ДО РАБОТ; два парных промта выданы; сплошной инвентарь живых доков.** Кадр: `Finished.Stop{mode,…}` присутствием (прецедент `Volume`), `estimated{rows,micro_usd}` на ОБОИХ кадрах, `Money` на `stopped` всегда, запасной канал — обязанность платформы; минор потока `1.3→1.4`. ⛔ Эррата к `D39.234` п.1б: «отказ на гейте» ратифицированных ~20 мин НЕ даёт — резервация держит ВСЮ цепочку ретраев, нужен и `retryLoop`. ⛔ Замер исполнением: платформенный `Stop` без `--no-block` блокируется на весь грейс (15,21 с против 0,019 с) ⇒ сломал бы `202` контракта. Инвентарь: **19** мест починено, самый урожайный класс — УСЛОВНОЕ ЗАКРЫТИЕ. Контракт `0.13.0→0.13.1`: `Run.required` требовал отставленный член ⇒ каждый ответ был невалиден. Закрыта строка **166** | стоп · шов · контракт · инвентарь |
|
||||
| D39.236 | 10.09 | **ДИСПОЗИЦИИ ПО ЭХО-ПРОТОКОЛАМ обеих сессий пака «две остановки»: шесть возражений, шесть приняты, ТРИ — мои ошибки.** (1) счётчик оценки СИДИРУЕТСЯ из стора, а не копится с нуля — иначе пин равенства двух каналов зелен на пустом сценарии; (2) расширение правила присутствия `Money` формально МАЖОР, везём минором `1.3→1.4` как осознанное исключение (мажор читателем отвергается целиком); (3) «опора готова» для строки оператору — преувеличение, прогонного реестра летящих вызовов нет; (4) платформа поднимает `StreamVersion` и тем же движением пишет, каких полей 1.2/1.3 не читает; (5) «свип встанет на 20 минут» — неверный механизм, настоящий ущерб — ложная тревога `StalledAfter`; (6) 1240 с — свойство ПАРЫ, не константа платформы. ⭐ Все шесть пришли ПОСЛЕ двух кругов ревью: эхо-протокол — третий рубеж, а не формальность | стоп · шов · метод |
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Журнал решений оркестратора — контракт D1–D39.235 (живой файл: карта · эрраты · живые тела · голова D39.124+ (подрезка D39.139); тела закрытых эр — в слайсах `docs/archive/architecture/`, указатель ниже; реестр всех нот — `05-decisions-index.md`)
|
||||
# Журнал решений оркестратора — контракт D1–D39.236 (живой файл: карта · эрраты · живые тела · голова D39.124+ (подрезка D39.139); тела закрытых эр — в слайсах `docs/archive/architecture/`, указатель ниже; реестр всех нот — `05-decisions-index.md`)
|
||||
|
||||
> **⟶ КАРТА АКТУАЛЬНОСТИ (ревизия D31, продлена до D38.2 [12.07]; исторические записи ниже НЕ переписываются — дисциплина D23.3).** Работая с контрактом (греп номера: живой файл → слайсы, целиком НЕ читать — D39.125), держи под рукой, что чем перекрыто:
|
||||
> ⚠ **Эррата 09.08 (D39.125):** D39.111 п.1 предписывал промту S3 «максимум = баланс МИНУС открытые холды» — формула ОШИБОЧНА (вычитание дважды), исправлена D39.115 п.2(а): максимум = Balance КАК ЕСТЬ; тело D39.111 — в слайсе `../archive/architecture/05-decisions-D39-106-123.md` (испр. 05.09: прежнее «живёт ниже в этом файле» протухло подрезкой D39.139) (голова D39.106+).
|
||||
|
|
@ -3316,3 +3316,21 @@ bought NOTHING». ⇒ **`tmctl manifest` есть НИЖНЯЯ граница,
|
|||
**7. Сверка носителей — теперь в том же движении.** Закрыта и убрана строка **166** (обе половины построены, условие «дерево платформы в полёте» отпало: `platform/internal/pricing/pricing.go` тронут последний раз 06.09, дерево чистое). Пере-наведены мёртвые адреса: два в строке 146 бэклога, `render.Messages` в реестре рисков памяти, словарь кодов выхода в README контракта. Строки 212 · 231 · 208 · 210 · 113 · 184, на которые ссылались живые доки как на открытые, помечены закрытыми по месту.
|
||||
|
||||
**8. Границы.** Пункт 4 — единственный замер ИСПОЛНЕНИЕМ, и он не мой: сделан старшим коллегой на его юнитах, платформенной сессии велено пере-снять своей рукой. Пункт 2 пере-снят мной по коду. Пункт 5 — три отчёта панели, каждая находка с `file:line` и контрольной величиной; я пере-снимал выборочно (`09`, `01`, `03`, `13`, свою собственную ошибку в `15`), а не все девятнадцать. ⚠ **Одна из девятнадцати — МОЯ ВЧЕРАШНЯЯ ПРАВКА:** я записал в путь денег, будто оплаченный `2xx` с нечитаемым телом «прежде не попадал в `request_log`», — ветвь писала эту строку с 24.07 (`2f91b04`), пак её не касался (0 хитов в диффе), а процитированный мною носитель обслуживает другой класс ошибки. Исправлено и названо здесь, потому что это ровно тот класс, который я в этом же акте вменяю другим.
|
||||
|
||||
## D39.236 — ДИСПОЗИЦИИ ПО ЭХО-ПРОТОКОЛАМ ОБЕИХ СЕССИЙ ПАКА «ДВЕ ОСТАНОВКИ»: шесть возражений, шесть приняты, три из них — мои ошибки (10.09, оркестратор №23) ✅
|
||||
|
||||
**0. Почему нота.** Обе сессии ответили эхо-протоколом ДО первой правки кода и обе принесли возражения по существу. Возражения — диспозиции, а диспозиция ратифицируется ИЛИ получает строку ТЕМ ЖЕ движением, каким отправляется ответ (`D39.231` п.1). ⭐ **Метод, который стоит отметить: шесть находок пришли ПОСЛЕ двух кругов ревью — панель читателей и старший коллега их не увидели.** Эхо-протокол — не формальность входа, а третий рубеж, и он окупился.
|
||||
|
||||
**1. ⛔ ПРИНЯТО, и это моя ошибка: счётчик оценки СИДИРУЕТСЯ ИЗ СТОРА, а не копится с нуля.** Движковый пак §4.11 нёс мою скобку «эмиттер копит на лету». Она давала бы РАСХОЖДЕНИЕ ровно там, где §4.11 требует равенства двух каналов. Замер сессии, пере-снят мной: соседнее число того же кадра `committed_micro_usd` берётся из СТОРА и пожизненно для книги (`backend/internal/store/ledger.go`, греп `SELECT COALESCE(SUM(committed_usd)`), а пара `estimated_rows`/`estimated_usd` в `status --json` считается по ВСЕМ чекпойнтам книги плюс синтетическая строка «committed без чекпойнта» (`backend/internal/pipeline/paidtail.go`, греп `func estimatedSpend`). ⇒ внутрипроцессный счётчик с нуля равен им только на СВЕЖЕМ одиночном прогоне, а на резюме и после редрайва — нет, и пин был бы зелёным на пустом сценарии. **Форма: сидировать из стора при старте, дальше инкременты по тому же определению.** Прецедент в том же файле и назван сессией: `waveCounters.counted` (`backend/internal/pipeline/events.go`, греп `counted` starts as the units ALREADY resolved`) заведён ровно так и ровно поэтому. Равенство ПО ПОСТРОЕНИЮ, а не по совпадению фикстуры.
|
||||
|
||||
**2. ПРИНЯТО КАК ОСОЗНАННОЕ ИСКЛЮЧЕНИЕ из правила версий, и это записывается здесь, чтобы правило не сгнило молча.** Расширение правила присутствия `Money` («потолок сработал» → «потолок ИЛИ остановка», `D39.235` п.1в) формально меняет СМЫСЛ существующего поля, а правило дословно: «adding a field or an event type bumps the minor, **changing what an existing field MEANS bumps the major**» (`backend/internal/runevents/runevents.go`, греп `bumps the major`). ⇒ по букве это МАЖОР. **Решение: везём минором `1.3 → 1.4`.** Довод не «так удобнее», а механический: мажор читателем ОТВЕРГАЕТСЯ ЦЕЛИКОМ («a MAJOR bump is refused by the reader outright»), то есть мажорный бамп сломал бы платформу ради поля, на котором она и так не действует (`platform/internal/ingest/events.go`, греп `does not ACT on this line`). Исключение узкое: оно про ПРАВИЛО ПРИСУТСТВИЯ, а не про смысл величины — сама сумма как была деньгами, так и осталась. ⚠ Назвала сессия, не я.
|
||||
|
||||
**3. ПРИНЯТО: моё «опора готова» в §4.13 было преувеличением.** Число летящих вызовов действительно есть (`backend/internal/pipeline/reservegate.go`, греп `func (g *reserveGate) stateNow`), а вот ДЕДЛАЙН живёт только внутри горутины хартбита каждого вызова (`backend/internal/pipeline/stagerun.go`, греп `attempt_deadline`) — прогонного реестра «кто летит и до какого срока» НЕТ. ⇒ строка оператору «N вызовов, самый долгий дедлайн X» — это РАБОТА, а не «уже есть». Реестр принят: он же нужен кадру, потому что `in_flight_finished`/`in_flight_cut` считаются по тем же объектам.
|
||||
|
||||
**4. ПРИНЯТО: платформа поднимает `StreamVersion` до `1.4` и ТЕМ ЖЕ ДВИЖЕНИЕМ пишет, каких полей миноров 1.2/1.3 она не читает и почему.** Иначе константа лжёт по критерию, который сама себе задаёт: её комментарий говорит, что это «a claim about what this build UNDERSTANDS», а декодер несёт `Finished{Outcome}` без `Volume` и без `Money` и `Ceiling{Halted, Scope}` без `ShortfallMicroUSD` (`platform/internal/ingest/events.go`). Из трёх непрочитанных `Money` пак и так заказывает, а два оставшихся — не забывчивость, а решения зоны с записанным доводом. Это не расширение пака: одна правка комментария рядом с той, которую пак уже велел сделать.
|
||||
|
||||
**5. ПРИНЯТО как исправление МОЕГО §4.7: «свип встанет до двадцати минут» — неверный механизм.** `reconcileOne` заворачивает каждый прогон в СВОЙ бюджет (`platform/internal/runs/reconcile.go`, греп `context.WithTimeout(ctx, s.runBudget())`), а команда строится на этом контексте (`platform/internal/runner/runner.go`, греп `exec.CommandContext`) ⇒ блокирующий `stop` упрётся в бюджет, а не в двадцать минут. **Настоящий ущерб тише и хуже:** израсходованный бюджет САМ ПО СЕБЕ считается провалом реконсиляции (там же, греп `SPENDING the budget counts as a failure`), значит каждый мягко останавливающийся прогон получает `ReconcileFailures++`, отсрочку и через несколько проходов — `StalledAfter`, то есть ложную тревогу оператору; а фаза прохода съедается одним таким прогоном. Починка не меняется (`--no-block`), меняется формулировка следствия.
|
||||
|
||||
**6. ПРИНЯТО: «законное ожидание 1240 с» — свойство ПАРЫ, а не константа платформы.** Оно равно ожиданию после SIGTERM только если движковая половина посадит «мягкая остановка видна МЕЖДУ попытками и в бэкоффе» (`D39.235` п.2). Не сядет — ожидание снова становится цепочкой (~3×1240 + 2×60 ≈ 64 мин), и любой грейс, выведенный из 1240, снова окажется ниже. ⇒ в отчёте платформы число пишется как ЗАВИСИМОСТЬ с названным носителем, а не как своя константа. ⚠ Заодно обе сессии независимо пере-считали каталог и подтвердили мою вчерашнюю поправку: `attempt_max_s` задан у ТРЁХ провайдеров из восьми, у пяти его нет и он инертен.
|
||||
|
||||
**7. Границы.** Все шесть пере-сняты мной на дереве по адресам, которые дали сессии; ни одно не принято со слов. Пункты 1, 3 и 5 — ошибки в МОИХ паках (скобка про счётчик, «опора готова», механизм следствия), пункт 2 — правило, которое я нарушил бы молча. Пункты 4 и 6 — работа сессий сверх заказа. Живого прогона не было, $0.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue