textmachine/platform/docs/p9/door-live-probe.md

169 lines
9.6 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.

# P9 — транскрипт живого пробоя двери правок банка (27.08.2026)
Требование §4.2 промта пака: дверь пробита ЖИВЫМ стендом против НАСТОЯЩЕГО движка. Ниже — команды
и СЫРЫЕ фрагменты их вывода из сессии, дословно (норма «заявление = команда»; вторая редакция —
первая была пересказом, что приёмка справедливо назвала).
## Стенд
Демон и движок собраны из дерева сессии; свои порты/БД/каталоги, чужой стенд не тронут:
```sh
W=~/tm-p9-work
cd backend && go build -o $W/tmctl ./cmd/tmctl
cd platform && go build -o $W/tmplatformd ./cmd/tmplatformd && go build -o $W/tmplatformctl ./cmd/tmplatformctl
~/.local/pgsql/bin/psql -h 127.0.0.1 -p 5432 -U postgres -d postgres -c "create database tmp9stand"
# env: TM_PLATFORM_DSN=…/tmp9stand · _MIGRATE=1 · _ADDR=127.0.0.1:8123 · _DEV_LOGIN=p9dev ·
# _INSECURE_COOKIES=1 · _BOOKS_DIR=$W/stand/books · _STATE_DIR=$W/stand/state ·
# _ENGINE_BIN=$W/tmctl · _BOOK_TEMPLATE=$W/book-template.yaml · _CTL_BIN=$W/tmplatformctl ·
# _LANGUAGE_PAIRS='zh>ru' · _METRICS_ADDR=off · _ENGINE_KEYS_PATH=<repo>/backend/.env
nohup $W/tmplatformd > $W/stand/daemon.log 2>&1 &
curl -s --noproxy '*' http://127.0.0.1:8123/readyz # → ready
$W/tmplatformctl seed --url http://127.0.0.1:8123
```
Вывод seed (дословно):
```
account u_QNMBL43CZVBE42IJ (identity dev/p9dev)
credit granted 25.000000 to u_QNMBL43CZVBE42IJ (key seed-u_QNMBL43CZVBE42IJ); balance is 25.000000
book bk_QLS63SDD3NWF2YUV (parsing)
intake not_started, 3 chapters
```
## Почему провайдер — локальная $0-заглушка
Первый прогон демо-книги упал классом 10; журнал юнита (дословно):
```
tmctl[823168]: tmctl: missing API keys (fill in backend/.env):
tmctl[823168]: - provider deepseek: env DEEPSEEK_API_KEY is not set (needed for model deepseek-v4-flash)
```
Механика `--keys-file` при этом доказана двумя $0-пробами на КОПИИ книги (значения ключей в сессию
не читались — гардрейл `.env` цел):
```
$ tmctl translate --config book.yaml --keys-file /nonexistent/keys.env --ceiling-usd 0.05
tmctl: --keys-file /nonexistent/keys.env cannot be read: open /nonexistent/keys.env: no such file or directory
$ echo "DEEPSEEK_API_KEY=sk-dummy-p9-probe" > keys-dummy.env && tmctl translate … --keys-file keys-dummy.env …
… msg="calling model" model=deepseek-v4-flash attempt=0 … # пре-флайт пройден, файл загружен
```
Пробы остальных провайдеров тем же способом (`--ceiling-usd 0.000001`: отказ резервации ДО вызова,
`committed=$0.000000 reserved=$0.000000`, exit 10 = ключа нет):
```
gemini-3.1-pro-preview EXIT=10 :: … env GEMINI_API_KEY is not set …
mistral-large-2512 EXIT=10 :: … env MISTRAL_API_KEY is not set …
gpt-5-mini EXIT=10 :: … env OPENAI_API_KEY is not set …
```
Живого облачного ключа в файле деплоя нет ⇒ пробой цепи — на `provider: local` (models.yaml),
которого на стенде обслуживает OpenAI-совместимая заглушка `$W/fake_provider.py` (переводчику —
проза, терминологу/классификатору — TSV по строкам `key:`). Майнингу даны `langpack_root` (реальные
langpacks движка) и фабрикованный jieba-контраст (76 частотных слов); книга — крафтовый исходник
(方源 ×54, 苏长老, 青云山; 3 главы, 1222 байта).
## Цепь, команда за командой
Загрузка и старт (сессия `curl -c jar` через `/auth/dev-login`, всюду `-H "X-TM-Client: p9"`):
```
$ curl … -F title="Проба P9" -F source_lang=zh -F target_lang=ru -F file=@probe-book.txt /v0/books
"id": "bk_MNPEAQTOVKK5SMCI", "status": "parsing" … → not_started 3
$ curl … -d '{"stop_for_signing":true,"ceiling_chapters":3}' /v0/books/bk_MNPEAQTOVKK5SMCI/runs
run_BMLFFO5TCESMXRW4 translating {'done': 0, 'total': 6, 'stage': 'drafting', 'eta_seconds': None}
```
Стоп достигнут (поллер карточки, дословно): `23:12:10 awaiting_bank 3 6 editing` — полоса на стопе
50%, НЕ обнулилась. Чтение банка на стопе:
```
$ curl … /v0/books/bk_MNPEAQTOVKK5SMCI/bank
{"revision": 23, "next_cursor": null, "structure_version": 1, "total": 0, "signed": 0, "terms": []}
```
— ни `pending_decisions`, ни `complete` (PD-399 живьём); пустота банка на стопе — строка 224
(читающая сторона — движковый пак). Поверхности стопа — из карты подписи на сервере
(`sample-zh.db.mined-signature.yaml`: `方源`, `苏长老`, …; `.bank-stop.txt`: «BANK VERIFICATION
TABLE — 3 term(s)»).
ПРЕВЬЮ (approve 方源 → «Фан Юань-П9» kind name + decline 苏长老), ответ дословно:
```
{"preview": true, "changed": true, "depth": "refinement",
"accepted": [
{"index": 0, "action": "approve", "id": "e1e2b5625d031d33", "src": "方源",
"dst": "Фан Юань-П9", "state": "applied", "displaced": false},
{"index": 1, "action": "decline", "id": "bf4a082f8bf17aed", "src": "苏长老",
"dst": null, "state": "applied", "displaced": false}],
"preexisting_faults": 0,
"signature": {"surfaces": 3, "undecided": 1, "unreadable": false}}
```
ПРАВКА и ПОВТОР того же документа (вывод скрипта сверки, дословно):
```
== APPLY ==
preview False changed True accepted [('方源', 'applied', False), ('苏长老', 'applied', False)] signature {'surfaces': 3, 'undecided': 1, 'unreadable': False}
== RETRY SAME ==
changed False states ['already_applied', 'already_applied']
```
ОТКАЗ (противоречие в одном документе: decline 方源 + approve 方源):
```
code bank_corrections_refused refusals [('/corrections/1', 'decision 0 already decides this term (sense "", window [0,0]')]
HTTP=409
```
RESUME и правка при живом прогоне (второй замер — на живом прогоне демо-книги, тело дословно):
```
$ curl … /v0/runs/run_BMLFFO5TCESMXRW4/resume
translating {'done': 3, 'total': 6, 'stage': 'editing', 'eta_seconds': 1} # полоса ПРОДОЛЖИЛА с 3/6
$ curl … -d @corr-apply.json /v0/books/…/bank/corrections # прогон живой
{"type":"about:blank","title":"Run in flight","status":409,"code":"run_in_flight","request_id":"5M6SCTCU4XYQP5P2"}
```
Финал (поллер + чтение банка, дословно):
```
23:14:04 ready 6 6 editing
$ curl … /v0/books/bk_MNPEAQTOVKK5SMCI/bank
{"revision": 34, …, "total": 2, "signed": 1, "terms": [
{"id": "tm_73f73a5b396d7d40b68bac09", "src": "方源", "dst": "Фан Юань-П9",
"kind": "name", "status": "approved", …},
{"id": "tm_9e446a871eb17f39eade265c", "src": "青云山", "dst": "", "kind": "place",
"status": "proposed", "since_chapter": 1, …}]}
```
Следующий прогон правку УВИДЕЛ: `方源` — approved с моим dst; задеклайненный `苏长老` из
предложений исчез; нерешённый `青云山` стоит proposed.
## Деньги (ось §5.1 — леджер двумя путями)
```
$ $W/tmplatformctl balance --user u_QNMBL43CZVBE42IJ
balance 25.000000
$ psql … -d tmp9stand -c "select kind, count(*), sum(amount_micro_usd) from credit_ledger group by kind order by kind"
grant | 1 | 25000000
hold | 3 | -270000
hold_release | 3 | 270000
settlement | 3 | 0
```
Сошлось до цента. Три холда = три попытки (демо-книга exit 10; пробная книга, попытки 1 и 2 через
resume); расчёты $0 — заглушка. Оговорка силы замера: расчёты нулевые, открытого холда в момент
сверки не было; сверку на открытом холде и после ненулевого расчёта исполнил ревьюер приёмки на
этом же дереве — расхождений нет.
## Что пробой доказал
Цепь строк 199/202 срослась: правка термина через контрактную дверь доезжает до движковых файлов
решений, возобновление пере-собирает банк с ней, читающая поверхность следующей границы её
показывает. Плюс живьём: сквозная полоса через обе волны без обнуления на стопе; PD-399 не на
проводе; превью/идемпотентность/отказ/взаимоисключение — по канону 0.5.0. Ограничение честно:
качество перевода и поведение под латентностью настоящего провайдера пробой НЕ доказывает —
заглушка, строка 202 «по-настоящему» ждёт живого ключа.