No description
Find a file
Joey Yakimowich-Payne 019f3987b4
feat(engine): primitive seed manifest + consumer integrity check + zombie cleanup
T3 audit follow-ups Q3.2 (declared consumers), Q4.6 (zombie fact
cleanup on capture), Q4.7 (aura convergence semantics locked in).

Q3.2 — Load-time consumer integrity check:
  - EffectPrimitive gains optional seedsAttrs + seedsAttrsFor fields
    declaring which ChessAttrKey facts a primitive writes during
    apply(). Every T3 primitive now annotates its seeds:
      * Static (single attr always written): reflect-damage,
        absorb-damage-with-attribute (the two control facts),
        add-aura, add-direction, set-capture-flag, modify-movement-
        range, override-promotion, block-move-type, on-turn-start,
        on-capture, on-damaged, conditional.
      * Dynamic (attr is a param): seed-attribute, add-to-attribute,
        multiply-attribute, absorb-damage-with-attribute (also
        dynamic via params.attr for the charge-holding attribute).
  - new primitives/manifest.ts:
      * getStaticPrimitiveSeedManifest() union of all static
        seedsAttrs, cached after first call.
      * collectDynamicSeedsInTree(nodes) walks a primitive tree
        collecting both static and dynamic seeds, used by the
        zombie-cleanup path with the in-engine CustomModifierRegistry.
      * registerAttrConsumer(attr) + getRegisteredConsumers() for
        engine subsystems to declare 'I read this attr'.
      * assertSeedConsumerIntegrity() asserts every declared seed
        has a registered consumer; throws loudly with the full list
        of unsatisfied attrs.
  - Consumer registrations:
      * apply.ts: damage pipeline + movegen filter + trigger
        dispatchers register AbsorbDamage*, ReflectDamagePercent,
        BlockedMoveTypes, DamageResistance, CaptureFlags,
        DirectionAdditions, On*Hooks, ConditionalHooks, AuraSpec.
      * effective-attr.ts: HpBonus, RangeBonus, AuraContributions.
      * rules/promotion.ts: PromotionOverride.
  - Integrity check fires once lazily in ChessEngine constructor;
    engine boot throws if a primitive declares a seed that no
    subsystem reads. Silent-inert primitives are now impossible.

Q4.6 — Zombie fact cleanup:
  - engine.dealDamage default-kill path + piece-hp's onDamage kill
    path both extend their retract-on-death loop to include
    getEngineSeedManifest(customModifiers). Captures now fully
    clean up primitive-seeded attrs (HpBonus, AuraSpec,
    ReflectDamagePercent, trigger hooks, user-authored dynamic
    targets) in addition to the preset-declared core attrs.

Q4.7 — Aura convergence:
  - New test in auras.test.ts 'mutual auras converge in a single
    pass' locks in the declarative semantics: mutual auras each see
    the OTHER piece's contribution against a positional snapshot,
    producing commutative deltas in one compute pass. Second
    compute pass is idempotent (no cascade/loop). Decision
    documented for downstream 'aura of aura' consumers.

5 new manifest.test.ts scenarios + 1 aura convergence test.
1394 → 1399 unit tests green.
2026-04-20 17:47:38 -06:00
.github/workflows chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
.sisyphus chore(sisyphus): T3 Final Verification Wave — all reviewers APPROVE 2026-04-19 22:04:36 -06:00
docs docs(adr): T4 scripted modifiers forward-design 2026-04-19 21:09:52 -06:00
packages feat(engine): primitive seed manifest + consumer integrity check + zombie cleanup 2026-04-20 17:47:38 -06:00
scripts feat(rete): add replay engine + state-hash determinism verifier (P3.3) 2026-04-16 15:25:13 -06:00
.gitignore chore: ignore .org.chromium.Chromium.* runtime files 2026-04-19 10:20:42 -06:00
eslint.config.js feat(engine): damage-resistance modifier descriptor 2026-04-18 22:22:31 -06:00
lefthook.yml chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
LICENSE chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
package.json feat(rete): add replay engine + state-hash determinism verifier (P3.3) 2026-04-16 15:25:13 -06:00
playwright.config.ts fix(rete): inject clock into EventLog; use tsc for DTS; fix cycle.test.ts private access; add Playwright worker limit 2026-04-16 18:25:49 -06:00
README.md chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
tsconfig.base.json chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
tsconfig.json chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00
vitest.workspace.ts chore(root): scaffold monorepo — Phase 0 complete 2026-04-16 13:32:21 -06:00

@paratype

A Doorenbos-style Rete II rules engine for TypeScript games, with an authoritative WebSocket chess demo.

Packages

Docs

Getting Started

bun install && bun run check