Research: Rules Engine and Authoritative RNG Contract
Baseline#
Fact: At study start the repository had PRD/research rules and RNG
invariants but no shared executable engine, randomness port, idempotency store
or expected-version handler. The parallel
2026-07-25-ai-gm-vertical-slice study then supplied a shared engine, event log,
state model, fixture loader and authoritative Game Contract/rules profile. This
study connected its pre-registered authority cases to those public modules
instead of keeping a duplicate engine or profile.
The mechanical baseline is not a product implementation. Knave 1.0 is used only as an attributed source of high-level rules-light principles: classless characters, d20 ability-driven resolution and equipment-defined roles. The shared executable profile uses original genre-neutral names and contains no Knave setting, items, spells, prose or compatibility claim.
Метод#
- Extract roll completeness, invalid-command, recovery, idempotency and version requirements from canonical PRD/research.
- Record the official Knave 1.0 page, access date, version indicator, license statement and only the high-level principles stated there.
- Keep one original declarative profile in the shared Game Contract fixture.
- Import the shared
executeProposal,InMemoryEventLog,loadFixtureBundle,stateHashandcreateInitialStateAPIs. - Execute controlled fixed-RNG, fabricated-result, invalid-command, duplicate and stale-version cases with fresh state/event contexts.
- Compare roll fields with independently worked literals and inspect RNG call count, event count/reference, state hash/version and structured errors.
- Run the root strict TypeScript compiler after the behavior suite.
No statistical RNG-quality gate is set. Distribution, entropy, concurrency and latency are separate production measurements and are not inferred from fixed test values.
Реестр доказательств#
| ID | Тип | Описание | Источник, путь или команда | Дата или версия |
|---|---|---|---|---|
| E-001 | Fact | FR-05 prevents roll/commit for schema-invalid commands; FR-06 requires raw result, formula, modifiers, rule version and event reference; FR-12 prevents reconnect duplication | ../../docs/prd/2026-07-22-global-party-ai-rpg.md |
PRD Draft, 2026-07-22 |
| E-002 | Fact | Technical Context requires append-only events, materialized state, expected state version, idempotency keys and logged server RNG | ../../docs/prd/2026-07-22-global-party-ai-rpg.md |
PRD Draft, 2026-07-22 |
| E-003 | Fact | Research specifies server-generated logged RNG and checking idempotency/expected version before a new event after slow AI/STT work | ../../research/06-product-mvp-and-ai-gm.md |
2026-07-21 research pack |
| E-004 | Fact | Pilot criteria require every roll to retain reproducible formula/modifiers/event reference and reconnect not to duplicate an action | ../../research/06-product-mvp-and-ai-gm.md |
2026-07-21 research pack |
| E-005 | Fact | Official author page lists Knave 1.0 files, classless play, d20 rolls using abilities, equipment-defined roles and CC BY 4.0 adaptation with attribution | Questing Beast — Knave | Accessed 2026-07-25; downloadable version shown as Knave 1.0 |
| E-006 | Fact | loadFixtureBundle() loads the single shared game-contract.json; its quick-kit rules profile contains Knave 1e/Ben Milton/CC BY 4.0/official URL attribution and original executable fields |
../2026-07-25-ai-gm-vertical-slice/prototype/src/fixtures.ts; ../2026-07-25-ai-gm-vertical-slice/prototype/fixtures/game-contract.json |
2026-07-25 |
| E-007 | Fact | Rules tests import the shared contracts, engine, event log, fixture loader, hash and state modules; the former study-local profile duplicate is absent | prototype/rules-engine.verification.test.ts; rg --files RnD/technical/2026-07-25-rules-engine-authoritative-rng |
2026-07-25 |
| E-008 | Measurement | Behavior suite completed with 6 tests, 6 pass, 0 fail, 0 skipped and 0 TODO on Node.js v24.14.0 |
node --test RnD/technical/2026-07-25-rules-engine-authoritative-rng/prototype/rules-engine.verification.test.ts from repository root |
2026-07-25 final rerun |
| E-009 | Measurement | Root strict TypeScript compilation completed with exit code 0 | npm run typecheck; root tsconfig.json |
2026-07-25 final rerun |
| E-010 | Unknown | Production entropy quality, distributed idempotency, concurrent persistence and mechanical balance have not been measured | Scope boundary and VALIDATION.md |
2026-07-25 |
Журнал экспериментов#
| Время | Изменение или попытка | Наблюдение | Artifact или evidence ID | Вывод |
|---|---|---|---|---|
| 2026-07-25T01:04:02+07:00 | Read the official Knave page and canonical PRD/research requirements | Version 1.0 and licensed high-level mechanical inspiration are attributable; product-specific text/content is unnecessary | E-001–E-006 | Proceed with an original genre-neutral profile |
| 2026-07-25T01:10:14+07:00 | Initial manifest-only run | Historical suite reported 7 tests: 2 manifest/profile checks passed and 5 behavior cases were TODO | Historical test output retained from study start | This pre-registration did not verify rules/RNG behavior and is superseded by the final executable suite |
| 2026-07-25 | Connected AC-01–AC-06 to shared vertical-slice public APIs and removed the local duplicate profile | All tests now use loadFixtureBundle() and the shared game-contract.json |
E-006, E-007 | Shared fixture is the authoritative rules-profile source |
| 2026-07-25 | First executable Node.js v24.14.0 behavior run |
Failed with ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX because FixedRandomSource used a TypeScript constructor parameter property, which built-in strip mode cannot erase |
Initial command output; test edit history | Replace the parameter property with an ordinary class field plus constructor assignment |
| 2026-07-25 | Re-ran after the erasable-syntax fix | Six AC tests passed with no fail, skip or TODO | E-008 | AC-01–AC-06 pass |
| 2026-07-25 | Ran the root strict compiler | tsc --project tsconfig.json --noEmit exited successfully |
E-009 | Shared imports and test types compile |
Выводы#
- Fact: All six executable acceptance tests pass on the recorded final
environment. Основание:
E-008. - Fact: Fabricated client roll fields are schema-rejected before RNG; valid
commands store only the injected server result. Основание:
E-007,E-008. - Fact: Duplicate and stale-version commands return before a second/new RNG
call, event append or state mutation in the registered cases. Основание:
E-007,E-008. - Fact: The shared authoritative profile preserves official attribution
while its executable fields remain original and genre-neutral. Основание:
E-005,E-006,E-008. - Inference: The tested ordering and capability boundary is suitable as the
reference contract for a production rules/event implementation. Основание:
E-001–E-009. - Unknown: Fixed in-memory tests do not establish production entropy,
durability, distributed concurrency or balance. Основание:
E-010.
Рассмотренные альтернативы#
| Подход | Что проверили | Почему не выбран | Evidence |
|---|---|---|---|
| LLM chooses roll/outcome | Submitted fabricated raw/success fields | Payload is rejected and cannot become canonical randomness | E-001–E-004, E-008 |
| Consume RNG before idempotency/version checks | Compared duplicate and stale-version call counts | Would waste/change randomness and risk duplicate effects; tested ordering consumes no extra roll | E-002–E-004, E-008 |
| Keep a study-local rules profile | Compared local study contents with the shared loader/fixture | Creates divergent sources of truth; the duplicate was removed | E-006, E-007 |
| Copy Knave text/content into the profile | Compared with actual executable needs | Unnecessary; original profile uses only attributed high-level inspiration | E-005, E-006 |
| Select a production RNG dependency now | Compared with the authority question | Fixed port proves source authority/order but provides no entropy or threat-model evidence for a dependency decision | E-008, E-010 |
Неизвестные#
- Unknown: deterministic PRNG versus system entropy policy and seed disclosure; close through a dedicated fairness/threat decision.
- Unknown: idempotency retention, partition key and transactional persistence; close when the room/event store is selected.
- Unknown: behavior under actual concurrent writers and reconnect storms; close with multi-process integration/chaos cases.
- Unknown: modifier ordering and rounding beyond the current original profile; close with worked balance fixtures.
- Unknown: throughput/latency under concurrent commands; measure against an approved product gate after a durable implementation exists.