houserules/packages
Joey Yakimowich-Payne 33b5910839
fix(engine): wire consumers for AuraContributions / ReflectDamage / BlockedMoveTypes
T3 audit gaps 3, 4, 5 — three primitives that wrote facts but whose
facts no engine subsystem read, making the primitives inert despite
passing validation.

Gap 3 — AuraContributions consumer wiring:
- New modifiers/effective-attr.ts: getEffectiveNumericAttr(session,
  pieceId, attrName) reads direct fact + layers AuraContributions[attr]
  delta on top. Zero allocation on the no-aura path.
- rules/sliding.ts getRangeMaxSteps now reads through the helper so
  aura-granted RangeBonus extends piece range.
- modifiers/reconcile.ts clampHpToNewMax now reads through the helper
  so aura-granted HpBonus raises the HP clamp ceiling.

Gap 4 — ReflectDamage consumer wiring:
- modifiers/apply.ts integration preset's onDamage hook:
  ReflectDamagePercent check runs BEFORE absorb/resistance
  short-circuits (matches 'magical thorns' mental model — fully
  absorbed hits still reflect). Rounds damage down via Math.floor
  (50% of 1 = 0, matches partial-resistance rounding). Routes
  reflected damage back to attacker via engine.dealDamage with
  kind='reflect'. Uses queueMicrotask to defer so we don't recurse
  during the current damage event's resolution.
- Swallows errors on the reflected call — attacker may have been
  retracted between scheduling and execution (reflection against a
  dead target is a no-op, not an error).

Gap 5 — BlockedMoveTypes consumer wiring:
- modifiers/apply.ts integration preset's filterMoves hook extended
  with a mover-side check. Reads BlockedMoveTypes on the MOVING
  piece once per piece-move generation; drops any move whose
  classification (capture / step / slide) is in the blocked set.
  classifyNonCaptureMove helper: Chebyshev distance ≤ 1 = 'step',
  > 1 = 'slide'. Knight jumps count as slides (documented).

Oracle Q3.1: 6-scenario primitive-smoke-test matrix in
consumer-integration.test.ts asserts observable gameplay delta for
each of gaps 3-5 (aura HP clamp, aura range, reflect, partial
reflect rounds down, blocked capture, blocked step). Catches this
class of silent-inert regression for future primitives.

1387 → 1393 unit tests.
2026-04-20 16:53:18 -06:00
..
chess fix(engine): wire consumers for AuraContributions / ReflectDamage / BlockedMoveTypes 2026-04-20 16:53:18 -06:00
rete refactor(rete): use asEntityId for AGG_FACT sentinel id 2026-04-19 16:49:50 -06:00
server fix(server): widen ModifierKindIdSchema to accept custom modifier ids 2026-04-20 16:43:38 -06:00