textmachine/docs/NEAR_TERM_PLAN.md

152 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ближайший горизонт — 35 промтов
> Рабочая записка оркестратора №23. **Только порядок и зоны**, не заказы. Живёт до исполнения, потом в архив.
> Долг живёт строками `BACKLOG.md`, решения — нотами. Разобрано со старшим коллегой 11.09, его правки внесены.
>
> ⚠ **Раскладка (слово владельца 11.09):** одновременно лежат промты РАЗНЫХ зон — бэкенд · платформа ·
> полигон · фронт. **Двух промтов одной зоны быть не может**; слот освобождается закрытием пака актом.
## Критерий полноты базового функционала — ответ на сомнение владельца
**Фронт размораживать, когда каждый шаг пути имеет на бэкендах: (а) смонтированную дверь по канону,
(б) СОДЕРЖИМОЕ, которое эта дверь отдаёт, (в) словарь исходов, которым она отказывает.** Реестр требований
целиком критерием быть не может — 🔶 стоит у 24 строк из 45, «без 🔶 на ядре» не наступит никогда.
По этому критерию путь ОДНОГО гостя zh→ru полон до последнего шага, а неполнота сидит в **трёх местах**:
1. **ВХОД — ⛔ ФОРМУЛИРОВКА ИСПРАВЛЕНА 11.09 ЗАМЕРОМ, ДВЕ ТРЕТИ ЕЁ БЫЛИ МОЕЙ ОШИБКОЙ.** Пере-снято:
**(а)** пригласительного гейта и allow-list действительно НЕТ — учётку получает кто угодно, прошедший
провайдера (греп `invite|allowlist|AllowedDomains` по `platform/internal` и `cmd`: живых механизмов 0
при контрольных 204 Go-файлах); **(б)** грант новичку 0 — это НЕ дыра, а **ратифицированное решение
владельца** (`D39.176` п.1: «никаких квот, живём на покупке API; бонусы зачисляются из админки»), и он же
работает экономическим гейтом закрытой беты: аккаунт заводится, но без ручного пополнения не может
ничего; **(в)** «лимита размера загрузки нет» — **НЕВЕРНО**: байтовый потолок стоит на маршруте интейка,
`platform/internal/httpapi/server.go:98`=`UploadLimits{MaxBytes: 64 << 20, Deadline: 10 * time.Minute}`,
механизм — `http.MaxBytesReader` (`middleware.go:22`).
⇒ **Живой остаток — операционная гигиена, и `D39.176` п.1 прямо называет её инженерной, без слова
владельца:** число аплоадов ничем не ограничено · у статуса `rejected` нет выхода · каталоги-сироты никто
не подметает. Плюс три ряда регистра (`PD-162` · `PD-455` · `PD-448`). Платформа, дни.
**Продуктовых квот и фри-тир-лимитов НЕ ПРОЕКТИРОВАТЬ**`D39.176` п.1 закрыл вопрос целиком.
2.**СОДЕРЖИМОЕ УЗЛА ПОДПИСИ БАНКА** — человеческий узел потока показывает ПУСТОТУ: у секции предложений
читателя нет (`json:"proposed` — 0 хитов при 356 json-тегах), живой экран 04.09 отдал `total 0, signed 0`.
3. **ВТОРАЯ ПАРА** — японская книга получает китайскую транскрипцию. «Требуется проекту», не показу zh→ru.
Условное (4): **CORS/same-origin**`Access-Control` 0 хитов при 201 Go-файле. ⛔ **Испр. 11.09 (поправка старшего коллеги, пере-проверена по ячейке пункта 9): это НЕ предусловие прогона B.** B идёт «платформа → бэкенд → ФАЙЛ», то есть `curl`/API, а браузерного источника в нём нет вовсе — фронт заморожен тем же словом владельца. CORS — предусловие РАЗМОРОЗКИ ФРОНТА (пункт 6), и там его место.
**«Качественно готовы» имеет ВТОРОЕ чтение, и его надо назвать владельцу:** качество перевода на целевом
жанре не измерено и кодом не обещано. Эта готовность наступает только ПОСЛЕ настоящей книги — то есть после
прогона, а не до него.
## Горизонт
| № | зона | предмет | цена | состояние на 11.09 |
|---|---|---|---|---|
| 1 | **бэкенд** | структура глав, ДИЗАЙН | $0 | ✅ **ЗАКРЫТ АКТОМ `D39.245`** без сходимости, правилом остановки |
| 2 | **платформа** | правда у двери: `PD-455` · `PD-448` (разбор) · `PD-162` | $0 | ✅ **ЗАКРЫТ АКТОМ `D39.246`** с дофиксом по двум находкам приёмки |
| 3 | ~~полигон~~ | **прогон A**: настоящая книга до ФАЙЛА, платный провайдер | **факт $0.419424** | ✅ **ЗАКРЫТ АКТОМ `D39.247`**; строка 16 закрыта замером; ⚠ зона ВНЕ СКОУПА с 11.09 |
| 4 | **бэкенд** | ⛔ **КОНСИСТЕНТНОСТЬ, КОТОРУЮ МОЖНО ПРЕДЪЯВИТЬ**: ряды **406** · **407** · **408** · **409**, плюс купленные прогоном **417** (закон банка не виден в тексте) и **419** (стеммер: 11 из 18 промахов — ложные) | пак, почти весь $0 | ⏳ **ВЫДАН 11.09** сессии `textmachine-c9`; приёмка, круг 2 (шесть посадок выжили → дофикс) |
| 5 | **бэкенд** | «ВЫДАЧА, КОТОРУЮ ВИДИТ ЧИТАТЕЛЬ»: ряды **284** · **201** · **283** · **307** · **291** | пак | после 4; форму гранулярности решает дизайн глав |
| 6 | **фронт** | поверхность показа | пак | разморозка + пункты 15 |
| 7 | ~~полигон~~ | ⛔ **ЗОНА ВНЕ СКОУПА — слово владельца 11.09**; четыре промта уведены в `archive/prompts/` с баннерами | — | снято |
| 8 | **бэкенд/деньги** | ⛔ **«ПАДЕНИЕ, КОТОРОЕ ВИДНО»** — четверть COGS в одном механизме (**415**), слепые приборы отказа (**414**, **422**), молчащая подстановка цены. ⚠ Пин цены **413** из пака ВЫНУТ: это данные и отдельное решение | пак, $0 | ✍️ **НАПИСАН 11.09**`BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md`; выдаётся СВЕЖЕЙ сессии сразу по закрытии 4 ⛔ **КРИТЕРИЙ ПРИЁМКИ ПАКА — МЕХАНИЗМ, А НЕ ПРОПОРЦИЯ** (поправка старшего коллеги 11.09): лекарство есть распространение ратифицированного образца `D2` п.3 на вторую причину, и оно верно при 25 % и при 5 % — пропорция задаёт очерёдность, не форму. ⇒ судить по строкам «ни одного удвоения без вердикта о вырождении; каждая выброшенная попытка — строкой леджера с причиной», а не по «с 25.4 % до X». Значит прогон B пак не гейтит и паком не гейтится.|
| 9 | **платформа+бэкенд** | ⭐ **ХОЛОДНЫЙ ПРОГОН B — платформа → бэкенд → файл, ВТОРОЙ раз.** Уточнение владельца 11.09: спрашивая «перепрогоны нужны», он имел в виду именно сквозной прогон, а не пере-запуск тестов. Покупает ЧЕТЫРЕ вещи, которых нет ни у кого: **(1)** миграция **v17** (`wave_selection`) пака консистентности ни разу не шла на живом прогоне — только в тестах; **(2)** прибор консистентности впервые даст числа с ЖИВОГО прогона, а не с пере-скана сохранённой базы прогона A — сегодня все `I1`/`I2` получены повторным чтением одних и тех же данных; **(3)** платформенный пак (идемпотентный резюм, терминальное состояние) проверяется сквозь, а не юнитами; **(4)** ⛔ **вторая точка по денежной дыре, и она нужна по норме, а не для красоты** — весь довод «четверть денег купила пустоту» стоит на ЧЕТЫРЁХ одиночных розыгрышах, а квирки §3д прямо говорят: смета DeepSeek с одиночного вызова может ошибиться на порядок, сметы строятся на ПОВТОРАХ. ⇒ у числа 25.4 % есть знак и нет величины, пока прогон не повторён. **Цена ≈$0.42 по образцу прогона A, машинный кап ≈$2.5.****ПРЕ-РЕГИСТРАЦИЯ ЗНАМЕНАТЕЛЯ, иначе B ответит числом на другой вопрос** (поправка старшего коллеги 11.09): B — ЕЩЁ ОДИН одиночный прогон, и две точки распределением не станут. Настоящая ценность B не «вторая точка к 25.4 %», а `request_log` ВСЕХ единиц прогона ⇒ **доля выброшенных первых попыток ПО ЕДИНИЦАМ, а не по вызовам.** Это и пре-регистрируется. ⚠ И идёт B **ПАРАЛЛЕЛЬНО** паку о падениях, а не после: они в РАЗНЫХ слотах (бэкенд против платформы), и правило «один промт на зону» их не сталкивает | ≈$0.42 | ждёт лендинга паков 4 и 7-платформенного |
**ПОЧЕМУ 4 ВСТАЛ ПЕРЕД 5 (решение 11.09 по мерилу владельца).** Мерило — «качественный КОНСИСТЕНТНЫЙ
перевод длинных книг». Аудит банка 11.09 показал, что **книжного вопроса о консистентности не задаёт ни один
прибор**: мера расхождения форм построена, но считается по ЧЕРНОВИКУ до редакторской волны, а по
отгружаемому тексту её нет вовсе. Пока её нет, приоритет №1 владельца непроверяем в принципе — и любая
работа над ВИДОМ выдачи улучшает то, что мы не умеем измерять. Ряды 406409 почти целиком $0 и
переиспользуют построенное; ряд 408 — вообще ДАННЫЕ, а не Go. Носитель разбора —
`docs/research/34-memory-bank-quality-audit.md`, акт — `D39.243`.
## Прогон A — точечно (пере-написано 11.09 после разбора со старшим коллегой)
**ПРЕДМЕТ — строка 16: цена книги, ДОВЕДЁННОЙ ДО КОНЦА, не измерена ни разу.** Цикл замкнут живьём 04.09
(`D39.194` п.1: скачанный EPUB прошёл `epubcheck`), но книги, дошедшей до `exports.complete = true`, через
API не было: 04.09 упёрлось в потолок (`PD-440`, с тех пор лечено `D39.206`/`D39.208`). Прогон A ведёт одну
настоящую книгу от двери до ФАЙЛА и печатает, чем каждый узел предъявлен.
**ЛОКАЛЬНОЙ МОДЕЛИ НЕТ** (слово владельца 11.09 — на машине нет видеокарты): провайдер `local` смотрит в
`http://127.0.0.1:11434/v1`, а на хосте нет ни `nvidia-smi`, ни `ollama`, ни слушателя на 11434 (контроль:
слушателей всего 5, на 11434 — 0). Значит настоящие узлы можно пройти только платно.
**ТРИ МОИ ОШИБКИ В ЭТОМ РАЗДЕЛЕ, СНЯТЫЕ РАЗБОРОМ 11.09:**
1. **«Книга со стенда P9»** — на P9 (27.08) стояла встроенная трёхглавая ЗАГЛУШКА (`seed` «demo.txt») и
крафтовая проба в 1222 байта на `fake_provider.py`. Настоящая короткая книга — это 04.09:
`books/gu-zhenren/coldrun-v16/guzhenren-ch1-10.gb18030.txt` (10 глав, 14 юнитов). Брать **главы 13**
(≈4 юнита, глава 1 двухъединичная — пере-проверить манифестом ДО фриза).
2. **«Пробой 27.08 оборвался на правке банка»** — неверно: транскрипт показывает preview → apply →
`already_applied``409` на противоречии → resume → `ready 6/6`. Он не оборвался, а кончился там, где
кончался тогдашний контракт: без провайдера, без настоящей книги и без двери выгрузки.
3. **«Заглушка годится только как двадцатиминутный дым»** — наоборот: **$0-дым по заглушке ОБЯЗАТЕЛЕН
фазой 0.** Он валидирует драйвер, сборщики следов и дверь выгрузки бесплатно; без него первая же
инфраструктурная осечка сожжёт «холодность» платной книги.
**ДЕНЬГИ — ДВА ЧИСЛА, И Я ЗНАЛ ТОЛЬКО ОДНО.** Ожидаемая трата ≈ **$0.30** (замер 08.09: 10 глав за
`committed=$1.259217`). Но машинный КАП — это ХОЛД, а не ожидание: на `c1` книжный бонд
`book_once = budget_usd 1.00 + classify_budget_usd 1.00 = $2.00`, поэтому холд трёхглавой книги ≈ **$2.32.5**,
и грант обязан быть не меньше, иначе допуск откажет. ⇒ **владельцу называются оба: «ждём ≈$0.30, кап ≈$2.5».**
**Предусловия, которых в плане не было (замерены 11.09):** артефакта контраста майнинга нет НИ ОДНОГО на
файловой системе (`CheckMiningContrast` откажет на старте и оставит `failed`-прогон, после которого книга уже
не холодная) · `eval/.venv` не существует, jieba не установлен · кластер Postgres опущен · `epubcheck`/`java`
на хосте нет. Всё это ставится ДО фриза.
**Фриз** — sha коммита ПЛЮС бинари, собранные из `git worktree add <путь> <sha>`: сборка из главного дерева
даёт `vcs.modified=true` от любого untracked-файла, и драйвер обязан отказывать по `go version -m`.
⚠ Прогону A **запрещено чинить найденное** — только пинги. Приёмка узла — по ТРЁМ независимым следам
(Postgres · диск и systemd · HTTP), не по самоотчёту движка. Ожидаемый исход каждого шага пишется ДО
прогона. ⛔ **Претрейн:** 蛊真人 узнаётся моделями 4 из 5 ⇒ пре-рег объявляет, что клеймов О КАЧЕСТВЕ пак
не делает вовсе; узлы судятся механизмом (кадры, флаги, леджер), а не чтением текста.
## Решения владельца, уже полученные (носитель — ЗДЕСЬ; заведён 11.09, прежде его не было ни в одном доке)
-**ПЛАТНЫЙ ПРОГОН A РАЗРЕШЁН** (слово 11.09: «Разрешаю»). Ожидание ≈$0.30, машинный кап ≈$2.5 (холд, см.
раздел выше). ⚠ Санкция названа ЗДЕСЬ, потому что опровергатель 11.09 поймал: промты ссылались на неё как
на факт, а в дереве её не было ни строкой — «известное со слов» не носитель.
-**Остановка остаётся ЖЁСТКОЙ, деньги терять ДОПУСТИМО, но остановка обязана быть КОРРЕКТНОЙ** — без
гонок, без половинчатых состояний, с верным возобновлением (`D39.240`).
-**ГОЛОС ВХОДИТ В ПРИОРИТЕТ №1** (слово 11.09: «Входит»). Прежнее расхождение канона проекта («термины/голоса») и ратифицированного списка 05.09 (голос №3) снято. ⛔ **Форма работы задана тем же словом: проектирует и контролирует голос FABLE, исполняет ОПУС** — сессии обсуждают имплементацию с агентом Fable 5, а не решают сами. Носитель предмета — строка бэклога **410**. ⚠ **Её голова ПЕРЕПИСАНА 11.09 пере-замером: «мёртв в четырёх местах» было НЕВЕРНО** — голос построен сквозь (схема сида · загрузчик · хранилище · инъекция · флаггер по отгруженному тексту · поле отчёта) и выключен ровно двумя вещами: профиля не написал никто ни разу, и `InjectVoice` — константа без ключа конфига, чьё включение стоит полного `--resnapshot`. ⇒ работа мельче, чем читалась: не «построить голос», а написать профиль, открыть ручку и заплатить ре-снапшотом.
-**Автономия смены (11.09):** решения принимаю сам, советуясь со старшим коллегой; мерило — главные
ценности продукта (качественный консистентный перевод длинных книг), затем архитектура и чистый код,
необходимый рефакторинг и отсутствие велосипедостроения.
## Что решает владелец — ОСТАЛОСЬ
- **Определение показа:** аудитория и вход · какая книга · один гость или несколько · **бюджет времени**
(`ПТ-19` называет скорость киллерфичей, а времени у экрана никто не мерил).
- **Деньги гостя на показе** — стенд сеет $25, продукт 0; дневного потолка в шаблоне намеренно нет.
- Какую из двух «готовностей» он имел в виду — полноту функционала или качество перевода.
-**ПЯТЬ ВОПРОСОВ ПО СТРУКТУРЕ ГЛАВ** (дизайн `backend/docs/CHAPTER_STRUCTURE_DESIGN.md` §11; носителя вне документа не было до 11.09 — заведён аудитом смены). **В-1** каким номером глава зовётся в глазах пользователя, если адрес стал контентным · **В-2** что происходит с уже переведёнными книгами при перекрое · **В-3** платит ли кто-нибудь за пере-нарезку · **В-4** когда твердеет НАРЕЗКА (это деньги) · **В-5** когда твердеет ВИД (это читатель). ⚠ Последние два разделены сознательно: схлопнутый вопрос получил бы схлопнутый ответ, а платит за разницу перекрой. Ни одна из двух точек затвердевания D-нотой НЕ ратифицирована.
-**ДЕНЬГИ ЗА ПУСТОТУ — КТО ПЛАТИТ. Новый вопрос 11.09, куплен прогоном A, и он ПРОДУКТОВЫЙ, а не инженерный.**
Замер: 4 вызова из 27 вернулись без пригодного текста и стоили **$0.106472 = 25.4 % цены книги**; три из
них дали РОВНО 0 знаков. Деньги списаны с читателя — они в `cost_usd`, и арифметика движка безупречна.
Инженерную половину («не лечить удвоением потолка, классифицировать прежде») я решаю сам и она уже в паке.
**Владельческая половина одна: считается ли доставленная пустота РЕАЛЬНЫМ расходом читателя.** Варианты:
**(а)** платит читатель, но видит пометку класса — честно и дёшево, механизм пометки уже есть (`degraded`);
**(б)** платит продукт — движок не выставляет счёт за генерацию, которую сам же признал негодной; дороже,
и требует решить, что делать, когда негодность спорна; **(в)** платит читатель и не видит ничего — так
сегодня, и это единственный вариант, который я не рекомендую ни при каких условиях. ⚠ Цена вопроса растёт
с числом читателей, а не с числом книг. Носители — ряды **415** · **414** · **422**.
- **Пять вопросов банка памяти**, поднятых аудитом 11.09 (стоп или флаг на разъехавшемся термине · входит ли
ГОЛОС в приоритет №1 · один перевод у НЕподписанного термина · накапливать ли банк между прогонами ·
остановка на подпись — опция или свойство продукта). Носитель разбора — `docs/research/34-*`.
## Вычеркнуто
Лендинг (строка **384**) — отдельная поверхность. Брокер конкурентности — решается определением «один гость».
Корректность остановки — после A, объёмом по его уликам; четыре однострочника «без мусора» идут приложением
к пункту 4, kill-харнесс — следующим слотом.
## Мои ошибки, снятые разбором — чтобы не повторить
1. «По рецепту P9» — рецепт идёт мимо фронта и обрывается до последней трети.
2. «Второй контур наблюдения» как условие — гейтил бы прогон стройкой ненужного ему.
3. «Приоритет №1 не исполняется кодом вовсе» — **неверно**: консистентность держится инъекцией банка и
пост-проверкой, которая ФЛАГУЕТ и ОТГРУЖАЕТ. Это «нет ОТКАЗА», а не «нет носителя».
4. «Прогон A — зона платформы» — **нет, полигона**: он не пишет кода зон, это эксперимент с пре-регистрацией.
Слот платформы поэтому свободен.
5. **«Вход» как дыра из трёх частей** — две части оказались не дырами (грант ратифицирован, байтовый
потолок построен), и я объявил их отсутствующими, не спросив дерево. Замер и правка — в самой дыре 1.