Skip to content

fix(parser): support N-ary "your choice of" keyword-grant lists#6192

Merged
matthewevans merged 2 commits into
phase-rs:mainfrom
tryeverything24:fix/issue-5992
Jul 22, 2026
Merged

fix(parser): support N-ary "your choice of" keyword-grant lists#6192
matthewevans merged 2 commits into
phase-rs:mainfrom
tryeverything24:fix/issue-5992

Conversation

@tryeverything24

@tryeverything24 tryeverything24 commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Fixes #5992.

Golem Artisan: "{2}: Target artifact creature gains your choice of flying, trample, or haste until end of turn."

Root cause & fix

This is a 3-way Oxford-comma keyword choice. parse_keyword_choice_grant (crates/engine/src/parser/oracle_effect/subject.rs) only handled a binary "X or Y" split via split_once_on(text, " or ") — for "flying, trample, or haste" that splits into "flying, trample," / "haste", the left half fails parse_granted_keyword_fragment, and the whole clause falls through to Unimplemented. (Also: the real card has no "you control" restriction on its target — verified against Scryfall, correcting the issue's own paraphrase.)

Fixed by reusing the existing nom-based N-ary Oxford-comma splitter (split_choice_list_items, already shared by the counter-choice and "from among" paths) instead of the binary split_once_on, changing the return type to Vec<Keyword>. Its two call sites (build_keyword_choice_clause, build_keyword_choice_sub_ability) now build branches via .into_iter().map(...).collect() instead of a hardcoded 2-element vec!. The sibling protection-choice shape ("protection from X or from the color of your choice") keeps its existing binary logic, just adapted to the new Vec-based return type — no behavior change there.

Effect::ChooseOneOf's runtime (choose_one_of.rs, GameAction::ChooseBranch) already takes Vec<AbilityDefinition> generically with no arity assumption anywhere in the crate (confirmed by grepping every ChooseOneOf reference) — this is a parser-only fix.

Testing

  • New parser tests: Golem Artisan's verbatim 3-way clause (asserts 3 branches + a positive target.controller == None check proving the no-"you control" correction), plus Assassin Initiate's verbatim 3-way clause proving the fix generalizes beyond the one reported card. Existing 2-way test kept unchanged as a regression guard.
  • New end-to-end integration tests (issue_5992_golem_artisan.rs) drive the real activation pipeline: GameRunner::activate(...).resolve() halts at the real ChooseOneOfBranch prompt (3 branches), GameAction::ChooseBranch picks Trample, evaluate_layers confirms the keyword actually lands (and the other two do not). A second test targets an OPPONENT-controlled artifact creature to prove the no-"you control" correction holds through the real targeting-legality pipeline, not just the parsed AST.
  • Verified locally (isolated CARGO_TARGET_DIR): cargo fmt --check clean, cargo clippy -p engine --all-targets --features test-support -- -D warnings clean, full cargo test -p engine --test integration --features test-support: 3544 passed, 0 failed, 2 ignored, 0 regressions.

Summary by CodeRabbit

  • New Features

    • Added support for granting keywords by choosing from three or more options (N-ary “your choice of” effects).
    • Expanded handling of modal keyword grants so any valid choice count is supported.
  • Bug Fixes

    • Correctly parses and applies the selected keyword while ensuring unselected options are not granted.
    • Ensures the granted keyword applies to the correct target, including opponent-controlled targets.
  • Tests

    • Added unit and integration coverage for N-option keyword-grant scenarios (including Golem Artisan).

@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 extends the MTG engine's parser to support N-branch keyword choice grants (such as Golem Artisan's three-way choice of flying, trample, or haste) by utilizing the nom-based list splitter, and adds corresponding integration tests. The review feedback points out a style guide violation where a rules-touching comment block in parse_keyword_choice_grant lacks the mandatory CR 608.2d annotation.

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.

Comment on lines +3381 to +3385
// Shape 1: "gain your choice of X, Y, or Z" — an explicit keyword-grant menu
// of two OR MORE options (Golem Artisan: "flying, trample, or haste"). Reuse
// the nom-based `split_choice_list_items` splitter (shared with the counter-
// choice and "from among" paths) so an Oxford-comma N-ary list parses without
// manual byte slicing.

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.

medium

According to the repository style guide, every rules-touching line of engine code must carry a comment of the form CR : . Since this block parses the choice of keywords governed by CR 608.2d, please add the appropriate CR annotation to the comment. Additionally, ensure we reuse the robust nom-based parser combinators rather than manual byte slicing or verbatim string matching to parse these Oracle phrases.

Suggested change
// Shape 1: "gain your choice of X, Y, or Z" — an explicit keyword-grant menu
// of two OR MORE options (Golem Artisan: "flying, trample, or haste"). Reuse
// the nom-based `split_choice_list_items` splitter (shared with the counter-
// choice and "from among" paths) so an Oxford-comma N-ary list parses without
// manual byte slicing.
// CR 608.2d: "gain your choice of X, Y, or Z" — an explicit keyword-grant menu
// of two OR MORE options (Golem Artisan: "flying, trample, or haste"). Reuse
// the nom-based split_choice_list_items splitter (shared with the counter-
// choice and "from among" paths) so an Oxford-comma N-ary list parses without
// manual byte slicing.
References
  1. Every rules-touching line of engine code must carry a comment of the form CR : . (link)
  2. Avoid verbatim string equality for parsing Oracle phrases as it bypasses the robust nom-based parser and creates fragile matches. Instead, decompose compound phrases into modular, reusable parsers for constituent parts and compose them using idiomatic combinator aggregates to prevent combinatorial explosion and improve maintainability.

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown

Parse changes introduced by this PR · 15 card(s), 19 signature(s) (baseline: main 5a3e1f51763b)

🟢 Added (7 signatures)

  • 9 cards · ➕ ability/ChooseOneOf · added: ChooseOneOf (duration=until end of turn, kind=activated)
    • Affected (first 3): Assassin Initiate, Butcher of the Horde, Ezrim, Agency Chief (+6 more)
  • 1 card · ➕ ability/ChooseOneOf · added: ChooseOneOf (duration=until end of turn)
    • Affected (first 3): Wingnut, Bat on the Belfry
  • 1 card · ➕ ability/TargetOnly · added: TargetOnly (conditional=when you do, duration=until end of turn, target=you control creature)
    • Affected (first 3): Atraxa's Skitterfang
  • 1 card · ➕ ability/TargetOnly · added: TargetOnly (duration=until end of turn, kind=activated, target=another you control creature, targets=0-1, timing=sorcery speed)
    • Affected (first 3): Gideon Blackblade
  • 1 card · ➕ ability/TargetOnly · added: TargetOnly (duration=until end of turn, kind=activated, target=artifact creature)
    • Affected (first 3): Golem Artisan
  • 1 card · ➕ ability/TargetOnly · added: TargetOnly (duration=until end of turn, target=you control creature)
    • Affected (first 3): Steel Seraph
  • 1 card · ➕ ability/TargetOnly · added: TargetOnly (target=creature)
    • Affected (first 3): Smogbelcher Chariot

🔴 Removed (12 signatures)

  • 3 cards · ➖ ability/grant Lifelink · removed: grant Lifelink (affects=self, duration=until end of turn, grants=grant Lifelink, kind=activated)
    • Affected (first 3): Butcher of the Horde, Ezrim, Agency Chief, Sawtooth Avenger
  • 2 cards · ➖ ability/grant Vigilance · removed: grant Vigilance (affects=self, duration=until end of turn, grants=grant Vigilance, kind=activated)
    • Affected (first 3): Multiform Wonder, Veteran Warleader
  • 1 card · ➖ ability/grant Bushido, grant DoubleStrike, grant Fear, grant Flying, grant FirstStrike,… · removed: grant Bushido, grant DoubleStrike, grant Fear, grant Flying, grant FirstStrike, grant Haste, grant Landwalk, grant Protection, grant Provoke, grant Rampage, gr…
    • Affected (first 3): Greater Morphling
  • 1 card · ➖ ability/grant Deathtouch · removed: grant Deathtouch (affects=parent target, grants=grant Deathtouch, target=creature)
    • Affected (first 3): Smogbelcher Chariot
  • 1 card · ➖ ability/grant Deathtouch · removed: grant Deathtouch (affects=self, duration=until end of turn, grants=grant Deathtouch, kind=activated)
    • Affected (first 3): Assassin Initiate
  • 1 card · ➖ ability/grant FirstStrike · removed: grant FirstStrike (affects=self, duration=until end of turn, grants=grant FirstStrike, kind=activated)
    • Affected (first 3): Lunar Avenger
  • 1 card · ➖ ability/grant Lifelink · removed: grant Lifelink (affects=parent target, duration=until end of turn, grants=grant Lifelink, kind=activated, target=another you control creature, targets=0-1, tim…
    • Affected (first 3): Gideon Blackblade
  • 1 card · ➖ ability/grant Menace · removed: grant Menace (affects=self, duration=until end of turn, grants=grant Menace)
    • Affected (first 3): Wingnut, Bat on the Belfry
  • 1 card · ➖ ability/grant Trample · removed: grant Trample (affects=parent target, duration=until end of turn, grants=grant Trample, kind=activated, target=artifact creature)
    • Affected (first 3): Golem Artisan
  • 1 card · ➖ ability/grant Trample · removed: grant Trample (affects=self, duration=until end of turn, grants=grant Trample, kind=activated)
    • Affected (first 3): Shifting Ceratops
  • 1 card · ➖ ability/grant Vigilance · removed: grant Vigilance (affects=parent target, duration=until end of turn, grants=grant Vigilance, target=you control creature)
    • Affected (first 3): Steel Seraph
  • 1 card · ➖ ability/grant Vigilance, grant Deathtouch · removed: grant Vigilance, grant Deathtouch (affects=parent target, conditional=when you do, duration=until end of turn, grants=grant Deathtouch, grants=grant Vigilance,…
    • Affected (first 3): Atraxa's Skitterfang

@matthewevans matthewevans self-assigned this Jul 19, 2026
@matthewevans

Copy link
Copy Markdown
Member

Maintainer update — nested keyword choices now remain honestly unsupported; fresh CI is pending.

The original N-ary menu handling is correct for fixed keyword options such as Golem Artisan and Assassin Initiate. However, the current parse-diff also included Greater Morphling, whose Oracle text has nested selections: landwalk of your choice and protection from a color of your choice.

I pushed 4d5d75faddc51b0b57d575c8c9e8c4b37c43591b to keep this distinct case out of the fixed-keyword ChooseOneOf path. The parser now reports that shape as a strict unsupported result before generic static parsing can turn it into fixed or simultaneous grants, and the regression asserts the full parse is Effect::Unimplemented. This also adds the verified CR 608.2d annotation requested in the existing review.

No approval yet: the new head needs the required checks and an updated parse-diff artifact. Once green, the fixed-option N-ary class can be re-reviewed without claiming unsupported nested choices.

@matthewevans matthewevans added the enhancement New feature or request label Jul 19, 2026
@matthewevans

Copy link
Copy Markdown
Member

Maintainer CI repair — fresh checks running.

GitHub CI identified two compile errors in the previous maintainer follow-up: both let-else bindings were destructuring an Option as a tuple. I pushed a5520c696f9db568a6d59ef1b38564239e362bf2, which matches Some(...) at both parser-result sites and preserves the existing NoMatch fallback. An independent source pass confirmed this is a compile-only correction with no behavior change.

Fresh required CI and the parse-diff artifact are now pending; this PR remains unapproved until they complete successfully.

@matthewevans

Copy link
Copy Markdown
Member

Maintainer CI follow-up: the replacement run exposed that the new coverage-honesty test in oracle_effect/tests.rs could not access the helper and enum in subject.rs (E0425/E0433). I made only that test seam pub(super) in 79dd643, so the test can compile without widening it beyond the parent parser module. Formatting plus the repository pre-commit parser gates passed locally; a fresh CI run is now required before approval.

@matthewevans

Copy link
Copy Markdown
Member

Maintainer CI follow-up: the prior test-only visibility repair exposed two linked issues — the test module is a sibling of subject, so super::… cannot name that helper, and exporting the enum made Clippy reject its large variant. I replaced that internal enum with the existing lightweight Result<Option<…>, ()> tri-state at 4aceb045, removed only the inaccessible duplicate assertion, and kept the end-to-end honest-unsupported regression. The repository parser gates passed; a fresh CI run is required before approval.

@matthewevans

Copy link
Copy Markdown
Member

Maintainer CI repair — strict nested choices now stop before generic fallback.

The previous strict-failure plumbing still returned None to the subject parser, which then reached the imperative fallback and reinterpreted Greater Morphling's nested menu as fixed Landwalk("of your choice"). I pushed 230bc161aa: the private Result<Option<_>, ()> outcome now reaches the subject-predicate AST, where the nested-choice case is emitted through Effect::unimplemented before any fallback.

Evidence: the failing current-head CI assertion in nary_keyword_choice_grant_defers_nested_choice_keywords; the fixed source boundary is subject.rs's try_parse_subject_predicate_ast. The existing N-ary fixed-keyword paths remain unchanged. Parser gates and an independent adversarial source review passed. Fresh GitHub CI and a current parse-diff are required before any approval.

@matthewevans

Copy link
Copy Markdown
Member

Maintainer status — processed current head 230bc161aa; held for CI.

The strict-fallback repair is now the PR head. The nested-choice regression is intentionally preserved as unsupported, parser gates plus independent adversarial source review passed, and the required GitHub run is still pending. No approval or queue action will occur until that run and its refreshed parse-diff complete.

@matthewevans

Copy link
Copy Markdown
Member

Maintainer CI repair — fixed the current Rust-lint failure; fresh CI required.

GitHub's Rust-lint job failed only on clippy::type_complexity for parse_keyword_choice_grant's Result<Option<(Vec<Keyword>, Option<Duration>)>, ()> return type (subject.rs:3404). I pushed c76206996e, a private KeywordChoiceGrant alias that preserves the exact three-state parser contract and strict nested-choice behavior. Parser gates passed; no direct build was run. This PR remains held until fresh required CI and the updated parse-diff complete.

@matthewevans

Copy link
Copy Markdown
Member

Maintainer fixup on current head 066184a3d0abaa426d8c33c1200bf0da820bd59b:

  • threaded the nested-choice error through the pump-compound helper instead of collapsing it to generic fallback;
  • added a regression for the pump + nested-choice form, which now reaches the existing Effect::Unimplemented boundary; and
  • added the paired fixed-keyword pump assertion to preserve the supported ChooseOneOf path.

cargo fmt and the repository parser gates passed locally; no direct build or test command was run. The previous parse-diff comment is stale (09:16 UTC, before prior head c76206996e at 10:57 UTC), and this new head needs fresh CI plus a current parse-diff before any approval or merge-queue action. The PR remains held.

@matthewevans

Copy link
Copy Markdown
Member

Maintainer follow-up on current head 031e7bef24ca92a29508ab6c3f4a48757da754ef:

  • normalized the strict unsupported category from prose to the stable coverage key nested_keyword_choice;
  • strengthened both nested-choice regressions, including the pump path, to assert that exact key.

cargo fmt and the repository parser gates passed locally; no direct build or test command was run. This new head still requires fresh CI and a current parse-diff artifact, so the PR remains held with no approval or merge-queue action.

@matthewevans

Copy link
Copy Markdown
Member

Reprocessed current head 031e7bef24ca92a29508ab6c3f4a48757da754ef after green CI.

This PR remains held, not approved or enqueued: the required <!-- coverage-parse-diff --> artifact is stale. Its only body was posted at 09:16 UTC and still reports the old 15-card / 20-signature shape (baseline 11cc01581edc), so it cannot evidence the current strict nested_keyword_choice behavior or the current head. The dashboard timestamp alone is not sufficient because it is not tied to a new sticky body.

Please publish a parse-diff generated for this exact head, then this evidence gate can be re-run.

@matthewevans matthewevans removed their assignment Jul 19, 2026
Fixes phase-rs#5992.

Golem Artisan's second ability ("Target artifact creature gains your
choice of flying, trample, or haste until end of turn.") is a 3-way
Oxford-comma keyword choice. parse_keyword_choice_grant only handled a
binary "X or Y" split via split_once_on(text, " or "), so the 3-way
list split into "flying, trample," / "haste" -- the left half failed
parse_granted_keyword_fragment and the whole clause fell through to
Unimplemented.

Also corrects the issue's own paraphrase: the real card has no "you
control" restriction on its target (any artifact creature is a legal
target), verified against Scryfall.

parse_keyword_choice_grant now reuses the existing nom-based N-ary
Oxford-comma splitter (split_choice_list_items, already shared by the
counter-choice and "from among" paths) instead of a binary
split_once_on, and returns Vec<Keyword> instead of a fixed pair. Its
two callers (build_keyword_choice_clause,
build_keyword_choice_sub_ability) build branches via
.into_iter().map(...).collect() instead of a hardcoded 2-element vec.
The sibling protection-choice shape ("protection from X or from the
color of your choice") keeps its existing binary logic unchanged, just
adapted to the new Vec-based return type.

Effect::ChooseOneOf's runtime (choose_one_of.rs, GameAction::ChooseBranch)
already takes Vec<AbilityDefinition> generically with no arity
assumption, confirmed by grepping every ChooseOneOf reference in the
crate -- this is a parser-only fix.

- New parser tests: Golem Artisan's verbatim 3-way clause (asserts 3
  branches + a positive `target.controller == None` check), plus
  Assassin Initiate's verbatim 3-way clause to prove the fix
  generalizes beyond the one reported card. Existing 2-way test kept
  unchanged as a regression guard.
- New end-to-end integration tests
  (issue_5992_golem_artisan.rs) drive the real activation pipeline:
  GameRunner::activate(...).resolve() halts at the real
  ChooseOneOfBranch prompt (3 branches), GameAction::ChooseBranch picks
  Trample, evaluate_layers confirms the keyword actually lands (and the
  other two do not). A second test targets an OPPONENT-controlled
  artifact creature to prove the no-"you control" correction holds
  through the real targeting-legality pipeline, not just the parsed
  AST.
- Verification (CARGO_TARGET_DIR isolated): cargo fmt --check clean,
  cargo clippy -p engine --all-targets --features test-support -- -D
  warnings clean, full cargo test -p engine --test integration
  --features test-support: 3544 passed, 0 failed, 2 ignored.

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

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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: be88048f-3896-4e50-ba73-a97c4386b789

📥 Commits

Reviewing files that changed from the base of the PR and between 53d70d4 and d464c89.

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

📝 Walkthrough

Walkthrough

Changes

N-ary keyword choice support

Layer / File(s) Summary
Generalize keyword-choice parsing
crates/engine/src/parser/oracle_effect/subject.rs
Keyword-grant parsing now returns all parsed options and constructs one ChooseOneOf branch per keyword, including Oxford-comma lists with at least two items.
Validate parser expansion
crates/engine/src/parser/oracle_effect/tests.rs
Parser tests cover three-branch target-specific and generic keyword grants, including duration and controller behavior.
Exercise runtime branch resolution
crates/engine/tests/integration/issue_5992_golem_artisan.rs, crates/engine/tests/integration/main.rs
Integration tests activate Golem Artisan, select keyword branches, settle resolution, and verify effects on self-owned and opponent-owned artifact creatures.

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

Suggested labels: bug

Suggested reviewers: matthewevans

Sequence Diagram(s)

sequenceDiagram
  participant GolemArtisan
  participant ChooseOneOfBranch
  participant GameEngine
  participant evaluate_layers
  GolemArtisan->>GameEngine: activate keyword-choice ability
  GameEngine-->>ChooseOneOfBranch: present three keyword branches
  ChooseOneOfBranch->>GameEngine: select requested keyword
  GameEngine->>evaluate_layers: settle resolution and evaluate layers
  evaluate_layers-->>GolemArtisan: apply selected keyword to target
Loading
🚥 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 matches the main parser change: supporting N-ary "your choice of" keyword-grant lists.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

🧹 Nitpick comments (1)
crates/engine/tests/integration/issue_5992_golem_artisan.rs (1)

97-107: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Loop exits silently without asserting full resolution.

If 16 passes never drain the stack/deferred_triggers, the loop just ends and evaluate_layers runs anyway — the keyword assertions still pass because resolve_branch applies the continuous effect synchronously before this loop starts. A future regression that causes the stack to hang would go undetected by this test.

♻️ Proposed fix: assert convergence
-    for _ in 0..16 {
+    for i in 0..16 {
         match &runner.state().waiting_for {
             WaitingFor::Priority { .. } => {
                 if runner.state().stack.is_empty() && runner.state().deferred_triggers.is_empty() {
-                    break;
+                    evaluate_layers(runner.state_mut());
+                    return;
                 }
                 runner.pass_both_players();
             }
             other => panic!("unexpected waiting state after choosing the branch: {other:?}"),
         }
+        if i == 15 {
+            panic!("stack/deferred_triggers did not settle within 16 priority passes");
+        }
     }
-
-    evaluate_layers(runner.state_mut());
🤖 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/tests/integration/issue_5992_golem_artisan.rs` around lines 97
- 107, Update the bounded loop after branch selection to assert that resolution
has converged after all 16 passes, requiring both runner.state().stack and
runner.state().deferred_triggers to be empty before evaluate_layers proceeds.
Preserve the existing early break when both are already empty and retain the
unexpected WaitingFor panic.

Source: Path instructions

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

Nitpick comments:
In `@crates/engine/tests/integration/issue_5992_golem_artisan.rs`:
- Around line 97-107: Update the bounded loop after branch selection to assert
that resolution has converged after all 16 passes, requiring both
runner.state().stack and runner.state().deferred_triggers to be empty before
evaluate_layers proceeds. Preserve the existing early break when both are
already empty and retain the unexpected WaitingFor panic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 73b8617a-3f29-45ae-b3fb-f3fa148faa97

📥 Commits

Reviewing files that changed from the base of the PR and between 6fc7356 and 53d70d4.

📒 Files selected for processing (4)
  • crates/engine/src/parser/oracle_effect/subject.rs
  • crates/engine/src/parser/oracle_effect/tests.rs
  • crates/engine/tests/integration/issue_5992_golem_artisan.rs
  • crates/engine/tests/integration/main.rs

@matthewevans matthewevans self-assigned this Jul 22, 2026
@matthewevans

Copy link
Copy Markdown
Member

Maintainer test hardening is now on the current head d464c89554: the bounded priority loop in the Golem Artisan integration test now fails if stack/deferred triggers do not settle, rather than evaluating layers after a silent timeout.

The required GitHub CI checks and CodeRabbit review have restarted for this head. The existing <!-- coverage-parse-diff --> artifact predates the push, so approval and merge-queue action remain held until both the checks and a current-head parse-diff complete.

@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: the N-ary fixed-keyword choice reuses the existing list splitter, preserves nested choices as unsupported, and has discriminating runtime coverage.

@matthewevans
matthewevans added this pull request to the merge queue Jul 22, 2026
@matthewevans matthewevans removed their assignment Jul 22, 2026
Merged via the queue into phase-rs:main with commit 76b0864 Jul 22, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Golem artisan — The ability that allows you to give the 2nd capacity, for example, Celerity is malfunctioning.

2 participants