Write down what three independent readings found about the spend ceiling: the shape is wrong rather than the rate, a paid call can vanish from the ledger on the happy path, and the fork is the owner's
This commit is contained in:
parent
1b8aa86cce
commit
0fafdd4bee
1 changed files with 116 additions and 0 deletions
|
|
@ -69,3 +69,119 @@
|
|||
| Бэклог-строки | `docs/PROGRESS.md` строки 78 · 136 · 137 · 166 (135 и 165 закрыты D39.131) |
|
||||
| Контракт наружу | `14-api-contract/openapi.yaml` (`CeilingBounds`, `Usage`); ПТ-35 |
|
||||
| Запрет денег на экране | D39.84; D39.100/К-8; ПТ-35 |
|
||||
|
||||
---
|
||||
|
||||
## ⚠ ОТКРЫТАЯ РАЗВИЛКА 04.09: КНИГУ НЕЛЬЗЯ ДОЧИТАТЬ — разбор трёх независимых чтений, решение за владельцем
|
||||
|
||||
> **Статус: НЕ РАТИФИЦИРОВАНО.** Это разбор, а не контракт: ниже нет ни одного решения, только сходящаяся
|
||||
> фактура и названная развилка. Носитель дефекта — `PD-440`/`PD-441` в регистре платформы. Собрано по
|
||||
> прямому указанию владельца «посоветуйся с зонами и со старшей моделью»: читали независимо зона движка,
|
||||
> зона платформы и внешний рецензент другой модели; расхождения между ними названы, а не сглажены.
|
||||
|
||||
**ЧТО НАБЛЮДАЛОСЬ.** Первый живой ПЛАТНЫЙ прогон книги через API (04.09) остановился, не продвинув книгу
|
||||
ни на юнит, и воспроизвёлся дважды. Прогон умирает за 10–15 секунд, списание не двигается.
|
||||
|
||||
**ПОЧЕМУ — цепь, проверенная тремя чтениями независимо.** Запас нового прогона на НОВЫЕ траты равен
|
||||
`chaptersLeft × ставка` (`platform/internal/runs/spawn.go`, греп `func (m meter) bookCap`; ставка
|
||||
`DefaultPerChapter = 30_000` микро-USD). Резерв ОДНОГО редакторского вызова — worst case по `maxTokens`
|
||||
(`backend/internal/pipeline/stagerun.go`, греп `func (r *Runner) callEstimateUSD`), замеренный отказ в
|
||||
ряду `PD-440` — `denied estimate=$0.069828`. Отказ резервации трактуется как **авария всей книги**:
|
||||
`runWave` зовёт `cancel()` производного контекста на ПЕРВОЙ ошибке любого рода, и уже допущенные
|
||||
параллельные вызовы гасятся.
|
||||
|
||||
**ТРИ УТВЕРЖДЕНИЯ, СОШЕДШИЕСЯ У ВСЕХ ТРЁХ ЧТЕНИЙ:**
|
||||
|
||||
1. **Форма потолка неверна, а не только его размер.** Запас сжимается вместе с остатком книги, стоимость
|
||||
неделимого шага — нет. Ставку можно поднять, стену это отодвинет, но не уберёт. Правильная форма —
|
||||
`max(главы × ставка, шаг)`, а не `главы × ставка`.
|
||||
2. **Резервацию убирать нельзя.** Она — единственный сериализованный контроль и единственное, что держит
|
||||
обещание «не потратить больше, чем дано». Отраслевой стандарт тот же (см. прайор-арт ниже).
|
||||
3. **Менять надо ТРАКТОВКУ ОТКАЗА**, а не наличие резервации: «не начинаем новое» вместо «гасим всё».
|
||||
|
||||
**ЧИСЛА, В КОТОРЫХ ЧТЕНИЯ РАСХОДЯТСЯ — и оба верны на своём числе воркеров.** Зона платформы: стена
|
||||
стоит везде, где `chaptersLeft × ставка < workers × шаг`, при боевых четырёх воркерах это
|
||||
`chaptersLeft ≤ 9` — недостижим не хвост, а **последние девять глав любой книги**. Внешний рецензент:
|
||||
даже при ОДНОМ воркере `2 × $0.03 = $0.06 < $0.07` одного вызова, то есть **последние две главы
|
||||
недостижимы в принципе**, независимо от параллельности. Второе — инвариантный пол, первое — сегодняшняя
|
||||
конфигурация.
|
||||
⚠ **Предсказание зоны платформы, ЗАМЕР ЗАКАЗАН, на момент записи НЕ подтверждён:** книга из ≤9 глав может
|
||||
не переводиться вообще никогда. Проверяется за $0 на пятиглавой книге. До подтверждения — предсказание.
|
||||
|
||||
**ЧЕТВЁРТОЕ, ЧЕГО НЕ БЫЛО В ИСХОДНОМ ДИАГНОЗЕ (зона движка).** Резерв завышен ПО ПОСТРОЕНИЮ: оценка
|
||||
считается по потолку выдачи. Под нынешним поведением он никогда не превращается в факт — его отпускают,
|
||||
и следующее решение о допуске принимается против тех же завышенных чисел. Под «не начинаем новое»
|
||||
соседи доседают по ФАКТИЧЕСКОЙ цене и освобождают разницу. Это само по себе может быть разницей между
|
||||
«встала» и «дошла».
|
||||
|
||||
**ПЯТОЕ — ПРЕЦЕДЕНТ ВНУТРИ ЭТОГО ЖЕ ПАКЕТА, и он решает спор о направлении.** Объёмный потолок уже
|
||||
построен с нужной семантикой и САМ противопоставляет себя денежному:
|
||||
`backend/internal/pipeline/volume.go`, греп `THE STOP IS A COMPLETION, NOT A HALT` — «денежный потолок
|
||||
останавливает прогон ПОСРЕДИ работы, которую он собирался сделать». Там же названа причина, по которой
|
||||
допуск не сделан счётчиком у воркеров: «воркер, которому отказали в слоте, был бы вынужден бросить свой
|
||||
элемент навсегда» — то есть ровно тот дефект, который денежный путь и имеет. Плюс три места уже
|
||||
деградируют по `errReserveCeiling` вместо аборта (`escalation.go`, `repair.go`, `terminologist.go`);
|
||||
не деградирует только главная волна.
|
||||
|
||||
**ШЕСТОЕ — ДЕФЕКТ, ПЕРЕЖИВАЮЩИЙ ЛЮБУЮ ПОЧИНКУ РАЗМЕРА И ФОРМЫ (зона платформы).** Стена МОЛЧАЛИВА:
|
||||
прогон, вставший мгновенно, неотличим на всех поверхностях от работавшего — одинаковый статус, одинаковая
|
||||
причина паузы, одинаковая полоса (наблюдение H16 зонного журнала, два прогона: $0.081 и $0). Недобрать
|
||||
можно при любом потолке; сказать об этом сегодня нечем.
|
||||
|
||||
**ВЕС — ЖИВУЧЕСТЬ, НЕ ДЕНЬГИ.** Мёртвые прогоны рассчитались в ноль, леджер сходится тремя источниками
|
||||
до микродоллара. Пользователь теряет ВРЕМЯ. ⚠ Отдельно и с другим весом — `PD-441`: на пути отмены есть
|
||||
расход, который, ЕСЛИ он был, невидим для леджера по построению. Доказуемая форма именно такая; «деньги
|
||||
потрачены» НЕ измерено. Одна движковая попытка — до трёх запросов к провайдеру (`backend/internal/llm/httpllm.go`,
|
||||
греп `for att := 0; att < profile.MaxAttempts`, дефолт 3) под ОДНИМ резервом и ОДНОЙ строкой `request_log`:
|
||||
след не просто беден, он агрегирован и не различает «не ушло ничего» от «ушло трижды».
|
||||
|
||||
**ПРАЙОР-АРТ (внешний рецензент, ссылки — в отчёте сессии).** LiteLLM делает буквально наше:
|
||||
worst-case-резерв → отказ до отправки → замена фактической ценой; их известные баги — про ОБХОД бюджета
|
||||
при параллельных запросах, то есть отраслевая беда противоположна нашей. Ближайший по смыслу стандарт —
|
||||
Diameter Credit-Control (RFC 4006/8506) с `Final-Unit-Indication`: «это последний грант, доработай его и
|
||||
не начинай нового» — ровно та семантика, которой нам не хватает. Kubernetes `ResourceQuota`: отказ — это
|
||||
недопуск НОВОГО, уже созданное квота не трогает. Slurm `GraceTime`: слив вместо убийства. Карточная
|
||||
пре-авторизация: холд с запасом, списание по факту. ⚠ Про биллинг при обрыве: OpenRouter документирует,
|
||||
что для непотоковых запросов отмена клиентом биллинг НЕ останавливает — это факт о ЕГО платформе, для
|
||||
наших провайдеров вопрос обязан быть закрыт вендор-докой по правилу `experiments/00-provider-quirks.md`,
|
||||
а не рассуждением.
|
||||
|
||||
**РАЗВИЛКА ВЛАДЕЛЬЦА — ОДНА, И ЕГО ПРЕДЛОЖЕНИЕ ЕЁ РЕШАЕТ, А НЕ ОБХОДИТ.** Предложение владельца
|
||||
(«называть примерную цену и останавливаться, когда деньги кончились») означает, что потолком становится
|
||||
БАЛАНС. Тогда холд берёт весь баланс вперёд, и вторая книга не стартует, пока не рассчитается первая.
|
||||
Это ровно та развилка, которую код уже держит открытой и помечает вопросом к владельцу:
|
||||
`platform/internal/pricing/pricing.go`, греп `which fraction is a product question`. ⚠ Отдельный выбор
|
||||
того же разговора: платят вызовом за ЮНИТ, а человек видит и выбирает ГЛАВЫ, и ставка за главу сама
|
||||
признаёт слабость (греп `chapters differ in length`); `units_total` известен платформе до всякой оплаты.
|
||||
|
||||
**ЧТО СЧИТАЕТСЯ ЗАКРЫТЫМ И БОЛЬШЕ НЕ ОБСУЖДАЕТСЯ:** уже проданные прогоны смену ставки переживают без
|
||||
миграции — продолжение оценивается по тому, за что прогон был ПРОДАН, бюджет читается обратно из холда
|
||||
первой попытки, пин `TestARestartHoldsWhatTheRunWasSoldForWhenTheRateHasMovedSince`.
|
||||
|
||||
**СЕДЬМОЕ — ЕДИНИЦА УЧЁТА НЕ СОВПАДАЕТ С ЕДИНИЦЕЙ БИЛЛИНГА, и это бьёт не в отчётность, а в ЦЕЛОСТНОСТЬ
|
||||
потолка** (найдено зоной движка чтением под вопрос, проверено оркестратором по строкам). Класс
|
||||
`BilledDecodeError` заведён ровно для того, чтобы оплаченный-но-нечитаемый вызов стал ВИДЕН: рантайм
|
||||
консервативно доседает его по оценке. Комментарий рядом сам называет цену ретрая —
|
||||
`backend/internal/llm/httpllm.go`, греп `each retry is a new billed`, — и по этой причине УСЕЧЁННЫЙ ответ
|
||||
сделан терминальным. Но битое тело осталось ретраябельным, а `retryLoop` при успешном ретрае возвращает
|
||||
ответ и предыдущую ошибку ВЫБРАСЫВАЕТ (греп `if err == nil {` в `retryLoop`). Тогда рантайм видит один
|
||||
успешный ответ, доседает его `Usage`, и оплаченный 2xx перед ним не попадает НИКУДА — ни в списание, ни
|
||||
отдельной строкой лога. **Механизм, построенный чтобы сделать оплаченный вызов видимым, обходится ровно
|
||||
на том пути, где всё прошло хорошо.** Следствие для потолка: допуск выдан один раз под одну оценку; если
|
||||
под ней прошло два оплаченных ответа, `Reserve` об этом не узнает никогда — он сравнивает с потолком
|
||||
сумму, в которой невидимого запроса нет. Потолок не «пробивается громко», он считает не то.
|
||||
⚠ **Границы:** структурность доказана чтением; ЧАСТОТА пути НЕ измерена и, вероятно, мала — владельцу
|
||||
эти две вещи давать раздельно. Более слабый родственник — сетевой обрыв/таймаут (там же комментарий про
|
||||
`mid-generation RST that re-bills the call`): вход тот же, но «оборвалось на середине ⇒ оплачено» уже
|
||||
вывод о провайдере, а не утверждение кода.
|
||||
|
||||
**ВЕНДОРСКИЙ ВОПРОС — ДВОЙНОЙ, и вторая половина конкретнее первой:** (1) платит ли провайдер за запрос,
|
||||
оборванный КЛИЕНТОМ после начала генерации; (2) сколько раз он берёт деньги, когда мы ретраим ПОСЛЕ
|
||||
оплаченного 2xx. Второй случай не гипотетический — он уже назван оплаченным в нашем собственном коде.
|
||||
Оба закрываются вендор-докой по правилу `experiments/00-provider-quirks.md`, а не рассуждением.
|
||||
|
||||
**ГРАНИЦА ИНСТРУМЕНТА, ЗАМЕРЕННАЯ ЭТИМ ЖЕ ЗАХОДОМ.** Каталог мутаций (141 запись, 136 красных, ноль
|
||||
переживших) доказывает ПОВЕДЕНИЕ и молчит о том, что код УТВЕРЖДАЕТ о себе. Круг 3 нашёл четыре
|
||||
сверх-утверждения — и **ни одно не нашла посадка**; обе сегодняшние денежные находки получены чтением под
|
||||
вопрос. Рабочая форма вопроса, выведенная зоной движка: не «правда ли то, что здесь написано», а **«что
|
||||
должно было бы сломаться, если это правда, и ломается ли оно»**.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue