Rules Engine and Authoritative RNG Contract
- Status:
complete - Outcome:
pass - Started: 2026-07-25
- Updated: 2026-07-25
- Research ID:
2026-07-25-rules-engine-authoritative-rng
Проверяемый вопрос#
Можно ли задать rules-engine boundary, который принимает только validated typed commands, проверяет idempotency и expected state version, использует только server RNG и создаёт полностью аудируемый roll record до state transition?
Почему решение нужно сейчас#
PRD запрещает narrator/LLM определять исход броска или применять state change. Rules and randomness contract нужен до production reducer/event API, иначе formula, modifier order, rule version, retries и concurrency будут иметь несколько несовместимых источников истины.
Scope#
- Rules input as a schema-valid typed command.
- Deterministic preconditions and effects around an injected server RNG port.
- Auditable roll evidence: raw result, formula, modifiers, rule version and enclosing stored event reference.
- Idempotency key and expected state version checks before RNG/event/state work.
- Original genre-neutral shared profile inspired by attributed Knave 1.0 mechanical principles, without Knave wording, content or compatibility claim.
- Executable behavioral tests against the shared vertical-slice engine, event-log, state and authoritative fixture.
Non-goals#
- Production reducer, durable event store, distributed idempotency store or deployment topology.
- Full combat, character creation, bestiary, items, spells or adventure content.
- Cryptographic fairness/provably-fair protocol or statistical RNG-quality measurement.
- Knave/D&D text, setting, product name or compatibility.
- Balance, fun, throughput or latency claims.
Критерии успеха#
| ID | Обязательный критерий | Порог или ожидаемое поведение | Способ проверки |
|---|---|---|---|
| AC-01 | Accepted roll is fully auditable | Every committed roll record contains raw roll value(s), canonical formula, ordered modifier, rules profile/version and event reference | Execute both registered roll-producing command kinds with fixed RNG; compare every roll field to worked literal values and resolve the committed event by command ID |
| AC-02 | RNG authority is server-side | Client/LLM cannot supply or overwrite accepted raw result; rules engine consumes only injected server RNG output and commits no success before that result exists | Submit a fabricated raw/success payload, then a valid command against a controlled server RNG; inspect rejection, RNG calls, stored events and accepted raw/source |
| AC-03 | Invalid command stops before randomness or mutation | 100% labelled schema-invalid state-changing fixtures return structured rejection/clarification with zero RNG calls and unchanged event/state snapshot |
Submit null, missing-field and ill-typed fixtures; compare RNG calls, event count and state hash |
| AC-04 | Idempotency prevents double application | Repeating a command with the same idempotency key returns the original committed result or structured duplicate response and appends no second event/state effect | Execute the same command twice and compare event ID, event count, state hash and RNG calls |
| AC-05 | Expected-version conflict fails closed | Command whose expected state version differs from authoritative version returns structured conflict before RNG/event/state mutation | Submit a stale-version command and inspect conflict code/state version, RNG calls, event count and state hash |
| AC-06 | Mechanical profile is attributed and original | Fixture names Knave 1.0/Ben Milton/official URL/CC BY 4.0 as inspiration, while executable design is genre-neutral and contains no Knave/D&D branding | Load the shared Game Contract fixture and assert attribution, source URL, versioned profile data and unbranded executable fields |
The PRD supplies the 100% invalid-command gate and “every roll” completeness
requirement. No latency, throughput, distribution-quality or fairness number is
invented here. Criteria did not change after implementation began.
Рабочие гипотезы#
- Hypothesis H-01: checking idempotency and expected version before consuming RNG makes duplicate/retry/concurrency behavior deterministic; the registered duplicate and stale-version cases consumed no second/new roll or effect.
- Hypothesis H-02: a declarative, versioned rules profile separates original game design from the engine and prevents LLM mechanics improvisation; the shared fixture passed attribution/originality assertions without a local profile copy.
Материалы#
- Исследование и evidence log
- Техническое решение и запуск
- Проверка и итог
prototype/— six executable AC tests- Shared authoritative Game Contract/rules profile
- Official primary source: Questing Beast — Knave
Итог#
Локальный Node.js v24.14.0 прогон завершился 6/6 passing tests, без
failures, skips или TODO. AC-01–AC-06 выполнены: roll evidence complete for the
registered check/attack paths, fabricated client rolls rejected, invalid
commands stop before RNG/state, duplicate and stale-version commands fail
closed, and the shared profile is attributed/original. Root
npm run typecheck также завершился успешно. Подробности находятся в
VALIDATION.md.
Ограничения#
- Fixed RNG verifies authority and calculation, not entropy quality, distribution or cryptographic fairness.
- In-memory sequential tests do not prove distributed idempotency, durable transactionality or multi-process conflict handling.
- Shared profile values are research design choices, not validated product balance.
- The official Knave page supports the attributed high-level inspiration and license statement, not product demand, suitability or legal clearance.
Следующее решение#
GO для использования проверенного ordering/authority contract в production
design: validation, idempotency and expected-version checks must stay before RNG
consumption; accepted rolls must remain server-sourced and attached to a stored
event. Production promotion separately requires a durable transactional store,
RNG threat/entropy decision, concurrent-writer tests and balance validation.