# Solution: genre-neutral Adventure Contract boundary ## Выбранный подход Минимальное решение разделяет creative intent, proposal и authority: 1. `validateHostPreferences` принимает только недоверенный high-level brief, session envelope и content boundaries. 2. `validateAdventureDraft` проверяет предложенные planner-ом characters, facts, clocks, scenes, endings, refs, reachability и fail-forward. 3. `compileAdventureContract(preferences, draft)` требует совпадающий `adventureId`, клонирует данные, добавляет authority markers, выводит typed triggers и повторно вызывает `validateAdventureContract`. Только contract с нулём issues разрешено передавать rules/state ядру. Compilation полностью deterministic: без LLM, сети, времени и RNG. ## Архитектура и поток данных ```text HostPreferences (untrusted, any genre/story) → host-intent validation → planner proposes AdventureDraft (still untrusted) → draft graph/reference/reachability validation → matching adventureId check → cloned facts/characters/clocks/scenes/endings → authority markers + immutable narrator policy → derived typed triggers → compiled-contract validation → AdventureContract + stable SHA-256 → later: map/rules binding and viewer-scoped narration ``` ### Границы authority | Объект | Кто предлагает | Кто валидирует | Может ли narrator менять | |---|---|---|---| | HostPreferences | Host | Input validator | Не применимо: это ещё не канон | | AdventureDraft | Scenario planner | Draft validator + compiler | Не применимо: это ещё proposal | | Story facts | Planner до старта | Draft validator + contract compiler | Нет | | Scene exit | Adventure contract | Rules/state orchestration | Нет; narrator описывает уже выбранный exit | | Clock advance | Typed trigger | Authoritative event/state layer | Нет | | Ending | Contract + validated event | State layer | Нет | | Incidental description | Narrator | Output/safety layer | Да, если не создаёт canonical effect | ### Improvisation envelope Contract допускает description, мотивированную NPC-речь и incidental props без rules effect. Он всегда запрещает прямую мутацию: - story facts; - rules; - map topology; - visibility; - ending conditions. Новый canonical element может быть только proposal, который проходит отдельный validator и event commit. ## Структура прототипа - `prototype/adventure-types.ts` — HostPreferences, AdventureDraft, output и visibility types. - `prototype/adventure.ts` — boundary и contract validation, graph checks, deterministic compile. - `prototype/adventure-support.ts` — trigger derivation и stable SHA-256. - `prototype/fixtures/sci-fi-comedy.ts` — original non-canonical host brief и отдельный planner draft. - `prototype/adventure.test.ts` — positive, mutation и invariant tests. - `prototype/demo.ts` — compile/validate executable path. - `prototype/README.md` — краткие команды. ## Требования - Проверено: macOS 26.4, Apple Silicon. - Runtime фактического test path: `/usr/local/bin/node` v22.14.0. - TypeScript выполняется встроенным experimental type stripping. - Static check: TypeScript 7.0.2 и `@types/node` 24.13.3 из root toolchain. - Внешние сервисы: `none`. - Runtime demo/test не требуют package install или network; static check использует уже установленный root toolchain. ## Установка Из папки исследования: ```bash node --version ``` Ожидаемый проверенный runtime: `v22.14.0`. Prototype не имеет install step. ## Запуск ```bash node --no-warnings --experimental-strip-types prototype/demo.ts ``` Ожидается JSON с `fixtureIsCanonical: false`, `validationIssueCount: 0` и deterministic `contractSha256`. ## Тестирование ```bash node --no-warnings --experimental-strip-types --test prototype/adventure.test.ts ``` Ожидается `tests 7`, `pass 7`, `fail 0`. Scoped static check из папки исследования: ```bash ../../../node_modules/.bin/tsc --ignoreConfig --noEmit --strict \ --noUncheckedIndexedAccess --exactOptionalPropertyTypes --target ES2024 \ --module NodeNext --moduleResolution NodeNext --allowImportingTsExtensions \ --rewriteRelativeImportExtensions --erasableSyntaxOnly --types node \ prototype/*.ts prototype/fixtures/*.ts ``` Ожидается exit `0` без diagnostics. ## Конфигурация Environment variables и secrets отсутствуют. Два входа передаются обычными TypeScript objects. Для нового жанра меняются HostPreferences и AdventureDraft, а не compiler branches. ## Ограничения и безопасность - Node v22 type stripping остаётся experimental; static checking выполняется отдельной командой. - Runtime validator покрывает исследованные invariants, но не semantic truth, moderation или авторские права. - Free-text consequences не являются state mutation; production слой должен связывать effect с typed event, а не разбирать текст. - Prototype не запускает LLM и не доказывает narrative quality. - Fixture не переносится в product canon. ## Условия переноса в production - Добавить выбранный static typecheck/build pipeline и versioned serialization. - Заменить hand-authored shape checks утверждённой schema boundary, сохранив behavioral graph validation. - Связать trigger effects с canonical event/rules types. - Добавить content moderation, provenance/rights review и audit log. - Зафиксировать schema migration и backward-compatibility policy. - Провести separate model adherence evaluation на viewer projections. - Интеграцию выполнять отдельной production-задачей; prototype не импортировать молча.