feat(parser): parameterize superlative-property aggregate direction (least/lowest/smallest → Min)#5698
Conversation
…(greatest→Max, least/lowest/smallest→Min)
There was a problem hiding this comment.
Code Review
This pull request extends the superlative property suffix parser to support minimum superlatives ("least", "lowest", "smallest") mapping to AggregateFunction::Min, alongside the existing maximum superlatives, and adds comprehensive unit tests. The review feedback correctly identifies a violation of Rule R6 regarding a hallucinated Comprehensive Rules (CR) citation in the test comments, where CR 701.21 (drawing a card) was cited instead of CR 701.16 (sacrifice).
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.
Parse changes introduced by this PR · 3 card(s), 3 signature(s) (baseline: main
|
matthewevans
left a comment
There was a problem hiding this comment.
Verified the parameterized Min/Max superlative parser, current three-card parse diff, and current CI; Gemini’s CR finding is refuted by docs/MagicCompRules.txt (701.21 is Sacrifice).
Summary
Parameterizes the superlative-property suffix combinator in
parse_superlative_property_suffixso the aggregate direction is a singlealt:greatest/highest/most→AggregateFunction::Max(existing), andleast/lowest/smallest→AggregateFunction::Min(new). Both directions feed the same genericsuperlative_property_filter_prop, so this closes the entireleast/lowest/smallestsuperlative-selection class — over power, toughness, and mana value — across every card that uses the "with the <superlative> <property> among <set>" shape.No new engine variant. The runtime already ships
AggregateFunction::Min(used byvalues.min()ingame/quantity.rs); previously only theMaxhead was reachable from the parser, soMinselection was a pure parser gap. The Sacrifice/Destroy/return resolvers consume the resultingPtComparison/Cmcfilter prop unchanged.Concretely, The Dining Car's upkeep clause "sacrifice a creature with the least toughness among creatures you control" now parses to a
Sacrificewhose target carries a tie-inclusive (Comparator::EQ)PtComparisonon toughness bound toAggregate { function: Min, property: Toughness, filter: creatures you control }— i.e. it selects the least-toughness creature, as the Oracle text specifies.This was split out of #5651 at matt's request ("GAP A is clean; if you split GAP A out, I'd take it as-is"). GAP B from that branch never touched
oracle_target.rsand is not included here — this PR is superlative-direction-only.Tier: Standard
Files changed
crates/engine/src/parser/oracle_target.rsCR references
CR 208.1— power and toughness (superlative selection over power/toughness)CR 202.3— mana value (superlative selection over mana value)CR 701.21— Sacrifice (The Dining Car's upkeep least-toughness sacrifice)Implementation method (required)
Method: not-applicable — single-combinator parameterization split verbatim out of the already-reviewed #5651 branch (matt approved GAP A as-is); reuses an existing runtime
AggregateFunctionwith no new engine variant.Track
Developer
LLM
Model: claude-opus-4-8
Thinking: high
Verification
Required checks ran clean, or the exact CI-owned alternative is stated below.
Gate A output below is for the current committed head.
cargo fmt --all— clean./scripts/check-parser-combinators.sh <merge-base>— Gate A PASS (see below)cargo clippy -p engine -p phase-ai -p engine-wasm --all-targets -- -D warnings— clean (exit 0, no warnings)cargo test -p engine -p phase-ai— all pass; new testssuperlative_direction_maps_word_to_aggregate_functionandsuperlative_least_toughness_suffix_emits_min_aggregate_pt_comparisongreencargo run --profile tool --features cli --bin oracle-gen -- data --filter "the dining car|goblin ringleader"— The Dining Car upkeep clause emitsSacrifice+Aggregate { function: Min, property: Toughness, filter: creatures you control },Comparator::EQ; 0 Unimplemented/Unknown on the fixed clause; Goblin Ringleader fully clean; no regressionGate A
Gate A PASS head=de39411921ca8a62a5daddec8274100bffced85a base=302fab2fee76251c4ed835dfd8bc20fd3e02ee8a
Anchored on
crates/engine/src/parser/oracle_target.rs:4658— the pre-existingvalue(AggregateFunction::Max, alt((tag("greatest "), tag("highest "))))head this change lifts into analtof twovalue(function, alt(...))branches (PATTERNS.md §8b cross-product factoring)crates/engine/src/parser/oracle_target.rs:4670— the sibling propertyalt(Power/Toughness/ManaValue) that already parameterizes the second axis of this combinator, the pattern the direction axis now mirrorsClaimed parse impact
Validation Failures
None.
CI Failures
None.