OptionalattackerAttacker has not moved this turn — Heavy fires its +1 to hit.
OptionalattackerAttacker made a charge move this turn — drives the charged-this-turn
condition (e.g. World Eaters' Relentless Rage). Left undefined when the
caller can't determine it — the condition then evaluates as "unknown" and
the SPA surfaces a diagnostic (mirrors attackerStationary / timing).
OptionalwithinWithin half the weapon's range — Melta / Rapid Fire fire.
OptionalattackerAttacker benefits from cover (mostly informational; cover applies to defenders).
OptionaltargetTarget is in cover — the resolver flips on cover, the engine applies +1 to save.
OptionalattackerAttacker keywords (union of unit.keywords + faction_keywords), lower-cased.
OptionaltargetTarget keywords (union of unit.keywords + faction_keywords), lower-cased.
OptionaltimingSub-phase timing flag (e.g. "start-of-phase", "end-of-phase",
"on-destroyed"). Consumed by the timing-is condition. Left undefined
when the caller can't pin a sub-phase down — the condition then evaluates
as "unknown" and the SPA surfaces a diagnostic.
OptionalattackerThe buffed unit is part of a combined ("attached") unit — a leader is
attached to a bodyguard, or vice-versa. Drives the is-attached and
model-is-leader conditions. Derived from a non-empty
EligibilityInput.attachedUnitIds. Left undefined when the caller can't
determine attachment — the conditions then evaluate as "unknown" and the
SPA surfaces a diagnostic (mirrors how timing undefined behaves).
Shared engine context. Carries the phase plus a few attacker/target flags the keyword translator and the resolver both need. The engine fills it from its
EngineInput.contextplus the unit-keyword unions; the resolver reads only the subset relevant to itsapplicableWhenchecks.