Skip to content

ship/fix engine preserve tracked delayed target pins 2 - #7283

Closed
matthewevans wants to merge 18 commits into
mainfrom
ship/fix-engine-preserve-tracked-delayed-target-pins-2
Closed

ship/fix engine preserve tracked delayed target pins 2#7283
matthewevans wants to merge 18 commits into
mainfrom
ship/fix-engine-preserve-tracked-delayed-target-pins-2

Conversation

@matthewevans

@matthewevans matthewevans commented Aug 12, 2026

Copy link
Copy Markdown
Member
  • fix(engine): preserve tracked delayed target pins
  • fix(engine): borrow tracked delayed effect in test
  • fix(engine): compare tracked set id by value

Summary by CodeRabbit

  • Bug Fixes
    • Improved delayed zone changes when objects leave and re-enter play.
    • Prevented stale or invalid pinned targets from being moved.
    • Preserved parent-target and target-slot constraints in nested effect filters.
    • Improved contextual targeting for parent objects and tracked sets.
    • Ensured tracked-set membership and provenance are cleaned up correctly when consumed.
    • Preserved delayed-trigger targeting through event-context returns and nested filters.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8951fe04-b81f-4573-a4e2-5735e9e38cb0

📥 Commits

Reviewing files that changed from the base of the PR and between c423995 and fcecfb4.

📒 Files selected for processing (1)
  • crates/engine/tests/integration/niko_light_of_hope.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/engine/tests/integration/niko_light_of_hope.rs

📝 Walkthrough

Walkthrough

ParentTarget and ParentTargetSlot filters now normalize into concrete filters, including nested tracked-set filters. Delayed ChangeZone effects preserve these constraints. ChangeZoneAll validates target incarnations and cleans tracked-set provenance.

Changes

Parent-target incarnation handling

Layer / File(s) Summary
Contextual filter normalization
crates/engine/src/game/filter.rs, crates/engine/src/game/effects/delayed_trigger.rs
ParentTarget references now resolve into concrete filters. Nested TrackedSetFiltered and ChosenDamageSource filters are normalized recursively. Invalid slots resolve to TargetFilter::None.
Delayed ChangeZone tracking
crates/engine/src/game/effects/delayed_trigger.rs, crates/engine/src/game/effects/mod.rs, crates/engine/src/game/effects/change_zone.rs, crates/engine/tests/integration/niko_light_of_hope.rs
Delayed zone changes preserve parent-target filters during ChangeZoneAll conversion. Parent references inside tracked-set filters are detected. Integration coverage verifies delayed-trigger targets and incarnation pins.
Current target validation and cleanup
crates/engine/src/game/effects/change_zone.rs, crates/engine/src/game/engine.rs
Delayed returns accept only the current or immediately succeeding incarnation. Tracked-set consumption removes object membership and cause provenance. Source references are updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DelayedTrigger
  participant normalize_contextual_filter
  participant ChangeZoneAll
  participant TargetObject
  DelayedTrigger->>normalize_contextual_filter: Normalize ParentTarget filter
  normalize_contextual_filter-->>DelayedTrigger: Return concrete filter
  DelayedTrigger->>ChangeZoneAll: Preserve TrackedSetFiltered target
  ChangeZoneAll->>TargetObject: Check incarnation pin
  TargetObject-->>ChangeZoneAll: Return matching incarnation
  ChangeZoneAll->>TargetObject: Move matching object
Loading

Possibly related PRs

  • phase-rs/phase#7099: Extends delayed-trigger incarnation pinning to nested tracked-set filters and ChangeZoneAll resolution.
  • phase-rs/phase#7257: Modifies delayed-trigger tracked-set handling and preservation of delayed ChangeZone target context.
  • phase-rs/phase#6808: Shares delayed-trigger, parent-target, tracked-set, and incarnation handling changes.

Suggested labels: bug, needs-maintainer

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title identifies the engine fix for preserving tracked delayed target pins, which is the primary change in the pull request.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch ship/fix-engine-preserve-tracked-delayed-target-pins-2
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ship/fix-engine-preserve-tracked-delayed-target-pins-2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@matthewevans
matthewevans enabled auto-merge August 12, 2026 03:53
@matthewevans
matthewevans force-pushed the ship/fix-engine-preserve-tracked-delayed-target-pins-2 branch 2 times, most recently from ffe10cd to d98efd0 Compare August 12, 2026 05:43
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown

Generated for head c4239958a2453f4d586011810e87809166c9901d.

Parse changes introduced by this PR

✓ No card-parse changes detected.

@matthewevans
matthewevans force-pushed the ship/fix-engine-preserve-tracked-delayed-target-pins-2 branch from d98efd0 to 984f2eb Compare August 12, 2026 06:52

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/engine/src/game/effects/delayed_trigger.rs`:
- Around line 989-995: Update change_zone::resolve_all to clean up concrete
tracked-set ids for both TargetFilter::TrackedSet and
TargetFilter::TrackedSetFiltered, including removal from tracked_object_sets and
tracked_set_member_causes. Preserve existing resolution behavior, and add a
regression covering cleanup of both maps for each tracked-set variant.

In `@crates/engine/src/game/filter.rs`:
- Around line 1029-1033: Update the documentation comment above the contextual
parent-target normalization to remove the inaccurate CR 608.2c citation, or
replace it with a verified citation whose rule explicitly requires this
resolution before filter scanning; do not cite CR 608.2c unless the comment
describes resolving written instructions in order.
- Around line 1084-1087: Update the TargetFilter::ParentTargetSlot handling to
return TargetFilter::None when the positive parent target index is absent,
preventing missing slots from matching all targets. Preserve TargetFilter::Any
only for the negated-slot case, and ensure multi-target consumers retain the
declared target-slot index.
- Around line 1100-1109: Update normalize_contextual_filter to remove the
wildcard arm and explicitly handle every leaf variant by cloning it, while
recursively normalizing every nested filter. Include recursion through
ChosenDamageSource.filter and preserve the existing handling of
TrackedSetFiltered, so adding future contextual variants requires deliberate
matching.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 85ee9b96-cfc3-4cc3-b72e-2eac3447d90b

📥 Commits

Reviewing files that changed from the base of the PR and between c22f9c0 and 984f2eb.

📒 Files selected for processing (4)
  • crates/engine/src/game/effects/change_zone.rs
  • crates/engine/src/game/effects/delayed_trigger.rs
  • crates/engine/src/game/effects/mod.rs
  • crates/engine/src/game/filter.rs

Comment thread crates/engine/src/game/effects/delayed_trigger.rs
Comment thread crates/engine/src/game/filter.rs Outdated
Comment thread crates/engine/src/game/filter.rs Outdated
Comment thread crates/engine/src/game/filter.rs
@matthewevans
matthewevans force-pushed the ship/fix-engine-preserve-tracked-delayed-target-pins-2 branch 2 times, most recently from cee468c to 434d57c Compare August 12, 2026 09:45
@matthewevans

matthewevans commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

Follow-up repair pushed after fresh CI exposed three real regressions. The incarnation check now applies only to TrackedSetFiltered paths whose member filter names the delayed parent object (#7100); ordinary tracked-set returns may move their members across zones. Consumed TrackedSetFiltered sets now remove provenance alongside membership. I also aligned the delayed-condition out-of-range-slot unit assertion with normalize_contextual_filter’s established match-nothing contract. No Cargo command was run in this worktree; CI will validate the rebased head.

@matthewevans

Copy link
Copy Markdown
Member Author

Follow-up pushed: Niko uses a single ChangeZone { Exile → Battlefield, ParentTarget } return, which was still going through the general stale-pin target filter. The repair restores its direct delayed snapshot on that explicit return path; #7100’s mass tracked-set stale-member guard remains unchanged. A clean rebase against current main conflicted in unrelated engine.rs, so this head is intentionally pushed on the existing PR branch for CI validation.

@matthewevans
matthewevans force-pushed the ship/fix-engine-preserve-tracked-delayed-target-pins-2 branch from 1670870 to 661efca Compare August 12, 2026 10:37

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/engine/src/game/effects/change_zone.rs`:
- Around line 1661-1671: Update the tracked-set pin validation and cleanup
around tracked_members_name_parent_object to use the existing recursive filter
helpers, including normalize_contextual_filter and recursive parent-object
reference detection, so nested And, Or, and Not wrappers are traversed. Collect
every concrete tracked-set ID from the normalized filter, apply the pin rule to
matching members, and remove both tracked_object_sets and
tracked_set_member_causes entries for every consumed set. Add regression
coverage for nested And, Or, and Not filters.
- Around line 483-495: Update the Exile-to-Battlefield delayed-return branch
around effective_targets to validate the post-Exile zone-change identity or
incarnation pin before cloning ability.targets, so it does nothing if the object
leaves and re-enters Exile. Annotate this delayed-return identity check with
verified descriptive CR 603.7c language, and add a regression test covering
Exile → another zone → Exile → delayed return.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a1b99714-09b3-4567-84a3-6679e95b6a4a

📥 Commits

Reviewing files that changed from the base of the PR and between 984f2eb and 661efca.

📒 Files selected for processing (4)
  • crates/engine/src/game/effects/change_zone.rs
  • crates/engine/src/game/effects/delayed_trigger.rs
  • crates/engine/src/game/effects/mod.rs
  • crates/engine/src/game/filter.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/engine/src/game/effects/mod.rs
  • crates/engine/src/game/effects/delayed_trigger.rs
  • crates/engine/src/game/filter.rs

Comment thread crates/engine/src/game/effects/change_zone.rs Outdated
@matthewevans
matthewevans force-pushed the ship/fix-engine-preserve-tracked-delayed-target-pins-2 branch 2 times, most recently from 79f1181 to 0180e5d Compare August 12, 2026 11:33

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
crates/engine/src/game/engine.rs (1)

16031-16040: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a drift-log entry for the effects/mod.rs +4 shift.

The three game/effects/mod.rs pins moved by a uniform +4. The comment block directly above ends with the #7018, #6958, and #6976 adjudications, none of which accounts for this round's +4.

The assertion message at Lines 15930-15934 requires each census move to be adjudicated in this document with the site named, not merely re-numbered. The game/engine.rs entry follows that rule: Lines 16353-16357 record the #7128 cause and restate set preservation. Apply the same treatment to these three pins: name the commit or change that inserted the four lines above all three producers, and state that the producers are unchanged and the partition stays 5/7/25.

Run the following script to locate the four inserted lines and confirm the producers are unchanged:

#!/bin/bash
# Description: Re-derive the three effects/mod.rs CR 603.5 producer coordinates by content.
set -euo pipefail

f=crates/engine/src/game/effects/mod.rs
rg -nP 'WaitingFor::OptionalEffectChoice \{' "$f" | rg -v '\.\.'
for n in 6304 6381 9574; do
  printf '=== %s:%s ===\n' "$f" "$n"
  sed -n "${n}p" "$f" | sha256sum
done
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/engine/src/game/engine.rs` around lines 16031 - 16040, Add a drift-log
entry immediately above the three game/effects/mod.rs pins identifying the
commit or change that inserted four lines above all producers. State that the
producers remain unchanged and explicitly record preservation of the 5/7/25
partition, while retaining the existing `#7018`, `#6958`, and `#6976` adjudications.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/engine/src/game/effects/change_zone.rs`:
- Around line 524-535: Update the special effective_targets branch in the
change-zone resolution logic to also require non-empty
ability.target_incarnations. Keep the delayed_exile_return_targets path gated by
the existing zone, destination, and ParentTarget checks, and use
resolved_targets for unpinned abilities with no target incarnations.
- Around line 1701-1708: Update the tracked-set pin-validation condition near
tracked_members_name_parent_object so ParentTarget-based delayed ChangeZone
effects retain validation when dest_zone is Battlefield; do not disable it
solely because of the destination zone. Add a regression test covering a
Battlefield return and document the specific card-related exemption for ordinary
tracked-set returns, preserving that exemption without weakening parent-bound
validation.

---

Nitpick comments:
In `@crates/engine/src/game/engine.rs`:
- Around line 16031-16040: Add a drift-log entry immediately above the three
game/effects/mod.rs pins identifying the commit or change that inserted four
lines above all producers. State that the producers remain unchanged and
explicitly record preservation of the 5/7/25 partition, while retaining the
existing `#7018`, `#6958`, and `#6976` adjudications.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1a34034c-083b-460e-b1fc-a7e9e5b10474

📥 Commits

Reviewing files that changed from the base of the PR and between 661efca and 0180e5d.

📒 Files selected for processing (3)
  • crates/engine/src/game/effects/change_zone.rs
  • crates/engine/src/game/engine.rs
  • crates/engine/src/game/filter.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/engine/src/game/filter.rs

Comment thread crates/engine/src/game/effects/change_zone.rs
Comment thread crates/engine/src/game/effects/change_zone.rs
@matthewevans
matthewevans force-pushed the ship/fix-engine-preserve-tracked-delayed-target-pins-2 branch from 15ff09e to 063cddb Compare August 12, 2026 12:22
@matthewevans

Copy link
Copy Markdown
Member Author

Superseded by #7300, rebuilt from current origin/main after this branch became merge-conflicted. #7300 retains the tracked delayed-target incarnation fix and is enabled for merge-queue delivery.

auto-merge was automatically disabled August 12, 2026 14:01

Pull request was closed

@coderabbitai coderabbitai Bot mentioned this pull request Aug 12, 2026
4 tasks
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.

1 participant