Rebuild the stand on the new machine, anchor the books ignore rule, and repair the cold-entry route the blind onboarding probe measured

This commit is contained in:
heaven 2026-08-24 15:54:32 +03:00
parent 89ee7a3429
commit ff03dcaa95
6 changed files with 125 additions and 10 deletions

5
.gitignore vendored
View file

@ -45,3 +45,8 @@ node_modules/
# Codex - настройки # Codex - настройки
.codex/config.toml .codex/config.toml
# Данные: каталог книг переехал В репозиторий и версионируется СВОИМ git (свой origin).
# Якорь `/` обязателен: без него правило ловит ЛЮБОЙ каталог `books` на любой глубине —
# проверено, `platform/internal/books/<новый файл>` уходил в игнор молча.
/books/

View file

@ -32,7 +32,7 @@ Go-бэкенд издательского художественного пер
| **Фронт** | `frontend/` | нет — лендит оркестратор | читать можно; пинги, итоги и вопросы — ЗОННЫЙ журнал `frontend/docs/frontend-PROGRESS.md` (решение владельца; в `docs/PROGRESS.md` фронт НЕ пишет), туда же пишет и оркестратор; продуктовые требования — `docs/product-requirements.md` | | **Фронт** | `frontend/` | нет — лендит оркестратор | читать можно; пинги, итоги и вопросы — ЗОННЫЙ журнал `frontend/docs/frontend-PROGRESS.md` (решение владельца; в `docs/PROGRESS.md` фронт НЕ пишет), туда же пишет и оркестратор; продуктовые требования — `docs/product-requirements.md` |
| **Платформа** | `platform/` (SaaS control plane: пользователи/квоты/очередь/HTTP; движок дёргает процессами, D39.81) | нет — лендит оркестратор | читать можно; пинги и итоги — ЗОННЫЙ журнал `platform/docs/platform-PROGRESS.md` (решение владельца), в `docs/PROGRESS.md` не пишет | | **Платформа** | `platform/` (SaaS control plane: пользователи/квоты/очередь/HTTP; движок дёргает процессами, D39.81) | нет — лендит оркестратор | читать можно; пинги и итоги — ЗОННЫЙ журнал `platform/docs/platform-PROGRESS.md` (решение владельца), в `docs/PROGRESS.md` не пишет |
Координация — журнал `docs/PROGRESS.md` (секции «Бэкенд»/«Полигон»; сверху CURRENT-STATE). Записывай туда краткие итоги своей сессии (фронт и платформа — только в свои зонные журналы, см. таблицу выше). Закрытые хроники вынесены в слайсы `docs/archive/PROGRESS-*.md`НЕ читать при онбординге, только по конкретной ссылке. Параллельные сессии — норма: чужие незакоммиченные файлы в дереве не трогать; сессия считается ЖИВОЙ, пока владелец не сказал обратное. Координация — журнал `docs/PROGRESS.md` (секции «Бэкенд»/«Полигон»; сверху CURRENT-STATE). Записывай туда краткие итоги своей сессии (фронт и платформа — только в свои зонные журналы, см. таблицу выше). ⚠ Это ЕДИНСТВЕННОЕ исключение из «`docs/` — зона оркестратора»: бэкенд и полигон пишут в СВОИ секции этого журнала (полигон — ещё и в `docs/experiments/`), всё прочее в `docs/` правит только оркестратор. Закрытые хроники вынесены в слайсы `docs/archive/PROGRESS-*.md`НЕ читать при онбординге, только по конкретной ссылке. Параллельные сессии — норма: чужие незакоммиченные файлы в дереве не трогать; сессия считается ЖИВОЙ, пока владелец не сказал обратное.
## Источники истины ## Источники истины
@ -66,14 +66,14 @@ Go-бэкенд издательского художественного пер
- **Не оставляй свои файлы застейдженными** между операциями: пока они в индексе, их может унести чужой коммит. Стейдж и коммит — одной командой. - **Не оставляй свои файлы застейдженными** между операциями: пока они в индексе, их может унести чужой коммит. Стейдж и коммит — одной командой.
- **НИКАКИХ `reset --hard`, перезаписей истории (amend/rebase несвежих коммитов) и `checkout` поверх грязного дерева**, пока возможны незакоммиченные правки параллельных сессий — rewrite стирает их безвозвратно; history-rewrite — только по согласованию через оркестратора при чистом дереве. - **НИКАКИХ `reset --hard`, перезаписей истории (amend/rebase несвежих коммитов) и `checkout` поверх грязного дерева**, пока возможны незакоммиченные правки параллельных сессий — rewrite стирает их безвозвратно; history-rewrite — только по согласованию через оркестратора при чистом дереве.
- **Чужое уже уехало в твой коммит?** Историю НЕ переписывать — сообщить владельцу/оркестратору; содержимое при этом цело, теряется только атрибуция. - **Чужое уже уехало в твой коммит?** Историю НЕ переписывать — сообщить владельцу/оркестратору; содержимое при этом цело, теряется только атрибуция.
- Никогда не коммитить: `START_PROMT.MD` (файл владельца) · `.claude/settings.local.json` · книгу и производные (живут вне git). - Никогда не коммитить В ЭТОТ репозиторий: `START_PROMT.MD` (файл владельца) · `.claude/settings.local.json` · книгу и производные. ⚠ С 24.08 книги лежат в `<репозиторий>/books` и версионируются ОТДЕЛЬНЫМ git-репозиторием со своим origin; внешний держит `/books/` в `.gitignore`. Следствия: `git status` внешнего репо правки книг НЕ показывает (смотреть `git -C books status`), а `clean -xdf` снёс бы каталог вместе с его историей.
## Онбординг новой сессии (порядок чтения) ## Онбординг новой сессии (порядок чтения)
**Развилка ПЕРВАЯ, до всего остального — есть ли у тебя хендофф-промт (файл задания, выданный оркестратором).** **Развилка ПЕРВАЯ, до всего остального — есть ли у тебя хендофф-промт (файл задания, выданный оркестратором).**
- **С промтом:** этот файл → СВОЙ промт; его карта чтения (≤5 позиций) — ЗАКОН, дальше только по её ссылкам. README, CURRENT-STATE и голову журнала решений читать НЕ нужно: ратифицированное вложено в тело промта, остальное берётся грепом по мере вопросов. - **С промтом:** этот файл → СВОЙ промт; его карта чтения (≤5 позиций) — ЗАКОН, дальше только по её ссылкам. README, CURRENT-STATE и голову журнала решений читать НЕ нужно, ЕСЛИ карта промта их не называет (у ролевого промта оркестратора называет — там его номер и очередь): ратифицированное вложено в тело промта, остальное берётся грепом по мере вопросов.
- **Без промта (холодный вход):** полный маршрут ниже. - **Без промта (холодный вход): СНАЧАЛА таблица активных промтов в конце `docs/README.md`.** Назван промт твоей роли — он и есть твой: дальше действует ветка «С промтом», и его карта чтения ЗАКОН. Не назван («активного НЕТ») — полный маршрут ниже. ⚠ Порядок именно такой: слепой замер входа 24.08 показал, что послушная холодная сессия проходит весь маршрут (~300 тыс. знаков) и только потом узнаёт, что её работа уже заказана промтом.
1. Этот файл → `docs/README.md` (карта) → CURRENT-STATE в `docs/PROGRESS.md`. Непонятный жаргон/сокращения — `docs/glossary.md`. 1. Этот файл → `docs/README.md` (карта) → CURRENT-STATE в `docs/PROGRESS.md`. Непонятный жаргон/сокращения — `docs/glossary.md`.
2. `docs/architecture/05-decisions-log.md`: карта актуальности (шапка) + живая голова (её граница названа в шапке файла). Целиком НЕ читать; тела закрытых эр — в слайсах `archive/architecture/` (греп: живой файл → слайсы). 2. `docs/architecture/05-decisions-log.md`: **шапка** (карта актуальности + эрраты) и **реестр** `docs/architecture/05-decisions-index.md` — одна строка на ноту. Из тел — только 23 последние. ⚠ «Живая голова» целиком в обязательное чтение НЕ входит: это 33 ноты, и требование её прочесть противоречило бы дисциплине «целиком НЕ читать» выше; остальные номера грепаются по мере вопросов. Тела закрытых эр — в слайсах `docs/archive/architecture/` (греп: живой файл → слайсы).
3. По роли: Бэкенд — шапка-таблица `09-target-architecture.md` (что построено) → `backend/README.md``03-implementation-notes.md` (через баннер) → `12-go-style-notes.md`; ⚠ порядок именно такой: сессии, впервые видящей движок, механика нужнее стиль-норм; Полигон — `eval/README.md` + `experiments/00` + `09-pilot-protocol.md`; Фронт/продукт — `docs/product-requirements.md` + `research/16` (через ревью-шапку) + контракт `architecture/14-api-contract/`; Платформа — `platform/README.md` + зонный журнал + `research/23` + контракт 14; всем — шапка-таблица `09-target-architecture.md` (статус слоёв). 3. По роли (пути от КОРНЯ репозитория — прежняя редакция писала их от `docs/`, и от корня они не резолвились): Бэкенд — шапка-таблица `docs/architecture/09-target-architecture.md` (что построено) → `backend/README.md``docs/architecture/03-implementation-notes.md` (через баннер) → `docs/architecture/12-go-style-notes.md`; ⚠ порядок именно такой: сессии, впервые видящей движок, механика нужнее стиль-норм; Полигон — `eval/README.md` + `docs/experiments/00-provider-quirks.md` + `docs/experiments/09-pilot-protocol.md`; Фронт/продукт — `docs/product-requirements.md` + `docs/research/16-reader-ide-alignment.md` (через ревью-шапку) + контракт `docs/architecture/14-api-contract/`; Платформа — `platform/README.md` + зонный журнал + `docs/research/23-engine-platform-seam.md` + контракт 14; всем — шапка-таблица `docs/architecture/09-target-architecture.md` (статус слоёв). Как поднять тулчейн и стенд на чистой машине — `docs/dev-stand.md`.

View file

@ -146,7 +146,7 @@ D-ссылка грепается по D-логу · mid-flight аддендум
в отчёте» = дефект, гейты зоны его не видят по построению · триаж находок — МАШИННАЯ сверка «каждая в отчёте» = дефект, гейты зоны его не видят по построению · триаж находок — МАШИННАЯ сверка «каждая
рекомендация → живой носитель», не рекомендация → живой носитель», не
глазами · отчёт с пошаговым планом сверяется ПО ПУНКТАМ плана · каждое «отложено/вернуться» получает глазами · отчёт с пошаговым планом сверяется ПО ПУНКТАМ плана · каждое «отложено/вернуться» получает
строку бэклога или жильца реестра выселенных тел (`architecture/13-tech-debt-anchors.md` §Б) ТЕМ ЖЕ строку бэклога или жильца реестра загейченных триггеров (`13-tech-debt-anchors.md` §Б-108) ТЕМ ЖЕ
лендингом · при закрытии строки её тело грепается на лендингом · при закрытии строки её тело грепается на
«остаток/реопен/гейт», гейты в ДРУГИХ строках пере-диспозиционируются · глаз владельца — рабочий «остаток/реопен/гейт», гейты в ДРУГИХ строках пере-диспозиционируются · глаз владельца — рабочий
рубеж: прайми его артефактами, не пересказом. рубеж: прайми его артефактами, не пересказом.

File diff suppressed because one or more lines are too long

View file

@ -7,6 +7,7 @@
## Карта ## Карта
- [glossary.md](glossary.md) — жаргон и сокращения (D-номер, паки, банк, голден, K/DC/H/L…) одним экраном. - [glossary.md](glossary.md) — жаргон и сокращения (D-номер, паки, банк, голден, K/DC/H/L…) одним экраном.
- [dev-stand.md](dev-stand.md) — **поднять проект на чистой машине**: что поставить, в каком порядке, что требует root и чего стенд НЕ проверяет. Версий и рецептов зон не дублирует — называет носитель и команду чтения.
- [product-requirements.md](product-requirements.md) — реестр «что продукт обязан уметь»: производное живого брифа владельца и его находок, статусы сверены кодом. - [product-requirements.md](product-requirements.md) — реестр «что продукт обязан уметь»: производное живого брифа владельца и его находок, статусы сверены кодом.
- `architecture/` — синтез и контракты: - `architecture/` — синтез и контракты:
- [05-decisions-log.md](architecture/05-decisions-log.md) — **источник истины по решениям**: ратифицированный контракт, при конфликте побеждает он. Дисциплина чтения (грепать номер, не читать целиком, баннер прежде тела) — в каноне `../CLAUDE.md`, здесь не дублируется. Статус и тело ЛЮБОГО номера одним хопом — реестр [05-decisions-index.md](architecture/05-decisions-index.md) (все ноты, колонка тем для грепа «какой закон по X»). - [05-decisions-log.md](architecture/05-decisions-log.md) — **источник истины по решениям**: ратифицированный контракт, при конфликте побеждает он. Дисциплина чтения (грепать номер, не читать целиком, баннер прежде тела) — в каноне `../CLAUDE.md`, здесь не дублируется. Статус и тело ЛЮБОГО номера одним хопом — реестр [05-decisions-index.md](architecture/05-decisions-index.md) (все ноты, колонка тем для грепа «какой закон по X»).
@ -17,7 +18,7 @@
- `research/` — фактура ресёрчей; у принятых — ревью-шапки, часть тел под ⚠ superseded: **читай баннер прежде содержимого**. Ключевые для навигации: 15 голос · 16 ридер-IDE · 17 внешняя критика · 18 рычаги качества · 19 нарезка · 20 банк-майнинг · 21 обзор транспорта · 22 доменные харнессы · 23 шов движок↔платформа · 25 холодное ревью шва — **читать перед любым кодом стыка** · 24 арбитраж банка · 26 официальные практики Anthropic · 28 контракт-ревью API v0 — **носитель для исполняющих сессий, читать оригинал, не пересказ**. - `research/` — фактура ресёрчей; у принятых — ревью-шапки, часть тел под ⚠ superseded: **читай баннер прежде содержимого**. Ключевые для навигации: 15 голос · 16 ридер-IDE · 17 внешняя критика · 18 рычаги качества · 19 нарезка · 20 банк-майнинг · 21 обзор транспорта · 22 доменные харнессы · 23 шов движок↔платформа · 25 холодное ревью шва — **читать перед любым кодом стыка** · 24 арбитраж банка · 26 официальные практики Anthropic · 28 контракт-ревью API v0 — **носитель для исполняющих сессий, читать оригинал, не пересказ**.
- [PROGRESS.md](PROGRESS.md) — журнал: CURRENT-STATE + **ЕДИНЫЙ БЭКЛОГ** (единственный трекер) + живой хвост хроники. НЕ источник решений. - [PROGRESS.md](PROGRESS.md) — журнал: CURRENT-STATE + **ЕДИНЫЙ БЭКЛОГ** (единственный трекер) + живой хвост хроники. НЕ источник решений.
- `scripts/counts.py`**производные числа доков считаются им, а не руками** (голова по трём носителям · счёт очереди и зон · вес открытых строк регистра платформы · полнота реестра нот); `--check` даёт ненулевой код на расхождении; `--lint` — линтер file:line-якорей живых доков (D39.126). Его же зовёт зонный хук `scripts/githooks/pre-commit`: **`--lint` якорей — при коммите, задевающем ЛЮБОЙ док или `CLAUDE.md`; `--check` чисел и головы — при коммите с D-логом или PROGRESS** (оба `--from-index`, предупреждает, не блокирует). ⚠ Шапка систематически отстаёт от хвоста у ЛЮБОГО автора — потому проверка механическая, а не «посмотрю внимательно». - `scripts/counts.py`**производные числа доков считаются им, а не руками** (голова по трём носителям · счёт очереди и зон · вес открытых строк регистра платформы · полнота реестра нот); `--check` даёт ненулевой код на расхождении; `--lint` — линтер file:line-якорей живых доков (D39.126). Его же зовёт зонный хук `scripts/githooks/pre-commit`: **`--lint` якорей — при коммите, задевающем ЛЮБОЙ док или `CLAUDE.md`; `--check` чисел и головы — при коммите с D-логом или PROGRESS** (оба `--from-index`, предупреждает, не блокирует). ⚠ Шапка систематически отстаёт от хвоста у ЛЮБОГО автора — потому проверка механическая, а не «посмотрю внимательно».
- **Активные хендофф-промты — какой файл ТВОЙ** (состав обновляется при каждом лендинге, D39.80; статусы паков, хроника и причины — CURRENT-STATE и D-лог, здесь НЕ дублируются): - **Активные хендофф-промты — какой файл ТВОЙ** (состав обновляется при каждом лендинге, D39.80; здесь — только то, что отвечает на вопрос «какой файл мой»; хроника, причины и статусы РАБОТ — CURRENT-STATE и D-лог):
| Роль | Активный промт | Статус | | Роль | Активный промт | Статус |
|---|---|---| |---|---|---|
| Оркестратор | [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) | роль и нормы; счётчик роли — CURRENT-STATE | | Оркестратор | [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) | роль и нормы; счётчик роли — CURRENT-STATE |

106
docs/dev-stand.md Normal file
View file

@ -0,0 +1,106 @@
# Стенд разработки — поднять проект на чистой машине
> Отвечает на ОДИН вопрос: что поставить и в каком порядке, чтобы все четыре зоны собрались и их
> батареи прошли. **Версий и рецептов зон здесь НЕТ** — каждая строка называет свой носитель и
> команду, которой номер читается: скопированный сюда номер стал бы вторым носителем и разошёлся
> бы с первым (D39.112). Что уже построено и что в очереди — CURRENT-STATE в [PROGRESS.md](PROGRESS.md),
> здесь только «как поднять».
>
> ⚠ **Проверено исполнением 24.08.2026** на чистой Ubuntu 26.04 LTS (WSL2), пользователь `ubuntu-26`,
> репозиторий `~/projects/textmachine`. Результаты прогонов — в теле; всё, что не прогнано, названо
> вслух в разделе «Чего этот стенд не проверяет».
## 1. Что ставится БЕЗ root, и где оно живёт
Схема одна для всех: дистрибутив разворачивается в `~/.local/opt/<инструмент>`, а исполняемое
симлинкуется в `~/.local/bin` — он уже в `PATH` из `~/.profile` Ubuntu, поэтому rc-файлы править не
надо. Каждый архив ставится ТОЛЬКО после сверки sha256 с подписью вендора.
| Инструмент | Кто требует и какой версии (носитель) | Как ставится |
|---|---|---|
| **Go** | `backend/Makefile` `GO_MIN_VERSION` и `platform/Makefile` `GO_MIN_VERSION` (у платформы выше — она сетевая, разбор — комментарий `toolchain` в `platform/go.mod`). Прочесть: `grep -h GO_MIN_VERSION backend/Makefile platform/Makefile` | тарбол с `go.dev/dl``~/.local/opt/go`, симлинки `go`/`gofmt`. ⚠ Брать ПОСЛЕДНИЙ ПАТЧ ПИНОВАННОГО МИНОРА, а не следующий минор: линтер пинован и его находки версионно-зависимы |
| **golangci-lint** | `GOLANGCI_VERSION` в обоих Makefile, точным равенством (`tools-check` сверяет строку версии). Прочесть: `grep -h GOLANGCI_VERSION backend/Makefile platform/Makefile` | release-бинарь с GitHub → `~/.local/bin/golangci-lint`; чексуммы — `golangci-lint-<v>-checksums.txt` того же релиза |
| **Node + npm** | `frontend/package.json` `engines.node`; менеджер — npm из поставки Node (`frontend/docs/STACK_DECISIONS.md` §1). Прочесть: `python3 -c "import json;print(json.load(open('frontend/package.json'))['engines'])"` | тарбол с `nodejs.org/dist``~/.local/opt/node`; чексуммы — `SHASUMS256.txt` того же каталога. ⚠ `frontend/.npmrc` ставит `engine-strict=true` — Node ниже пола это ОШИБКА установки, а не предупреждение |
| **PostgreSQL** | `platform/README.md` (мажор) — рецепт целиком, включая порт и DSN, живёт в `platform/docs/STACK_DECISIONS.md` §«Postgres на стенде без root» | ровно по тому рецепту: micromamba + conda-forge в `~/.local/pgsql`, кластер в `~/.local/share/tmstand/pgdata`, сокет в `/tmp`. Рецепт ратифицирован зоной и sudo не требует |
| **micromamba** | нужен только предыдущей строке | один статический бинарь; ⚠ на чистой Ubuntu 26 НЕТ `bzip2`, поэтому `tar -xjf` падает — архив распаковывается модулем `tarfile` питона (`bz2` в stdlib есть) |
## 2. Что БЕЗ root не ставится — и почему обход недопустим
| Пакет | Кто без него не работает | Почему нельзя обойти |
|---|---|---|
| **`build-essential`** (`gcc` + `make`) | `make test`/`make battery`/`make check` ОБЕИХ Go-зон | Обе цели гоняют `go test -race`, а `-race` требует cgo, то есть C-компилятора. Комментарий над целью в `backend/Makefile` говорит прямо: снять `-race` значит превратить отсутствие тулчейна в зелёный прогон, доказывающий меньше, чем он заявляет. `make` нужен и сам по себе: `platform` `TestTheToolchainGateComparesVersionsRatherThanMatchingThem` зовёт `make version-check` и без `make` СКИПАЕТСЯ |
| **`python3-venv`** | вся зона `eval/` | В системном питоне Ubuntu 26 нет `ensurepip`, поэтому `python3 -m venv .venv` создаёт окружение БЕЗ pip. Ратифицированная зоной установка — `python3 -m venv .venv && .venv/bin/pip install -r requirements.txt` (`eval/README.md` п.5) — на этом и останавливается |
Ставится одной командой; она же — единственное, что в этом файле просит пароль:
```sh
sudo apt-get update && sudo apt-get install -y build-essential python3-venv
```
## 3. Порядок подъёма
1. **Go + golangci-lint**`cd backend && make battery` (после шага 2 — `make battery-stand`).
2. **Postgres** по рецепту зоны → `cd platform && TM_PLATFORM_TEST_DSN=<из рецепта> make check`.
3. **Node**`cd frontend && npm ci && npm run check`. ⚠ `npm ci` через `prepare` ставит
pre-commit-диспетчер в `.git/hooks/` — **это единственный путь, которым включается гейт якорей
доков** (`docs/scripts/githooks/pre-commit`). На клоне, где во фронте не ставили зависимости, гейт
МОЛЧА выключен. Поставить его отдельно, без установки зависимостей:
`node frontend/scripts/githooks/install.mjs`.
4. **Python-окружение полигона** — по `eval/README.md` п.5.
5. **Данные книг** — раздел 4 ниже.
6. **Дев-стенд платформы целиком** (демон + сид через живой интейк + дев-прокси фронта) — рецепт в
`platform/deploy/README.md` §«Дев-стенд». Он же — самая дешёвая сквозная проверка: сид гоняет
движковый бинарь настоящим вызовом.
## 4. Каталог книг
Книги и производные лежат в **`<репозиторий>/books`** и версионируются ОТДЕЛЬНЫМ git-репозиторием
(свой `origin`, свой лог); внешний репозиторий держит `books/` в `.gitignore` и о нём ничего не знает.
Инвариант канона «книга и производные вне git» этим не нарушен — вне ЭТОГО git, — но следствия
новые:
- `git clean -xdf` во внешнем репозитории снёс бы весь каталог вместе с его историей. `clean` и так
запрещён каноном (`CLAUDE.md` §Гардрейлы); здесь у запрета появилась вторая цена.
- `git status` внешнего репозитория НЕ показывает правки книг. Состояние книг читается только
`git -C books status`.
- ⚠ Прежний адрес каталога был `~/books`, и он захардкожен в трёх местах движка и в скриптах
полигона. Диспозиция — строки бэклога; до их закрытия корпус-гейченные тесты движка запускаются с
переопределениями (`TM_CHECKER_LABELS_DIR`, `TM_MINER_PARITY_{RECORDS,SEED}`), которые в коде уже
предусмотрены.
## 5. Чего этот стенд не проверяет
Гейт обязан печатать, чего он не смотрит, — иначе его молчание читается как покрытие.
- **`-race` не гонялся ни в одной зоне** (нет C-тулчейна, раздел 2). Все зелёные прогоны ниже —
БЕЗ детектора гонок, и это не «батарея прошла».
- **`make` не гонялся** — цели исполнялись командами из самих Makefile. Расхождение цели и того, что
запускали, этим не поймано.
- **Ни одного платного вызова.** Всё зелёное — $0-пути: сборки, юнит-тесты, `tmctl manifest/status`,
интейк платформы. `tmctl translate` не запускался.
- **`TestMinerFullBookParity` СКИПАЕТСЯ на любом клоне**: ему нужен `eval/exp16/data/jieba_dict_general_zh.txt`,
который в git не попадает (`.gitignore`) и пересобирается — носитель диспозиции — строка бэклога 123.
- **Браузеры Playwright не скачаны**`npm run check:full` (цели `shot`/`scenes`, оси axe) не гонялся;
`npm run check` их не включает.
- **Локальной модели нет:** ни `ollama`, ни GPU (`nvidia-smi` отсутствует). Замеры полигона, которым
нужна локальная модель, на этой машине не воспроизводимы.
- **OIDC-провайдера нет** — вход на стенде идёт дев-логином; боевой путь входа не проверялся.
## 6. Ловушки, подтверждённые на этой машине
- **`no_proxy=<local>` в окружении WSL — это Windows-синтаксис, и curl его не понимает.**
`curl http://127.0.0.1:8080/healthz` отдаёт **403** от прокси, и это читается как дефект кода,
которого нет. Лечится по месту: `curl --noproxy '*'` (так и записано в
`platform/docs/STACK_DECISIONS.md` §«Грабли стенда») или `NO_PROXY=127.0.0.1,localhost,::1`.
**Go-бинари проекта эта грабля НЕ задевает, и не потому, что понимают `<local>`:** пробой
`http.ProxyFromEnvironment` показано, что loopback не проксируется и при `no_proxy=""` вовсе —
это встроенное правило, а не заслуга переменной. Значит симптом асимметричен: ручная проверка
curl'ом краснеет там, где сам сервис зелёный.
- **`tmctl` берёт глагол ПЕРВЫМ аргументом, флаги после**: `tmctl manifest --config book.yaml`.
Обратный порядок печатает `--config book.yaml is required` — сообщение выглядит как «флаг не
передан», хотя флаг передан.
- **`tmplatformctl seed` требует и `TM_PLATFORM_DSN`, и `TM_PLATFORM_DEV_LOGIN`** в СВОЁМ окружении,
а не только в окружении демона: он ходит и в базу, и в HTTP.
- **Шаблон книги для платформы (`TM_PLATFORM_BOOK_TEMPLATE`) обязан нести АБСОЛЮТНЫЕ пути** к
`pipeline:`/`models:`. `backend/example/book.yaml` годится как заготовка, но его относительные
`../configs/...` из каталога книги платформы не разрешаются.