Solution: genre-neutral Adventure Contract boundary
Выбранный подход#
Минимальное решение разделяет creative intent, proposal и authority:
validateHostPreferencesпринимает только недоверенный high-level brief, session envelope и content boundaries.validateAdventureDraftпроверяет предложенные planner-ом characters, facts, clocks, scenes, endings, refs, reachability и fail-forward.compileAdventureContract(preferences, draft)требует совпадающийadventureId, клонирует данные, добавляет authority markers, выводит typed triggers и повторно вызываетvalidateAdventureContract.
Только contract с нулём issues разрешено передавать rules/state ядру. Compilation полностью deterministic: без LLM, сети, времени и RNG.
Архитектура и поток данных#
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/nodev22.14.0. - TypeScript выполняется встроенным experimental type stripping.
- Static check: TypeScript 7.0.2 и
@types/node24.13.3 из root toolchain. - Внешние сервисы:
none. - Runtime demo/test не требуют package install или network; static check использует уже установленный root toolchain.
Установка#
Из папки исследования:
node --version
Ожидаемый проверенный runtime: v22.14.0. Prototype не имеет install step.
Запуск#
node --no-warnings --experimental-strip-types prototype/demo.ts
Ожидается JSON с fixtureIsCanonical: false,
validationIssueCount: 0 и deterministic contractSha256.
Тестирование#
node --no-warnings --experimental-strip-types --test prototype/adventure.test.ts
Ожидается tests 7, pass 7, fail 0.
Scoped static check из папки исследования:
../../../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 не импортировать молча.