Fix Alacrian Jaguar#4
Closed
keloide wants to merge 1 commit into
Closed
Conversation
…ignation "Whenever this creature attacks while saddled" parsed to TriggerMode::Attacks with condition: null — the while-gate was silently dropped, so the trigger fired even when the Mount was unsaddled. Fixes the whole 27-card class (Alacrian Jaguar target; parser-misparse-backlog categories 2 and 22). Parser: new elided-subject participle leaf combinator (parse_elided_subject_state_condition, bare "saddled" -> StaticCondition::SourceIsSaddled) composed only at the strip_while_state_clause seam via alt() after the subject-ful parse_inner_condition authority; the SourceIsSaddled bridge arm in static_condition_to_trigger_condition lowers to the existing TriggerCondition::SourceMatchesFilter + FilterProp::IsSaddled via the shared source_saddled_filter() helper (no new enum variants; CR 603.2 + CR 702.171b, official ruling 2025-02-07: the gate binds at attack declaration, CR 508.1). Runtime: thread the saddled designation through last-known information so the CR 603.4-machinery resolution recheck survives battlefield exit — LKISnapshot.is_saddled + ZoneChangeRecord.is_saddled (#[serde(default)], mirroring is_suspected), populated at every production snapshot site, and FilterProp::IsSaddled moved out of the zone-change fail-closed arm to read record.is_saddled (CR 608.2h + CR 113.7a). The recheck is truth-preserving: saddle activates only as a sorcery (CR 702.171a) and the designation persists until end of turn or exit (CR 702.171b). Tests: parser shape test with no-Unimplemented reach-guard plus four real-pipeline combat tests (saddled pump, unsaddled negative with condition-presence reach-guard, per-source gating in a shared attack, and the Ornery Tumblewagg dies-in-response LKI fixture: counters still double after the Mount leaves the battlefield). Backlog hygiene: 19 confirmed-fixed entries removed (11 from category 2, 8 from category 22); counts decremented; category-22 fix hint updated to the landed design. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KckwxCXXvTgVgwLq2tQkyb
Owner
Author
|
Superseded by the upstream contribution: phase-rs#6232 (same branch, same head Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the "attacks while saddled" trigger-gate misparse for Alacrian Jaguar and its whole 27-card class (parser-misparse-backlog categories 2 and 22). "Whenever this creature attacks while saddled, …" parsed to
TriggerMode::Attackswithcondition: null— the while-gate was silently dropped, so the trigger fired even when the Mount was unsaddled. Official ruling (2025-02-07): the ability triggers only if the creature was saddled when declared as an attacker (CR 508.1); the saddled designation persists until end of turn or battlefield exit (CR 702.171b).Design: an elided-subject participle leaf combinator (
parse_elided_subject_state_condition, bare"saddled"→StaticCondition::SourceIsSaddled) composed only at the existingstrip_while_state_clausewhile-gate seam; theSourceIsSaddledbridge arm lowers to the existingTriggerCondition::SourceMatchesFilter+FilterProp::IsSaddledvia the sharedsource_saddled_filter()helper — the/add-engine-variantgate rejected a bespokeTriggerCondition::SourceIsSaddledsibling (REFUSE_WITH_EXISTING_SLOT), so zero new enum variants. The saddled designation is additionally threaded through last-known information (LKISnapshot.is_saddled/ZoneChangeRecord.is_saddled,#[serde(default)], mirroringis_suspected) so the CR 603.4-machinery resolution recheck survives battlefield exit (CR 608.2h + CR 113.7a) — without it, a Mount destroyed in response would wrongly nullify its own trigger (Ornery Tumblewagg / Giant Beaver shapes). Backlog list hygiene included: 19 confirmed-fixed entries removed (11 from category 2, 8 from category 22), counts decremented, category-22 fix hint updated to the landed design.Implementation method (required)
Method: /engine-implementer
Plan-review ran 2 rounds (round 1: one blocker — the original plan's LKI claim was factually wrong, and was redesigned into the Part-B LKI thread — plus 2 minor findings; round 2: approvable with one reviewer-prescribed mechanical amendment — the
loop_shortcut.rsgolden Debug string — folded in verbatim). Implementation-review ran 1 full round returning exactly one LOW finding (a comment referencing a plan-internal test label), fixed with code; the mandatory final read-only review pass then ran clean against the committed head (PASS line below).Files changed
is_saddledthreading)CR references
CR 113.7a, CR 508.1, CR 603.2, CR 603.4, CR 608.2h, CR 701.60b, CR 702.171a, CR 702.171b, CR 702.171c, CR 704.5m/n (mirrored comment) — every number grep-verified against
docs/MagicCompRules.txtbefore annotation.Track
Developer
LLM
Model: claude-fable-5
Thinking: high
Tier: Frontier
Verification
Tilt is down in this environment; direct cargo used (sanctioned fallback). Container is disk-limited, so the full 145-binary integration link was not run locally — the touched integration binaries were run individually; CI covers the rest.
cargo fmt --all— clean (no diff)cargo clippy -p engine --lib --tests -- -D warnings— exit 0cargo test -p engine --lib— 17,165 passed / 0 failedcargo test -p engine --test integration attacks_while_saddled— 4 passed / 0 failed (real saddle → declare-attackers → stack pipeline; the unsaddled negative carries a condition-presence reach-guard and fails on revert; the Ornery Tumblewagg dies-in-response fixture proves the LKI recheck: counters still double 3→6 after the Mount leaves the battlefield)cargo test -p engine --test integration -- saddle_state_model attack_qualifier loop_shortcut— 52 passed / 0 failed (sibling guards)./scripts/gen-card-data.sh— all 27 "attacks while saddled" cards now carrySourceMatchesFilter{Typed([IsSaddled])}on their attacks trigger; 26/27 fully clean; Calamity, Galloping Inferno retains only its pre-existing, unrelated copy-abilityUnimplementedcargo coverage— Alacrian Jaguar:supported: true, gap_count: 0; global supported count unchanged 31454 / 35425 before vs after (misparse fix — no support flips, coverage stays honest)./scripts/check-parser-combinators.sh— exit 0 (output below)Gate A
Gate A PASS head=a7e100b3cf91622b4f26500fbe8838fbad1645de base=f741e3ab819a2e9ee4a04bc9c16a27eccdc7a0bd
Anchored on
SourceIsEnchanted => Some(TriggerCondition::SourceMatchesFilter { … }): the existing designation/state bridge arm instatic_condition_to_trigger_conditionwhose exact shape the newSourceIsSaddledarm follows (sameSourceMatchesFilterlowering, no bespoke variant).strip_while_state_clause: the existing "while [state]" trigger-gate seam (Fire Lord Azula class) that delegates toparse_inner_condition; the fix widens exactly this call site with analt()fallback.parse_source_is_saddled: the subject-ful sibling combinator (samevalue/tagfamily) beside which the new elided-subject leaf lives.is_suspectedLKI field +FilterProp::Suspected => record.is_suspectedevaluator arm: the precedent theis_saddledLKI thread mirrors field-for-field.Final review-impl
Final review-impl PASS head=a7e100b3cf91622b4f26500fbe8838fbad1645de
Claimed parse impact
Alacrian Jaguar, Autarch Mammoth, Bounding Felidar, Bridled Bighorn, Brightfield Glider, Brightfield Mustang, Bulwark Ox, Calamity Galloping Inferno (gate fixed; unrelated pre-existing copy gap remains), Congregation Gryff, District Mascot, Dracosaur Auxiliary, Drover Grizzly, Fortune Loyal Steed, Giant Beaver, Gila Courser, Gilded Ghoda, Gloryheath Lynx, Guardian Sunmare, Lagorin Soul of Alacria, Ornery Tumblewagg, Quilled Charger, Rambling Possum, Routeway Moose, Seraphic Steed, Trained Arynx, Unswerving Sloth, Venomsac Lagac
Validation Failures
None.
CI Failures
None.
🤖 Generated with Claude Code
https://claude.ai/code/session_01KckwxCXXvTgVgwLq2tQkyb
Generated by Claude Code