Card-Expert Tuning Lab

Plan execution report — plan/tuning/2026-07-08-win-path-scaling.md · run of 2026-07-08 · evidence: Battle Lab round 2 (200 runs/cell) + preset-spread telemetry (greedy · seed 1 · 30 runs/cell)
5 / 7 plan items landed on main Penitent late 2% → 40% Grace late 0% → 75% 70/70 cards effectiveness-linted all gates green (mechanics · mobile 2400 · card-editor)
01

The Work — seven plan items, five landed

LANDED

Item 4 — Per-preset floors & dominance ceiling

60b1e26b

The objective function moved from stage averages to per-preset floors (targets 40/25/10 by stage) and a ≤98% ceiling. New [preset-spread] telemetry prints every preset's early/mid/late rate on every run — the 53.7% mid average was hiding four presets near 100% next to four near 0%.

LANDED

Item 7 — Keyword atlas scored from round 2

8f646629

All 21 signature rows gate-marked: PREMISE/PERORATION and STAGGER/BACKFIRE flagged dominant; RUPTURE/REAP/KINDLE/PIP flagged cap-blocked; SWAY/OMEN/SOUL/THORNS flagged late-unreachable; ECHO/REPRISE proven by the Ouroboros fix.

LANDED

Item 2 — Burst caps scale with enemy max HP

8d853dcbcap = max(floor, 0.25 × maxHP)

The flat 80-HP RUPTURE cap (bottleneck named by four decks) became a scaling formula; the Tithe 200-cap exception was retired into the same formula as a floor. Early/mid behavior bit-identical; against a 1,500 HP boss the cap is now 375. Swept at f = 0.20 / 0.25 through the matrix.

Penitent: mid 0.80→0.92, late 0.02→0.40 (the round-2 regression, erased) · Erosion late 0.00→0.08

LANDED

Item 6 — Card effectiveness lint

679ba16870/70 strict · 37 mechanic kinds mapped

Every card's PAID face is played into one rich fixture (DoT fuel, MARK stacks, FALLEN, Souls, Premises, dice, discard) and must produce the observable delta its data declares — magnitudes checked, so a payoff bursting for 0 fails. Unmapped future mechanic kinds throw. The Ouroboros class of bug ("card plays but does nothing") is now caught at commit time.

LANDED

Item 1 — Win-path scaling

63cfb3baCONCEDE 8/10/12 · CAPITULATE resolve threshold · boss rung-regrowth

CONCEDE premises scale by enemy class (8 normal / 10 elite / 12 boss). CAPITULATE became a Dawncaster-Charmed-style threshold — SWAY ≥ max(10, 0.35 × maxHP), clamped to current HP — instead of matching the entire health bar. Bosses regrow 1 telegraph rung/turn (capped 2× natural). 15 new hermetic e2e incl. pins proving small-enemy behavior is byte-identical.

Grace late 0.00→0.75 — Charm's no-strike win is finally reachable against bosses. Every other preset exactly unchanged.

OPEN

Item 3 — Persistence-by-stack DoTs

re-scoped: still needed

Erosion late reached only 0.08 under scaled caps — durationed DoTs still decay before eroding an 11-round boss. The fix (afflictions persist by stacks, never round timers — the Dawncaster model) reprices ~a third of the library, so it stayed owner-gated.

OPEN

Item 5 — Theme pressure valve (boss-tech rares)

Foundry (no tier-3 line) and Bastion (no kill-path vs non-attackers) still hit hard walls that no constant fixes. Each theme's rare redesigned as its own boss answer — see Recommendations below.

Late-stage win rate — before the run → after (greedy, seed 1)

PresetLate beforeLate afterMovementWhat moved it / what still blocks it
Penitent0.020.40
+38 pts
Scaling caps (item 2) — the round-2 regression is gone
Grace0.000.75
+75 pts
CAPITULATE resolve threshold (item 1)
Erosion0.000.08
+8 pts
Caps helped; DoT decay wall remains (item 3)
Refrain0.650.65
held
Already fixed by the round-2 Ouroboros repair
Oratory / Standstill1.001.00
ceiling breach
See Finding F2 — the dominance isn't where we thought
Foundry / Tithe / Augury / Bastion0.000.00
unmoved
Structural theme gaps — items 3 & 5 + Recommendations
02

Findings & what to do about them

F1 — Honesty barely moves win rates; scaling does

Round 2's correctness pass (fixing every lying card) moved stage averages ~4-6 pts. Two scaling changes (items 1+2) moved individual decks +38 and +75 pts. Suggestion: spend future tuning effort on scaling shape (how a number grows across stages), not magnitude nudges — the pricing lint already polices magnitudes.

F2 — Oratory/Standstill dominance is NOT the thresholds

With scaled CONCEDE, Oratory concedes less (81/120 vs ~100%) but still wins 119/120 — it falls through to ordinary damage wins. Standstill's late lock is BACKFIRE's flat per-rung drip, not permanent denial (rung regrowth verified working). Suggestion: this is now a forge-side numbers item — tune BACKFIRE intensity and Oratory's premise-fueled damage down via sandbox A/B; no engine work needed. The 0.98 ceiling in the balance-band e2e is the ratchet to enforce it.

F3 — The DoT decay wall survives the cap fix

Even with a 375-HP detonation ceiling, Erosion late = 0.08: durationed DoTs expire before eroding an 11-round boss pool. Suggestion: item 3 (persist-by-stack, the Dawncaster affliction model) is confirmed necessary, not speculative. Bound payoff windows, not the afflictions.

F4 — Four dead-at-mid decks share one shape

Foundry, Augury, Tithe, Bastion all: fine early, ~0 from mid boss fights on. Their engines (pips, omens, souls, walls) build resources but their spenders don't scale. Suggestion: every engine theme needs exactly one spender whose output scales with something that grows during the fight (bank size, fight length, enemy maxHP) — see Recommendations.

F5 — The lint has one blind spot, and it's static

The effectiveness lint catches a declared PAID mechanic that silently no-ops. It cannot see a payoff authored only on the FREE face (absent from PAID data entirely — the original Ouroboros shape). Suggestion: a small static authoring rule ("damage-bearing riders on rank ≥ 5 spells must appear on the PAID face") closes it; runtime testing can't.

F6 — Impossible stage is still 0% for everything

Target is ~1% (losing is the design), currently 0% flat. Low priority, but once late is healthy, verify a lucky run CAN thread it — a hard-0 "impossible" reads as scripted, not brutal.

03

Misc. — what the subagents turned up along the way

Dead API surface effectiveness-lint agent

Four mechanic kinds exist in the CardSpecialMechanic union that no library card uses: strip_random_buff, befriend_attempt, convert_die_color, reroll_spent. A meta-test now pins this so a card adopting one gets a strict assertion written for it. Candidates for pruning or for future card designs.

Repo hygiene card-system explorer

  • src/CLI/_audit-preset-sim.ts is marked TEMP / delete-after-use and still present.
  • src/Cards/types.ts comments reference src/Tuning/focus.parser.ts — that file doesn't exist (aspirational/stale).
  • agent-vitest-reporter.engine.test.ts fails on Windows only (path-separator expectations); green on Linux CI.

Knowledge-base facts KB explorer

  • Dawncaster corpus: 1,692 card records + 141 keywords, all community-sourced (draft / medium confidence) — leads, not canon.
  • Keyword function census: Deck Management 65 · Offense 28 · Defense 15 · Various 13 · Buff 12 · Energy Mgmt 11 · Blood Ritual 7 · Healing 7.
  • Board-game reception corpus covers 8 games; the Slay the Spire board game's better-if docs are the closest tuning prior art.

Engine notes win-path agent

  • The old CONCEDE gate was a level-threshold hack (CONCEDE_HIGH_TIER_LEVEL/_STEP) — replaced by enemy.difficulty-derived floors.
  • New state field bossRungGrowth + rung-regrown event are UI-visible if the mobile app wants to telegraph "the boss recovers."
  • No existing test pinned the old capitulate/concede contracts on big enemies — the new suite adds explicit regression pins both ways.
04

The elephant: static decklists vs a growing player

You're right — and it reframes every "late = 0%" number above

The matrix pits the same 15-card preset against early wolves and 1,500-HP late bosses. Real play doesn't work that way: the player drafts, learns higher-rank cards, and upgrades as they go. So "Foundry late = 0%" conflates two different questions — "is the theme broken late?" and "is a starter deck supposed to beat a boss?" (it isn't). Some of the late wall is real (the DoT decay math), but some is measurement artifact.

Fix the harness, not just the cards — add a deck-maturity axis:

  • Three snapshots per theme: base (current 15-card recipe), developed (mid: swap 2 commons for the theme's uncommons at full copies), apex (late: + both rares guaranteed, commons upgraded to their higher-rank versions when item "upgrade paths" exist).
  • Pair maturity to stage in the matrix: early×base, mid×developed, late×apex become the banded cells; off-diagonal cells (late×base) stay as informational "underdog" telemetry, not targets.
  • Re-baseline after: the per-preset floors (item 4) then mean "an appropriately-grown deck wins reasonably," which is the promise the game actually makes.
  • Long-term: this motivates an in-run growth keyword family (see UPGRADE/ASCEND below) so deck growth is a mechanic the player feels, not just a sim configuration — prior art: Dawncaster's Upgrade/Upgradeable/Ascend keywords and StS's card-upgrade economy.

Implementation is cheap: presets already have card-id lists; snapshots are two more lists per theme in combat.deck-presets.ts + a matrix flag. No engine changes.

05

Recommendations — keywords & cards per stage

Grounded in the spread data and Dawncaster prior art (all analogues are community-sourced leads — kb:dawncaster, confidence medium). The 30-keyword proving gate still holds: anything marked NEW KW is a candidate for when you open the registry (or a swap for a failing keyword); everything else composes existing keywords.

EARLY avg 96.8% — above target: add teaching, not power

  • No new power. Early is already trivialized-adjacent; the risk is boredom, not difficulty.
  • Teaching cards: cheap Doxa/Lemma spells that demonstrate the theme's engine loop in one play — e.g. a Tithe common that applies a 1-stack affliction AND grants a SOUL immediately, so the harvest loop is legible in turn one.
  • Consistency verbs, not damage: attach small DRAW/FORETELL riders to weak commons (Dawncaster lead: Reliable — guaranteed-effect cards) so bad hands are rarer without raising ceiling.
  • Watch dominance: the ceiling ratchet (0.98) matters here first — early is where 1.00 rows already live.

MID avg 53.7%, bimodal — give every engine ONE scaling spender

  • Foundry: an uncapped-by-count pip spender — Thesis/Theorem spell: "spend ALL pips: RUPTURE with fuel per pip spent." Scales with bank size, honors strike-dead. (Dawncaster leads: Charges, Empower.)
  • Tithe: SOUL on affliction application (not just expiry) on one uncommon — halves the rebuild cycle that makes late harvests impossible. (Lead: Souls economy cards.)
  • Augury: an omen-chain payoff — "if this Omen lands, your next Omen's rider fires twice" (composes ECHO). Prophecy should snowball. (Lead: Foretell + Momentum-shaped escalation.)
  • Bastion: RIPOSTE fires on denied turns too, not only full blocks — gives the wall a kill-path against non-attackers within its own vocabulary.
  • Uncommon rank band is the home for all of these (Thesis/Theorem): they arrive exactly when the mid wall bites — and with maturity snapshots, mid decks will actually contain them.

LATE avg 23.8% vs target 70 — persistence & proportional payoffs

  • Ship item 3 first (persist-by-stack DoTs) — no card design out-tunes decaying DoTs vs 11-round fights.
  • NEW KW — DOOM (Dawncaster: Affliction, delayed detonation): stacks accumulate silently, detonate as one burst when the count is reached. The late-game affliction: long fights become its natural habitat. First candidate when the registry opens.
  • NEW KW — MOMENTUM (Dawncaster: Blessing, grows per turn): a player-side escalator ("+1 intensity to your next payoff per turn held") that makes fight LENGTH an ally — the exact inversion of the current late-game math.
  • NEW KW — LIFEDRAIN (Dawncaster: sustain function): DoT ticks heal you for a fraction. Long grinds currently lose on attrition even when damage suffices; Bastion/Erosion need sustain that scales with their own engine.
  • Proportional payoffs on Axiom/Aporia rares: affliction-gated finishers priced as % of enemy max HP — e.g. "if the enemy carries ≥ 6 affliction stacks: RUPTURE ignores the cap fraction floor and adds 10% of max HP as fuel." Execute-shaped without violating strike-dead (it's still status-fueled).
  • NEW KW family — UPGRADE / ASCEND (Dawncaster: Upgrade, Upgradeable, Ascend): in-run card growth ("this card permanently gains +1 intensity each time it's played this run") — the mechanical face of the deck-maturity fix in §04.

Sequencing suggestion: maturity snapshots (§04) → re-baseline floors → item 3 → the four mid spenders as sandbox A/Bs via /deck-tuning → late rares → then judge whether DOOM/MOMENTUM/LIFEDRAIN earn registry slots with the proving-gate scoreboard as the evidence.