Re-point the anchors the engine's loop moved, mark one dead from its cure, and lengthen four tokens too short to identify a target: the anchor lint reads zero

This commit is contained in:
heaven 2026-09-04 21:05:50 +03:00
parent ecf063e58f
commit 1b8aa86cce
5 changed files with 16 additions and 16 deletions

File diff suppressed because one or more lines are too long

View file

@ -11,7 +11,7 @@
## 1. Канон одним абзацем
Деньги видимы с первого вызова: телеметрия, потолки, явное согласие на пере-оплату (CLAUDE.md, цель 5). Леджер без потолка запрещён — Р7: книга обязана нести хотя бы один из `book_usd`/`day_usd` (`backend/internal/config/book.go:321`=`a ledger with no ceiling is forbidden`, текст валидатора: «a ledger with no ceiling is forbidden, Р7»). Суммы на пользовательский экран НЕ выходят — запрет D39.84, подтверждён D39.100/К-8 (дословно: «страница лимитов/использования в настройках (СТАТУС, не суммы — запрет денег на экране D39.84 в силе и НЕ superseded)» — `docs/architecture/05-decisions-log.md`, греп `^## D39.100` → пункт К-8, дословная подстрока `СТАТУС, не суммы — запрет денег на экране`; ⚠ адресуем НОМЕРОМ ноты, а не строкой журнала) и держится в контракте (`docs/architecture/14-api-contract/openapi.yaml`, греп `State of the credit balance. No window` — ⚠ номер не ставим: контракт переверстывается минорами, греп-форма дешевле поддержки). Защита от перерасхода двойная и не зависит от событий: холд платформы делает кредит недоступным следующему прогону, а движок сам останавливается на потолке — «an overspend is impossible even while the platform is blind. The event stream is freshness only» (док-коммент `Hold``platform/internal/pgstore/credits.go`, греп `an overspend is impossible even`).
Деньги видимы с первого вызова: телеметрия, потолки, явное согласие на пере-оплату (CLAUDE.md, цель 5). Леджер без потолка запрещён — Р7: книга обязана нести хотя бы один из `book_usd`/`day_usd` (`backend/internal/config/book.go:332`=`a ledger with no ceiling is forbidden`, текст валидатора: «a ledger with no ceiling is forbidden, Р7»). Суммы на пользовательский экран НЕ выходят — запрет D39.84, подтверждён D39.100/К-8 (дословно: «страница лимитов/использования в настройках (СТАТУС, не суммы — запрет денег на экране D39.84 в силе и НЕ superseded)» — `docs/architecture/05-decisions-log.md`, греп `^## D39.100` → пункт К-8, дословная подстрока `СТАТУС, не суммы — запрет денег на экране`; ⚠ адресуем НОМЕРОМ ноты, а не строкой журнала) и держится в контракте (`docs/architecture/14-api-contract/openapi.yaml`, греп `State of the credit balance. No window` — ⚠ номер не ставим: контракт переверстывается минорами, греп-форма дешевле поддержки). Защита от перерасхода двойная и не зависит от событий: холд платформы делает кредит недоступным следующему прогону, а движок сам останавливается на потолке — «an overspend is impossible even while the platform is blind. The event stream is freshness only» (док-коммент `Hold``platform/internal/pgstore/credits.go`, греп `an overspend is impossible even`).
## 2. Деньги ДВИЖКА (зона `backend/`)
@ -20,8 +20,8 @@
- **leftover-reserved зануляется write-open.** `store.Open` (путь записи, каждый `translate`) выполняет `recoverReservations` (`backend/internal/store/store.go:110`=`s.recoverReservations(ctx)`; сама функция — `backend/internal/store/store.go:278-279`=`UPDATE spend SET reserved_usd = 0`) — файл владеется одним процессом, значит любой reserved на открытии принадлежит несеттлённому прогону. `OpenReadOnly` этого прохода намеренно НЕ делает (`backend/internal/store/store.go:124`=`does not run that pass`) ⇒ **reserved, увиденный read-only `status` В МОМЕНТ СПАВНА, — остаток мёртвого процесса** (несущий факт формулы PD-158, см. §3). ⚠ Но НЕ «всегда»: `OpenReadOnly` построен ровно затем, чтобы `status` работал ВО ВРЕМЯ живого прогона (`backend/internal/store/store.go:122`=`allows concurrent readers while a writer is live`), и конкурентный `status` покажет ЖИВУЮ резервацию между `Reserve` и settle. Узко формулирует и сам код: «after a run crashes, reserved_usd stays non-zero until the next WRITE command» (`backend/internal/store/store.go:130`=`after a run crashes, reserved_usd stays non-zero`), и платформа — «at spawn there is no other writer … so anything reserved is by construction a leftover, never a live promise» (`platform/internal/runs/spawn.go`, греп `never a live promise`).
- **`--max-units` — ОБЪЁМНЫЙ потолок прогона, ортогональный денежному** (D39.165 §1б, принят D39.170). Ограничивает не деньги, а РАБОТУ: не больше N выходных ЮНИТОВ (гранулярность `units_total` манифеста — та же, в которой платформа продаёт главы) возьмут СЛОТ гранта в этом прогоне; юниты, отданные за $0 (резюм, ре-пин), ретраи и эскалации внутри юнита потолок не тратят. ⚠ **«Слот» ≠ «оплата», и с 03.09 это РАЗНЫЕ числа** (пак «число согласия», строка бэклога 232): юнит, который прежний прогон НАЧАЛ и не отгрузил, дописывается ВНЕ гранта, поэтому грант N оплачивает ДО 2N выходных юнитов — замерено приёмкой на живом раннере (грант 2 → `Paid()=4`, шесть вызовов провайдера). Единственный денежный бонд здесь — `--ceiling-usd`. ⛔ **Семантика переноса НЕ ратифицирована — слово владельца 03.09 «подумаем на этот счёт»**, и до его решения читать это как замеренный факт, а не как норму. Принимает только `translate`. **Остановка по объёму — ЗАВЕРШЕНИЕ (exit 0), не пауза:** словарь кодов выхода не расширялся и нового значения `Finished.Outcome` тоже нет — ⚠ **но с 31.08 признак едет ЧИСЛАМИ в кадре `finished` шва, а не только прозой** (D39.181 п.2, закон раскрытия: прозаическая строка отчёта до потребителя потока не доезжала): носитель — `Finished.Volume`, леджер доставки. Различение при этом живёт и в отчёте прогона, и в логе; отчёт разводит ДОСТАВКУ и ПЕРЕ-ДЕЛКУ. Носитель — `backend/internal/pipeline/volume.go:13`=`the VOLUME ceiling — the run's second stop`; словарь флага дословно — `backend/cmd/tmctl/invocation.go:143`=`Stopping on it is a COMPLETION (exit 0), not a pause`. ⚠ Проводка в платформу ГЕЙЧЕНА (`PD-422`): единственный писатель признака движения банка — дверь правок, рост АВТО-банка от майнинга флага не ставит.
- **`--ceiling-usd` — КНИЖНЫЙ потолок, не бюджет прогона.** Дословно из флага: «the book USD ceiling in force for THIS RUN ONLY — it OVERRIDES book.yaml `ceilings.book_usd` and is never written back. It caps the book's CUMULATIVE committed+reserved spend, not this run's increment…» (`backend/cmd/tmctl/invocation.go:142`=`the book USD ceiling in force for THIS RUN ONLY`; ⚠-коммент `backend/cmd/tmctl/main.go:260`=`--ceiling-usd is NOT a per-run budget`; многоточие закрывает обрыв цитаты — во флаге дальше стоит «, and must be > 0»). Ратификация — D39.122 п.2(в): пересчёт «пользовательский прирост → абсолют» — обязанность ПЛАТФОРМЫ, вторая денежная ось не заводится. День-потолок флаг НЕ перекрывает (PD-157). Проводка внутри: `Ceilings.BookUSD` в `Reserve` и именование сработавшего потолка в ошибке — `backend/internal/pipeline/stagerun.go:496`=`BookUSD: r.bookCeilingUSD()` и `backend/internal/pipeline/stagerun.go:525`=`overrides the book's ceilings.book_usd` (стоп = `errReserveCeiling`, `backend/internal/pipeline/escalation.go:49`=`var errReserveCeiling`).
- **Потолки — wiring, не семантика:** `Ceilings` намеренно исключены из `BriefHash` («Wiring fields (paths, ceilings, db) deliberately excluded», `backend/internal/config/book.go:334`=`Wiring fields (paths, ceilings, db) deliberately excluded`; канон — `backend/internal/config/book.go:350`=`canon := struct {`) ⇒ смена ДЕНЕЖНОГО потолка не двигает ни снапшот, ни ре-билл (D39.110 п.2б). ⚠ Верно ровно про ДЕНЬГИ: потолок СЕГМЕНТАЦИИ `edit_ceiling_out` в снапшот ВХОДИТ и меняет границы чанков (`backend/internal/pipeline/snapshot.go:34`=`EditCeilingOut int`).
- **`status --json` отдаёт фигуры платформе:** `committed_usd`, `reserved_usd`, `book_ceiling_usd`, `ceiling_pct` = 100·(committed+reserved)/book_ceiling (`backend/internal/pipeline/status.go:311`=`book_ceiling_usd,omitempty`; арифметика `ceiling_pct``backend/internal/pipeline/status.go:811`=`100 * (committed + reserved)`). Дневной фигуры в status нет (PD-157 — `platform/docs/DEFECT_REGISTER.md`, греп `PD-157`).
- **Потолки — wiring, не семантика:** `Ceilings` намеренно исключены из `BriefHash` («Wiring fields (paths, ceilings, db) deliberately excluded», `backend/internal/config/book.go:345`=`Wiring fields (paths, ceilings, db) deliberately excluded`; канон — `backend/internal/config/book.go:369`=`canon := struct {`) ⇒ смена ДЕНЕЖНОГО потолка не двигает ни снапшот, ни ре-билл (D39.110 п.2б). ⚠ Верно ровно про ДЕНЬГИ: потолок СЕГМЕНТАЦИИ `edit_ceiling_out` в снапшот ВХОДИТ и меняет границы чанков (`backend/internal/pipeline/snapshot.go:34`=`EditCeilingOut int`).
- **`status --json` отдаёт фигуры платформе:** `committed_usd`, `reserved_usd`, `book_ceiling_usd`, `ceiling_pct` = 100·(committed+reserved)/book_ceiling (`backend/internal/pipeline/status.go:311`=`book_ceiling_usd,omitempty`; арифметика `ceiling_pct``backend/internal/pipeline/status.go:835`=`100 * (committed + reserved)`). Дневной фигуры в status нет (PD-157 — `platform/docs/DEFECT_REGISTER.md`, греп `PD-157`).
- **Леджер = НИЖНЯЯ граница** (строка 78 бэклога, `docs/PROGRESS.md`, греп `Леджер денег = НИЖНЯЯ граница`): «2xx body decode failed (call IS billed)» — провайдер списал, попытка в `request_log` не попадает; живой замер D39.86 — 3 вызова из 14, неизвестность $0.015111 при леджере $0.114378; движок сеттлит оценку и печатает `estimated-cost rows: 3`. Канал виден, фикс — money-паком (дизайн GENERALITY_PHASE2 §5.6).
- **Согласие на пере-оплату — ДВИЖКОВЫЙ гейт**. Прогон, который пере-покупает уже оплаченные юниты дороже порога, ОСТАНАВЛИВАЕТСЯ и требует явного согласия. Порог по умолчанию ратифицирован D20.2-Q2: `min($0.50, 5% × ProjectedBookUSD)`. Носитель — `backend/internal/pipeline/rebill.go`, греп `rebillConsentThreshold`; единственная ручка книги — `rebill_consent_usd` (валидатор `backend/internal/config/book.go`, греп `rebill_consent_usd`; 0 = ратифицированный дефолт). ⚠ Порог считается БЕЗ контура банк-ролей (D39.182 §3), то есть срабатывает позже, чем подсказывает полная проекция.

View file

@ -43,8 +43,8 @@
(`platform/internal/ingest/tail.go:17`=`const JournalFile = "events.jsonl"`, D39.106); без этого выноса буква ломает главный канал самого шва.
*Прецеденты:* потолок аргументом (D39.110 п.2б`--ceiling-usd`, D39.122) · `--verify-bank`
флагом (`platform/internal/runner/engine.go:99`=`func TranslateArgs(workdir string, verifyBank bool`) · дефолт `project_db` по конвенции каталога
(`backend/internal/config/book.go:189`=`b.ProjectDB = filepath.Join(dir, b.BookID+".db")`) · конвенционное опциональное чтение `.auto-bank.yaml`
(`backend/internal/pipeline/mining.go:617`=`.auto-bank.yaml`).
(`backend/internal/config/book.go:200`=`b.ProjectDB = filepath.Join(dir, b.BookID+".db")`) · конвенционное опциональное чтение `.auto-bank.yaml`
(`backend/internal/pipeline/mining.go:618`=`.auto-bank.yaml`).
2. **Посреди прогона внутрь идёт ТОЛЬКО сигнал.** `SIGTERM` = «дочти чанк и отпусти лок»; всё
остальное — на границах процессов. Арбитр — эксклюзивный flock проекта на всю жизнь прогона

File diff suppressed because one or more lines are too long

View file

@ -5256,7 +5256,7 @@ user-сообщения» на глаз. 2 436 токенов на 7 525 зна
шкале глоссарий в 300 знаков весит ~100 токенов и в оценке «на глаз» просто теряется.
**⛔ И это правит записанную ЦЕНУ движкового дефекта — но не открывает его заново.**
`backend/internal/pipeline/render.go:247-258`=`Role: "system"` кладёт первым `system` — **сам промт
`backend/internal/pipeline/render.go:311-316`=`Role: "system"` кладёт первым `system` — **сам промт
стадии**, вторым `system` — инъекцию банка (глоссарий/STM). Записанное следствие звучало как
«эскалационный хоп на Gemini тихо теряет глоссарий» (`00-provider-quirks.md:158`). По
установленному правилу всё наоборот:
@ -6877,7 +6877,7 @@ RL reasoning_tokens: 511 · 512 · 512 · 512 · 1005 · 1022 · 1023 · 1024
`temperature` — общие;
3. **исходник главы тот же** — манифест единиц приколот, и чтение никогда не переотбирает:
при смене текста uid меняется, приколотый исчезает из пересчитанных кандидатов и **покупка
останавливается** (`eval/role_topology/pair_en.py:132`=`def units`). Покупка 30.08 прошла ⇒ текст не менялся.
останавливается** (`eval/role_topology/pair_en.py:132`=`def units(n_per_stratum: int | None = None`). Покупка 30.08 прошла ⇒ текст не менялся.
⚠ Это не рассуждение, а гейт, который обязан был сработать и не сработал;
4. **шаблон промта не менялся**`onepass-core.md` последний раз тронут **20.08**, за день до
покупки `RN`; пар-блоки и бриф с 20.08 не менялись вовсе (`git log --since=2026-08-20`, пусто);
@ -7085,7 +7085,7 @@ RN» переносила отношение с САМОЙ ДУМАЮЩЕЙ гл
**$0.078 (кэш прогрет) … $0.133 (кэш холодный на каждой клетке)**. ⛔ ~~то есть запас ~2× даже по худшему концу~~ — **СНЯТО, разбор абзацем ниже: запаса не было вовсе.**
**Как именно защищены деньги — по коду, а не по намерению.** Гард `money.Guarded.afford()`
(`eval/tenant_panel/money.py:149`=`def afford`) проверяется **перед КАЖДОЙ клеткой** и отказывает, когда
(`eval/tenant_panel/money.py:149`=`def afford(self) -> tuple[bool, str]`) проверяется **перед КАЖДОЙ клеткой** и отказывает, когда
`потрачено + ожидание > потолок`.
⛔⛔ **И ЗДЕСЬ Я СОЛГАЛ САМ СЕБЕ ИМЕННО В ТОЙ ФРАЗЕ, ГДЕ ОБЕЩАЛ ЧИТАТЬ КОД (баннер консилиума 30.08).**
@ -7736,8 +7736,8 @@ $0.040093 — расхождение 0.0%). Значит прайс-таблиц
`rerun2` ставил dspro первым (0.679 против 0.589) — приборы согласны лишь в том, что зазор мал;
(2) пик у DeepSeek — только будни 0104 и 0610 UTC, то есть ответ зависит от РАСПИСАНИЯ прогона,
а не только от модели; (3) выбор жильца — конфиг `backend/`, зона бэкенда и лендинг оркестратора.
* ⛔ **Носитель решения врёт прямо сейчас.** `backend/configs/pipeline-c1.yaml:65`=`×2 дешевле glm` и
`backend/configs/pipeline-arm-glm.yaml:6`=`×2 дешевле` до сих пор обосновывают выбор словами «×2 дешевле glm».
* ⛔ **Носитель решения врёт прямо сейчас.** `backend/configs/pipeline-c1.yaml:95`=`×2 дешевле glm` и
`backend/configs/pipeline-arm-glm.yaml:6`=`×2 дешевле). glm-5 держим ЖИВЫМ` до сих пор обосновывают выбор словами «×2 дешевле glm».
Это устаревшее обоснование в БОЕВОМ конфиге. Правка — зона бэкенда; **пинг сдан этой секцией.**
### Д51.4. Дешёвый ход, который виден из этих же данных