Skip to content

fix(coverage): expose ChangeZone ETB entry qualifiers in the parse-diff signature (Closes #5495) - #5500

Closed
minion1227 wants to merge 2 commits into
phase-rs:mainfrom
minion1227:minion_5495
Closed

fix(coverage): expose ChangeZone ETB entry qualifiers in the parse-diff signature (Closes #5495)#5500
minion1227 wants to merge 2 commits into
phase-rs:mainfrom
minion1227:minion_5495

Conversation

@minion1227

Copy link
Copy Markdown
Contributor

Closes #5495.

Summary

effect_details built the ChangeZone / ChangeZoneAll parse-diff signature from origin, destination and target only — every ETB entry qualifier was swallowed by the shared arm's ... A parser change flipping one produced no row in the coverage-parse-diff sticky, so that class of parser change read as "No card-parse changes". Surfaced on Senu, Keen-Eyed Protector (#5494), whose "put it onto the battlefield attacking" (CR 508.4) sets enters_attacking with no diff-visible evidence.

This splits the two variants (their qualifier sets diverge) and emits each qualifier only when set, so unqualified signatures stay byte-identical — the "push only when set" pattern established by #5493 for PreventDamage.

Fields now surfaced:

  • ChangeZone: owner_library (CR 400.7), enter_transformed (CR 712.2), enters_under (CR 110.2a), enter_tapped (CR 614.1), enters_attacking (CR 508.4), up_to (CR 608.2d), enter_with_counters (CR 122.1), conditional_enter_with_counters (CR 122.1), face_down_profile (CR 708.2a), enters_modified_if (CR 614.12).
  • ChangeZoneAll: enters_under (CR 110.2a), enter_tapped (CR 110.5b), enter_with_counters (CR 122.1), face_down_profile (CR 708.2a), library_position (CR 401.4), random_order (CR 401.4).

Anchored on

Gate A

./scripts/check-parser-combinators.shexit 0 (no violations). This change adds no parser-dispatch code — it extends a review-signature renderer with typed field reads.

CR

Every emitted qualifier reuses the CR citation already documented on its field definition in types/ability.rs (e.g. enters_attacking → CR 508.4 "enters tapped and attacking"; library_position → CR 401.4). No new rule interpretation is introduced.

Verification

  • cargo test -p engine --lib coverage::tests98/98 pass, including the new change_zone_signature_exposes_enters_attacking (reverting the enters_attacking emission fails it).
  • cargo fmt -p engine clean.
  • The full destructure (no ..) compiles, so if a future field is added to either variant the signature renderer fails to compile until it is considered — a deliberate guard against this family recurring one field at a time.

Scope / risk

Single file, review-signature tooling only (effect_details feeds the coverage-parse-diff sticky). No game-logic, parser, or serialization change — it does not alter how any card parses or resolves, only what the diff sticky reports. Zero runtime/gameplay impact.

Model: claude-opus-4-8
Tier: Frontier
Thinking: High

@minion1227
minion1227 requested a review from matthewevans as a code owner July 10, 2026 11:11

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the effect_details function in crates/engine/src/game/coverage.rs to separately match and destructure all fields for Effect::ChangeZone and Effect::ChangeZoneAll instead of grouping them and discarding qualifiers with ... This ensures that parser-alterable qualifiers (such as enters_attacking, enter_tapped, etc.) are correctly exposed in the coverage-parse-diff signatures when set, preventing them from being silently swallowed. A corresponding unit test has been added to verify this behavior. There are no review comments, and I have no additional feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@github-actions

Copy link
Copy Markdown

Parse changes introduced by this PR · 978 card(s), 56 signature(s) (baseline: main 0b998ffd8424)

437 card(s) · ability/ChangeZone · field enter_tapped: Tapped

Examples: A-Lantern of Revealing, A-Llanowar Greenwidow, A-Narfi, Betrayer King (+434 more)

213 card(s) · ability/ChangeZone · field enters_under: You

Examples: A-Soul of Windgrace, Accursed Witch, Acquire (+210 more)

88 card(s) · ability/ChangeZone · field enter_transformed: true

Examples: Accursed Witch, Aclazotz, Deepest Betrayal, Ajani, Nacatl Pariah (+85 more)

76 card(s) · ability/ChangeZone · field up_to: true

Examples: Ainok Wayfarer, Airlift Chaplain, Ancient Brass Dragon (+73 more)

55 card(s) · ability/ChangeZone · field owner_library: true

Examples: Alabaster Dragon, Angel of Fury, Audacious Swap (+52 more)

39 card(s) · ability/ChangeZone · field enter_with_counters: [(Plus1Plus1, Fixed { value: 1 })]

Examples: A-Graveyard Shift, Butcher Ghoul, Cauldron's Gift (+36 more)

37 card(s) · ability/ChangeZone · field enters_attacking: true

Examples: Alesha, Who Smiles at Death, Arni Metalbrow, Chorale of the Void (+34 more)

32 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("finality"), Fixed { value: 1 })]

Examples: A-Llanowar Greenwidow, Admiral Brass, Unsinkable, Balustrade Wurm (+29 more)

27 card(s) · ability/ChangeZoneAll · field enters_under: You

Examples: Afterlife from the Loam, Boneyard Parley, Breach the Multiverse (+24 more)

26 card(s) · ability/ChangeZone · field enter_with_counters: [(Minus1Minus1, Fixed { value: 1 })]

Examples: Aerie Ouphes, Furystoke Giant, Glen Elendra Archmage (+23 more)

20 card(s) · ability/ChangeZoneAll · field enter_tapped: Tapped

Examples: Aftermath Analyst, Clarion Ultimatum, Clear the Land (+17 more)

16 card(s) · ability/ChangeZone · field enter_with_counters: [(Time, Fixed { value: 3 })]

Examples: Arc Blade, Charnel Serenade, Chronomantic Escape (+13 more)

9 card(s) · ability/ChangeZoneAll · field library_position: Bottom

Examples: Arjun, the Shifting Flame, Endurance, Hallowed Burial (+6 more)

8 card(s) · ability/ChangeZone · field enter_with_counters: [(Plus1Plus1, Fixed { value: 2 })]

Examples: Dodecapod, Evil Reawakened, Infernal Vessel (+5 more)

4 card(s) · ability/ChangeZone · field enter_with_counters: [(Keyword(Flying), Fixed { value: 1 })]

Examples: Ascent of the Worthy, Ghost Vacuum, Luminous Broodmoth (+1 more)

3 card(s) · ability/ChangeZone · field enter_with_counters: [(Time, Ref { qty: ObjectManaValue { scope: Recipient } })]

Examples: Amy's Home, The Eleventh Doctor, The Wedding of River Song

3 card(s) · ability/ChangeZone · field face_down_profile: FaceDownProfile { power: None, toughness: None, body: Creature, extra_core_types: [], subtypes: [], ward: None }

Examples: Ashcloud Phoenix, Shorecrasher Elemental, Yarus, Roar of the Old Gods

3 card(s) · ability/ChangeZoneAll · field library_position: Top

Examples: Harmonic Convergence, Head Games, Jester's Mask

2 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("corpse"), Fixed { value: 1 })]

Examples: From the Catacombs, Isareth the Awakener

2 card(s) · ability/ChangeZone · field enter_with_counters: [(Keyword(Lifelink), Fixed { value: 1 })]

Examples: Metamorphosis Fanatic, Unbreakable Bond

1 card(s) · ability/ChangeZone · field conditional_enter_with_counters: [(Typed(TypedFilter { type_filters: [Artifact], controller: None, properties: [] }), Plus1Plus1, Fixed { value: 2 })]

Examples: Oviya, Automech Artisan

1 card(s) · ability/ChangeZone · field conditional_enter_with_counters: [(Typed(TypedFilter { type_filters: [Subtype("Hero")], controller: None, properties: [] }), Plus1Plus1, Fixed { value: …

Examples: Winter Soldier, Reborn Avenger

1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("aegis"), Fixed { value: 1 })]

Examples: Livio, Oathsworn Sentinel

1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("blood"), Fixed { value: 1 })]

Examples: Rayami, First of the Fallen

1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("brain"), Fixed { value: 1 })]

Examples: Rex, Cyber-Hound

… 31 more signature(s) (31 card-changes) — see parse-diff.json
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("charge"), Fixed { value: 4 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("croak"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("dream"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("egg"), Fixed { value: 3 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("fetch"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("hatching"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("hit"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("ice"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("luck"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("manifestation"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("mannequin"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("scream"), Fixed { value: 2 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("silver"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("stash"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("study"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Generic("void"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Keyword(Hexproof), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Keyword(Indestructible), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Plus1Plus1, Fixed { value: 3 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Stun, Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Stun, Fixed { value: 2 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Time, Fixed { value: 17 })]
  • 1 card(s) · ability/ChangeZone · field enter_with_counters: [(Time, Fixed { value: 4 })]
  • 1 card(s) · ability/ChangeZone · field enters_modified_if: enchantment
  • 1 card(s) · ability/ChangeZone · field face_down_profile: FaceDownProfile { power: None, toughness: None, body: Noncreature, extra_core_types: [Land], subtypes: ["Forest"], ward…
  • 1 card(s) · ability/ChangeZone · field face_down_profile: FaceDownProfile { power: Some(2), toughness: Some(2), body: Creature, extra_core_types: [Artifact], subtypes: ["Cyberma…
  • 1 card(s) · ability/ChangeZoneAll · field enter_with_counters: [(Generic("finality"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZoneAll · field enter_with_counters: [(Generic("necrodermis"), Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZoneAll · field enter_with_counters: [(Minus1Minus1, Fixed { value: 1 })]
  • 1 card(s) · ability/ChangeZoneAll · field face_down_profile: FaceDownProfile { power: Some(2), toughness: Some(2), body: Creature, extra_core_types: [Artifact], subtypes: ["Cyberma…
  • 1 card(s) · ability/ChangeZoneAll · field random_order: true

1 card(s) had Oracle-text changes (errata/reprint) — excluded as non-parser.

@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.

This is a really good PR, and I want to be specific about why before I get to the one thing holding it up.

What this gets right

The exhaustive destructuring is the best thing here, and it is a genuine improvement over how #5493 solved the same problem for PreventDamage. That PR added one field alongside a surviving .., which fixed the symptom and left the mechanism intact. This one fully destructures both Effect::ChangeZone and Effect::ChangeZoneAll, so the next field added to either variant is a compile error rather than another silent omission. You converted a recurring class of bug into one the compiler catches for us. That is the durable fix #5495 was actually asking for.

Splitting the two variants was the right call, too. Their qualifier sets genuinely diverge (ChangeZoneAll has library_position / random_order, ChangeZone has enters_attacking / enter_transformed / conditional_enter_with_counters / enters_modified_if), so a shared arm could never have destructured both. That is a structural reason, not churn.

The "push only when set" discipline is also exactly right, and it keeps unqualified signatures byte-identical so we get no gratuitous baseline noise. It mirrors the pattern #5493 established.

And the PR self-tests. Its own coverage-parse-diff sticky reports 978 cards across 56 signatures, including ChangeZone · field enters_attacking: ∅ → true on 37 cards, enter_tapped on 437, enters_under on 213, and enter_transformed on 88. To be unambiguous for anyone reading this later: that 978-card sticky is expected one-time baseline churn from surfacing previously hidden fields. It is not a regression. Reviewers of subsequent PRs will see a clean baseline. The sticky is the proof the change works, at the scale of the blind spot it closed.

The payoff is immediate and concrete. #5494 (Senu, Keen-Eyed Protector) sets enters_attacking for "put it onto the battlefield attacking", and until this PR that parser change was invisible to the sticky. Thirty-seven cards sat in that blind spot.

All twelve checks are green.

Blocking: three CR citations point at rules that say something else

This is the only reason I'm not approving. This repo treats a wrong CR number as worse than no CR number, because it manufactures false confidence that code was checked against a rule it was never checked against, and because a later grep -rn "CR 400.7" audit will surface a line that has nothing to do with that rule.

I grep-verified all eleven citations against docs/MagicCompRules.txt. Eight are correct and apt: 110.2a, 508.4, 608.2d, 122.1, 708.2a, 614.12, 110.5b, and 401.4 where it sits on library_position. Three are wrong.

1. owner_library cites CR 400.7crates/engine/src/game/coverage.rs:2588

CR 400.7 reads: "An object that moves from one zone to another becomes a new object with no memory of, or relation to, its previous existence." That is the incarnation rule. It says nothing about owner-versus-controller libraries.

The governing rule is CR 400.3: "If an object would go to any library, graveyard, or hand other than its owner's, it goes to its owner's corresponding zone."

2. enter_tapped cites CR 614.1 in one arm and CR 110.5b in the othercoverage.rs:2597 vs coverage.rs:2646

Same field, two different anchors. CR 614.1 is the generic section header ("Some continuous effects are replacement effects."). The correct anchor is the one you already used in the ChangeZoneAll arm, CR 110.5b: "Permanents enter the battlefield untapped, unflipped, face up, and phased in unless a spell or ability says otherwise." Use 110.5b in both.

3. random_order cites CR 401.4coverage.rs:2661

CR 401.4 reads: "If an effect puts two or more cards in a specific position in a library at the same time, the owner of those cards may arrange them in any order. That library's owner doesn't reveal the order in which the cards go into the library."

That is owner-chosen ordering, which is the opposite of randomization. 401.4 is correct where you used it on library_position and should stay there. For random_order, please drop the citation rather than reach for a rule that doesn't say it.

To keep the ask proportionate: CLAUDE.md says not to annotate boilerplate, serialization, or plumbing, only code that implements a rule. effect_details is a signature renderer, so none of these annotations is strictly required in the first place. Dropping the three questionable ones is just as acceptable as correcting them. What isn't acceptable is leaving a citation that points at a rule saying something else.

Non-blocking suggestion

change_zone_signature_exposes_enters_attacking covers enters_attacking in both directions, present when set and absent when not. That is the right shape for the test. It covers none of the other ten newly emitted fields, though. Given that the whole premise of this PR is that omitted fields go unnoticed, a table-driven test asserting each field appears when set would fit the theme nicely. Worth considering; I'm not going to hold the PR on it.

Summary

The exhaustive destructuring is precisely the structural fix #5495 hoped for, and the 978-card sticky proves it works at scale. This should merge as soon as the three citations are corrected or dropped.

minion1227 added a commit to minion1227/phase that referenced this pull request Jul 10, 2026
…notations

Addresses review feedback on phase-rs#5500:
- owner_library: CR 400.7 (incarnation) -> CR 400.3 (goes to owner's zone)
- enter_tapped (ChangeZone arm): CR 614.1 (generic header) -> CR 110.5b,
  matching the ChangeZoneAll arm's existing correct citation
- random_order: drop CR 401.4 (that rule is owner-*chosen* order, the
  opposite of randomization); 401.4 stays on library_position where it fits

Verified all three against docs/MagicCompRules.txt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@minion1227

Copy link
Copy Markdown
Contributor Author

Thanks for the careful CR audit — all three citations fixed in ee353a2 (verified against docs/MagicCompRules.txt):

  1. owner_libraryCR 400.7CR 400.3 ("a card going to a library other than its owner's goes to its owner's"). 400.7 was the incarnation rule as you noted.
  2. enter_tapped (ChangeZone arm)CR 614.1CR 110.5b, now matching the ChangeZoneAll arm's existing citation. Both arms cite the same rule for the same field.
  3. random_orderdropped the citation. Agreed that CR 401.4 describes owner-chosen ordering, the opposite of randomization; it stays on library_position where it fits.

Left the table-driven test suggestion out of this pass since you flagged it non-blocking, happy to follow up if you'd like it in-scope. Ready for another look.

@matthewevans

Copy link
Copy Markdown
Member

You were first, by two minutes, and you had the right idea.

Here is what happened, plainly. #5501 is a near-identical fix to this one, arrived at independently: the same thirteen fields, the same exhaustive destructuring of both ChangeZone and ChangeZoneAll, even the same test name. I have landed that one, for two reasons. It carries none of the three misapplied CR citations I flagged in my review above, and it is already green and mergeable while this branch is behind and needs a round trip.

I want to be clear about what was valuable here, because it was not the annotations. It was the structural choice you both made: removing the .. from both variants so that adding a field to either one becomes a compile error rather than another silent omission. That is what turns this from a patch into a closed hole, and it is why the fix is worth having. Your PR made that call.

The duplicated effort is my fault. I filed #5495 without assigning it or saying whether I intended to pick it up, so two people independently spent time on the same function within two minutes of each other. That is a process failure on my side, not a judgment about your work.

I am not closing this PR. That decision belongs to the human maintainer, and I have surfaced it to them. If you would rather correct the three citations and land yours instead, say so and I will re-review.

@matthewevans

Copy link
Copy Markdown
Member

Your corrections are right. I verified all three against docs/MagicCompRules.txt at head ee353a28:

  • owner_library no longer cites CR 400.7; it now points at CR 400.3 ("If an object would go to any library, graveyard, or hand other than its owner's, it goes to its owner's corresponding zone").
  • enter_tapped is consistent on CR 110.5b in both arms; the stray CR 614.1 is gone.
  • random_order carries no citation, and CR 401.4 stays on library_position where it belongs.

So this PR is now correct and equivalent to #5501, which was already approved and sitting at position 1 in the merge queue when you pushed. I am not going to dequeue a green PR to re-run the same change, so #5501 will land and this one becomes redundant through no fault of yours.

To say it plainly: you were first, your structural call was the right one, and your citations are now correct. The duplicated work happened because I filed #5495 without assigning it. Closing this is the human maintainer's decision, not mine, and I have surfaced it to them.

minion1227 and others added 2 commits July 10, 2026 04:59
…n the parse-diff signature (phase-rs#5495)

`effect_details` built the ChangeZone/ChangeZoneAll signature from origin,
destination and target only — every ETB entry qualifier (enters_attacking,
enter_tapped, enter_transformed, owner_library, enters_under, up_to,
enter_with_counters, conditional_enter_with_counters, face_down_profile,
enters_modified_if; library_position, random_order for the mass case) was
swallowed by `..`. A parser change flipping one produced no row in the
coverage-parse-diff sticky, reading as "No card-parse changes" — surfaced on
Senu (phase-rs#5494), whose "put it onto the battlefield attacking" (CR 508.4) sets
enters_attacking with no diff-visible evidence.

Split the two variants (their qualifier sets diverge) and emit each field only
when set, so unqualified signatures stay byte-identical — the "push only when
set" pattern phase-rs#5493 established for PreventDamage. Adds
change_zone_signature_exposes_enters_attacking (appears when set, omitted when
false; reverting the emission fails it). Closes phase-rs#5495.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…notations

Addresses review feedback on phase-rs#5500:
- owner_library: CR 400.7 (incarnation) -> CR 400.3 (goes to owner's zone)
- enter_tapped (ChangeZone arm): CR 614.1 (generic header) -> CR 110.5b,
  matching the ChangeZoneAll arm's existing correct citation
- random_order: drop CR 401.4 (that rule is owner-*chosen* order, the
  opposite of randomization); 401.4 stays on library_position where it fits

Verified all three against docs/MagicCompRules.txt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@minion1227

Copy link
Copy Markdown
Contributor Author

Thanks — that's a fair and generous read, and I appreciate you separating the structural value from the annotation slip.

Two quick updates in case they tip the decision:

  • The three misapplied CR citations were already corrected in ee353a282 (before your comment above), each re-verified against docs/MagicCompRules.txt. So the specific blocker your review named is resolved.
  • I've rebased this branch onto latest main (0b998ffd8), so it's no longer behind and needs no round trip — CI is green and it's mergeable.

Taking you up on your re-review offer: this is now citation-clean, rebased, and green, so I'm glad to land it if that's useful. That said, #5501 is substantively identical and already in the merge queue — if it goes through, I've no objection to this closing as a duplicate. Either way the hole gets closed, which is the point. Just flagging that the reasons not to land this one are now both addressed.

@matthewevans

Copy link
Copy Markdown
Member

Closing note, and thank you.

#5501 merged at 12:01:03Z, so the fix you wrote is now on main. I confirmed it: coverage.rs on main carries the exhaustive destructure and the change_zone_signature_exposes_enters_attacking test at line 10366. Your branch has gone DIRTY against it, which is what you would expect when two branches change the same function the same way.

The review tooling suggested I update your branch. I am deliberately not doing that. Rebasing this onto a main that already contains the identical change would produce either an empty diff or a conflict resolution that reintroduces nothing. There is no version of this PR that still adds value, and that is a statement about timing rather than about your work.

For the record, since it should be on the record: you opened first, you made the right structural call (removing the .. from both variants so the compiler catches the next omission), and you corrected all three CR citations promptly and correctly. I verified those corrections against docs/MagicCompRules.txt before #5501 merged.

The duplication happened because I filed #5495 without assigning it or saying I wanted it picked up. That is a process failure on my side. I am carrying it forward: issues I want a specific contributor to take will say so.

Closing is the human maintainer's call and I have surfaced it. Nothing further needed from you here.

@minion1227

Copy link
Copy Markdown
Contributor Author

Closing this as a duplicate. @davion-knight's #5501 landed the same exhaustive-destructure fix for #5495 — all twelve ChangeZone/ChangeZoneAll entry qualifiers, split arms, push-only-when-set — and merged first, so this is now redundant against main.

Thank you @matthewevans for the exceptionally thorough review; it's appreciated even on a PR that won't land. Noted and agreed on all three CR corrections, for the record and anyone auditing later:

  • owner_libraryCR 400.3 (owner's-corresponding-zone), not CR 400.7 (the new-object/no-memory rule).
  • enter_tappedCR 110.5b in both arms (not CR 614.1, the generic section header).
  • random_orderdrop the citation — CR 401.4 is owner-chosen ordering, the opposite of randomization; it stays correct only on library_position.

Glad the "fully destructure so the next added field is a compile error, not another silent omission" direction was what the issue wanted. Credit to @davion-knight for getting there first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

coverage-parse-diff sticky is blind to ChangeZone's enters_attacking (same family as #5492)

2 participants