Skip to content

fix(ai): choose issued flexible mana products - #7057

Merged
matthewevans merged 4 commits into
mainfrom
ship/choose-issued-flexible-mana-products
Aug 6, 2026
Merged

fix(ai): choose issued flexible mana products#7057
matthewevans merged 4 commits into
mainfrom
ship/choose-issued-flexible-mana-products

Conversation

@matthewevans

@matthewevans matthewevans commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Bug Fixes

    • Improved AI mana-color choices to honor only valid available options.
    • Added safer fallback behavior when preferred combinations are unavailable.
    • Corrected decision-making so choices are evaluated for the appropriate player.
    • Fixed progression after restoring a saved game during a mana-choice prompt.
  • Tests

    • Added coverage for bounded mana choices, player-specific decision contexts, restored game states, and continued play after resolving a prompt.

@matthewevans
matthewevans enabled auto-merge August 6, 2026 09:07
@coderabbitai

coderabbitai Bot commented Aug 6, 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: 34 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: e2f3327b-d5fa-4f48-8beb-52c672d91e6c

📥 Commits

Reviewing files that changed from the base of the PR and between 84a4d01 and 017e1d0.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • crates/phase-ai/fixtures/scenarios/invisible-woman-cosmic-crucible-mana.json.gz is excluded by !**/*.gz
📒 Files selected for processing (3)
  • crates/phase-ai/Cargo.toml
  • crates/phase-ai/src/search.rs
  • crates/phase-ai/tests/scenarios.rs
📝 Walkthrough

Walkthrough

Mana-color AI decisions now honor engine-issued action domains and semantic-owner scoping. Tests cover capped fallback, owner-specific scoring, and restoration of a compressed saved-state mana prompt.

Changes

Mana choice domain enforcement

Layer / File(s) Summary
Issued mana selection
crates/phase-ai/src/search.rs
Mana-choice resolution receives issued actions, validates preferred combinations, ranks issued alternatives, and passes action domains through deterministic selection.
Owner-scoped scoring
crates/phase-ai/src/search.rs
Scoring uses issued candidates and decision contexts for the requested semantic owner.
Regression coverage and fixtures
crates/phase-ai/src/search.rs, crates/phase-ai/tests/scenarios.rs, crates/phase-ai/Cargo.toml
Tests cover issued domains, capped fallback, owner scoping, and restored gzip-compressed mana prompts. The test dependency includes flate2.

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

Sequence Diagram(s)

sequenceDiagram
  participant AI Search
  participant AiDecisionContract
  participant Mana Choice Resolver
  AI Search->>AiDecisionContract: Request issued actions for semantic owner
  AiDecisionContract-->>AI Search: Return bounded action domain
  AI Search->>Mana Choice Resolver: Evaluate preferred mana choice
  Mana Choice Resolver->>AiDecisionContract: Validate choice against issued domain
  AiDecisionContract-->>Mana Choice Resolver: Accept or reject candidate
  Mana Choice Resolver-->>AI Search: Return valid or ranked issued choice
Loading

Possibly related PRs

  • phase-rs/phase#6785: Both changes modify mana-payment candidate validation, fallback, and scoring in crates/phase-ai/src/search.rs.
  • phase-rs/phase#6829: Both changes constrain AI action selection to engine-issued candidate domains.
  • phase-rs/phase#6973: Both changes use engine-issued action domains for mana-choice fallback and ranking.

Suggested reviewers: lgray, ntindle, claytonlin1110

🚥 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 and concisely describes the main change: selecting issued flexible mana products in AI decision-making.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ship/choose-issued-flexible-mana-products

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.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/phase-ai/src/search.rs (1)

2353-2421: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Keep resolving-effect mana preferences when no issued ChooseManaColor exists.

quiesce() passes the quiesce candidates as &actions, and deterministic_choice() routes resolve resolving-effect ChooseManaColor only from the passed slice. When that slice contains no ChooseManaColor, resolving_effect_mana_choice now returns None; return the preferred calculation when no matching issued option is supplied.

🤖 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/phase-ai/src/search.rs` around lines 2353 - 2421, Update
resolving_effect_mana_choice so it returns the computed preferred action when
issued_actions contains no matching ChooseManaColor, rather than falling through
to None. Preserve the existing matching-issued-action preference and fallback
behavior when issued choices are available.
🧹 Nitpick comments (3)
crates/phase-ai/src/search.rs (3)

6689-6696: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Reuse build_decision_context_for_semantic_owner in the test helper.

issued_actions re-derives the owner's action domain from AiDecisionContract::issue. Production derives the same list through build_decision_context_for_semantic_owner at Line 2867. If that production derivation ever adds filtering, the helper silently diverges and the tests stop covering the real domain.

♻️ Proposed helper change
     fn issued_actions(state: &GameState, owner: PlayerId) -> Vec<GameAction> {
-        AiDecisionContract::issue(state, owner)
+        build_decision_context_for_semantic_owner(state, owner)
             .candidates
             .into_iter()
             .map(|candidate| candidate.action)
             .collect()
     }
🤖 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/phase-ai/src/search.rs` around lines 6689 - 6696, The test helper
issued_actions should reuse build_decision_context_for_semantic_owner instead of
calling AiDecisionContract::issue directly, then extract and collect the
resulting candidate actions while preserving the owner-specific action domain
used by production.

Source: Coding guidelines


6890-6906: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Neither new capped-domain test pins the selected mana product. Both tests assert only that the answer is inside the engine-issued domain. Neither states which of the 64 products the AI must choose, so both pass for a demand-blind allocation and neither would detect a change in the engine's candidate ordering.

  • crates/phase-ai/src/search.rs#L6890-L6906: replace the issued.first()-derived expected with the literal ManaChoice::Combination the four-green demand must produce.
  • crates/phase-ai/tests/scenarios.rs#L101-L117: add an assertion on run[0].action naming the expected ManaChoice::Combination for this capture's color demand.
🤖 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/phase-ai/src/search.rs` around lines 6890 - 6906, Pin both
capped-domain tests to the expected mana product instead of deriving it from
issued_actions: in crates/phase-ai/src/search.rs lines 6890-6906, replace the
issued.first()-derived expected value with the literal ManaChoice::Combination
required for the four-green demand; in crates/phase-ai/tests/scenarios.rs lines
101-117, assert run[0].action equals the expected ManaChoice::Combination for
that capture’s color demand.

2860-2887: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Hoist the owner-scoped decision context.

score_candidates_core builds build_decision_context_for_semantic_owner(state, ai_player) in the mana branch, then builds the same context again later when the earlier early-exit branches miss. Since AiDecisionContract::issue enumerates candidates and sorts them, the mana-miss path pays for two identical enumerations. Build the context once above the early branches and reuse it.

🤖 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/phase-ai/src/search.rs` around lines 2860 - 2887, In
score_candidates_core, build build_decision_context_for_semantic_owner(state,
ai_player) once before the resolving-effect mana-choice branch, then reuse that
context when collecting issued_actions and in the later scored path. Remove the
duplicate context construction while preserving the existing candidate
enumeration and early-return behavior.
🤖 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/phase-ai/src/search.rs`:
- Around line 2403-2421: Update the fallback in the preferred-action selection
to rank all issued ChooseManaColor actions by demand instead of taking the first
stable match. Add issued_mana_rank beside mana_product_rank, handling
SingleColor and Combination choices and returning i32::MIN for other actions,
then select the maximum-ranked issued action while preserving the issued-domain
constraint. Adjust mana_product_rank parameter types to use this module’s
existing ColorDemand types.

---

Outside diff comments:
In `@crates/phase-ai/src/search.rs`:
- Around line 2353-2421: Update resolving_effect_mana_choice so it returns the
computed preferred action when issued_actions contains no matching
ChooseManaColor, rather than falling through to None. Preserve the existing
matching-issued-action preference and fallback behavior when issued choices are
available.

---

Nitpick comments:
In `@crates/phase-ai/src/search.rs`:
- Around line 6689-6696: The test helper issued_actions should reuse
build_decision_context_for_semantic_owner instead of calling
AiDecisionContract::issue directly, then extract and collect the resulting
candidate actions while preserving the owner-specific action domain used by
production.
- Around line 6890-6906: Pin both capped-domain tests to the expected mana
product instead of deriving it from issued_actions: in
crates/phase-ai/src/search.rs lines 6890-6906, replace the
issued.first()-derived expected value with the literal ManaChoice::Combination
required for the four-green demand; in crates/phase-ai/tests/scenarios.rs lines
101-117, assert run[0].action equals the expected ManaChoice::Combination for
that capture’s color demand.
- Around line 2860-2887: In score_candidates_core, build
build_decision_context_for_semantic_owner(state, ai_player) once before the
resolving-effect mana-choice branch, then reuse that context when collecting
issued_actions and in the later scored path. Remove the duplicate context
construction while preserving the existing candidate enumeration and
early-return behavior.
🪄 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: cbeac124-d22a-4271-965a-cd0ab582c9c7

📥 Commits

Reviewing files that changed from the base of the PR and between 1c3edb7 and 7335801.

⛔ Files ignored due to path filters (1)
  • crates/phase-ai/fixtures/scenarios/invisible-woman-cosmic-crucible-mana.json.gz is excluded by !**/*.gz
📒 Files selected for processing (3)
  • crates/phase-ai/Cargo.toml
  • crates/phase-ai/src/search.rs
  • crates/phase-ai/tests/scenarios.rs

Comment thread crates/phase-ai/src/search.rs Outdated
@matthewevans
matthewevans force-pushed the ship/choose-issued-flexible-mana-products branch from 8992a42 to 50a574f Compare August 6, 2026 14:10
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Generated for head 017e1d099ef164e3ca41fdcefc1784d268a28808.

Parse changes introduced by this PR

✓ No card-parse changes detected.

@matthewevans
matthewevans added this pull request to the merge queue Aug 6, 2026
Merged via the queue into main with commit 8c6e1d1 Aug 6, 2026
17 checks passed
@matthewevans
matthewevans deleted the ship/choose-issued-flexible-mana-products branch August 6, 2026 15:06
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