# Solution: Rules Engine and Authoritative RNG Contract ## Выбранный подход Use executable contract tests against the shared vertical-slice engine and a single authoritative Game Contract/rules-profile fixture. This study owns ordering, authority, idempotency and auditability assertions; it does not duplicate the engine, event log, state model, fixture loader or profile. The central invariant is ordering: schema validation, idempotency and expected state-version checks complete before RNG consumption and event/state mutation. Only the injected server RNG can supply an accepted raw result. ## Архитектура и поток данных ```text untrusted command-shaped data -> schema validation -> authorize actor/turn/resource -> resolve command ID / idempotency -> compare expected state version -> evaluate deterministic preconditions -> consume server RNG if required -> calculate formula and modifier -> append event with roll evidence -> materialize next state -> return committed event reference ``` Client and LLM payloads may propose intent but never an accepted raw roll or outcome. Duplicate and stale commands exit before another RNG call. ## Структура прототипа - [`prototype/rules-engine.verification.test.ts`](prototype/rules-engine.verification.test.ts) — six executable tests covering AC-01–AC-06. - [`../2026-07-25-ai-gm-vertical-slice/prototype/src/engine.ts`](../2026-07-25-ai-gm-vertical-slice/prototype/src/engine.ts) — shared `executeProposal` rules/event boundary. - [`../2026-07-25-ai-gm-vertical-slice/prototype/src/event-log.ts`](../2026-07-25-ai-gm-vertical-slice/prototype/src/event-log.ts) and [`../2026-07-25-ai-gm-vertical-slice/prototype/src/state.ts`](../2026-07-25-ai-gm-vertical-slice/prototype/src/state.ts) — shared event/state evidence. - [`../2026-07-25-ai-gm-vertical-slice/prototype/src/fixtures.ts`](../2026-07-25-ai-gm-vertical-slice/prototype/src/fixtures.ts) — authoritative `loadFixtureBundle()` loader. - [`../2026-07-25-ai-gm-vertical-slice/prototype/fixtures/game-contract.json`](../2026-07-25-ai-gm-vertical-slice/prototype/fixtures/game-contract.json) — the single shared original/attributed rules profile. The former study-local `original-genre-neutral-profile.ts` duplicate was deleted. No second rules profile is maintained here. ## Требования - Verified OS/hardware: macOS 26.4 (`25E246`), arm64. - Verified runtime: Node.js `v24.14.0`, whose built-in TypeScript strip mode runs erasable `.ts` syntax without an experimental flag. - Root compiler dependency: TypeScript `7.0.2`. - Package manager declared by the root project: npm `11.9.0`. - External services: `none`. These requirements reproduce the prototype only and do not select a production runtime, RNG or storage system. ## Установка From the repository root: ```bash npm ci ``` The behavior suite itself uses Node’s built-in test runner and root-declared dependencies. There is no study-local dependency installation. ## Запуск From the repository root: ```bash node --test RnD/technical/2026-07-25-rules-engine-authoritative-rng/prototype/rules-engine.verification.test.ts ``` Equivalent command from this study directory: ```bash node --test prototype/rules-engine.verification.test.ts ``` Expected result in the recorded environment: `6` tests, `6` pass, `0` fail, `0` skipped and `0` TODO. ## Тестирование Run the behavior suite, then the root strict compiler: ```bash node --test RnD/technical/2026-07-25-rules-engine-authoritative-rng/prototype/rules-engine.verification.test.ts npm run typecheck ``` Both commands passed in the final recorded run. ## Конфигурация No environment variables, network calls or external services are used. - `FixedRandomSource` supplies explicit raw results and counts RNG calls. - Every case constructs fresh shared state and `InMemoryEventLog`. - The shared rules profile declares `quick-kit` version `0.1.0`, d20 `roll_plus_modifier_gte_difficulty` resolution and official Knave 1e attribution. - Official primary source: [Questing Beast — Knave](https://questingbeast.itch.io/knave). ## Ограничения и безопасность - Fixed RNG verifies accepted-result authority and calculation, not entropy, distribution or cryptographic fairness. - In-memory sequential execution does not establish durable transactionality, distributed idempotency or actual concurrent-writer behavior. - Built-in Node strip mode accepts erasable TypeScript syntax only. The first run exposed a constructor parameter property; the test uses an ordinary field plus constructor assignment and now runs without transpilation flags. - The shared profile contains no copied adventure, spell, item, setting or branded compatibility content. - Passing authority tests do not measure balance, fun, latency or throughput. ## Условия переноса в production - Preserve validation/idempotency/version ordering on every command path. - Choose a production RNG source, seed/audit policy and threat model separately. - Replace in-memory storage with a transactional persistent implementation while retaining command-ID and expected-version behavior. - Add concurrent-writer, reconnect and failure-injection integration tests. - Keep complete roll evidence and stored event references replayable. - Validate balance/content separately; passing authority tests is not game quality evidence.