Summary
You get a one-time boon with "<ability>" is not recognized anywhere in the parser, so the entire boon sentence — quote characters and all — is fed to the counter-clause grammar. On two cards the result is a CounterType::Generic whose name is a complete English sentence.
grep -rn "one-time boon\|boon" crates/engine/src/parser/ returns nothing; there is no boon handling at all.
Reproduction
Parse each card's full Oracle text through parse_oracle_text:
CARD March Toward Perfection: abilities=1 triggers=0 replacements=1
repl[0] counter_type = "\"when you cast a phyrexian creature spell,
that creature enters with an additional +1/+1"
CARD Arcane Archery: abilities=1 triggers=0 replacements=1 (same shape)
CARD Tenacious Pup: abilities=0 triggers=1 replacements=0
Affected cards (the full printed class, from a corpus sweep over every enters/enter with … counter line):
- March Toward Perfection —
You get a one-time boon with "When you cast a Phyrexian creature spell, that creature enters with an additional +1/+1 counter and deathtouch counter on it."
- Arcane Archery —
… "When you cast a creature spell, that creature enters with an additional +1/+1 counter, reach counter, and trample counter on it."
- Tenacious Pup —
… "When you cast a creature spell, that creature enters the battlefield with an additional +1/+1 counter, trample counter, and vigilance counter on it."
Mechanism
- The boon line's trigger prefix is inside a quoted grant, so
has_trigger_prefix(&lower) is false at the head of the line. The Priority 5-pre interceptor (crates/engine/src/parser/oracle.rs:5226) never fires, and parse_whenever_you_cast_enters_with_trigger is never reached — hence triggers=0.
- The line falls through to the generic object-hosted replacement path,
parse_enters_with_counters.
strip_after(work_text, "with ") matches the boon's own boon with , not the counter clause's with . The counter grammar receives text beginning with a " character.
- The conjoined-list reader correctly rejects that, and the single-counter fallback's unbounded
take_until(" counter") consumes everything up to the first counter as the counter type, producing the Generic above.
Impact
A counter type that is an English sentence is meaningless at runtime — it matches no counter the engine can place, remove, or query, and it is not the counter the card prints. This is worse than a dropped counter: the ability appears "supported" while placing a phantom counter type. It also means enters with counter riders on all three cards are entirely non-functional.
Note that Tenacious Pup fails differently (routed to a trigger, no replacement at all), so a fix needs to cover both shapes.
Suggested fix
Strip the You get a one-time boon with "<ability>" wrapper and parse the quoted text as a granted ability, the way other quoted-ability grants are handled — rather than widening the counter grammar, which is downstream of the real problem. Loch Larent prints the same wrapper (crates/engine/src/parser/oracle_tests.rs:10023) and is worth checking as part of the same class.
Not a regression
Pre-existing on main. Confirmed by the CI parse diff on #7490, which reports ✓ No card-parse changes detected — these cards parse identically with and without that PR's counter-grammar changes. Found while investigating #7490; that PR's elided-count grammar is correct but unreachable for these cards until this wrapper is handled.
Summary
You get a one-time boon with "<ability>"is not recognized anywhere in the parser, so the entire boon sentence — quote characters and all — is fed to the counter-clause grammar. On two cards the result is aCounterType::Genericwhose name is a complete English sentence.grep -rn "one-time boon\|boon" crates/engine/src/parser/returns nothing; there is no boon handling at all.Reproduction
Parse each card's full Oracle text through
parse_oracle_text:Affected cards (the full printed class, from a corpus sweep over every
enters/enter with … counterline):You get a one-time boon with "When you cast a Phyrexian creature spell, that creature enters with an additional +1/+1 counter and deathtouch counter on it."… "When you cast a creature spell, that creature enters with an additional +1/+1 counter, reach counter, and trample counter on it."… "When you cast a creature spell, that creature enters the battlefield with an additional +1/+1 counter, trample counter, and vigilance counter on it."Mechanism
has_trigger_prefix(&lower)is false at the head of the line. The Priority 5-pre interceptor (crates/engine/src/parser/oracle.rs:5226) never fires, andparse_whenever_you_cast_enters_with_triggeris never reached — hencetriggers=0.parse_enters_with_counters.strip_after(work_text, "with ")matches the boon's ownboon with, not the counter clause'swith. The counter grammar receives text beginning with a"character.take_until(" counter")consumes everything up to the firstcounteras the counter type, producing theGenericabove.Impact
A counter type that is an English sentence is meaningless at runtime — it matches no counter the engine can place, remove, or query, and it is not the counter the card prints. This is worse than a dropped counter: the ability appears "supported" while placing a phantom counter type. It also means
enters withcounter riders on all three cards are entirely non-functional.Note that
Tenacious Pupfails differently (routed to a trigger, no replacement at all), so a fix needs to cover both shapes.Suggested fix
Strip the
You get a one-time boon with "<ability>"wrapper and parse the quoted text as a granted ability, the way other quoted-ability grants are handled — rather than widening the counter grammar, which is downstream of the real problem.Loch Larentprints the same wrapper (crates/engine/src/parser/oracle_tests.rs:10023) and is worth checking as part of the same class.Not a regression
Pre-existing on
main. Confirmed by the CI parse diff on #7490, which reports✓ No card-parse changes detected— these cards parse identically with and without that PR's counter-grammar changes. Found while investigating #7490; that PR's elided-count grammar is correct but unreachable for these cards until this wrapper is handled.