Take the double-payment order into the tree with its premise the right way up: the retry works, and the two causes behind it need different answers
This commit is contained in:
parent
fdc514cd50
commit
b983d5e516
3 changed files with 380 additions and 2 deletions
369
docs/BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md
Normal file
369
docs/BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
# Бэкенд-пак: ЗА ОДНУ ЕДИНИЦУ ПЛАТИМ ДВАЖДЫ — и по двум РАЗНЫМ причинам, которые движок не различает
|
||||
|
||||
> Выдан оркестратором №23, 11.09. Зона записи — `backend/`. Пак КОДОВЫЙ, платных вызовов НЕ несёт.
|
||||
> ⚠ **Редакция 2.** Первая была построена на перевёрнутой посылке («движок лечит болезнь возбудителем») и
|
||||
> заказывала отключить восстановление, которое на замере работало. Опровергатель это снял; ниже —
|
||||
> исправленное, и след правки виден в §1.
|
||||
|
||||
## 1. Какая проблема и что решит твой результат
|
||||
|
||||
На живом платном прогоне книги 11.09 **движок заплатил дважды за четыре единицы из двадцати семи**:
|
||||
первая попытка вернула HTTP 200 без пригодного текста, выходные токены были выкуплены и выброшены, вторая
|
||||
попытка вернула текст. Цена выброшенного — **$0.106472 = 25.4 % всей цены книги**. Из них три вызова дали
|
||||
РОВНО ноль знаков (**$0.094835 = 22.6 %**), четвёртый — обрезок с текстом ($0.011637).
|
||||
|
||||
⛔ **И вот что надо знать ДО того, как начнёшь чинить: лекарство работает.** Перевыпуск с удвоенным
|
||||
потолком вернул текст **4 раза из 4**. Претензия к нему ДЕНЕЖНАЯ (оплачена выброшенная попытка), а не
|
||||
медицинская. **Не выключай его.** Первая редакция этого промта утверждала обратное, и сессия, исполнившая
|
||||
её буквально, отключила бы восстановление трёх чанков из четырёх.
|
||||
|
||||
**Настоящая находка — в том, что двойных оплат ДВЕ РАЗНЫХ, а движок применяет к ним одно лекарство.**
|
||||
Пере-снято мною по базе прогона (`bk_ROEHZBD46ALFI43E/project.db`, стадии `draft`/`edit`, `tm_hit=0`):
|
||||
|
||||
| единица | 1-я попытка | 2-я попытка | что это значит |
|
||||
|---|---|---|---|
|
||||
| `draft` ch1u0 | comp **8496** · `length` · пусто · $0.012044 | **15869** · `stop` ✓ | потолка не хватило |
|
||||
| `draft` ch2u1 | comp **8496** · `length` · обрезок · $0.011637 | **13004** · `stop` ✓ | потолка не хватило |
|
||||
| `draft` ch3u0 | comp **8496** · `length` · пусто · $0.011782 | **14034** · `stop` ✓ | потолка не хватило |
|
||||
| `edit` ch2u0 | comp **16000** · `length` · пусто · **$0.071009** | **11717** · `stop` ✓ | потолка ХВАТАЛО |
|
||||
|
||||
⭐ **Контроль, и он режет популяцию без единого исключения.** Успешных черновых вызовов в прогоне ШЕСТЬ,
|
||||
их размеры: `6468 · 7932 · 8243 · 13004 · 14034 · 15869`. **Все три, что уложились в 8496, прошли с первого
|
||||
раза. Все три, что не уложились, с первого раза упали и прошли на удвоенном потолке. 6 из 6, исключений
|
||||
ноль.** ⇒ на черновике это НЕ болезнь размышления и не случайность: **первый потолок просто меньше того,
|
||||
что эта стадия реально производит на половине единиц**, и удвоение делает работу, которую должна была
|
||||
сделать оценка бюджета.
|
||||
|
||||
⛔ **А четвёртый случай — противоположный, и он стоит ДВУХ ТРЕТЕЙ всей потери в ОДНОМ вызове.** У `edit`
|
||||
потолок 16000 был заведомо достаточен: вторая попытка уложилась в 11717. Значит первый вызов выкупил 16000
|
||||
токенов чего-то, что не было текстом. Это размышление — у DeepSeek оно считается ВНУТРИ выходных токенов
|
||||
(`reasoning ⊆ completion`), и здесь удвоение потолка действительно даёт ему вдвое больше места.
|
||||
|
||||
**Что решит твой результат.** Движок научится отличать «не хватило потолка» от «потолок съело размышление»
|
||||
и перестанет платить за первое по цене второго. Плюс причина станет ВИДНА: сегодня спросить «что
|
||||
случилось» нечем — колонка `reasoning_tokens` не несла числа ни разу за историю проекта, а цена считается
|
||||
подстановкой, о которой никто не узнаёт.
|
||||
|
||||
⛔ **Чего этот пак НЕ делает:** не выключает перевыпуск (он работает) · не меняет боевые значения
|
||||
`reasoning` в конфигах (ждёт полигонного замера, §4.2) · не правит пин цены flash (данные, ряд 413) · не
|
||||
трогает `books/` · не заводит новых стадий пайплайна.
|
||||
|
||||
## 2. Зона записи и git
|
||||
|
||||
Зона — **`backend/`**. Читать можно всё; писать — только в свою зону.
|
||||
|
||||
⛔ **Ты НЕ коммитишь.** Коммитит оркестратор при лендинге. Готовое дерево оставляешь как есть и
|
||||
сообщаешь. Не делай `git add`, `git commit`, `git stash`, `reset --hard`, `checkout` поверх грязного
|
||||
дерева: в дереве параллельно работают другие сессии, и их незакоммиченные правки стираются безвозвратно.
|
||||
Канон — `CLAUDE.md` §«Git-координация мультисессий», он сильнее этого абзаца.
|
||||
|
||||
Свои итоги, пинги и вопросы пиши в СВОЮ секцию «Бэкенд» журнала `docs/PROGRESS.md`. Это единственное
|
||||
исключение из «`docs/` — зона оркестратора».
|
||||
|
||||
## 3. Карта чтения (ЗАКОН, пять позиций; дальше — только по её ссылкам)
|
||||
|
||||
1. `CLAUDE.md` — ты его уже получила.
|
||||
2. **`docs/experiments/00-provider-quirks.md`, пункт 3 ЦЕЛИКОМ** (подпункты 3а · 3б · 3в · 3г · 3д —
|
||||
именно все пять). ⛔ Читать ДО любой правки адаптеров и вызовов; здесь их копий нет, а §3г
|
||||
переписывался ТРИЖДЫ и две прежние редакции были неверны — читай действующую, не мой пересказ.
|
||||
3. `backend/README.md` — механика движка.
|
||||
4. `docs/architecture/12-go-style-notes.md` — норматив стиля, только больные места.
|
||||
5. Ряды бэклога **414 · 415 · 422** и **413** (`docs/BACKLOG.md`) — носители замеров, на которых стоит пак.
|
||||
|
||||
**Код-факты добывай САМА.** Все `file:line` ниже — отправные точки, а не истина: истина — дерево.
|
||||
Если адрес уехал, это находка, и она идёт в отчёт.
|
||||
|
||||
**Ратифицированное, что тебе понадобится (вложено сюда, грепать не надо):**
|
||||
|
||||
* ⭐ **`D2` — основание пака, и читать надо ОБА уточнения, 2 и 3.** Решение: `finish=length` → ретрай с
|
||||
бо́льшим `max_tokens` до капа, потом флаг; пустой оплаченный → skip+flag (не падение прогона).
|
||||
⛔ **п.2 ратифицировал, что `empty` ПЕРЕАТАКУЕТСЯ:** «`retry-flagged` переатакует **только**
|
||||
`length`/`empty` на той же модели». Это исполнено и ЗАПИНЕНО — `internal/pipeline/disposition.go:211`=`func (r FlagReason) retryable() bool`
|
||||
`func (r FlagReason) retryable() bool { return r == FlagLength || r == FlagEmpty }`, пин
|
||||
`TestRetryableSubset` (`disposition_test.go:90`=`TestRetryableSubset`). ⇒ **всякое изменение ТОГО, ЧТО переатакуется, отменяет
|
||||
`D2` п.2 и двигает этот пин — это пинг мне ДО кода, а не правка.** Не соблазняйся «подогнать»
|
||||
`TestRetryableSubset` как заказанную смену поведения: она НЕ заказана.
|
||||
⭐ **п.3 — принцип, который ты распространяешь:** «Детектор вырождения ПЕРЕД удвоением max_tokens…
|
||||
бо́льший max_tokens лишь оплачивает больше повтора… при вырождении сразу флаг, без оплаты цикла».
|
||||
Он исполнен ДЛЯ ОДНОЙ причины (петля повтора, `disposition.go` рядом с `distinctRatio`) и не исполнен
|
||||
для второй — «размышление съело потолок», которую тогда не знали. **Твоя работа — распространить наш
|
||||
же образец, а не завести новый.**
|
||||
* **`D24` п.3** — per-model флор `min_max_tokens` РАТИФИЦИРОВАН схемой (capability-слой `models.yaml`, не
|
||||
комментарий); флор у `deepseek-v4-flash`/`pro` там назван **8000**. ⚠ Подъём `pro` до **16000** — НЕ из
|
||||
ноты: это `backend/configs/models.yaml` (блок `deepseek-v4-pro`, `min_max_tokens: 16000`) по замеру
|
||||
мини-прогона 25.07, и цена того замера — 15.5 % счёта прогона в двух выброшенных генерациях.
|
||||
* **`D39.86`/`D39.87`** (02.08) — гипотеза «поднять флор» ФАЛЬСИФИЦИРОВАНА замером. ⛔ **Но узко, и
|
||||
`D39.90` п.9 это прямо сузил, сняв над-клейм:** «число флора влияет на цену ретрая, а не на
|
||||
проходимость» — незамеренная экстраполяция; **при `low` флор не варьировался НИ РАЗУ**. ⇒ «потолок не
|
||||
рычаг» проверено на вендор-дефолтном эффорте; **на `low` не проверено никем — а черновик прогона шёл
|
||||
именно на `low`.** Это прямо касается §4.1: три из четырёх двойных оплат живут в непроверенной области.
|
||||
* **`D39.87` §2 — приёмочный вопрос, который держит тебя от тиражирования дефекта.** Дословно: «появится
|
||||
ЧЕТВЁРТАЯ такая стадия — она унаследует ручку сама или её опять забудут?». Ответ в дереве уже
|
||||
структурный: единственная деривация стадии для внутреннего вызова — `internal/config/internal_call.go`,
|
||||
единственный словарь эффорта — `ValidReasoningEffort` там же, и оба стережёт статический анализатор
|
||||
`internal/archguard/` («an engine-internal call must derive its stage through config.InternalCall.Stage()»),
|
||||
который гоняется обычной батареей. ⇒ **новое измерение решения обязано ехать ЭТИМ швом.** Рукописных
|
||||
`config.Stage{…}` в шиппинг-коде сегодня ноль — проверь сама и не заведи первый.
|
||||
* **`D39.121`** — тесты и гейты не подгонять под зелень. Правка теста, вызванная ЗАКАЗАННОЙ этим паком
|
||||
сменой поведения, — обслуживание, и её надо ОБЪЯВИТЬ в отчёте (что изменилось, какой тест это
|
||||
описывал, куда уехала гарантия). Правка *чтобы прошло* — недопустима.
|
||||
|
||||
## 4. Заказ. У каждого пункта размечена свобода
|
||||
|
||||
### 4.1. Две причины — два лекарства — ЯДРО ПАКА · «реши сама и аргументируй»
|
||||
|
||||
**Что уже построено и что ты ЧИТАЕШЬ, а не заводишь.** Классификация отказа есть и сохраняется:
|
||||
`FlagEmpty`/`FlagLength` (`internal/pipeline/disposition.go:59`=`2xx with no usable text`), `degradedTag` (`stagerun.go:921`=`degradedTag surfaces a flag reason`),
|
||||
колонка `request_log.degraded`. ⭐ **И дискриминатор «размышление внутри выходных токенов» ТОЖЕ уже
|
||||
построен и живёт в ДАННЫХ:** в `backend/configs/models.yaml` у провайдера `deepseek` стоит
|
||||
`reasoning: subset`, у `xai` — `additive`, у `gemini` — `additive_total`; поле объявлено в
|
||||
`internal/config/models.go` (`Reasoning string`, комментарий `subset | additive | additive_total`),
|
||||
резолвер — `providerReasoning()` там же, словарь — `internal/llm/provider_openai.go`
|
||||
(`ReasoningSubset`/`ReasoningAdditive`/`ReasoningAdditiveTotal`). ⇒ **ось «subset против additive»
|
||||
ЧИТАЕТСЯ. Второй разметки не заводить.** Найдёшь расхождение — находка, в отчёт.
|
||||
|
||||
А выбор лекарства этого не спрашивает: `maxTokensForAttempt(base, escalations)`
|
||||
(`internal/pipeline/disposition.go:481`=`func maxTokensForAttempt`) принимает **счётчик удвоений и больше ничего**.
|
||||
|
||||
**Что построить: различение двух причин и разные ответы на них.** Приор — опровергается аргументом или
|
||||
замером, и я жду именно опровержения, если оно у тебя будет:
|
||||
|
||||
| причина | улика в данных | сегодня | приор |
|
||||
|---|---|---|---|
|
||||
| **потолок мал** — ответ не влез | 2-я попытка дала БОЛЬШЕ, чем потолок 1-й | удвоить и заплатить дважды | **чинить ОЦЕНКУ первого потолка**, а не перевыпуск: единица, которой заведомо мало, не должна покупать заведомо провальную попытку |
|
||||
| **размышление съело потолок** | 2-я попытка дала МЕНЬШЕ, чем потолок 1-й (`edit`: 11717 < 16000) | удвоить — то есть дать размышлению вдвое больше места | **ступень эффорта ниже при ТОМ ЖЕ потолке** — но см. ⛔ ниже, величина не замерена |
|
||||
| `length` **с текстом** | обрезок доехал | удвоить | **оставить как есть** — это ровно решение `D2` |
|
||||
|
||||
⛔ **ЧЕГО В ТАБЛИЦЕ НЕТ И НЕ ДОЛЖНО БЫТЬ: «не перевыпускать».** На замеренных данных это стоило бы трёх
|
||||
восстановленных чанков из четырёх и отменяло бы `D2` п.2. Вопрос — в ЦЕНЕ попытки, а не в её отмене.
|
||||
|
||||
⛔ **И ВОТ ГДЕ ВЫРАСТЕТ ВЕЛОСИПЕД, ЕСЛИ НЕ СМОТРЕТЬ.** «Ступень ниже» требует знать, какие ступени есть у
|
||||
ЭТОГО провайдера, — а словарь эффорта в движке **намеренно провайдер-СЛЕПОЙ**, и это объявлено известным
|
||||
пределом: доккомментарий `ValidReasoningEffort` дословно — «Validating against the RESOLVED model's
|
||||
capability would need a new per-model table — a new mechanism, not a use of an existing one — so it stays
|
||||
a named finding, not a silent gap». ⇒ **пер-модельная таблица ступеней — НОВЫЙ механизм, молча его не
|
||||
заводить.** Три законных выхода, выбирай с доводом: (1) шаг вниз по НЕЙТРАЛЬНОМУ словарю движка; (2) не
|
||||
трогать эффорт вовсе и решать денежную задачу через оценку первого потолка — тогда таблица не нужна
|
||||
совсем; (3) таблица — но это отдельное решение и пинг мне ДО кода. ⚠ Разница с осью `subset`/`additive`
|
||||
выше именно в этом: та **построена и читается**, эта **не построена и без письма не заводится**.
|
||||
|
||||
⛔ **ДВЕ ОГОВОРКИ О СИЛЕ УЛИК, обе обязательны в твоём отчёте.**
|
||||
**(а) Величина среза размышления НЕ УСТАНОВЛЕНА.** Квирки §3г: параметр `low` до `pro` ДОХОДИТ (доказано
|
||||
поведенческой пробой 30.08), но «ВЕЛИЧИНА среза по-прежнему не установлена… наблюдённые ×2.52 сняты
|
||||
блоками, разнесёнными на 9 дней». То есть «ступень ниже» — законный ПАРАМЕТР, но не доказанное лекарство.
|
||||
**(б) Весь денежный довод стоит на ЧЕТЫРЁХ одиночных розыгрышах.** Квирки §3д: «два одиночных розыгрыша
|
||||
дефолтного пути `deepseek-v4-pro` разошлись в 38 раз… любая смета DeepSeek, снятая с ОДИНОЧНОГО прошлого
|
||||
вызова, может ошибиться на порядок… сметы и сравнения нужно строить на ПОВТОРАХ». ⇒ у моих чисел есть ЗНАК
|
||||
и нет ВЕЛИЧИНЫ. Контроль «6 из 6 без исключений» (§1) знак усиливает, но повторами не является.
|
||||
|
||||
⛔ **Никаких велосипедов в остальном.** Не заводи вторую таксономию отказов, не пиши свой классификатор
|
||||
ответа, не добавляй параллельный счётчик попыток. Работа — **дать существующему лекарству прочитать
|
||||
существующий класс**. Если существующая классификация окажется непригодной — это находка, назови её и
|
||||
аргументируй, прежде чем строить рядом.
|
||||
|
||||
### 4.2. Ручка усилия у редактора — ⛔ НЕ ТРОГАЙ БОЕВОЙ КОНФИГ · «делай РОВНО так»
|
||||
|
||||
Соблазн: «на `edit` стоит `reasoning: "off"`, вызов всё равно думает — поставим `low`». **В этом паке не
|
||||
делай.** Причина не та, что подскажет интуиция:
|
||||
|
||||
* **Ручка есть и ратифицирована.** `ReasoningNone` — OpenAI-совместимая база: `low|medium|high` уходят как
|
||||
`reasoning_effort`; ничего не эмитят только `off` и пустая строка, и тогда едет вендор-дефолт `high`.
|
||||
Именно `off` стоит у редактора в `backend/configs/pipeline-c1.yaml` — **это ВЫБОР конфига, а не
|
||||
невозможность.** Проверь чтением `internal/llm/capability.go` сама.
|
||||
* **«На pro рычага нет» больше не правда.** Вендор сменил маппинг; полигон снял поведенческую пробу 30.08
|
||||
за $0.038276 и показал, что `low` до `pro` доходит. Живая запись — квирки §3г.
|
||||
* ⇒ **ось «`off` против `low`» измеряется ОТДЕЛЬНЫМ КОНФИГОМ КНИГИ. Это ДАННЫЕ**: ни правки Go, ни снятия
|
||||
защиты; гейт эхо-мины требует `off` только у шиппинг-конфигов `pipeline-c1`/`c2`.
|
||||
* ⛔ **Цена рычага измерена с другой стороны:** `effort: "low"` **пере-вооружает эхо-мину** — на плотном CJK
|
||||
с ослабленным размышлением модель возвращает ИСХОДНИК под HTTP 200. ⚠ Честно про силу этой улики: в
|
||||
квирках это **1 чистый китайский выход из 16**, то есть знак есть, а «воспроизводимо» было бы
|
||||
преувеличением. Единственная чистая проба на `low` шла на АНГЛИЙСКОЙ паре и предупреждения не снимает.
|
||||
|
||||
⇒ это **РАЗМЕН «дорого и пусто» против «дёшево и эхо»**, и вслепую его не разменивают. Замер закажет
|
||||
оркестратор полигону, на плотном CJK.
|
||||
|
||||
**Твоя работа — две вещи, обе без правки боевых значений.** (а) Построй §4.1 так, чтобы ступень усилия
|
||||
была ПАРАМЕТРОМ решения, а не константой, — через шов `internal_call.go`. (б) Напиши в отчёт ОДНИМ абзацем
|
||||
заказ полигону: что меряем, на каком входе, **сколько повторов** (см. §3д), какой результат означает
|
||||
«меняем», какой — «не меняем». Я отдам его дословно, поэтому пиши как заказ, а не как пожелание.
|
||||
|
||||
### 4.3. `reasoning_tokens` не несла числа ни разу · «реши сама и аргументируй»
|
||||
|
||||
Замер оркестратора 11.09: `request_log.reasoning_tokens > 0` — **0 строк**. Контроль рядом: найдено
|
||||
**448** файлов `*.db`, таблицу `request_log` несут **405**, прочитано **58 886** строк, колонка объявлена
|
||||
схемой и присутствует во всех. ⇒ единственная колонка, которой доказывают «потолок съело рассуждение»,
|
||||
структурно молчит, и её ноль неотличим от «рассуждения не было».
|
||||
|
||||
Причина известна и не баг нашего кода: DeepSeek считает рассуждение внутри `completion_tokens` и отдельным
|
||||
полем usage не присылает. Но следствие наше: **прибор врёт молчанием** — а именно этим прибором отличают
|
||||
две причины из §4.1 друг от друга.
|
||||
|
||||
Реши сама и аргументируй: вынуть число из тела ответа, где оно есть (у DeepSeek приходит
|
||||
`reasoning_content` — проверь), либо честно пометить «провайдер не сообщает» так, чтобы ноль перестал
|
||||
читаться как измеренный. ⛔ Запрет один: **не оставляй ноль без различения.**
|
||||
|
||||
### 4.4. Признак отказа и прибор, которым смотрят деньги · «реши сама и аргументируй»
|
||||
|
||||
⚠ Формулировка ряда 414 была неверна и исправлена 11.09 — не наследуй старую. Измеренная правда по базе
|
||||
прогона (33 строки): провал виден **тремя** колонками, и все три сходятся ровно на $0.106472 — `ok = 0` на
|
||||
четырёх провальных и `1` на остальных 29 · `finish_reason = 'length'` на тех же четырёх · `degraded`
|
||||
(`empty` ×3, `length` ×1). Из НЕСУЩИХ колонок пуста `err`. ⚠ Пуста не она одна: единственное значение по
|
||||
всем 33 строкам дают также `reasoning_tokens` (предмет §4.3), `cache_creation_tokens`, `estimated`,
|
||||
`est_tokens` — то есть «пуста ровно `err`» было бы отрицательным замером без контроля.
|
||||
|
||||
⇒ работа НЕ в том, чтобы «добавить носитель», их три. Работа — решить и обосновать: должен ли `err`
|
||||
заполняться на 2xx-без-текста (против: это не ошибка транспорта; за: рука аудитора тянется к `err`
|
||||
первой), и достаточно ли того, что `ok=0` уже есть. **Возможен полностью законный исход «менять нечего, а
|
||||
надо назвать»** — тогда так и напиши с доводом; это результат, а не увиливание.
|
||||
|
||||
### 4.5. Цена считается по модели, которой нет в каталоге · «делай РОВНО так» в части замера, «реши сама» в части лечения
|
||||
|
||||
Замер оркестратора 11.09 по всем базам машины (контроль: 448 файлов `*.db`, 405 с `request_log`, 58 886
|
||||
строк): **365 строк оплачены ПОДСТАНОВКОЙ** — провайдер вернул слаг, которого в каталоге нет. ⚠ Из них
|
||||
**344 боевые** (`deepseek-v4-flash` → `deepseek-flash`, 296 строк, $2.049737; `local-qwen3-8b` →
|
||||
`huihui_ai/qwen3-abliterated:8b`, 48 строк, $0) и **21 — тестовые фикстуры** (`m-req`→`m-act`,
|
||||
`fake-model`), которые обязаны быть вычтены: иначе $5.51 фикстуры уедут в денежный вывод.
|
||||
|
||||
**Сегодня это безвредно:** подстановка падает на ЗАПРОШЕННУЮ модель той же семьи. ⛔ Опасна не подстановка,
|
||||
а её молчание. `PriceForResponse` (`internal/ledger/pricing.go:61`=`func (p *Pricer) PriceForResponse`) пробует `actual`, потом `requested`,
|
||||
потом якорь — и ни одно из **двух** мест вызова (`stagerun.go:781`=`PriceForResponse(model, modelActual)`, `reprice.go:134`=`ledger.CostUSD(r.Pricer.PriceForResponse`) не различает, какая
|
||||
ветвь сработала. Комментарий там же охраняет РОВНО ОДНО направление («премиальный ответ не должен биться
|
||||
по дешёвому дефолту»); обратное — когда провайдер маршрутизирует ВНИЗ — не охраняет никто: запрошен `pro`,
|
||||
ответила модель дешевле, счёт по пину `pro`, $3.96 за 1M выходных против $1.20 вендорских у flash =
|
||||
**×3.3 из кармана читателя, молча**.
|
||||
|
||||
**Делай РОВНО так:** пере-сними число сама и напечатай рядом контроль — сколько баз прибор открыл и сколько
|
||||
строк прочёл, и **объяви фильтр** (боевые против фикстур). Моё число на слово не принимай: я уже публиковал
|
||||
занижённый контроль, потому что мой первый прибор не дошёл до ~170 баз.
|
||||
|
||||
**Реши сама и аргументируй**, как сделать подстановку наблюдаемой. Каталог — файл данных
|
||||
(`backend/configs/models.yaml`), и «завести слаг, который провайдер реально возвращает» законно; но слаги
|
||||
не меняются без live-фактчека вендор-доки (гардрейл `CLAUDE.md`), и «слаг живой» ≠ «модель та же». Нужен
|
||||
вендор-заход, которого ты сделать не можешь, — это пинг, а не догадка.
|
||||
|
||||
### 4.6. Параметр, который едет по проводу и ничего не делает · «реши сама и аргументируй»
|
||||
|
||||
Вендор-дока DeepSeek, дословно (снято полигоном): *«Thinking mode does not support the `temperature`,
|
||||
`top_p`, `presence_penalty`, or `frequency_penalty` parameters… setting these parameters will not trigger
|
||||
an error but will also have no effect»*. А ростер шлёт `deepseek-v4-pro` на стадии `edit`
|
||||
**`temperature: 0.4`** (`backend/configs/pipeline-c1.yaml`; на `draft`/flash стоит `0.3`, и оно же уезжает
|
||||
на `pro` при эхо-эскалации), и размышление у `pro` включено всегда. ⇒ **параметр в теле запроса есть,
|
||||
эффекта нет.**
|
||||
|
||||
Само по себе денег не стоит. Стоит другое: `temperature` **входит в `RequestHash`**
|
||||
(`internal/pipeline/render.go`, поле `req.Temperature`) — движок держит в ключе чекпоинта величину, которая
|
||||
на этом классе моделей ни на что не влияет, и правка «настроим температуру редактора» выглядела бы
|
||||
настройкой качества, а была бы громким `--resnapshot` без единого изменения в ответах.
|
||||
|
||||
Реши сама: снимать параметр на таких моделях (это смена ключа — назови цену) либо оставить и объявить в
|
||||
схеме модели, чтобы следующая смена не крутила мёртвую ручку. ⛔ Вендор-факт проверь сама по квиркам ПРЕЖДЕ
|
||||
чем решать — я его цитирую, а цитата не улика.
|
||||
|
||||
### 4.7. Чего НЕ брать
|
||||
|
||||
Не выключать перевыпуск (§1) · не менять боевые `reasoning` (§4.2) · не править пин цены flash — ряд 413,
|
||||
это данные и отдельное решение, и рядом висит неразрешённый вопрос, алиас ли `deepseek-flash` · не трогать
|
||||
`books/` · не заводить новых стадий пайплайна.
|
||||
|
||||
## 5. Самопроверка ИСПОЛНЕНИЕМ — и где у ЭТОГО пака мягко
|
||||
|
||||
Мандат: после того как работа сделана, проведи **адверсариальный проход по СВОЕЙ готовой работе**. Глубину
|
||||
и веер выбираешь сама. Субагенты РАЗРЕШЕНЫ явно. Артефакт — таблица «посадка → выжила/поймана → ЧЕМ
|
||||
поймана», в отчёте, с выжившими поимённо.
|
||||
|
||||
⚠ **Длинная сессия: раз в несколько часов работы — интервальная самоверификация субагентом против ЯВНЫХ
|
||||
критериев этого промта** (`D39.121`), а не «перечитаю сама».
|
||||
|
||||
⛔ **Мутация засчитывается по ТЕКСТУ падения, а не по факту красноты.** Правый вердикт по неправой причине —
|
||||
дыра, а не поимка.
|
||||
|
||||
⛔ **Копия под мутацию защищается ПОСТРОЕНИЕМ, а не `set -e`:** перед любой правкой в последовательности —
|
||||
`test -f go.mod` и сверка `pwd` с ожидаемым путём; копия живёт ВНЕ общего скретчпада.
|
||||
|
||||
**Четыре места, где мягко ИМЕННО У ЭТОГО пака:**
|
||||
|
||||
1. ⛔ **Пин на «не перевыпустили» вакуумен по построению.** Утверждение «второго вызова не было»
|
||||
удовлетворяется фикстурой, где второй вызов невозможен ни по какой причине. Нужна фикстура, где он
|
||||
ОБЯЗАН прозвучать при старом поведении и ДОЛЖЕН молчать при новом, и обе половины исполняются.
|
||||
2. ⛔ **Пин может удовлетворяться ЧУЖОЙ уликой.** Если фикстура гонит попытку через провод, признак
|
||||
«ступень снижена» может прийти не от твоего решения, а из поля предыдущей попытки. Спрашивай не
|
||||
«покраснело ли», а **ЧТО ИМЕННО удовлетворило утверждение**.
|
||||
3. ⛔ **Денежный пин, флейковый на мутанте, измеряет пустой сценарий.** Гоняй его НЕ ОДИН раз и строй
|
||||
фикстуру так, чтобы деньги были НЕИЗБЕЖНЫ, а не вероятны.
|
||||
4. ⛔ **Шов между решением и вызовом тоньше самого решения** (урок предыдущего пака этой зоны, 11.09:
|
||||
прибор был верен, провод от прибора к прогону не запинен ничем, и подмена аргумента прошла батарею
|
||||
зелёной). Спроси у своего кода: сколько тестов зовут путь, на котором причина доезжает до выбора
|
||||
лекарства, — и напечатай это число рядом со знаменателем (сколько тестовых файлов прибор прочёл).
|
||||
|
||||
## 6. Предметные оси ревью
|
||||
|
||||
Три, замена любой с аргументом:
|
||||
|
||||
1. **Деньги** — каждая новая ветвь отвечает числом, сколько вызовов покупает и сколько экономит.
|
||||
2. **Детерминизм и снапшот** — что из правки входит в `request_hash` и в `maxTokensPolicyVersion`; двинулось
|
||||
ли что-нибудь, что заставит пере-оплатить книги в переводе. Ответ исполнением, не рассуждением.
|
||||
3. **Общность движка** — «заработает ли пара, которой в репо ещё НЕТ, без правки Go?». Причина отказа и
|
||||
таблица лекарств не ветвятся по паре или книге. ⚠ Свойство биллинга провайдера уже живёт в данных и
|
||||
**читается** (§4.1) — его заводить не надо.
|
||||
|
||||
## 7. Записка-план
|
||||
|
||||
До первой правки кода положи в свою секцию `docs/PROGRESS.md` записку-план: что берёшь, в каком порядке,
|
||||
что считаешь опасным. Перед сдачей — механическая сверка комплектности против §4, по пунктам, таблицей.
|
||||
|
||||
## 8. Заявление = команда
|
||||
|
||||
Каждое число и каждая категорика в отчёте — **с командой, которой получены**. Приёмка пере-ранит и сверит.
|
||||
Число без команды считается неснятым.
|
||||
|
||||
⛔ **Отрицательный замер обязан доказать, что спросил существующее.** Рядом с любым нулём ПЕЧАТАЕТСЯ
|
||||
контрольная величина: «файлов прибор прочёл: N», «баз открыто: N». Не упоминается — печатается.
|
||||
|
||||
⚠ **Дифф `^func Test` — ИСПОЛНЕНИЕМ, а не по памяти:** список добавленных и изменённых тестов сними
|
||||
командой и приложи, иначе «я добавила пины» остаётся самоотчётом.
|
||||
|
||||
## 9. Эхо-протокол старта
|
||||
|
||||
**Первым действием, ДО работы**, вернись ко мне эхом ≤10 строк: **скоуп / инварианты / чего не делаю** —
|
||||
⚠ **СВОИМИ СЛОВАМИ.** Дословный пересказ подтверждает канал, но не понимание, и повторяет ошибку промта
|
||||
вместе с ним. Прямо скажи: **что поняла, что считаешь опасным, что считаешь неверным.** ⚠ Этот промт уже
|
||||
один раз стоял на перевёрнутой посылке и был переписан — возражение в эхо здесь особенно уместно.
|
||||
|
||||
## 10. Что НЕ удалось
|
||||
|
||||
Обязательная секция отчёта. ⛔ И вторая её половина, без которой она вырождена: **«ГДЕ ПРИБОР СЛЕП И Я ЭТО
|
||||
ЗНАЮ»** — что невидимо · почему не чинила · чем закрывается. Вопрос не «что не получилось», а **«что ты
|
||||
знаешь и не сказала»**: в коде названо, а в отчёте нет — значит для следующей смены НЕ названо.
|
||||
|
||||
## 11. Канал вопросов и право сказать «не надо»
|
||||
|
||||
Конфликт промта с кодом или доками → **пинг мне, НЕ интерпретация**. Ты вправе сказать «этого делать не
|
||||
надо» с аргументом — это исполнение пункта, а не отказ. ⛔ Особенно про §4.1: если существующая
|
||||
классификация окажется непригодной, я хочу знать письмом, а не увидеть рядом вторую.
|
||||
|
||||
⚠ **Правка промта на ходу доезжает ТОЛЬКО релеем:** я передаю её отдельным сообщением, ты подтверждаешь
|
||||
эхом и называешь ОТДЕЛЬНЫМ пунктом отчёта. Изменение, о котором не было релея, исполнению не подлежит.
|
||||
|
||||
## 12. Прямой канал
|
||||
|
||||
Механизм — `CLAUDE.md` §«Связь между сессиями»; здесь не повторяется. Впиши свой блок в
|
||||
`/tmp/textmachine-channel` первым делом, там же ищи адреса. Эхо (§9) шли по адресу оркестратора из этого
|
||||
файла — оно же проверка канала. ⚠ **Нужной роли в файле нет, файла нет или имя не отвечает ⇒ КАНАЛА НЕТ, и
|
||||
это НОРМАЛЬНЫЙ случай: НЕ опрашивай сессии подряд** — вопрос секцией в отчёт, работа продолжается.
|
||||
|
||||
## 13. Критерий завершённости
|
||||
|
||||
Работу доводишь до конца САМА. Приёмка идёт последней и вторым кругом твоей сессии не служит.
|
||||
|
||||
- [ ] У каждого пункта §4 — исход: сделано · **не делаю с доводом** · пинг.
|
||||
- [ ] Круги СОШЛИСЬ: последний проход не дал НОВЫХ находок; прежние закрыты таблицей
|
||||
«находка → что сделано → **ЧЕМ ПРЕДЪЯВЛЕНО**».
|
||||
- [ ] Таблица мутаций полная, **выжившие названы поимённо**.
|
||||
- [ ] Дифф `^func Test` снят командой и приложен.
|
||||
- [ ] Числа сняты ПОСЛЕ последней правки.
|
||||
- [ ] Всё живое — в ДЕРЕВЕ, а не в письме.
|
||||
- [ ] Явное «работа завершена, править не планирую». Без этой строки пак считается идущим.
|
||||
|
||||
⚠ Перед отчётом сверь КАЖДЫЙ клейм с результатом инструмента ЭТОЙ сессии · если последний абзац отчёта —
|
||||
план или обещание, сделай его сейчас · правка теста ради зелени недопустима, правка по заказанной смене
|
||||
поведения — объявляется.
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
| Бэкенд · ГЕЙТ ВМЕСТО ПРОЗЫ | активного НЕТ | пак ОТРАБОТАН и **ПРИНЯТ С ДОФИКСОМ 07.09** — акт **D39.225**; промт в `archive/prompts/` с баннером-исходом |
|
||||
| **Бэкенд · КОНСИСТЕНТНОСТЬ, КОТОРУЮ МОЖНО ПРЕДЪЯВИТЬ** | [BACKEND_CONSISTENCY_YOU_CAN_SHOW_SESSION_PROMPT.md](BACKEND_CONSISTENCY_YOU_CAN_SHOW_SESSION_PROMPT.md) | ✅ **ВЫДАН 11.09**: приоритет №1 владельца — прибор по ОТГРУЖЕННОМУ тексту (два инварианта: одна форма на термин по книге · где у банка есть форма, отгружена она) · запись выбора редакторской волны · дешёвая половина вопроса пост-проверки · совещательные правила линта сида. ⛔ Заказ стоит на замере: расхождения найдены и перечислены (⚠ **ИСПР. 11.09: их СЕМЬ, а не 18** — 11 из восемнадцати оказались ложной тревогой стеммера, ряд **419**), счётчик «промахи» даёт 0 при знаменателе 2, а пара 84/66 УЖЕ печатается — недостают ИМЕНА (держит одна строка `render.go:491`) и счёт по книге целиком. Вне пака: гейт · ряд 409 · актуатор · решение «закон ли для неподписанного» (вопрос владельца) |
|
||||
| Бэкенд · СТРУКТУРА ГЛАВ (ДИЗАЙН) | активного НЕТ | пак ОТРАБОТАН и **ПРИНЯТ 11.09 БЕЗ СХОДИМОСТИ, правилом остановки** — акт **D39.245** (`1d2fab6`, 3 пути, $0); результат — `backend/docs/CHAPTER_STRUCTURE_DESIGN.md` (2062 строки), статус ПРЕДЛОЖЕНИЕ до пака стройки. Глава становится ИДЕНТИЧНОСТЬЮ; предметная часть устояла в четырёх кругах опровержения, механика исполнения — нет, и пак стройки обязан начать с прогона миграционной механики ОПЫТОМ. Промт был — [CHAPTER_STRUCTURE_DESIGN_SESSION_PROMPT.md](CHAPTER_STRUCTURE_DESIGN_SESSION_PROMPT.md), выдан 11.09 (актуализирован пятью врезками + 19 правок по опровергателю: мёртвые адреса, две таксономии осей, три «уже построено», собственная зона записи `backend/docs/` с дизайном-оф-рекорд `D15.2` и прибором shiftmap). ⚠ **ПРОЕКТИРОВАНИЕ, НЕ СТРОЙКА** (`D39.136` п.3): дизайн окна большой пере-нарезки — чем адресуется глава и развязка чанкера (161) · карта осей сдвига · банк-окна на chapter-ID · контент-адресуемый resume `D15.2` · IR/адаптеры/индуктор · правило заголовка и не-CJK путь (303) · гранулярность EPUB (302) и выдача (283). Снимает временный отказ интейка книге из одной главы (`D39.221`). Пак 1 «форматы и честный словарь» ОТРАБОТАН и ПРИНЯТ 06.09 — акт **D39.210**, промт в `archive/prompts/`. ⚠ **ПАК 2 (лексиконы не-CJK, корпус, замер оракулом) — НЕ НАПИСАН и ждёт файлов владельца** |
|
||||
| **Бэкенд · ЗА ОДНУ ЕДИНИЦУ ПЛАТИМ ДВАЖДЫ** | [BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md](BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md) | ⏳ **НАПИСАН 11.09, редакция 2; выдаётся СВЕЖЕЙ сессии по закрытии пака консистентности актом.** Предмет — двойная оплата единицы: на платном прогоне $0.106472 = 25.4 % цены книги ушло в выброшенные первые попытки. ⛔ **Редакция 1 стояла на ПЕРЕВЁРНУТОЙ посылке** («движок лечит болезнь возбудителем») и заказала бы отключить восстановление, которое работает 4 раза из 4; опровергатель это снял — сессия, исполнившая её буквально, отключила бы восстановление трёх чанков из четырёх, отменила `D2` п.2 и сломала `TestRetryableSubset`. ⭐ Настоящая находка редакции 2: **причин ДВЕ, лекарство одно.** Черновик — потолок мал (контроль: 6 успешных вызовов, все ≤8496 прошли сразу, все >8496 упали и прошли на удвоенном; исключений 0), редактор — размышление съело достаточный потолок (2-я попытка 11717 против упавших 16000, $0.071009 = две трети потери в одном вызове). Плюс `reasoning_tokens` не несла числа ни разу за историю проекта (0 строк при 405 базах и 58 886 строках) и молчащая подстановка цены. Ряды **414** · **415** · **422**, пин flash **413** из пака ВЫНУТ |
|
||||
| Бэкенд · отозванный | активного НЕТ | пак КАЧЕСТВО написан и ОТОЗВАН до выдачи 05.09 (`archive/prompts/…_WITHDRAWN.md`): предмет дешевле пака — точность чекера уже измерена, пере-снять её стоит одной команды. Следующий пак — СТРУКТУРА ГЛАВ (решение владельца 05.09 «любая книга любого формата»), пишется |
|
||||
| Бэкенд · прежний | активного НЕТ | пак «денежный стоп» ОТРАБОТАН и ПРИНЯТ С ДОФИКСОМ 05.09 — акт **D39.206** (`81a89e9` + `616a8e4`), промт в `archive/prompts/` с баннером исхода. Следующая работа зоны — строки **291** (флаг вместо клина, `D39.204`) · **294** (форма «сколько добавить», `D39.203`) · **296** (точечная перегенерация по промаху глоссария, после 295) |
|
||||
| Платформа · ПРАВДА У ДВЕРИ | активного НЕТ | пак ОТРАБОТАН и **ПРИНЯТ С ДОФИКСОМ 11.09** — акт **D39.246** (`49f74d9`, 15 путей, $0). `PD-455` закрыт, `PD-162` наполовину у обеих денежных дверей, `PD-448` разобран и НЕ построен (четвёртый путь принят направлением, строит следующий пак вместе с минором **0.15.0**). ⛔ Приёмка нашла два дефекта ВНЕ карты автора: выживший мутант на единственной проводке `BooksDir` и тихо-зелёное в самом новом гейте. Живое — `PD-162` (эскроу), `PD-466`, `PD-139`. Промт был — [PLATFORM_TRUTH_AT_THE_DOOR_SESSION_PROMPT.md](PLATFORM_TRUTH_AT_THE_DOOR_SESSION_PROMPT.md), выдан 11.09: `PD-455` (форма обещает то, в чём дверь откажет — точка роста `Blocked.code`, не закрытый enum вердикта) · `PD-448` (двойной клик по «продолжить» — **исследуй и предложи, НЕ строй**: все три законных пути требуют контрактного минора или миграции) · `PD-162` (прогон книги с исчезнувшим каталогом висит с холдом — валидация каталога ПРИ ДОПУСКЕ). ⛔ Свип сирот и потолок аплоадов СНЯТЫ подписанным пропуском: их гейт — открытая регистрация, которой в закрытой бете нет (`PD-175` + `D39.176` п.1) |
|
||||
|
|
|
|||
|
|
@ -63,8 +63,16 @@
|
|||
| полигон | `POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md` | — | ⛔ **готов, адресата НЕТ** — все семь живых сессий отработали, свежую поднимает владелец |
|
||||
| фронт | заморожен | — | разморозка по критерию `NEAR_TERM_PLAN.md` |
|
||||
|
||||
**В очереди, написано и ждёт слота:** `BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md` (падение, которое
|
||||
видно) — выдаётся СВЕЖЕЙ бэкенд-сессии сразу, как c9 закроется актом. Опровергатель по нему запущен.
|
||||
**В очереди, написано и ждёт слота:** `BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md`, **редакция 2** —
|
||||
выдаётся СВЕЖЕЙ бэкенд-сессии, как c9 закроется актом. ⛔ **Опровергатель нашёл 17 находок, и первая
|
||||
перевернула пак:** я построил §1 на «движок лечит болезнь возбудителем», а замер говорит обратное —
|
||||
перевыпуск вернул текст 4 из 4, и в трёх случаях успешный ответ физически не влез бы в базовый потолок.
|
||||
Моя таблица лекарств отключила бы восстановление трёх чанков из четырёх и отменила бы `D2` п.2 с пином
|
||||
`TestRetryableSubset`. Пере-снял сам — потолок 8496 делит популяцию успешных черновиков БЕЗ ИСКЛЮЧЕНИЙ
|
||||
(≤8496 прошли сразу ×3, >8496 упали и прошли на удвоенном ×3), а у редактора наоборот. ⇒ причин две,
|
||||
лекарство одно — вот это и есть пак. Ещё опровергатель снял: три моих контрольных числа не сходились
|
||||
(`glob` не дошёл до ~170 баз), `D24.3` и `D39.87` мис-атрибутированы, `temperature` у pro 0.4 а не 0.3,
|
||||
мест вызова два а не три, «пуста ровно `err`» — пусты пять колонок. Все исправлены.
|
||||
|
||||
## Журнал выдач очереди №23
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue