Skip to content

test(engine): pin Underworld Breach's grant to its own battlefield presence (#1033)#5350

Merged
matthewevans merged 5 commits into
phase-rs:mainfrom
rykerwilliams:test/underworld-breach-self-recast-coverage
Jul 8, 2026
Merged

test(engine): pin Underworld Breach's grant to its own battlefield presence (#1033)#5350
matthewevans merged 5 commits into
phase-rs:mainfrom
rykerwilliams:test/underworld-breach-self-recast-coverage

Conversation

@rykerwilliams

Copy link
Copy Markdown
Contributor

Summary

  • Investigated the second half of [Card Bug] Underworld Breach is broken in multiple ways #1033 ("Underworld Breach recasts itself from the graveyard via its own granted escape"): already correct on main, no behavior change in this PR.
  • Per CR 604.2, a static ability's continuous effect (including a keyword grant like "each nonland card in your graveyard has escape") only exists while its source remains on the battlefield. for_each_static_effect_source sources these grants exclusively from battlefield_sources (game/layers.rs), so once Breach is sacrificed and sits in the graveyard, its own grant is inert — including toward itself.
  • This PR adds the missing coverage: places Underworld Breach directly in the graveyard (simulating post-sacrifice) and confirms neither it nor another graveyard card shows escape availability derived from its grant.
  • Complements the existing granted_escape_requires_exile_cost_payment test, which covers the first (and only actually-reproducing) half of the original report — the exile-cost enforcement bug, already fixed by aa4ee3455.

Test plan

  • New test escape_grant_from_graveyard_source_does_not_apply_to_itself passes locally.
  • Test-only change, no production code touched.

🤖 Generated with Claude Code

…esence (phase-rs#1033)

Investigated phase-rs#1033's second claim ("Breach recasts itself from the
graveyard via its own granted escape"): already correct per CR 604.2 —
a static ability's continuous effect only exists while its source
remains on the battlefield. Verified locally: with Breach placed
directly in the graveyard (simulating post-sacrifice), neither Breach
itself nor another graveyard card shows escape availability derived
from its grant. Adds permanent regression coverage alongside the
existing granted_escape_requires_exile_cost_payment test, which covers
the first (and only reproducing) half of the original report.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Note

Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported.

@matthewevans matthewevans self-assigned this Jul 8, 2026

@matthewevans matthewevans left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed test-only Underworld Breach coverage after maintainer test hardening. Scryfall confirms the Oracle text and CR 604.2 was verified locally. The test now makes the granted escape cost payable if Breach incorrectly grants escape from the graveyard, so the negative assertions are load-bearing for both Breach itself and another graveyard card. CI is pending on the fixup commit; auto-merge will wait for required checks.

@matthewevans matthewevans added test Add tests quality For high-quality minimal to no-churn PRs labels Jul 8, 2026
@matthewevans matthewevans enabled auto-merge July 8, 2026 00:35
@matthewevans matthewevans removed their assignment Jul 8, 2026
rykerwilliams added a commit to rykerwilliams/phase that referenced this pull request Jul 8, 2026
Audited all four "already fixed" GitHub comments posted tonight,
found real gaps where claims rested on a sub-agent's deleted scratch
test rather than executed local verification, and fixed each one with
a real permanent test (phase-rs#5348, phase-rs#5350, phase-rs#5351) plus updated comments.
Logged as standing lesson 11 so this doesn't need re-litigating.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Parse changes introduced by this PR · 656 card(s), 462 signature(s) (baseline: main e0a6f5d97c9c)

80 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control creature)

Examples: Aerith, Last Ancient, Aid the Fallen, Alter Fate (+77 more)

80 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control creature, to=hand)

Examples: Aerith, Last Ancient, Aid the Fallen, Alter Fate (+77 more)

49 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=self)

Examples: A-Earthquake Dragon, Abzan Devotee, Altar of the Wretched (+46 more)

49 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=self, to=hand)

Examples: A-Earthquake Dragon, Abzan Devotee, Altar of the Wretched (+46 more)

38 card(s) · ability/Bounce · removed: Bounce (target=self)

Examples: Adéwalé, Breaker of Chains, Aurora Eidolon, Aurora Phoenix (+35 more)

38 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=self, to=hand)

Examples: Adéwalé, Breaker of Chains, Aurora Eidolon, Aurora Phoenix (+35 more)

29 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control instant or in graveyard you control sorcery)

Examples: Archaeomancer, Ardent Elementalist, Call to Mind (+26 more)

29 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control instant or in graveyard you control sorcery, to=hand)

Examples: Archaeomancer, Ardent Elementalist, Call to Mind (+26 more)

28 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control card)

Examples: Auroral Procession, Bala Ged Recovery, Charnelhoard Wurm (+25 more)

28 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control card, to=hand)

Examples: Auroral Procession, Bala Ged Recovery, Charnelhoard Wurm (+25 more)

23 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control permanent)

Examples: Acolyte of Affliction, Aether Helix, Ancestral Communion (+20 more)

23 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control permanent, to=hand)

Examples: Acolyte of Affliction, Aether Helix, Ancestral Communion (+20 more)

22 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control creature, targets=0-2)

Examples: Another Chance, Back for Seconds, Baloth Null (+19 more)

22 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control creature, targets=0-2, to=hand)

Examples: Another Chance, Back for Seconds, Baloth Null (+19 more)

19 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control artifact)

Examples: Archaeomender, Call Damage Control, Catch-Up Mechanic (+16 more)

19 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control artifact, to=hand)

Examples: Archaeomender, Call Damage Control, Catch-Up Mechanic (+16 more)

12 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control creature)

Examples: Adun Oakenshield, Cabal Surgeon, Draugr Recruiter (+9 more)

12 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control creature, to=hand)

Examples: Adun Oakenshield, Cabal Surgeon, Draugr Recruiter (+9 more)

9 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=self)

Examples: Centaur Vinecrasher, Erebos's Titan, Furious Forebear (+6 more)

9 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control creature, targets=0-1)

Examples: A-Fates' Reversal, Courier Bat, Fates' Reversal (+6 more)

9 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control enchantment)

Examples: Auramancer, Call Damage Control, Dawn to Dusk (+6 more)

9 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control land)

Examples: A-Circle of the Land Druid, Call Damage Control, Cartographer (+6 more)

9 card(s) · ability/ChangeZone · added: ChangeZone (conditional=previous effect outcome, from=graveyard, target=self, to=hand)

Examples: Centaur Vinecrasher, Erebos's Titan, Furious Forebear (+6 more)

9 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control creature, targets=0-1, to=hand)

Examples: A-Fates' Reversal, Courier Bat, Fates' Reversal (+6 more)

9 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control enchantment, to=hand)

Examples: Auramancer, Call Damage Control, Dawn to Dusk (+6 more)

… 437 more signature(s) (664 card-changes) — see parse-diff.json
  • 9 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control land, to=hand)
  • 5 card(s) · ability/Bounce · removed: Bounce (conditional=when you do, target=in graveyard you control creature)
  • 5 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control artifact)
  • 5 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control card)
  • 5 card(s) · ability/Bounce · removed: Bounce (target=in graveyard creature)
  • 5 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control artifact or in graveyard you control enchantment)
  • 5 card(s) · ability/Bounce · removed: Bounce (target=mv 3- in graveyard you control creature)
  • 5 card(s) · ability/ChangeZone · added: ChangeZone (conditional=when you do, from=graveyard, target=in graveyard you control creature, to=hand)
  • 5 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control artifact, to=hand)
  • 5 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control card, to=hand)
  • 5 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard creature, to=hand)
  • 5 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control artifact or in graveyard you control enchantment, to=hand)
  • 5 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=mv 3- in graveyard you control creature, to=hand)
  • 5 card(s) · static/Continuous · field conditional: in battlefield you control permanent non-land entered this turn ≥ 2battlefield entries this turn (permanent non-land, you) ≥ 2
  • 5 card(s) · trigger/Phase · field condition: in battlefield you control permanent non-land entered this turn ≥ 2battlefield entries this turn (permanent non-land, you) ≥ 2
  • 4 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=self, timing=sorcery speed)
  • 4 card(s) · ability/Bounce · removed: Bounce (target=another in graveyard you control creature)
  • 4 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control artifact or in graveyard you control creature)
  • 4 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control creature or in graveyard you control land)
  • 4 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control permanent, targets=0-1)
  • 4 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control permanent, targets=0-2)
  • 4 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control sorcery)
  • 4 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=self, timing=sorcery speed, to=hand)
  • 4 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=another in graveyard you control creature, to=hand)
  • 4 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control artifact or in graveyard you control creature, to=hand)
  • 4 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control creature or in graveyard you control land, to=hand)
  • 4 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control permanent, targets=0-1, to=hand)
  • 4 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control permanent, targets=0-2, to=hand)
  • 4 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control sorcery, to=hand)
  • 3 card(s) · ability/Bounce · removed: Bounce (conditional=additional cost was paid, target=in graveyard you control creature)
  • 3 card(s) · ability/Bounce · removed: Bounce (conditional=additional cost was paid, target=in graveyard you control instant or in graveyard you control sorcery)
  • 3 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=in graveyard you control creature)
  • 3 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=another in graveyard you control creature)
  • 3 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control creature, timing=sorcery speed)
  • 3 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control enchantment)
  • 3 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control instant or in graveyard you control sorcery)
  • 3 card(s) · ability/Bounce · removed: Bounce (target=another in graveyard you control artifact)
  • 3 card(s) · ability/Bounce · removed: Bounce (target=creature, targets=0-1)
  • 3 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Aura or in graveyard you control Equipment)
  • 3 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control creature or in graveyard you control planeswalker)
  • 3 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control creature, targets=X-X)
  • 3 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control instant or in graveyard you control sorcery, targets=0-2)
  • 3 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control instant)
  • 3 card(s) · ability/Bounce · removed: Bounce (target=mv 3- in graveyard you control permanent)
  • 3 card(s) · ability/Bounce · removed: Bounce (target=shares creature type in graveyard you control creature, targets=2-2)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (conditional=additional cost was paid, from=graveyard, target=in graveyard you control creature, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (conditional=additional cost was paid, from=graveyard, target=in graveyard you control instant or in graveyard you control sorcery, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (conditional=previous effect outcome, from=graveyard, target=in graveyard you control creature, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=another in graveyard you control creature, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control creature, timing=sorcery speed, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control enchantment, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control instant or in graveyard you control sorcery, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=another in graveyard you control artifact, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=creature, targets=0-1, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control Aura or in graveyard you control Equipment, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control creature or in graveyard you control planeswalker, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control creature, targets=X-X, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control instant or in graveyard you control sorcery, targets=0-2, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control instant, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=mv 3- in graveyard you control permanent, to=hand)
  • 3 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=shares creature type in graveyard you control creature, targets=2-2, to=hand)
  • 3 card(s) · ability/ChangeZoneAll · field target: parent targetAura
  • 3 card(s) · ability/TargetOnly · added: TargetOnly (target=player)
  • 2 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=in graveyard you control instant or in graveyard you control sorcery)
  • 2 card(s) · ability/Bounce · removed: Bounce (conditional=when you do, target=in graveyard you control instant or in graveyard you control sorcery)
  • 2 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=card)
  • 2 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control creature, targets=0-2)
  • 2 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control creature, targets=0-3)
  • 2 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control instant or in graveyard you control sorcery, timing=sorcery speed)
  • 2 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control land)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=another in graveyard you control Elf)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=any)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=card, targets=0+)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=creature)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=historic in graveyard you control card)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Goblin)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Villain)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control card non-creature non-land)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control card, targets=X-X)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control creature or in graveyard you control enchantment)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control creature, targets=1-2)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control creature, targets=2-2)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control instant or in graveyard you control sorcery, targets=0-1)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control land, targets=0-3)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control permanent, targets=1-2)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=instant or sorcery)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=instant, targets=0-1)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=mv 2- in graveyard you control creature)
  • 2 card(s) · ability/Bounce · removed: Bounce (target=scoped player controls in graveyard creature)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (conditional=previous effect outcome, from=graveyard, target=in graveyard you control instant or in graveyard you control sorcery, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (conditional=when you do, from=graveyard, target=in graveyard you control instant or in graveyard you control sorcery, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=card, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control creature, targets=0-2, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control creature, targets=0-3, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control instant or in graveyard you control sorcery, timing=sorcery speed, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, kind=activated, target=in graveyard you control land, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=another in graveyard you control Elf, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=any, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=card, targets=0+, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=creature, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=historic in graveyard you control card, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control Goblin, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control Villain, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control card non-creature non-land, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control card, targets=X-X, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control creature or in graveyard you control enchantment, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control creature, targets=1-2, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control creature, targets=2-2, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control instant or in graveyard you control sorcery, targets=0-1, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control land, targets=0-3, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=in graveyard you control permanent, targets=1-2, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=instant or sorcery, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=instant, targets=0-1, to=hand)
  • 2 card(s) · ability/ChangeZone · added: ChangeZone (from=graveyard, target=mv 2- in graveyard you control creature, to=hand)
  • 2 card(s) · ability/ChangeZone · field target: parent targetcard
  • 2 card(s) · ability/ChangeZone · field target: parent targetin graveyard you control creature
  • 1 card(s) · ability/Attach · field target: selflast created
  • 1 card(s) · trigger/Attacks · field condition: in battlefield you control permanent non-land entered this turn ≥ 2battlefield entries this turn (permanent non-land, you) ≥ 2
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=# of power ≥4 in battlefield you control creature ≥ 1, target=in graveyard you control creature, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=additional cost was paid, target=card)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=additional cost was paid, target=in graveyard you control artifact)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=cost-paid object is permanent, target=another in graveyard you control permanent)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=another in graveyard you control Elf or in graveyard another you control Tyvar)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=another in graveyard you control creature)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=in graveyard you control Spirit, targets=0+)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=in graveyard you control artifact or in graveyard you control enchantment)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=in graveyard you control card)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=in graveyard you control creature Rat, targets=0-2)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=previous effect outcome, target=triggering source)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=when you do, target=another in graveyard you control permanent)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=when you do, target=in graveyard you control card, targets=0-# of each opponent whose PlayerCounter { kind: Poison, scope: ScopedPlayer } G…
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=when you do, target=in graveyard you control creature or in graveyard you control land)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=when you do, target=in graveyard you control instant or in graveyard you control sorcery, targets=0-2)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=when you do, target=in graveyard you control permanent non-land, targets=0-event amount)
  • 1 card(s) · ability/Bounce · removed: Bounce (conditional=when you do, target=in graveyard you control permanent)
  • 1 card(s) · ability/Bounce · removed: Bounce (duration=until end of combat, target=in graveyard you control creature or in graveyard you control planeswalker)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=another in graveyard you control Aura or in graveyard another you control Equipment)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=artifact, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=basic in graveyard you control land)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=black in graveyard you control card)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=card + cards exiled by source)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=chosen card type in graveyard you control card)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=creature, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=historic in graveyard you control card)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=historic in graveyard you control card, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard creature, timing=sorcery speed)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control Arcane)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control Bat or in graveyard you control Lizard or in graveyard you control Rat or in graveyard you control Squi…
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control Dinosaur)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control Equipment or in graveyard you control Vehicle)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control Myr)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control Zombie)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control artifact creature)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control artifact or in graveyard you control enchantment)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control artifact, timing=sorcery speed)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control card, timing=sorcery speed)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control creature Dragon or in graveyard you control planeswalker Ugin)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control creature, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control creature, targets=0-1, timing=sorcery speed)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control enchantment creature)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control land, targets=0-1, timing=sorcery speed)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=in graveyard you control permanent, timing=sorcery speed)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=multicolored in graveyard you control card, timing=sorcery speed)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=mv 1- in graveyard you control artifact)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=non-legendary in graveyard you control card, targets=X-X)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=with flashback you control in exile card)
  • 1 card(s) · ability/Bounce · removed: Bounce (kind=activated, target=you control card + cards exiled by source)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=another creature, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=another permanent)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=any, targets=0-2)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=artifact, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=black in graveyard you control creature)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=blue in graveyard you control creature or red in graveyard you control creature)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=blue in graveyard you control instant)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=blue scoped player controls in graveyard card)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=card + cards exiled by source)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=card)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=card, targets=0-event amount)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=card, targets=X-X)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=chosen card type scoped player controls in graveyard card)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=creature non-Avatar)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=creature, targets=0-# of named "~" in graveyard card+1)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=creature, targets=0-3)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=green in graveyard you control card)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=historic in graveyard you control card non-Assassin)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard artifact or in graveyard enchantment)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard card)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard creature or in graveyard land)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard instant or in graveyard sorcery or in graveyard creature)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard instant or in graveyard sorcery, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Arcane)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Assassin or Mercenary or Pirate or Rogue or Warlock card)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Aura or in graveyard you control Equipment, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Cleric)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Elf)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Goblin, targets=0-1)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Griffin)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Hero)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Knight)
  • 1 card(s) · ability/Bounce · removed: Bounce (target=in graveyard you control Mercenary)

@matthewevans matthewevans self-assigned this Jul 8, 2026
@matthewevans matthewevans added bug Bug fix and removed test Add tests quality For high-quality minimal to no-churn PRs labels Jul 8, 2026

@matthewevans matthewevans left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approved current head after maintainer fixups. The CI failure was from the off-zone static gate suppressing command-zone emblem statics; the current head preserves CR 114.4 emblems while keeping ordinary off-zone grants gated. Auto-merge can wait for the remaining checks.

@matthewevans matthewevans removed their assignment Jul 8, 2026
@matthewevans matthewevans added this pull request to the merge queue Jul 8, 2026
Merged via the queue into phase-rs:main with commit ddad0c5 Jul 8, 2026
13 checks passed
rykerwilliams added a commit to rykerwilliams/phase that referenced this pull request Jul 8, 2026
…lesson

Point 2 of phase-rs#1033 was wrongly concluded "not a bug" from source-tracing
alone, then correctly re-flagged as a real bug once actually tested.
Fixed by the maintainer's phase-rs#5350 plus a non-overlapping follow-up
(phase-rs#5381) covering 5 sibling functions their narrower fix didn't reach.
Logs two new standing lessons: confirmatory tests can refute instead
of confirm (treat that as the system working), and always defer to a
maintainer's own commits on a PR rather than pushing a competing one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
glorydavid03023 pushed a commit to glorydavid03023/phase that referenced this pull request Jul 8, 2026
…up to phase-rs#5350) (phase-rs#5381)

* fix(engine): migrate remaining zone-of-function statics gathers (phase-rs#1033 follow-up)

phase-rs#5350 fixed Underworld Breach's specific self-recast bug by narrowing
active_continuous_effects_from_base_static_source's admission via a
new caller-side pre-filter. That fix is scoped to the one call path
Underworld Breach hits; five other statics-gathering functions share
the identical "no zone-of-function check outside the command zone"
defect and were still live on main:

- active_static_definitions, game_functioning_statics, and
  battlefield_functioning_statics (functioning_abilities.rs) had no
  active_zones gate at all outside the command-zone branch.
- active_combat_assignment_rule_effects_from_static_definitions
  (layers.rs, distinct from the sibling phase-rs#5350 already fixed) skipped
  its gate entirely whenever active_zones was empty.
- compute_combat_tax (combat.rs) had no zone gate at all.

Fix: a single shared predicate, static_functions_in_zone, now backs
all five (CR 113.6/113.6b general case, CR 114.3/114.4 emblem
exemption for the command zone, CR 113.6g stack exception for
self-referential CantBeCountered/CantBeCopied distinguished from
grants-to-others via `affected`). Also deletes a redundant,
independently buggy duplicate (graveyard_permission_functions_in_zone)
that never exempted emblems, unlike every other command-zone consumer.

Each migration is backed by a permanent regression test, several
proven via live revert-and-rerun during review, including a matrix
covering self-referential vs. granting CantBeCountered on the stack
vs. battlefield with two co-resident definitions gated independently.

active_continuous_effects_from_static_definitions and its
active_continuous_effects_from_base_static_source caller (phase-rs#5350's
territory) are deliberately left untouched — this PR does not
second-guess that fix, only extends coverage to the siblings it
didn't reach. See the module doc's "Zone scope asymmetry" note for
where the two approaches currently diverge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(PR-5381): address statics gate review cleanup

* test(PR-5381): cover combat assignment zone gate

* fix(PR-5381): preserve chalice policy uncounterable prediction

* fix(engine): admit non-emblem command-zone opt-in sources in combat tax

Addresses matthewevans's CHANGES_REQUESTED review on phase-rs#5381: the
compute_combat_tax loop's outer command-zone gate was emblem-only
(source_obj.zone == Command && !is_emblem => skip), which silently
dropped legitimate non-emblem command-zone sources (planes, schemes,
conspiracies) that opt into functioning from the command zone via
active_zones — the exact CR 113.6b admission rule every other
command-zone-consuming gather already applies via
object_sources_static_from_command_zone. Their CantAttack/CantBlock
definitions never reached the per-def zone check.

Fix: replace the emblem-only outer gate with
object_sources_static_from_command_zone, matching the admission rule
used everywhere else. Two new tests, one proving the opt-in source is
now admitted (live revert-and-rerun confirmed it fails without the
fix) and a negative sibling proving a non-opted-in non-emblem source
still correctly taxes nothing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(phase-ai): use public iter_unchecked instead of private iter_all

CI broke the workspace build (E0624) after the chalice-avoidance
uncounterable prediction started calling
Definitions::iter_all, which is pub(crate) to the engine crate and
not visible from phase-ai. iter_unchecked is the existing public
escape hatch with identical semantics (raw slice iteration, no CR
gating) intended for exactly this kind of classification/prediction
use outside the engine crate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XbgwGxbU9NHN9kou9isp8K

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants