Fix Lictor#7
Open
keloide wants to merge 13 commits into
Open
Conversation
* fix(desktop): show native engine provisioning status * fix(release): recover main bundle and clarify desktop downloads --------- Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
Lictor's Pheromone Trail — "When this creature enters, if a creature
entered the battlefield under an opponent's control this turn, create a
3/3 green Tyranid Warrior creature token with trample" — dropped its
intervening-"if" condition (parsed to None), so the ETB trigger fired
unconditionally and the token was created every time Lictor entered.
The "under your control" surface of this class was already supported;
this adds the opponent-scoped, past-tense mirror. A new
`parse_entered_this_turn_under_opponent_control` combinator reuses the
shared `parse_or_more_entered_count` / `parse_entered_this_turn_subject`
helpers and carries the scope via `PlayerScope::Opponent { Max }` — the
existential "an opponent" reading already documented on
`parse_opponent_had_entered_this_turn` — over the CR 608.2i
`BattlefieldEntriesThisTurn` snapshot. No new engine variant.
The opponent surface in the QUANTITY path stays honestly Unimplemented
(no printed card); only the condition path, which Lictor uses, is added.
Adds parser unit tests (singular + count forms) and a discriminating
runtime test that casts Lictor and asserts the token is gated on an
opponent's entry (fails on revert). Removes Lictor from the parser
misparse backlog.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gw63XPowSxhpJaS9xM8Xyj
Parse changes introduced by this PR · 1 card(s), 1 signature(s) (baseline: main
|
* fix(ui): surface roll outcomes and turn order * fix(ui): address roll overlay review feedback * test(ui): isolate draft match provider state * fix(tauri): synchronize release lockfile version * fix(ci): attach migration bridge before release publish --------- Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
* fix(client): respect legal Adventure cast faces * fix(client): preserve waiting factory variant types * fix(client): retain concrete waiting factories --------- Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
* fix(ci): scope preview server secrets * fix(desktop): replay native engine progress --------- Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
phase-rs#6558) Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
…hange hub) (phase-rs#6560) Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
The three shape assertions matched `PlayerScope::Opponent { .. }`, which
also admits `AggregateFunction::Sum` — precisely the cross-opponent
summation the combinator's doc comment identifies as wrong and that is
only observable at three or more seats. Every test the PR adds would
still have passed if the parser were later changed to emit `Sum`.
Tighten all three sites to `{ aggregate: AggregateFunction::Max }` so the
existential "an opponent" reading is actually pinned by the test suite.
Co-authored-by: keloide <75585494+keloide@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the dropped intervening-"if" misparse for Lictor (Warhammer 40,000
Commander). Its Pheromone Trail — "When this creature enters, if a creature
entered the battlefield under an opponent's control this turn, create a 3/3
green Tyranid Warrior creature token with trample" — parsed with
condition: null, so the ETB trigger fired unconditionally and Lictor made a token everytime it entered, even with no opponent entry that turn.
The "under your control" surface of this class was already supported (13
cards); this adds the opponent-scoped, past-tense mirror. A new
parse_entered_this_turn_under_opponent_controlcombinator reuses the sharedparse_or_more_entered_count/parse_entered_this_turn_subjecthelpers andcarries the scope via
PlayerScope::Opponent { aggregate: Max }— theexistential "an opponent" reading already documented on
parse_opponent_had_entered_this_turn— over the CR 608.2iBattlefieldEntriesThisTurnsnapshot. No new engine variant.The opponent surface in the quantity path stays honestly
Unimplemented(no printed card uses it there — locked by
bbfu10_opponent_entry_surface_stays_unimplemented);only the condition path, which Lictor uses, is added. Removes Lictor from
docs/parser-misparse-backlog.md(root cause #2) and decrements its counts.Misparse fix (§3.1): "Fixes the dropped intervening-if for Lictor"; backlog
entry removed (root cause #2 count 591 → 590).
Files changed
crates/engine/src/parser/oracle_nom/condition.rscrates/engine/tests/integration/lictor_opponent_entered_this_turn.rscrates/engine/tests/integration/main.rsdocs/parser-misparse-backlog.mdImplementation method (required)
Method: not-applicable — implemented and reviewed inline by the driving
Frontier-tier LLM (plan → nom-combinator implementation →
/review-impl[clean] → verify → commit), per the
oracle-parser/add-engine-variantskill checklists. The change is a self-contained additive parser arm reusing
existing helpers with no new engine variant, so the
/engine-implementerplan→review→implement→review→commit contract was executed directly rather than
via spawned subagents.
CR references
trigger time and again on resolution)
Track
Developer
LLM
Model: claude-opus-4-8
Thinking: high
Tier: Frontier
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.
cargo fmt --all— clean (exit 0)cargo clippy-strict(clippy --all-targets -- -D warnings) — Finished, 0 warnings (exit 0)cargo test -p engine --lib entered_this_turn_under_opponent— 2 passed (new parser unit tests: singular + count)cargo test -p engine --test integration lictor_opponent_entered— 3 passed (shape-lock + positive + negative runtime)cargo test -p engine --test integration bbfu10— 17 passed (incl.bbfu10_opponent_entry_surface_stays_unimplemented— the quantity-path opponent lock stays intact)cargo test -p engine --lib parser::oracle_nom::condition— 412 passed (no regression in the touched module)Revert-probe — disabling the dispatch arm makes
lictor_makes_no_token_without_opponent_entryFAIL (1 token), proving the runtime test drives the real pipeline and is discriminatingcargo semantic-audit— Lictor no longer flagged; cards-with-findings 285 → 284; DroppedCondition 65 → 64; no new findings introducedcargo coverage— exit 0;supported_cards: 31528; Lictor remains supported with its intervening-if now populated (it was alreadysupported: true, so the count is unchanged)Gate A
Gate A PASS head=3d7672511ca1c7a8ff566677759d2ec2e8c4a663 base=c754a087a28ce6cabb46ea5c8fa6bfa095e79008
Anchored on
parse_opponent_had_entered_this_turn: the opponent-scoped sibling that carriesPlayerScope::Opponent { aggregate: Max }over the sameparse_or_more_entered_count/parse_entered_this_turn_subjecthelpers (same combinator family, same scope idiom).parse_entered_this_turn: the "under your control" sibling that delegates the count/subject surfaces to the identical shared helpers (the class this fix mirrors for the opponent scope).Final review-impl
Final review-impl PASS head=3d7672511ca1c7a8ff566677759d2ec2e8c4a663
Claimed parse impact
Generated by Claude Code