Description
Bounded follow-up after merged #551. Current main eb5daaf7a487bbccf75dc9c70ac90d64d7e53ad0 still carries spendOrdinaryMoveResources, runPreDamageReactions, and declaredChoiceAlreadyValidated independently inside BattleRuntime.applyAuthoritativeMoveInternal, and selects declaration validation from those booleans. This leaves committed-reaction execution unable to enter the ordinary single-target resolver without the ambiguous legacy tuple.
Pinned Python oracle inspected: Teffa14/AutoPTU@16d228efa63aabecb67fa788959a359aac7f8f03.
Bounded implementation contract:
- Change the authoritative internal move resolver to receive one
MoveRuntimeExecutionMode(orMoveRuntimeExecutionPolicy) instead of the three independent ownership/validation booleans. - Call
MoveRuntimeExecutionPolicy.requireValidDeclaration(...)exactly once before RNG consumption. - Derive ordinary action/frequency ownership only from
policy.spendOrdinaryMoveResources(). - Derive PRE-damage reaction execution only from
policy.runPreDamageReactions(). - Preserve ORDINARY, AREA_RESOLVED, and DELAYED behavior and event/RNG ordering.
- Add a committed-reaction runtime ingress that uses
CommittedReactionRuntimeIngress.resolveExecutionMode(...)andCOMMITTED_REACTION, never the legacy tuple. - Freeze an AoO Python-oracle fixture comparing action budget, move frequency, RNG draw order, accuracy/evasion, hook order, damage, HP/injury/history, ordered semantic events, and final state.
- Keep Minecraft/Cobblemon/Craftics outside the rules path.
Acceptance gates: compile, targeted Java tests, Java Core Parity, existing area/delayed regressions, Python-oracle parity, applicable rulebook conformance, and deterministic trace parity. Do not merge if any relevant gate is red.
Permanent audit category: terrain/weather/hazards/zones/forced movement/reactions. Cross-cutting unlock: full damage pipeline.
Activity