# Plan: The Reaper, King No More — Bracket 3 How to use AI + local tooling to find cards, test them, and simulate the deck entirely on this machine. ## 0. Read this first: the commander's actual text Scryfall oracle text (verified 2026-09-07): > **The Reaper, King No More** — {2/B}{2/R}{2/G} > Legendary Artifact Creature — Scarecrow > When The Reaper enters, put a -1/-1 counter on each of up to two target creatures. > Whenever a creature an opponent controls with a -1/-1 counter on it dies, you may > put that card onto the battlefield under your control. **Do this only once each turn.** Three consequences that shape the whole build, and one correction to the README: 1. **Color identity is Jund (B/R/G)**, and the hybrid {2/X} cost means it can be cast off any 6 lands — it is castable in any deck, but our identity is BRG. 2. **"Do this only once each turn" hard-caps the commander as a combo engine.** An infinite -1/-1 loop does *not* produce infinite steals off The Reaper. The loop's payoff has to come from somewhere else (a sac outlet + drain, Nest of Scarabs tokens, Blood Artist-style drains). 3. **The steal trigger only reads creatures an _opponent_ controls.** So the deck wants ways to spread -1/-1 counters onto *their* board, not just ours. This is a real tension with the Hapatra/Blowfly engine, which mostly counters our own stuff. The README's framing — "infinite combo with aristocrats ETB + -1/-1 synergy" — is sound, but the commander is a *value/removal* engine, not the combo's payoff. Build it as: aristocrats combo deck that happens to be in Jund, with The Reaper as a repeatable one-per-turn removal-plus-theft engine on top. ## 1. Bracket 3 constraints (the guardrails every tool must enforce) From the official brackets article: | Rule | Bracket 3 | | --- | --- | | Game Changers | **Up to 3** | | Mass land denial | **None** | | Extra turns | Sparse, no chaining/looping | | Two-card infinite combos | **None that go off cheaply within ~the first 6 turns** | | Tutors | Not explicitly limited (but keep them honest) | The Game Changers list is 53 cards as of 2026-09-06 and is queryable on Scryfall as `is:gamechanger` — so bracket legality is fully scriptable, no manual list to maintain. **Our house rule, stricter and simpler than the official wording: no two-card infinite combos that work in a vacuum.** If two cards go infinite with no third enabler and no board state required, they're out. Two-card lines that need an existing creature, a sac outlet, or a specific board are fine, as are 3+ card combos. This is checkable directly against the offline combo DB by filtering `len(uses) == 2`. **Good news for the README's plan: the Blowfly package passes this rule.** Checked against the offline DB — both `Blowfly Infestation + Hapatra` and `Blowfly Infestation + Nest of Scarabs` list identical `notablePrerequisites`: > You control at least two other creatures with toughness equal to 1. > You have a way to put a -1/-1 counter on a creature. So they are two *named* cards but four moving parts, needing a real board and a third enabler. That is a build-around engine, not a vacuum combo — exactly the kind of thing bracket 3 is meant to allow. Keep the package. The rule to enforce instead: **don't add tutors that assemble it**, and don't add a genuine 2-card-in-a-vacuum line alongside it. ## 1b. The blacklist — cards I won't play Separate from legality and separate from bracket rules: `blacklist.txt` holds cards excluded **by preference**, each with a reason. Format is `Card Name | reason`. ``` Sol Ring | boycott, not a power-level call Talisman of Indulgence | prefer land ramp Arcane Signet | prefer land ramp ``` Two categories so far: - **Boycott.** Sol Ring is out for personal reasons. No game-logic justification is needed or implied, and the tooling should never argue about it. - **Playstyle: ramp with lands, not rocks.** We're in green, so use it. All the Talismans, Signet, Mind Stone, Fellwar Stone, Chromatic Lantern etc. are out. This one *does* have a cost — see below. This is wired into both halves of the toolchain, which is the point of keeping it in one file: 1. `bracket_check.py` reports blacklisted cards **in their own section**, clearly marked "personal preference, not a bracket rule", so they never get confused with an actual bracket-3 violation. 2. `db.tagged()` filters them out of every search, so they don't get re-suggested later. Verified: `db.tagged("mana-rock")` no longer returns Sol Ring. **The honest tradeoff on cutting rocks:** land ramp is a turn slower and Sol Ring is the single best accelerant in the format. The deck swapped 5 rocks for Rampant Growth, Harrow, Wood Elves, Springbloom Druid, and Binding the Old Gods. Average MV went 2.92 → 3.02 and the deck is measurably slower out of the gate. Two things soften it: Wood Elves and Springbloom Druid are *creatures*, so they feed the sacrifice theme that rocks never would, and Binding the Old Gods is removal stapled to a fetch. **Measured, so it's settled.** 20,000 games each, identical seed, the only change being 5 rocks (incl. Sol Ring) swapped for the 5 land-ramp spells: | build | commander by T6 | engine assembled | -1/-1 online | 3+ lands on T4 | | --- | --- | --- | --- | --- | | land ramp (current) | **46.9%** | **35.7%** | median T6 | 95.5% | | rocks (blacklisted) | 54.8% | 34.6% | median T6 | 95.2% | The cost is real but small: **~8 percentage points on casting the commander by T6**, and essentially nothing everywhere else — engine assembly is actually a hair *better* with land ramp, and the -1/-1 engine comes online on the same turn. Sol Ring costs you a bit of explosiveness, not the deck's function. Blacklist stands, no regrets. ## 2. Tooling: what to install and what each thing is for Everything runs locally. Local runtimes present: Python 3.13, Node 25, Java 26 (Forge targets 17 — a newer JRE runs it fine), cargo. ### Layer A — Bulk data (download once, query offline forever) **No live API calls in the build loop.** Every dataset below is a static file. Total ~1.2GB on disk; refresh with a single `make data` when a set drops. All sizes and schemas below were verified by actually downloading them on 2026-09-07. | File | Size | Source | What it gives us | | --- | --- | --- | --- | | `oracle-cards.jsonl.gz` | 23MB | Scryfall bulk | One object per unique card: oracle text, mana cost, CI, `legalities`, `is:gamechanger` | | `oracle-tags.jsonl.gz` | 5.6MB | Scryfall bulk | **4,524 community tags** + full hierarchy | | `rulings.jsonl.gz` | 5.1MB | Scryfall bulk | Every ruling, joined by `oracle_id` | | `variants.json` | 646MB | Commander Spellbook | **108,535 combos**, each with `bracketTag` | | `AtomicCards.json.gz` | 51MB | MTGJSON | `edhrecRank` (popularity sanity check only) | | `embeddings.npz` | 64MB | **generated locally** | 35,312 × 768-dim mechanics vectors (see Layer B) | Endpoints (note: Scryfall bulk is **JSONL now**, the field is `jsonl_download_uri`, not the older `download_uri` — `GET api.scryfall.com/bulk-data` for current URLs): ``` https://data.scryfall.io/oracle-cards/oracle-cards-.jsonl.gz https://data.scryfall.io/oracle-tags/oracle-tags-.jsonl.gz https://json.commanderspellbook.com/variants.json # whole combo DB, no API https://mtgjson.com/api/v5/AtomicCards.json.gz ``` **The Scryfall Tagger data is the best part of this**, and it's the thing you can't reconstruct from oracle text with regex. 4,524 hand-curated tags, with `parent_ids` / `child_ids` forming a hierarchy. Tags that are directly load-bearing for this deck (counts are real, from the downloaded file): | Tag | Cards | Why it matters here | | --- | --- | --- | | `death-trigger-opponent` | 73 | **Triggers off an _opponent's_ creature dying** — maps exactly onto the commander's steal clause | | `free-sacrifice-outlet` | 192 | Sac outlets with no mana cost — the aristocrats core | | `sacrifice-outlet-universal` | 53 | Sac any permanent type | | `your-sacrifice-matters` | 122 | Payoffs for your own sacrifices | | `death-trigger-self` | 709 | Dies-triggers | | `repeatable-proliferate` | 43 | Repeatable -1/-1 counter multiplication | | `pseudo-proliferate` | 44 | Near-proliferate effects | | `shrink` | 107 | Toughness reduction | | `persist` / `gives-persist` | 26 / 7 | Persist + -1/-1 is the classic engine | `death-trigger-opponent` at 73 cards is the highest-signal query in the whole project. Grepping oracle text for that concept is miserable; the tag is exact. Read it as "the shortlist of cards that do what my commander does." Joining all three files (tags ∩ Jund identity ∩ commander-legal, sorted by `edhrecRank`) — run locally, output verbatim — yields **55 cards**, top of list: ``` #511 The Meathook Massacre #1031 Yahenni, Undying Partisan #512 Massacre Wurm #1695 Massacre Girl, Known Killer #753 Bloodchief Ascension #2536 Mari, the Killing Quill #2944 Necroskitter #3511 Overseer of the Damned ``` That's a real shortlist for "cards that care when an opponent's creature dies," produced in about a second with no network. This is the whole argument for Layer A. **Combos, fully offline.** The entire Spellbook DB is one JSON download — no `find-my-combos` POSTs. Verified locally: 108,535 combos, **24,699 within Jund identity**, and **30 that use The Reaper itself**. Each combo carries `uses`, `produces`, `identity`, `legalities`, `popularity`, and a `bracketTag` (E/S/P/O/R/B/C) we can filter on directly for bracket-3 policing. A real result from the offline file — the commander's own combos are mostly Mikaeus, the Unhallowed shells: ``` O [Mikaeus, the Unhallowed, The Reaper, Bloodthrone Vampire] => Infinite -1/-1 counters, Infinite creature ETB O [Mikaeus, the Unhallowed, Spawning Pit, The Reaper] => Infinite -1/-1 counters ``` Reimplementing `find-my-combos` offline is ~15 lines: index combos by card name, then `included` = combos whose `uses` ⊆ deck, `almostIncluded` = combos missing exactly one. ### Layer B — Semantic search ("try other cards") **Short answer to "how do I get all the cards": you generate them yourself, in 82 seconds, and you already have.** Don't download `minimaxir/mtg-embeddings` — it's stale (through Aetherdrift, Feb 2024) and, verified, **does not contain The Reaper**. Instead run the same model over our own current `oracle-cards.jsonl`: ``` python3 tools/embed.py # -> data/embeddings.npz ``` That encodes every card with `Alibaba-NLP/gte-modernbert-base` (the same model the HF dataset used) and writes a 64MB `.npz`. On this box (RTX 3060, 12GB) it took **1m22s for 35,312 cards**. It is a `pip install sentence-transformers` and one script — no account, no download, and it re-runs whenever a set drops. This is strictly better than the HF file in every dimension, which is why Layer B is now "build", not "fetch". **Two things I got wrong on the first pass, both worth knowing:** 1. **Don't put the card's name in the embedded text.** With `name` included, querying The Reaper returned Midnight Reaper, Reaper of the Wilds, Grim Reaper, Slum Reaper, Cemetery Reaper — it matched the *word* "Reaper", not the mechanics. `embed.py` deliberately omits the name field. 2. **Card-to-card similarity matches a card's overall _shape_, not its key ability.** With names removed, The Reaper's neighbors became Scarecrone, Grim Poppet, Blazethorn Scarecrow, Jousting Dummy — the model correctly saw "artifact creature Scarecrow" and matched creature type. Useless for deckbuilding. **So query by ability text, not by card.** That's what actually works: ``` python3 tools/similar_text.py "whenever a creature an opponent controls with a -1/-1 counter dies, put that card onto the battlefield under your control" ``` ``` 0.897 Instill Infection 0.891 Make Obsolete 0.890 Cower in Fear 0.882 Shrivel 0.880 Persist 0.876 Hazardous Conditions 0.874 Gnarled Effigy 0.872 Consumptive Goo 0.871 Quillspike ``` Genuine -1/-1 cards. Both scripts filter to Jund identity + commander-legal. **It's still fuzzy** — it ranks by "reads like", so it surfaces candidates, not recommendations. Use embeddings to *generate* a candidate list, then filter it through the Tagger tags and legality from Layer A. Tags are precise but only cover concepts someone thought to tag; embeddings cover anything but imprecisely. They fail in opposite directions, which is why the plan uses both. ### Layer C — Popularity / prior art MTGJSON `AtomicCards.json` (verified current: 2026-09-06, 35,022 cards) carries `edhrecRank` per card — no EDHREC scraping needed. Use rank only as a loose "how normal is this inclusion" sanity check. We are **not** tracking saltiness and not scoring the deck on it. The one power-level rule we *do* enforce mechanically: **no two-card-in-a-vacuum infinite combos.** Two cards that go infinite by themselves, with no third enabler and no board state required, are out — that's the bracket-3 line and it's checkable directly against the offline combo DB (`len(uses) == 2`). Longer combos, or two-card lines that need an existing creature / sac outlet / specific board, are fine. See §1 for how this lands on the Blowfly package. ### Layer D — Simulation (Forge) **Forge is the simulator. We are not writing our own.** A hand-rolled goldfish sim models mana and curve but not the game — no blockers, no interaction, no stack, no opponents. For a deck whose whole point is death triggers and sacrifice loops, that misses everything that matters. Forge implements the actual rules. **Installed and working:** Forge 2.0.14, `~/forge`, from the prebuilt `forge-installer-2.0.14.tar.bz2` (no Maven needed — the release ships a fat jar). Java 26 runs it fine despite the project targeting 17. It loads 33,617 cards. Exact syntax, from `SimulateMatch.java` and confirmed against the running binary: ``` sh forge.sh sim -d ... -f Commander -n -s -q ``` - `-d` decks (quote names with spaces) · `-f Commander` **required**, else constructed - `-n` games · `-m` best-of-M match · `-s` RNG seed (use it — reproducible runs) - `-a` AI profile per player · `-c` seconds before a draw (default 120) · `-q` quiet **Two gotchas that cost time, both now handled by the tooling:** 1. **Commander decks must live in `~/.forge/decks/commander/`.** The `-D` flag did *not* work for Commander format — Forge looks in its own profile directory and otherwise reports `Could not load deck`. `run_forge.sh` writes there directly. 2. **With one deck, Forge "wins" on turn 0 in 300ms** — no opponents, no game. You need real opponents. Forge ships **173 Commander precons** in `res/quest/commanderprecons/`; we use three (Faceless Menace C19, Merciless Rage C19, Arcane Maelstrom C20) for a 4-player pod. They're roughly bracket 2. Real 4-player games run ~31 turns in ~60 seconds each, so a 24-game batch is ~25 min. **The AI caveat is not a footnote.** Per Forge's own wiki the AI is heuristic, not trained: decent at aggro/midrange, moderate at control, **weak at combo decks**. Ours is a combo deck, so the AI systematically under-plays it and will miss sac-loop lines a human would take. Every report prints this. Read Forge's win rate as a **floor** and as proof the deck functions and its cards interact — never as a power rating. ## 3. The build loop Card selection is offline and instant. Simulation is Forge, and it's the slow step — ~60s per 4-player game — so it runs in batches, not on every edit. ``` make data (once/per set) ──► data/*.jsonl, variants.json, AtomicCards.json │ decklist.mtg ─────────────────────────► │ blacklist.txt ──┐ │ │ │ ├─► bracket_check.py ── game changers, MLD, vacuum combos, blacklist ──┐ ├─► combos.py ── included / almostIncluded (offline) ──────────┤ ├─► tags.py ── death-trigger-opponent, sac outlets ──────────┼─► out/ ├─► similar_text.py ── "cards whose text reads like ..." ──────────┤ │ │ └─► to_dck.py ──► run_forge.sh ──► forge_report.py ─────────────────────┘ (validates names) (24 games, 4-player pod) (.txt + .json + .log) ``` Every simulation run writes a timestamped triple into `out/`: the full Forge `.log`, a human `.txt` report, and a `.json` artifact — and the report footer names `decklist.mtg`, the log, the JSON, and itself, so any number is traceable. ## 4. Repo layout ``` reaper-king-no-more/ decklist.mtg # working deck, "1 Card Name" per line blacklist.txt # cards I won't play, "Card Name | reason" plan.md data/ # ~1.2GB, all gitignored oracle-cards.jsonl oracle-tags.jsonl rulings.jsonl variants.json AtomicCards.json embeddings.npz (generated) decks/ # RESULTS, one dir per archetype variant README.md no-mikaeus/ # decklist.mtg, bracket.txt, combos.txt, mikaeus/ # README.md, sim/.{log,txt,json} tools/ cards.py # shared index: oracle+tags+edhrec+combos+blacklist bracket_check.py # game changers, MLD, vacuum combos, blacklist combos.py # offline included / almostIncluded (no API) embed.py # generate embeddings.npz on GPU (~82s) similar.py # "cards like " similar_text.py # "cards whose text reads like " to_dck.py # decklist -> forge .dck, validates names vs Forge run_forge.sh # batch 4-player sim into decks//sim/ forge_report.py # Forge log -> .txt report + .json artifact variant.py # run the whole suite for one variant ``` **Variants are the unit of work.** A variant is one answer to "what if the deck were built this way" — its own 100 cards, its own legality verdict, its own combo profile, its own simulation history. Regenerate one with: ``` python3 tools/variant.py no-mikaeus # analysis only, ~10s python3 tools/variant.py mikaeus --sim 24 # + 24 Forge games, ~25 min ``` Analysis files are rewritten each run; sim runs are additive, so every batch is kept and runs stay comparable. External: `~/forge` (Forge 2.0.14) and `~/.forge/decks/commander/` (where Forge insists Commander decks live). ## 5. Build order 1. ~~`fetch_data.py`~~ — **done**, six files in `data/` (1.1GB). 2. ~~`cards.py`~~ — **done.** oracle + 4,369 tags + edhrecRank + combos + blacklist. 3. ~~`bracket_check.py`~~ — **done and passing.** 4. ~~`embed.py` / `similar.py` / `similar_text.py`~~ — **done** (Layer B). 5. ~~Draft the 100~~ — **done**, `decklist.mtg`. 6. ~~Forge installed + `to_dck.py` + `run_forge.sh` + `forge_report.py`~~ — **done.** 4-player pod vs precons, reproducible by seed. 7. Iterate on the list using Forge results + the offline combo/tag tools. **Dropped: the hand-rolled goldfish sim.** It was written and worked, but it models mana and curve only — no interaction, no blockers, no stack. For an aristocrats combo deck that's the wrong abstraction, and maintaining a second simulator that disagrees with the real one is worse than having one. Forge is the simulator. (`goldfish.py` and its `out/goldfish-*` runs are removed.) **Report convention** (every tool): a timestamped `.txt` human report plus a `.json` artifact in `out/`, with the report footer naming `decklist.mtg`, the raw log, the JSON, and itself. ## 6. Deck skeleton to draft against Rough shape, ~99 + commander: - **Lands 36–37** (hybrid commander is easy to cast; the rest of the deck is greedy) - **Ramp 10** — Jund has good rocks + Cultivate/Farseek effects - **-1/-1 engines** — Hapatra, Blowfly Infestation, Nest of Scarabs, Yawgmoth, Necroskitter (steals like the commander!), Contagion Clasp/Engine, Archfiend of Ifnir - **Sac outlets** — free ones matter: Viscera Seer, Carrion Feeder, Ashnod's Altar - **Drain payoffs** — Blood Artist, Zulaport Cutthroat, Bastion of Remembrance - **Removal/interaction 8–10** — bracket 3 pods interact - **One-offs that love the commander** — Humble Defector (per README), and note **Necroskitter** is close to a second copy of the commander's steal ability - **Game Changers: pick ≤3, deliberately.** Check with `bracket_check.py`. `Necroskitter` came straight out of the Scryfall query in §2 and is arguably the best non-commander card for this exact deck — good sign the search approach works. ## 6b. Variants — the unit of work Six variants, each a falsifiable hypothesis rather than a taste preference. All are generated from one spec (`tools/make_variants.py`) as cut/add lists against the baseline, so changing the baseline propagates everywhere. | variant | bracket 3 | vacuum | combos | outlets | cmdr synergy | avg MV | | --- | --- | --- | --- | --- | --- | --- | | **no-mikaeus** (baseline) | PASS | 0 | 11 | 8 | 6 | 3.02 | | lean-outlets | PASS | 0 | 10 | 5 | 7 | 2.97 | | commander-focus | PASS | 0 | 7 | 7 | 10 | 3.03 | | heavy-removal | PASS | 0 | 7 | 8 | 8 | 2.95 | | low-curve | PASS | 0 | 11 | 8 | 9 | 2.67 | | mikaeus | **FAIL** | **7** | 39 | 8 | 6 | 3.08 | The hypotheses: - **lean-outlets** — 8 sac outlets is more than the deck needs. Cut 3 for interaction and card advantage; does consistency actually drop? - **commander-focus** — the commander only steals from *opponents'* creatures, but our -1/-1 engine mostly counters our own. Push counters onto their board instead. (Raises synergy cards 6 → 10, at the cost of 4 combos.) - **heavy-removal** — bracket 3 pods interact. Trade combo redundancy for removal: does surviving longer beat assembling faster? - **low-curve** — the engine lands ~T6. Cut the top of the curve entirely (MV 3.02 → **2.67**) and see if coming online sooner wins more. - **mikaeus** — the control case. Confirms the house rule catches what it should. **Mikaeus is settled — the answer is no.** Adding it creates **7 two-card vacuum combos**, because it goes infinite with *every sac outlet in the deck*: ``` Mikaeus + Ashnod's Altar Mikaeus + Carrion Feeder Mikaeus + Phyrexian Altar Mikaeus + Viscera Seer Mikaeus + Goblin Bombardment Mikaeus + Woe Strider Mikaeus + Yahenni, Undying Partisan ``` Two cards, no third enabler, no board state — exactly what the house rule targets. Its combo count jumps 11 → 39, which is the same problem counted a different way. Kept as a variant so the comparison stays visible rather than buried in a chat log. **What the baseline's own numbers say:** `combos.py` finds 11 combos in the deck, all requiring board state — redundant three-card engines, no vacuum lines. That is the deck working as designed. ## 6c. How to design variants, and what to do with the results ### Designing variants A variant is only worth running if it can be **wrong**. The rule I'm using: each one states a hypothesis, changes 3-5 cards, and holds everything else constant. Anything bigger and you can't attribute the result; anything vaguer and there's no result to attribute. Where the hypotheses come from, in rough order of value: 1. **Structural facts about the list.** Count things and look for outliers. "8 sac outlets when 5 would do" and "22 three-drops, 5 of them ramp" both came from counting, not intuition. This is the best source. 2. **Loss data from previous sims.** 15 of 17 losses were life hitting 0 against aggro → that's `heavy-removal` and `low-curve`. 3. **Tension in the deck's own design.** The commander only steals from *opponents'* creatures while our engine counters our own → `commander-focus`. 4. **Control cases.** `mikaeus` exists to prove the house rule catches what it should. A test suite needs a case that fails on purpose. All of it lives in `tools/make_variants.py` as cut/add lists against the baseline, so changing the baseline propagates everywhere and no two lists silently drift apart. The generator refuses to add a card already in the deck (it caught three of my own mistakes) and validates every name against Forge's database before simming. ### Card-level weights from simulation data Run Forge **without `-q`** and it logs the whole game, attributed by player: ``` Add To Stack: Ai(1)-Reaper King No More cast Terminate targeting [Face-down card (H4)] Zone Change: Zulaport Cutthroat (33) was put into Graveyard from Battlefield. Life: Ai(2)-Faceless Menace 40 > 39 ``` `tools/card_stats.py` turns that into per-card numbers: how often a card was cast, the average turn it landed, and the deck's win rate in games where it was cast. That last column is the "weight". **What it's legitimately good for:** - **Cards never cast in any game.** The single most actionable output. A card that never gets played across dozens of games is dead weight, uncastable by the AI, or too expensive — all worth investigating. - **Average turn played** — measures whether the curve behaves as intended. - **Cast rate** — is this card doing anything, or is it a 100th-card filler? **What it is NOT:** a fitness function you can optimize against. Four reasons, all real: 1. **Sample size.** A card cast in 5 games has a +/-40% win-rate swing from noise. 2. **"Never cast" is three different failures wearing a trenchcoat** — bad card, card the AI can't pilot, card never drawn. They need opposite fixes. 3. **Correlation, not causation.** Cards cast in long games look good because long games are ones we *survived*. The card didn't cause the win; surviving did. 4. **The AI is weak at combo**, so it systematically under-casts our combo pieces — exactly the cards we care most about. So: use card stats to generate *hypotheses* (this card never gets cast — why?), then test the hypothesis with a variant. Don't let a win-rate column pick the deck. The loop is **stats -> hypothesis -> variant -> sim -> stats**, with a human deciding at each arrow. ## 7. Open questions - **Which variant is actually best?** Five pass bracket 3 and differ meaningfully on paper. Forge decides this, not argument — each needs a 24-game batch. - What's the primary wincon — a drain loop off infinite death triggers, or grinding value off stolen creatures? The commander's once-per-turn clause means it can't be the payoff, so something else has to close. - Do we want any Game Changers at all? Bracket 3 allows 3; running 0 is also fine and makes the deck's bracket unambiguous. - Is `commander-focus` right that the deck under-uses its own commander? It nearly doubles opponent-facing -1/-1 effects (6 → 10) but loses 4 combos. That trade is the single most interesting question in the list.