Skip to content

fix(parser): parse Faerie Miscreant singleton named condition - #7297

Merged
matthewevans merged 5 commits into
phase-rs:mainfrom
keloide:card/faerie-miscreant
Aug 12, 2026
Merged

fix(parser): parse Faerie Miscreant singleton named condition#7297
matthewevans merged 5 commits into
phase-rs:mainfrom
keloide:card/faerie-miscreant

Conversation

@keloide

@keloide keloide commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes Faerie Miscreant’s singleton named-card intervening-if condition so it lowers to a live battlefield presence check and preserves its draw effect. Adds parser and runtime coverage, including the resolution-time recheck required by an intervening “if” clause.

Closes #7154.

Files changed

  • crates/engine/src/parser/oracle_nom/condition.rs — accept singleton you control … named … conditions without inventing a connector.
  • crates/engine/src/parser/oracle_trigger_tests.rs — assert the full Faerie Miscreant parse shape and draw effect.
  • crates/engine/tests/integration/issue_7154_faerie_miscreant.rs — add positive, negative, and resolution-time recheck regressions.
  • crates/engine/tests/integration/main.rs — register the integration module.
  • docs/parser-misparse-backlog.md — clear the resolved Faerie Miscreant entry.

Track

Developer

LLM

Model: gpt-5.6-sol
Tier: Frontier
Thinking: high

Implementation method (required)

Method: /engine-implementer

CR references

CR 109.1; CR 201.2; CR 603.4.

Verification

  • Required checks ran clean, or the exact CI-owned alternative is stated below.

  • Gate A output below is for the current committed head.

  • Final review-impl below is clean for the current committed head.

  • Both anchors cite existing analogous code at the same seam.

  • /Users/lucacola/.rustup/toolchains/nightly-2026-04-19-aarch64-apple-darwin/bin/cargo fmt --all -- --check — passed.

  • /Users/lucacola/.rustup/toolchains/nightly-2026-04-19-aarch64-apple-darwin/bin/cargo test -p phase-engine --test integration issue_7154_faerie_miscreant -- --nocapture — passed: 3 passed, 0 failed.

  • /Users/lucacola/.rustup/toolchains/nightly-2026-04-19-aarch64-apple-darwin/bin/cargo test -p phase-engine you_control_named_rejects_empty_singleton_name -- --nocapture — passed: 1 passed, 0 failed.

  • cargo clippy-strict — completed before the final test-only assertion correction; no errors reported.

  • PHASE_REFRESH_MTGJSON=1 ./scripts/gen-card-data.sh — completed; no tracked card-data change.

  • cargo coverage — completed before the final test-only assertion correction; Faerie Miscreant remained supported.

  • cargo semantic-audit — completed: 32,749 cards audited; Faerie Miscreant has zero findings.

  • cargo test -p phase-engine — the post-correction full run was intentionally interrupted at the user’s request to reclaim disk space; GitHub Actions is the CI-owned full-suite verification.

Gate A

Gate G PASS (router/grant architecture: strict router vs permissive grant boundary intact)
Gate A PASS head=8a79a7e78b572ac59ecb6412d268e0e58c99fdd5 base=8a95d233016077c852d46cf8b5fc9c65aa20bebb

Anchored on

  • crates/engine/src/parser/oracle_nom/condition.rs:11294 — Scepter of Empires shared-type named pair parser regression.
  • crates/engine/src/parser/oracle_nom/condition.rs:11341 — Helm of the Host shared-type named serial-list parser regression.

Final review-impl

Final review-impl PASS head=8a79a7e78

Claimed parse impact

  • Faerie Miscreant

Scope Expansion

None.

Validation Failures

None.

CI Failures

None.

Summary by CodeRabbit

  • Bug Fixes

    • Corrected parsing of single-condition card text when no connector is present.
    • Preserved intervening-if conditions and exact card-name filters for Faerie Miscreant.
    • Faerie Miscreant now draws correctly only when another qualifying card remains present as required.
  • Tests

    • Added parser and integration coverage for valid, invalid, and changing game-state scenarios.

@keloide
keloide requested a review from matthewevans as a code owner August 12, 2026 12:59
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@matthewevans, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a0277d8c-5ab2-48d6-875f-3901fa69d6c0

📥 Commits

Reviewing files that changed from the base of the PR and between 8a79a7e and cda8ae0.

📒 Files selected for processing (3)
  • crates/engine/src/parser/oracle_trigger_tests.rs
  • crates/engine/tests/integration/issue_7154_faerie_miscreant.rs
  • crates/engine/tests/integration/main.rs
📝 Walkthrough

Walkthrough

The parser now accepts a single named creature condition without a connector while rejecting empty names and multiple unconnected conditions. Parser and integration tests cover Faerie Miscreant’s trigger, draw behavior, and intervening state.

Changes

Faerie Miscreant parser fix

Layer / File(s) Summary
Singleton named-condition parsing
crates/engine/src/parser/oracle_nom/condition.rs
Condition parsing supports optional connectors, accepts non-empty singleton names, rejects invalid unconnected conditions, and preserves the trailing effect boundary.
Trigger regression coverage
crates/engine/src/parser/oracle_trigger_tests.rs, crates/engine/tests/integration/issue_7154_faerie_miscreant.rs, crates/engine/tests/integration/main.rs
Tests validate Faerie Miscreant’s parsed condition, card draw behavior, missing companion behavior, and intervening state after the companion leaves.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: bug, test

Suggested reviewers: matthewevans

🚥 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 clearly identifies the parser fix for Faerie Miscreant’s singleton named condition.
Linked Issues check ✅ Passed The changes parse and execute Faerie Miscreant’s conditional draw effect and add parser and integration coverage for issue #7154.
Out of Scope Changes check ✅ Passed The parser changes, regression tests, harness update, and backlog cleanup directly support the linked issue and PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 self-assigned this Aug 12, 2026
@matthewevans

Copy link
Copy Markdown
Member

Maintainer HOLD (current head 8a79a7e78b572ac59ecb6412d268e0e58c99fdd5): required checks are still running, including Card data (so the current-head parse-diff sticky is not yet available), and CodeRabbit is still processing this head. Approval and merge-queue enrollment resume once those current-head gates settle.

@matthewevans matthewevans removed their assignment Aug 12, 2026

@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: 3

🤖 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/parser/oracle_nom/condition.rs`:
- Around line 965-976: Add a verified CR annotation directly above the
connector-less singleton handling in the named-card parsing function,
documenting the named-card rule basis and that a trimmed non-empty name is
accepted as one condition. Use the applicable Comprehensive Rules number and
description, preserving the existing empty-name error and singleton return
behavior.

In `@crates/engine/tests/integration/issue_7154_faerie_miscreant.rs`:
- Around line 118-120: Update the test flow around move_to_zone so the
companion’s move to Zone::Graveyard uses the replacement-aware production
pipeline via ProposedEvent::ZoneChange, rather than calling zones::move_to_zone
directly. Process the resulting events through the runner so replacement effects
and normal zone-change handling occur before the resolution-time recheck.
- Around line 69-85: Add a runtime integration scenario alongside
does_not_draw_without_another_faerie_miscreant that places another creature with
a different name under P0’s control, then cast and resolve Faerie Miscreant and
assert zero cards are drawn. Ensure the setup includes the required “another”
creature while differing from “Faerie Miscreant,” so evaluation exercises the
named companion condition rather than only FilterProp::Another.
🪄 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: ec630ae3-ec46-46f4-aa14-86324d42fdac

📥 Commits

Reviewing files that changed from the base of the PR and between 25ea946 and 8a79a7e.

📒 Files selected for processing (5)
  • crates/engine/src/parser/oracle_nom/condition.rs
  • crates/engine/src/parser/oracle_trigger_tests.rs
  • crates/engine/tests/integration/issue_7154_faerie_miscreant.rs
  • crates/engine/tests/integration/main.rs
  • docs/parser-misparse-backlog.md
💤 Files with no reviewable changes (1)
  • docs/parser-misparse-backlog.md

Comment on lines +965 to +976
) -> Result<(Vec<&'a str>, Option<ControlNamedConnector>), nom::Err<OracleError<'a>>> {
let Some((connector_index, connector_len, connector, serial_comma)) =
find_shared_control_named_final_connector(names_text)
else {
return Err(nom::Err::Error(nom::error::Error::new(
error_input,
nom::error::ErrorKind::Fail,
)));
let name = names_text.trim();
if name.is_empty() {
return Err(nom::Err::Error(nom::error::Error::new(
error_input,
nom::error::ErrorKind::Fail,
)));
}
return Ok((vec![name], None));

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.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add a verified CR annotation for singleton named-card parsing.

Lines 965-976 make a connector-less named card valid as one condition. This rules-facing behavior has no verified CR <number>: <description> annotation. Add an annotation that describes the named-card rule basis and the singleton condition semantics.

As per coding guidelines: “Implement MTG behavior according to the Comprehensive Rules; verify the relevant CR section before completion, and annotate rules-related code with a verified CR number and description.”

🤖 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/parser/oracle_nom/condition.rs` around lines 965 - 976, Add
a verified CR annotation directly above the connector-less singleton handling in
the named-card parsing function, documenting the named-card rule basis and that
a trimmed non-empty name is accepted as one condition. Use the applicable
Comprehensive Rules number and description, preserving the existing empty-name
error and singleton return behavior.

Sources: Coding guidelines, Path instructions

Comment thread crates/engine/tests/integration/issue_7154_faerie_miscreant.rs
Comment thread crates/engine/tests/integration/issue_7154_faerie_miscreant.rs Outdated
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown

Generated for head cda8ae096f6793abe66aa95d332b5ed356845dc9.

Parse changes introduced by this PR · 2 card(s), 5 signature(s) (baseline: main c162191c91ff)

🟢 Added (2 signatures)

  • 1 card · ➕ ability/Draw · added: Draw
    • Affected (first 3): Faerie Miscreant
  • 1 card · ➕ ability/Token · added: Token (conditional=# of named "~" in battlefield you control Equipment ≥ 1, token=+4/+4 Kaldra (Creature Avatar))
    • Affected (first 3): Helm of Kaldra

🔴 Removed (1 signature)

  • 1 card · ➖ ability/Attach · removed: Attach (target=self)
    • Affected (first 3): Helm of Kaldra

🟡 Modified fields (2 signatures)

  • 1 card · 🔄 trigger/ChangesZone · changed field condition: you control another named "~, draw a card" in battlefield you control creatureyou control another named "~" in battlefield you control creature
    • Affected (first 3): Faerie Miscreant
  • 1 card · 🔄 ability/sword · changed field conditional: # of named "~" in battlefield you control Equipment ≥ 1
    • Affected (first 3): Helm of Kaldra

@matthewevans matthewevans self-assigned this Aug 12, 2026
@matthewevans matthewevans added the bug Bug fix label Aug 12, 2026
@matthewevans

Copy link
Copy Markdown
Member

Maintainer HOLD (current head 3f0a333fc810a783a0a1e654b160b20eb98bd33c): the maintainer fixup now covers the wrong-name companion and drives the resolution-time recheck through the production Destroy target creature pipeline. Current-head GitHub checks and CodeRabbit have restarted; the current parse-diff artifact is also still baseline-pending. I will recheck these exact gates on the next sweep before approving or enrolling this PR in the merge queue.

@matthewevans

Copy link
Copy Markdown
Member

Maintainer HOLD (current head cda8ae096f6793abe66aa95d332b5ed356845dc9): performed the one permitted merge-main baseline refresh for the stale parse-diff baseline. Current-head CI, Card data/parse-diff evidence, and the independent CodeRabbit pass are now pending (the service is currently rate-limited). I will recheck these current-head gates on the next sweep before approving or enrolling this PR in the merge queue.

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

Approved — current-head implementation review is clean.

Reviewed cda8ae096f6793abe66aa95d332b5ed356845dc9 against the full diff, current CI, and the exact-head parse-diff artifact. The singleton branch at crates/engine/src/parser/oracle_nom/condition.rs:818-829 returns exactly one typed presence condition while preserving empty-name rejection and the trigger effect boundary; the existing CR 201.2 function documentation at :784-800 covers the named-card rule. Runtime regressions drive cast, ETB trigger collection, and resolution-time recheck through the production Destroy pipeline (crates/engine/tests/integration/issue_7154_faerie_miscreant.rs:47-133).

The prior CodeRabbit review is attached to 8a79a7e, not this head; its two functional findings are resolved by 3f0a333. Its annotation request is already satisfied by the adjacent named-card parser documentation. The current exact-head CI and parse artifact are green/available.

@matthewevans
matthewevans added this pull request to the merge queue Aug 12, 2026
@matthewevans matthewevans removed their assignment Aug 12, 2026
Merged via the queue into phase-rs:main with commit 7c681e9 Aug 12, 2026
15 checks passed
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.

Faerie Miscreant — Draw engine not working "When this creature enters, if you control another creature named Faerie Mis…

2 participants