19 KiB
17 — Закон входной двери шва движок ↔ платформа
СТАТУС: РАТИФИЦИРОВАНО D39.156 (слово владельца 23.08). Это НОРМА, ссылаться на неё можно, и у неё есть работающий образец: первая дверь по этому закону ПОСТРОЕНА и заленджена 27.08 —
tmctl bank-apply(D39.158). Онтология слоя, который дверь обслуживает, —18-bank-ontology.md.Ратифицирована ДИСЦИПЛИНА, а не каталог команд, и свойство этого выбора такое: новые двери встают паками без возврата к владельцу — ровно так, как код выхода
13встал в ратифицированную полосу 10–19 через ратификации ОРКЕСТРАТОРА (D39.131 п.2а → D39.132 п.2г → D39.134), а не новым решением владельца.Зачем понадобилось. Контракт фронт↔платформа ратифицирован (
14-api-contract/), а платформа↔движок — нет: исследование шва дошло до «события пишутся вevents.jsonl» и дальше отвечало только на вопрос «как запускать движок» (research/23, транспортная часть §1 superseded D39.106;research/25— ратифицированная форма и отвергнутые альтернативы). НАРУЖУ из движка идёт богатый поток — журнал событий по курсору, полоса кодов выхода, версионированные артефакты-проекции, — а ВНУТРЬ не шло ничего, кроме запуска с флагами: данные, которыми владеет пользователь продукта, движок принимать не умел вовсе.
Почему НОРМА, а не каталог команд
За осознанный контракт говорят три прожитых инцидента гниения нератифицированных входных конвенций:
дубль дефолта <book_id>.db у платформы (строка бэклога 213) · ручная константа версии API,
не поднятая при синке (D39.153) · три мины формата карты подписи, вскрытые только трассировкой
строки 199.
Против ПОЛНОГО каталога — то, что половина будущих дверей гейтится нерешёнными развилками: строка 192 прямо запрещена к проектированию до полигонных итогов (D39.144 п.1; ⚠ область сужена D39.165 — открыть дверь к построенному ≠ проектировать цикл, см. ⚠-строку под таблицей дверей), 161/185 ждут дизайн-пака, 170 — «после беты формы Б». Каталогизировать их сейчас значит выдумывать.
Прецедент — исходящее направление: там выиграла ратификация ПОЛОСЫ и ДИСЦИПЛИНЫ, а не перечня.
Закон: семь пунктов
-
Вход — это аргументы при спавне и файлы, названные аргументами. Данные, которыми владеет пользователь продукта, доезжают движковым ГЛАГОЛОМ; движок — единственный писатель файлов своей схемы и владелец их путей и конвенций. Платформа читает только версионированные артефакты по путям, которые ей СООБЩЕНЫ ДВИЖКОМ ИЛИ РАТИФИЦИРОВАНЫ КОНТРАКТОМ ШВА, и никогда не выводит путь сама. ⚠ Два выноса, без которых буква закона объявляет вне закона уже ратифицированное: (а) форма Б — одноразовый рендер стартового
book.yamlпри рождении книги (D39.130 п.2б): платформа пишет пять ключей идентичности, всё остальное проходит из шаблона непрочитанным (platform/internal/books/render.go:29-33=comes from the template unread and unjudged); живёт до формы В (строка 170). (б) фикс-имена ратифицированной конвенции шва —events.jsonlникто платформе не «сообщает», это константа (platform/internal/ingest/tail.go:17=const JournalFile = "events.jsonl", D39.106); без этого выноса буква ломает главный канал самого шва. Прецеденты: потолок аргументом (D39.110 п.2б →--ceiling-usd, D39.122) ·--verify-bankфлагом (platform/internal/runner/engine.go:116=func TranslateArgs(workdir string, verifyBank bool) · дефолтproject_dbпо конвенции каталога (backend/internal/config/book.go:200=b.ProjectDB = filepath.Join(dir, b.BookID+".db")) · конвенционное опциональное чтение.auto-bank.yaml(backend/internal/pipeline/mining.go:674=.auto-bank.yaml). -
Посреди прогона внутрь идёт ТОЛЬКО сигнал.
SIGTERM= «дочти чанк и отпусти лок» — ⚠ это ратифицированная ЦЕЛЬ, а не сегодняшнее дерево (пометка 10.09). Владелец ратифицировал две остановки (D39.234п.1а): первый сигнал — мягкий, он и означает «дочти и отпусти». В КОДЕ его ещё нет:backend/cmd/tmctl/main.go:207отменяет контекст прогона, летящий вызов рвётся, книжится по оценке и метитсяcancelled. ⇒ норму НЕ переписывать под дерево, дерево догоняет норму; носитель работы — строка бэклога 381, где этот адрес назван третьим. Всё остальное — на границах процессов. Арбитр — эксклюзивный flock проекта на всю жизнь прогона (backend/internal/store/store.go:55=EXCLUSIVE flock on), мутирующий глагол берёт его неблокирующе и при занятости отказывает ровно классом 12 (platform/internal/ingest/exit.go:69=ExitProjectLocked = 12), а НЕ 10: полоса различает их не косметически — 10 (platform/internal/ingest/exit.go:62=ExitConfigInvalid = 10) значит «деплой сломан, чинит человек, книги ждут», 12 значит «ничего не произошло, подожди и повтори» (D39.134 п.2а). Запись через слэш позволила бы исполнителю выбрать 10, и платформа отнесла бы занятый лок к операторским ошибкам. Почему жёстко: движок пере-читает сид ПОСРЕДИ прогона (mining.go:221), запись в живой прогон въехала бы в снапшот недетерминированно. Потолок посреди прогона менять НЕЛЬЗЯ — он едет со стартом и после не меняется, лекарство — новый прогон (platform/internal/runs/reconcile.go(греп202в обработчике возобновления; ⚠ номер строки снят 30.08 — файл правит живая сессия P12)). Дверь «менять потолок файлом» закрыта; не выдумывать её заново изresearch/25. -
Каждый JSON-выход глагола несёт версию документа — п. ИСПОЛНЕН, асимметрии нет:
tm-bank-v1(pipeline/bankexport.go:30=const bankExportVersion = "tm-bank-v1"),tm-manifest-v2(pipeline/manifest.go:46=const manifestVersion = "tm-manifest-v2") иstatus --json(backend/internal/pipeline/status.go:173=const statusVersion = "tm-status-v1", проставляется:485). -
Незнакомый флаг = громкий отказ при спавне. Сегодня это так по устройству разбора аргументов (
backend/cmd/tmctl/invocation.go:128=flag.NewFlagSet(cmd, flag.ContinueOnError)); зафиксировать законом, а не полагаться на случайность. -
Глагол зовётся ТЕМ ЖЕ пиннутым бинарём, что и возобновляемая попытка (
runs/spawn.go:250-258=engineBinary is the path an attempt is PINNED to, строка бэклога 139). Иначе файл, записанный новым бинарём, читается старым — а при нестрогом загрузчике сида (строка 212) новое поле теряется МОЛЧА (⚠ адрес испр. 10.09: строки 212 в живом трекере НЕТ — она закрыта; факт оставлен как довод, номер снят, чтобы не звать читателя в пустоту). -
Словарь движка ↔ словарь контракта — одна таблица, два направления, один файл. Сегодня перевод односторонний, на чтении (
platform/internal/ingest/bank.go:15-21=Every vocabulary crossing here is TRANSLATED and none is passed through). Запись делает таблицу двунаправленной, и две копии разъедутся. -
Мутирующий глагол сначала даёт проекцию, потом мутирует. «Почём ДО подтверждения». Прецеденты: rebill-смета с порогом согласия (D20.2-Q2,
pipeline/rebill.go) · строка 185 («сколько глав и почём до подтверждения») ·--dry-runстроки 124(в).
Совместимость без второго рукосинхронизируемого контракта
Версий у КОМАНД нет и заводить их не нужно: совместимость выводится из трёх уже существующих ног —
пиннинг попытки к бинарю (строка 139) · незнакомый флаг роняет спавн громко (п.4) · версионированный
конверт на каждом JSON-выходе (п.3). Плюс одна асимметричная норма: движок не меняет семантику флага
или поля без мажора, новые флаги едут «движок-первым» — расширение уже ратифицированного порядка
деплоя migrate (D39.134 п.3).
Хендшейк или capabilities-глагол движка — НЕ строить: один хост, «least mechanism»
(12-go-style-notes.md §1), а судьбу ручной константы показал инцидент ContractVersion.
⚠ Предположение, не механизм: окно «старая платформа + новый движок» считается покрытым обратной
совместимостью флагов. Если деплои разъедутся сильнее — вернуться к вопросу.
Двери, УЖЕ подразумеваемые живыми строками
| дверь | откуда следует |
|---|---|
resnapshot --dry-run |
строка 124(в), глагол поименован там дословно. ⚠ Испр. 10.09: ссылка на «родню строки 231» СНЯТА — такой строки в живом трекере нет, а обоснование стояло на ней и на слове «скорее всего», то есть на догадке без хозяина. Прежний текст: родня строки 231 просит ту же способность («оценить, ничего не покупая») со стороны ШВА, и решаться они, скорее всего, одним глаголом |
✅ И ПРОЧИТАНА платформой с 06.09 — механика ОДНИМ носителем: 15-money-path.md §3 (акт D39.208). Прежняя редакция: ⚠ движковая оценка $/глава — ПОСТРОЕНА и опубликована 05.09 (expected_usd · book_once_usd · step_max_usd в manifest --json/status --json, лендинг 81a89e9, акт D39.206); непостроена ПЛАТФОРМЕННАЯ половина — числа никем не читаются (`git grep -lE "StepMax |
step_max" -- platform/` пусто) |
tmctl init (форма В) |
строка 170; приоритет ПАДАЕТ после двери 199(а) — та забирает её главный довод |
⚠ ПОСТРОЕНЫ по этому закону и из таблицы сняты (форма читается по ним как по образцам): приём правок банка движковым глаголом tmctl bank-apply — 27.08, D39.158, развилка владения book.yaml (строка 199а) растворена · --keys-file — движок 27.08 (D39.158), передача с платформы 28.08 (P9/D39.162), строка 211 ЗАКРЫТА и блокером живого прогона больше не является (⚠ ⚠ испр. 05.09: строка 202 ЗАКРЫТА D39.200 — прогон отработал; её остаток о непокрытых поверхностях живёт строкой 255) · путь артефакта в ответе движка — конверт StatusArtifacts в status --json/manifest --json (project_db · bank_export · mined_delta · mined_rejects · book_files, D39.162/D39.175), строка 213 сужена до одной строки ДЕВ-супервизора · consent-флаги --resnapshot/--accept-rebill от платформы — 28.08, D39.166, продаются членом RunRequest.re_pass (канон контракта 0.7.0+); гейт «строка 192» СНЯТ владельцем (D39.165).
Не установлено, проверить при постановке: строка 198 (апгрейд стирает замечания) — возможно, подразумевает
глагол пере-анонса или бэкфилла, потому что движок анонсирует юнит один раз за жизнь книги
(backend/internal/pipeline/events.go:435=func unitOnceKey(bookID string, k unitWave) string); направление фикса консилиум НЕ установил.
Из чего двери НЕ следует (экономия паков): 255 (бывшая 202, закрыта D39.200) — потребитель всего набора, своих команд не
несёт · 208 · 210 (⚠ испр. 10.09: обеих строк в живом трекере НЕТ, закрыты; довод «дверь из них не следует» остаётся, номера сняты) · вайр-батч 182 ·
164 — не команда, а починка: смета уже едет в status --json.
Чего НЕ строить
-
Инбокс-каталог входящих команд как зеркало
events.jsonl. Все трассированные нужды садятся на границы процессов; единственный мид-ран кандидат закрыт каноном (п.2); инбокс-файл возвращает гонку, ради исключения которой существует flock. ⚠ Эррата, которую ратифицирующая нота обязана поставить наresearch/25: там «поднятие потолка файлом через atomic rename» отнесено к носителям D39.106 — в теле D39.106 этого механизма НЕТ вовсе (проверять по ЖИВОМУ телу ноты D39.106 («ШОВ: прогон переживает деплой платформы») вarchitecture/05-decisions-log.md, адресуя НОМЕРОМ, а не строкой; ⚠ в слайсеarchive/architecture/05-decisions-D39-106-123.mdтела D39.106 НЕТ — греп по нему подтвердил бы эррату вакуумно). Строка была КАНДИДАТОМ и никогда не ратифицировалась, а живой канон решил ось иначе (п.2). -
Пере-открытие транспорта (gRPC/сокет/брокер/пуш) —
research/25, у каждой альтернативы 0 голосов из ~18, решение владельца принято. -
Общий Go-пакет типов на две системы — сварка независимых деплоев против D39.81/85; перевод словаря на шве — сознательный контракт, а не недоделка.
-
Быстрый poll статуса —
statusдорог по построению (пере-ингест книги), свежесть даёт журнал событий; «status — это ремонт, а не поллинг» подтверждено вхолодную независимыми панелями.