Tags give the ability to mark specific points in history as being important
-
v0.23.0
Release: v0.23.0afe4cf7b · ·v0.23.0 Commits since v0.22.0: - fix: two CR citations this branch wrote, and the one it copied - chore(release): 0.23.0 — LTR 244/244 - docs(dev): run builds in the foreground, redirected - refactor(engine): ManaEmptyingStatic drops `face` too, and refuses a DFC at comptime - refactor(engine): drop the unexercised condition arm from ManaEmptyingStatic - test: pin the any_one slot guard in emptyExcept, and record the equivalent mutant on Fangorn's trigger condition - feat: Fangorn, Tree Shepherd - feat(engine): colour-scoped exemption from the CR 500.5 mana emptying - docs(plan): Q8 answered and closed, Fangorn unblocked, wave 39 findings - docs: plotting is a special action under CR 702.170b, not 702.170a - docs: analogue -> analog, the owner's call - chore: sync plan checkboxes after merge - test: a legendary permanent phasing in is not entering the battlefield - docs: second-pass American spellings — -ise/-isation family, and grey in app - refactor(tools): American spellings in tools, sim/tools, tests and one deck note - fix: payPlotCost pays without a spend-attribution sink - feat(app): American spellings in app strings, comments and CSS notes - docs(plan): American spellings in the plan files and FINDINGS - docs: American spellings across the prose docs and CI comments - chore: rebase onto next — the phasing arm, and the coverage table - fix: cite Sacrifice as CR 701.21, not 701.17 - docs: record the each_opponent seat restriction as unobservable at two seats - test: the combat-damage-to-player record is keyed on which player - feat: Tom Bombadil - refactor: a gated probe's rollback is one operation, not two - refactor: payment scratch leaves cloned game state - feat: one mana pool per player (CR 106.4) - feat: Gollum, Scheming Guide - feat: Witch-king of Angmar - feat: Gandalf the White - docs(plan): wave-39 merge pass — two overrules, seven landed steps, 13 findings - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - docs(sim): record that settleResolutionCastOfSpell's window guard is defensive - fix: a resolution-cast charges its life rider once, not twice - test: the phase-out ORDER is what the state hash uniquely carries - docs(sim): state the slot rule as a balance, not a direction - fix: status is CR 110.5, not 110.6 - test: the rollout clone and the position hash carry phased_out - fix: card headers verbatim, including the phasing reminder text - chore: regenerate COVERAGE.md — LTR 239/244 - test: a same-board control behind each proposal-refusal test - test(fixture): expectNoProposalFrom — only the log answers "was one announced" - fix: the phased-in battlefield append goes through zones' own funnel - feat: King of the Oathbreakers - feat: phasing (CR 702.26) - docs: delete the replay-break concern; correct REVIEW.md section 9 statuses - docs(sim): a vtable slot is cheap; the list is about merges - docs: the WASM smoke harness's own comment named a retired script - docs(review): four of section 12's six candidates have landed - docs(skills): cut two rules whose subject is deleted - docs: stop documenting commands that no longer exist - docs(master-plan): delete landed rows the file's own rule says to delete - docs(findings): collapse closed entries to their verdicts - docs(plan): wave 38 merged all five; two corrections that are the planner's - chore: regenerate the coverage table - chore: regenerate the card manifest - feat: Doc Aurlock, Grizzled Genius - feat: Aven Interrupter - feat: Kellan Joins Up - feat: Make Your Own Luck - feat: Brimstone Roundup - feat: Railway Brawler - feat: Outlaw Stitcher - feat: plot as an effect, and the cost primitives OTJ needs - test: pin the hand walk's stand-in pick - chore: sync plan checkboxes after merge - fix: a library search stops taking the card you were about to draw - feat: Pillage the Bog - docs: stop making the conductor's report an appraisal - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - fix: the copy-order frame survived at one spell left, which its own invariant rejects - docs: address the !840 review — six documentation defects, no behaviour change - docs(dev): an absence assertion needs a witness - docs: re-attach three doc comments this MR had detached - fix(sim): hexproof on a player is CR 702.11c, and the sweep focus is creature-first - fix: Sharkey's borrow really does have to except mana abilities - fix: protection from everything obeys CR 615.12 - test: the counterspell-vs-ordinary routing is invisible to cast enumeration - test: pin the routing half of Display's cast, not just the slot - feat: Display of Power - feat(sim): copy every targeted spell, in an order the controller picks - fix: three CR citations this diff wrote, and one absolute claim - fix: the new prompt kind had no board heading, and one test skipped the sweep - test: the library-top assertion ran against a one-card library - test: the copy-target window offers no second name for its keep line - test: the may-decline test asserted on a dead permanent's tapped bit - feat: Gandalf the Grey - feat(sim): a resolution_choices step may be modal - feat(sim): copy a spell chosen as a target at resolution, with CR 707.10c's window - revert(sim): the kicked propagation onto a targeted ETB's action was dead - chore(sim): regenerate COVERAGE.md for the BLB gift batch - feat: Coiling Rebirth - feat: Parting Gust - feat: Kitnap - feat: Scrapshooter - feat: Longstalk Brawl - feat: Dawn's Truce - feat: Sazacap's Brew - feat: Dewdrop Cure - feat: Consumed by Greed - feat: Mind Spiral - feat: Wildfire Howl - feat: Long River's Pull - feat: Valley Rally - feat: Into the Flood Maw - feat: Peerless Recycling - feat: Wear Down - feat: Nocturnal Hunger - feat: Blooming Blast - feat: Crumb and Get It - feat(sim): finish gift (CR 702.174) and the five surfaces its cards revealed - feat: refuse a delayed-only trigger event declared on Card.triggers - fix: the mana-emptying rule is CR 500.5, not CR 500.4 - chore: regenerate COVERAGE.md for the three LTR singletons - fix: an unknown `--flag` no longer blanks a card search - feat: The One Ring - feat: Sharkey, Tyrant of the Shire - feat: Fires of Mount Doom - docs: map which fixture verb answers which staged window - fix: derive vtable_slots from an append-only list so concurrent raises conflict - fix: resolveStack silently answered the choose-permanent window - fix: a triggered ability going on the stack can commit a crime (CR 700.13) - docs(plan): wave 38 sent five back and closed the FULL-drift question - fix: Manifold Mouse prints a choice and implemented one arm - docs(plan): wave 37 closed LTR's cheap tail and three findings' subjects - chore: sync plan checkboxes after merge - chore: refresh the coverage table - fix: copy_of_each owes grant_source_id, which the merge silently dropped - docs: the gates are gone, so stop naming them as live - fix: drop Lazav's inert resolve_on_decline - chore: sync plan checkboxes after merge - chore: refresh the coverage table - test: terminate Kaervek's filter test, and prove the filter behaviourally - feat: Oko, the Ringleader - chore: sync plan checkboxes after merge - chore: refresh the coverage table - chore: sync plan checkboxes after merge - chore: refresh the coverage table - chore: sync plan checkboxes after merge - feat: Kaervek, the Punisher - feat: Lazav, Familiar Stranger - feat: Marchesa, Dealer of Death - feat: Freestrider Lookout - feat: Gisa, the Hellraiser - feat: At Knifepoint - feat: Servant of the Stinger - feat: Rattleback Apothecary - feat: Intimidation Campaign - feat: Bandit's Haul - feat: Hardbristle Bandit - feat: Duelist of the Mind - feat: Vadmir, New Blood - feat: Take for a Ride - feat: Seize the Secrets - feat: Nimble Brigand - feat: Slickshot Vault-Buster - feat: Omenport Vigilante - test: the nonland assertion counted cast actions, and survived its mutation - docs(wave): a lane killed a sibling's build with a bare pkill - test: the routing pair was vacuous against its own mutation - fix(sim): apiBounce cited CR 701.11, which is Triple - test: the prompt driver honours a pending extra turn (CR 500.7) - chore(sim): regenerate COVERAGE.md for Press the Enemy - test: Press the Enemy values a returned {X} spell at its cast X - feat: Press the Enemy - feat(sim): a resolving effect may target a spell on the stack - chore: regenerate COVERAGE.md — LTR 225 → 226/244 - feat: extra turns (CR 500.7) and Lost Isle Calling - test: the only_controller bound had no test, and mutation proved it - chore: retire sim:lock, sim:fields and sim:oracle - fix: sendback — cover the reflexive half, assert ward, correct six citations - refactor(triggers): the watcher walk is `collect`, with the bound on the funnel - fix: the mill reporting bound was sized by the registry, not by the type - test: Shelob's provenance narrowing was untested - chore(sim): regenerate COVERAGE.md — LTR at 229/244 - feat: Shelob, Child of Ungoliant and Saruman of Many Colors - chore(sim): regenerate COVERAGE.md for this batch's two cards - fix(cards): the mill citation named no rule, and two headings went unnamed - chore: regenerate COVERAGE.md for the two LTR cards - feat: Sauron, the Necromancer - feat: Forge Anew - feat: Palantír of Orthanc - fix(sim:oracle): the becomes-the-target rule takes either reading - feat: Elrond, Master of Healing - docs: the changelog entry is a few sentences, not a wave report - docs(plan): LTR's tail is three units, not eleven cards - docs(plan): authorize BLB, close wave 36's findings, and record what a decline-by-reading costs - docs(plan): saddle is 702.171, mill is 701.17, and Q7 is answered BUILD - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - test: crewing a Vehicle records no saddling - test: pin both arms of the saddling relation on Giant Beaver - chore: regenerate COVERAGE.md for the OTJ saddle batch - feat: Archmage's Newt - feat: The Gitrog, Ravenous Ride - test: Slickshot Lockpicker's target filter was untested - feat: Calamity, Galloping Inferno - chore: regenerate COVERAGE.md for the OTJ batch - feat: Fortune, Loyal Steed - feat: Plan the Heist - feat: Unscrupulous Contractor - feat: Slickshot Lockpicker - feat: Rambling Possum - feat: Loan Shark - feat: Stubborn Burrowfiend - feat: Pitiless Carnage - feat: Giant Beaver - fix(traits,characteristics): Nowhere to Run suppresses hexproof and ward on creatures only - feat: Rise of the Varmints - feat: Gila Courser - feat: Seraphic Steed - feat: Bridled Bighorn - test(combat): pin CR 506.4's blocker half at the first-strike step - feat: Stingerback Terror - feat: Freestrider Commando - feat(engine): EnterCtx.totalManaSpent - fix(combat): enforce CR 506.4's blocker half - feat: Bounding Felidar - feat: Congregation Gryff - feat: Stagecoach Security - feat: Quilled Charger - feat: Drover Grizzly - feat: Sheriff of Safe Passage - feat: Dust Animus - feat: Trained Arynx - feat: Demonic Ruckus - fix(plan): stop `sim:plan sync` eating a plan file's head - docs(plan): rank 7 said suspend has no cards; it has 74 - docs(plan): OTJ is authorized, and it is dealt by parity so a family lands whole -
v0.22.0
Release: v0.22.0ee039b50 · ·v0.22.0 Commits since v0.21.0: - docs(changelog): 0.22.0 said LTR was 119, 183 and 225 in one entry - docs(changelog): extend 0.22.0 with wave 35 — The Hobbit is 188/188 - docs(plan): triage FINDINGS and re-measure MASTER-PLAN §11 after wave 35 - docs(plan): sweep LTR's engine claims, and restore the table sync deleted - docs(sim): triggerEventIndex's doc still said the index was a u64 - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - test: make Supper for Spiders' duration test discriminate - chore(sim): regenerate COVERAGE.md — HOB at 188/188 - feat: Supper for Spiders - feat: Kíli the Resourceful - chore(sim): regenerate COVERAGE.md for the six cards this batch landed - feat: The Balrog, Durin's Bane - chore: regenerate sim/COVERAGE.md for this batch - chore: regenerate registry mirror and coverage table - fix: a token copy created tapped entered untapped - feat: Storm of Saruman - feat: Shadowfax, Lord of Horses - feat: Wizard's Rockets - feat: Gandalf, Goblins' Bane // Flameshape - feat: Peregrin Took - feat: Mordor Trebuchet - feat: Pippin, Guard of the Citadel - feat: Troll of Khazad-dûm - docs(traits): record that the borrow's on_battlefield flag is measurably inert - feat: Phial of Galadriel - feat: The Watcher in the Water - feat: The Grey Havens - feat: Thranduil, the Elvenking - test: assert the event-set ceiling's shape, not its number - feat(sim): widen the trigger event set past u64, and unkey per-object budgets from it - feat: Saradoc, Master of Buckland - feat: Tale of Tinúviel - feat: Rosie Cotton of South Lane - feat: The Bath Song - feat: You Cannot Pass! - feat: Mirkwood Bats - fix: Heartless Act destroyed creatures that had -1/-1 counters - docs(plan): the full FINDINGS sweep the 2026-08-24 header said was owed - fix(plan): `sim:plan merge` has been broken since the tooling retirement - docs(plan): re-read LTR's exclusions and re-measure MASTER-PLAN §11 - docs(plan): collapse 175 closed findings to their titles - docs(plan): a shape line says what the card prints, not what the engine lacks - feat: Long List of the Ents - feat: Hew the Entwood - feat: Morgul-Knife Wound - chore(sim): regenerate manifest, coverage and LTR checkboxes after lane B - feat: Meneldor, Swift Savior - feat: Isildur's Fateful Strike - feat: Isolation at Orthanc - feat: Mauhúr, Uruk-hai Captain - feat: Lost to Legend - feat: Lotho, Corrupt Shirriff - feat: Minas Tirith Garrison - feat: Gwaihir the Windlord - docs(plan): harvest the wave-33 findings, and correct one of my own - chore(sim): regenerate manifest, coverage and LTR checkboxes after lane B - feat: Roads Go Ever, Ever On - chore(sim): regenerate manifest, coverage and LTR checkboxes after lane A - fix(docs): goad is CR 701.15, not 701.38 — 701.38 is Vote - feat: Glamdring - feat: Goldberry, River-Daughter - feat: Thranduil's Decree - feat: Gandalf, White Rider - feat: Glóin, Dwarf Emissary - docs: cut MASTER-PLAN 1762 -> 1523, and point the fixture trap at its cause - docs: write for grep; demote `sim:precedent`; add the `PRINTS:` convention - test(sim): delete a vacuous `exclude_source` test and write down why it was one - chore(sim): regenerate manifest, coverage and LTR checkboxes after lane A - chore(sim): regenerate manifest, coverage and HOB checkboxes after !812 - fix(sim): guard the two GameState clones with a comptime field count - feat: Doors of Durin - feat: Inside Information - chore(sim): regenerate manifest, coverage and LTR checkboxes after lane B - feat: Fall of Gil-galad - feat: Fog on the Barrow-Downs - feat: Fire of Orthanc - feat: Fear, Fire, Foes! - feat(sim): the five primitives this LTR batch revealed - feat: Gimli, Mournful Avenger - feat: Gollum, Riddle Master - docs(plan): write the wave-31 measured skips back into LTR.md - feat(charter): goad is in envelope — Q6 answered by the repo owner - test: the general /play save/restore round trip - chore(sim): regenerate manifest, coverage and LTR checkboxes after lane 2 - docs: stop reporting `replay_version`, and re-argue the round-trip pins honestly - chore(sim): regenerate COVERAGE.md for the five cards this batch added - feat: Bewitching Leechcraft - feat: Barrow-Blade - docs(sim): the damage-source invitation on PermanentDamagedEvent is answered - feat: East-Mark Cavalier - feat: Borne Upon a Wind - feat: Éowyn, Fearless Knight - chore(sim): regenerate the manifest, coverage table and plan checkboxes after !811 - fix(sim): hash `FloatingEffect.saddled`, and make the next omission a build error - docs(plan): file the saddled state-hash gap and the CR 120.3c miscitation - chore(sim): regenerate COVERAGE.md and sync LTR checkboxes after lane 1 - feat: The Eagles Are Coming! - feat: Bill the Pony - feat: Spiteful Banditry - feat: Gandalf's Sanction - docs(plan): classify HOB's Supper for Spiders, the last unshaped entry - docs(plan): lift 56 LTR exclusions that rested on the retired kernel-spec queue - docs: extend the 0.22.0 changelog entry through the wave-30 retirement - chore(sim)!: cut `sim:bench` to the WASM smoke path and rename it `sim:smoke` - docs: finish the MASTER-PLAN sweep — §7, §8 and §13 against the new direction - docs: sweep MASTER-PLAN, CHARTER, CONTRIBUTING and the wave skill for the new direction - chore(sim)!: retire the `paired` throughput A/B harness - chore(sim)!: retire the replay sweep, the golden corpus and `certifyReplay` - chore(sim)!: retire `sim:text` and the rules-text generation layer - chore(sim)!: retire `sim:symbols` and `sim:ratchet` - chore(plan): sync HOB checkboxes after the lane-1 merge - chore(sim): regenerate COVERAGE.md for the HOB lane-1 merge - fix(sim): CR 611.2b — `while_source_on_battlefield` never starts if the source is gone - docs(plan): file the mode-scoped certification gap the wave-30 sweep exposed - chore(sim): retire the one ReleaseFast quarantine row, and stamp the wave-30 certification - docs(plan): wave-30 merge harvest — findings, skip measurements, the mutation-worktree brief - chore: sync plan checkboxes after merge - chore: refresh the coverage table - chore: sync plan checkboxes after merge - feat: Old Fat Spider Can't See Me - docs: two comments the CR 603.3d fork falsified - feat: Sting, Bilbo's Sword - feat: Witch-king, Bringer of Ruin - feat: Mount Doom - chore(sim): regenerate COVERAGE.md for the LTR lane-2 batch - feat: There and Back Again - feat: Dwalin, Weaponmaster - feat: Orcish Bowmasters - feat: Rise of the Witch-king - feat: Minas Tirith - fix(plan): `workable` double-subtracted an entry that was done and excluded - docs(plan): wave-30 prep — refresh LTR/HOB, close the CR 603.3d cluster - docs: record the two debts from the CR 603.3d pass in §11 - feat(sim)!: CR 603.3d — an entry ability chooses its targets on the stack - feat(plan): `sim:plan merge` runs the replay certification it is responsible for - docs: finish the kernel-spec retirement outside tools/ - docs(dev): the two references that still told a dev to file a spec - docs(tools): three comments that outlived the kernel-spec queue - docs: the deleted `refIsSettled` is no longer a live anchor - chore: delete the kernel-spec machinery from tools/ - docs: re-derive MASTER-PLAN §11 from the tree; declare the CR 603.3d gap - chore(sim): the hone-counter CR drop landed — Dwalin and Sting are unblocked - docs(dev): `bun run test` is a landing gate, not an optional extra - test(sim): Lobelia's refusal test runs the fixture sweep - fix(sim): an engine hit must not shadow sim:precedent's card answer - chore(sim): regenerate COVERAGE.md for the HOB wave-29 batch - feat: Bilbo, Thief in the Night - refactor(sim): delete the dead .trigger_targets branch in castTargetSlotsFor - chore(sim): regenerate COVERAGE.md for the two LTR cards - feat: Lobelia Sackville-Baggins - test(sim): pin the modal-entry arm of the resolution-cast pool - feat: Azog, Moria's Ruin - feat: Aragorn, Company Leader - fix(sim): .attacks abilities fire at CR 508.1m, not per declaration - docs: record the face-resolution and back-face scope changes in AGENTS.md - fix(sim): resolve every printed face by name — 45 faces were gated by nothing - feat: An Unexpected Party // At the Door - chore(sim): strip every block annotation from the plan files - fix(sim): `sim:precedent`'s false blocker was the query, not the scope - chore(sim): retire the kernel-spec queue, salvaging what was measured - docs(wave): the merge pass certifies replay breaks, never a lane - chore: retire the kernel-spec queue — cards carry their own primitives - chore(sim): regenerate COVERAGE.md for the three HOB cards - test: Wizard's Staff — the Wizard equip's negative half - feat: Wizard's Staff - feat: Bard, King of Dale - feat: Dáin Ironfoot - chore: sync plan checkboxes after merge - chore(sim): regenerate COVERAGE.md for the LTR lane-1 batch - feat: Last March of the Ents - feat(sim): greatestStat — one parameterized slot for greatest power/toughness - feat: Sauron, the Lidless Eye - feat: Mithril Coat - feat: The Shire - feat: Rivendell - feat: Reprieve - fix(plan): next was red — three plan-integrity defects from the wave-28 adoption - docs(plan): wave-28 merge sweep — the Ring shape line, two adopted specs, seven findings - chore: data 2026.8.20 - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - fix(plan): sync plan checkboxes before merge runs its gates - chore: regenerate sim/COVERAGE.md - feat: Flame of Anor - feat: War of the Last Alliance - fix: Uruk-hai Berserker prints no menace - feat: Arwen, Mortal Queen - feat: Delighted Halfling - feat: Aragorn and Arwen, Wed - feat: Took Reaper - feat: Uruk-hai Berserker - chore: refresh the coverage table - test(triggers): pin the entry fan-out and the announcement's owner - docs: record the owner's standing directive on removing process and tooling - docs(plan): delete the wave-20 numbering block — 2,303 lines, eight waves stale - feat(kernel): one entry event fires every entry ability - fix: the lock's own scalar set missed usize, the shape it was written to fix - docs(plan): wave-27 sweep — HOB is kernel-only, and "N cards from a release" was false - chore(sim): stamp the wave-27 both-mode roundtrip re-verification - docs(plan): wave-27 merge sweep — HOB's workable queue was 15, and 4 of them were real - chore: sync plan checkboxes after merge - chore: regenerate sim/COVERAGE.md for the HOB batch - feat: Warg Tactics - feat: Long Lake Nuisance - test: split the merge-base raise check so it can be asserted - feat: Esgaroth Garrison - fix: sim:symbols was manufacturing four of its own findings - feat: lock descriptor flat scalars, demote the soft ceilings that never bound - fix(docs): validateEmblems is validateTriggerScopes, in four places - fix(docs): the other fifteen symbol citations that named nothing - feat: sim:symbols — a gate for the symbols comments cite - feat: Lake-town Lookout - fix(docs): target_override has two writers, not one - fix(docs): name the validator that actually exists - docs(plan): wave-26 sweep — the headline finding was false and this file promoted it - docs(plan): wave-26 merge sweep — the multi-ETB defect was guarded all along - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - test(sim): prove a staged division's provenance is hashed - feat: Gandalf, Spark Starter - feat(sim): trigger-side divided damage - fix(cards): cite Regenerate (701.19), not Goad (701.15), for a regeneration shield - feat(sim:plan,ci): run the CR-citation existence gate in merge and test:drift - feat(sim:review): audit the card modules' CR citations, and gate on existence - docs(sim): the funnel-family checklist is fifteen, and both copies say so - fix: terminate the two card tests that never swept their fixture - docs(plan): wave-25 sweep — ten green gates over two tests that never ran - fix(tools): a path-qualified .md is a kernel reference only under kernels/ - docs(plan): five kernel specs for the HOB skips, and re-triage four wrong annotations - docs(plan): harvest the wave-25 merge pass into FINDINGS.md - fix(sim): tap/untap cite CR 701.26, not 701.21 — and close two stale planner claims - chore(plan): retire the linked-duration control spec — a card batch solved it - chore: sync plan checkboxes after merge - chore(sim): regenerate COVERAGE.md for the HOB lane - feat: Radagast of Rhosgobel - feat: The Queen of Dale - feat: The Mountain-king's Return - docs: argue Frodo's trigger-time branch rather than caveating it - feat: The Lonely Mountain - chore: regenerate COVERAGE.md after the rebase onto next - fix: restore Adjust's docs, correct two citations, test the never-starts ruling - docs: AGENTS.md carries four rules, and the hatch count re-derived over 19 - feat: a Present-form claim so every kernel spec is falsifiable - chore: regenerate COVERAGE.md - feat: The Ring Goes South - feat: Sméagol, Helpful Guide - feat: one reveal-until funnel with whose-library, count, tapped and remainder - feat: Frodo, Sauron's Bane - feat: Scroll of Isildur - feat: Rangers of Ithilien - feat: one control-change funnel, and the duration LTR needs - feat: Stalwarts of Osgiliath - feat: Rohirrim Lancer - feat: The Black Breath - feat: Soothing of Sméagol - docs(plan): wave-24 sweep — the kernel queue falls for the first time - chore(sim): stamp the both-mode roundtrip for the LTR/HOB card wave - docs(plan): retire two kernel specs !788 satisfied in a better shape than they proposed - docs(plan): wave harvest — three filed harms were latent, and one exposure was 1 card not 3 - test(sim): pin the storied-ordering divergence on Bifur's own arrival - docs(sim): two paragraphs !788's block edge and graveyard origin falsified - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - chore: refresh the coverage table - revert: Aragorn, Company Leader — it cannot honestly be FULL yet - feat: Sauron's Ransom - feat: Riders of the Mark - feat: Aragorn, Company Leader - feat: One Ring to Rule Them All - feat: Samwise the Stouthearted - feat: Sting, the Glinting Dagger - feat: Bilbo's Ring - feat: Andúril, Flame of the West - feat: Bifur, Melodic Rider - feat: Elven Chorus - feat: Aragorn, the Uniter - feat: Dwarven Mauler - feat: Bard's Company - feat: Wose Pathfinder - feat: Flowering of the White Tree - docs(plan): rank 0 landed same day, and rule 3 has a vacuous-pass mode - docs(plan): clear the 8 baselined prose blocks; rule the three spec findings - fix(plan): a merged batch branch is not a live lane - feat(plan): gate block-annotation rot and phantom kernel specs in `check` - docs(wave): a brief may state a property only over the set it measured - feat(plan): batch refuses a lane count a live unit was not dealt under - docs(plan): wave-23 sweep — +16 cards, and four process defects no gate caught - docs(plan): wave-23 merge sweep — three MRs land, and half the skip list was already specced - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - chore: regenerate COVERAGE.md for the batch - feat: Sauron, the Dark Lord - feat: Shortcut to Mushrooms - feat: Ringwraiths - feat: Slip On the Ring - feat: Surrounded by Orcs - test(sim): Elvish Mariner's attack scry feeds its own watcher - refactor(sim): CommittedCounts assembles in one place, and a new arm cannot compile - docs(sim): warn at ctx.ringTemptsYou that nothing after it may read the bearer - feat: Sam's Desperate Rescue - feat: Elvish Mariner - feat(sim): CountSource.triggering_event — a count committed by the trigger event - chore(sim): regenerate COVERAGE.md — LTR 126 → 135 / 244 - fix: Ringsight searches after the Ring-bearer is designated - docs(plan): wave-23 prep — LTR adopts 21 orphans, and 41% of its block annotations were false - feat: Grishnákh, Brash Instigator - feat: Ringsight - feat: Now for Wrath, Now for Ruin! - feat: Horses of the Bruinen - feat: Gollum's Bite - feat: Gollum, Patient Plotter - feat: Inherited Envelope - feat: Faramir, Field Commander - feat: Mirrormere Guardian - docs(plan): wave-22 sweep — the first wave the merge pass rejected half of - fix(plan): derive the descoped-block test's rows instead of naming them - docs(plan): correct the equip-cost annotations where a dev can actually read them - docs(plan): wave-22 merge sweep — two merged, two sent back, and a false block annotation - chore: sync plan checkboxes after merge - chore: regenerate COVERAGE.md for the batch's four cards - feat: Éowyn, Lady of Rohan - feat: Legolas, Counter of Kills - feat: Gandalf, Friend of the Shire - feat: Galadriel of Lothlórien - fix: both dev-brief surfaces render through one `briefLine` - feat: Glorious Gale - feat: Ranger's Firebrand - feat: Relentless Rohirrim - fix: move `app.d.ts` into a tsc program - fix: a `sim:precedent` miss states the question it answered - fix: the dev brief prints a retired block, and DESCOPED does not skim as LANDED - docs(plan): wave-21 merge sweep — TriggerEvent hits its 64-arm ceiling - chore: sync plan checkboxes after merge - chore: sync plan checkboxes after merge - test(sim): Velomachus's modal free cast — the live repro the A/B found - refactor(sim): inline appendOptionalAdditionalCostCasts — it was an alias with a name that no longer described it - docs(sim): the reader's own comment says six copies, and names the four surfaces it deliberately does not claim - docs(sim): ENGINE.md — the announcement fan is one reader, and which surfaces route through it - refactor(sim): one CR 601.2 announcement reader, not six - test(sim): pin CR 701.54d's "complete" — the designation precedes the watcher - feat: Glorfindel, Dauntless Rescuer - chore: sync plan checkboxes after merge - feat(sim): the two printed Ring watcher events (CR 701.54a/d) - fix(test): the name census must not go red for a missing generated input - fix(plan): every number under a set code says what it counts - docs(sim): wave 20 merge pass — §11 rewritten, findings harvested, four doc paragraphs repaired - chore(plan): sync LTR checkboxes — 13 cards landed in wave 20 - chore(sim): regenerate COVERAGE.md for the batch - test: run the state-invariant checker while the delayed ability is on the stack - test: pin the choosing half of the delayed-trigger funnel (CR 603.3c) - fix: CR 603.3 puts a delayed triggered ability on the stack, so the step's window can answer it - feat: Council's Deliberation - chore: regenerate sim/COVERAGE.md for the five cards this batch landed - feat: Frodo Baggins - feat: Arwen Undómiel - feat: Elrond, Lord of Rivendell - feat: Dúnedain Rangers - feat: Boromir, Warden of the Tower - feat: Breaking of the Fellowship - fix: the 608.2b filter recheck dropped the targets already committed - feat: Bilbo, Retired Burglar - test: the temp-file leak assertion measures its own TMPDIR - feat: Dreadful as the Storm - feat: Bombadil's Song - feat: Enraged Huorn - fix(tools): every gate that reads a subprocess reads it through a file - feat: Fiery Inscription - feat: Claim the Precious - fix(tools): plan.ts reads its subprocesses through files, not pipes - chore: a .mailmap, because no git identity was configured at any level - docs: the wave-19 sweep — MASTER-PLAN §11, FINDINGS, and the 0.22.0 entry - docs(plan): release the Ring's 51 blocked-by entries in LTR.md - docs: retire the Ring kernel spec, and give applyEmblemTriggers its doc back - chore: sync plan checkboxes after merge - refactor(combat): gate CR 509.3d's walk on an emblem that watches it - fix(test): the scope test read its own subprocess short, and believed it - test: pin what the free-hand-cast over-approximation does and does not do - feat(kernel): the Ring, part 5 — tier 3's end-of-combat sacrifice - test(roundtrip): retire the free-cast-modal-etb quarantine row - fix(test): the scope test outran bun's 5 s budget, and misnamed why - refactor: one modal-ETB/multikicker precedence across both cast leaves - fix: announce a modal entry ability's mode on every cast walk (CR 601.2b) - docs: name the tools typecheck and sim:leak's third red path - fix(plan): specRepresentativeName ate the interior periods in a card name - fix(sim:leak): a mid-sentence FUNNEL CONTAINER claim now fails the gate - test: pin the typecheck's scope, so the next new directory cannot escape it - fix: typecheck tools/ and sim/tools/, which the gate never reached - docs(plan): the wave-18 sweep — the break is spent at v11, and three windows were one unit - docs: the three windows in ENGINE.md, AGENTS.md and the changelog - chore: reset the replay quarantine against the reset stream - chore: regenerate the golden corpus and re-record the WASM turn-cycle pin - test: pin CR 504.2, 507.2, 511.1 and 511.2, and regenerate the v11 replay fixtures - feat: open the draw, beginning-of-combat and end-of-combat priority windows - docs(plan): the Ring spec after parts 2 and 4 — only part 5 remains - feat: the Ring's tiered abilities — tiers 2 and 4, and an emblem that owns its own choices - refactor: one emblem-ability walk, and an emblem may have more than one trigger - docs: the leak gate's marker owns its line, and status names held specs - feat: a layer-4 supertype grant, and the Ring-bearer is legendary - refactor(plan): a seam under the process boundary, and the git reads behind it - feat(plan): status says which kernel specs are held, and what holding one costs - fix(sim:leak): a claim owns its comment line, so a citation stops claiming - docs: the wave-17 merge sweep — a CR 115.1a rules bug, and the Ring spec survived on purpose - docs(resolve_ctx): changeTarget reaches one target of the entry's own, not one committed ref - test(golden): pin the fixture-deck cell that crashed, and price what it leaves open - docs(sim): record parts 1+3, strike the emblem's phantom registry home - fix(lint-imports): the pass line says how many files it read - fix(plan): the MR body must not promise a deletion the merge will refuse - feat(sim): the Ring gets a real emblem, and its tier-1 block restriction - fix: a creature spell's entry-ability target is not the spell's target (CR 115.1a) - fix(tools): a tool must not report an outcome it did not verify - docs(findings): sim:plan debt's runtime section cannot see PlayerGame - docs: the wave-16 merge sweep — the Ring kernel is 1 of 5, and CI never had a cache - test(actions): the two states the projection bound assertion is about - test(golden): a solver fixture, because five greedy games saw no solver at all - feat: Birthday Escape - feat(sim): the Ring tempts you — CR 701.54's keyword action - chore: sync plan checkboxes after merge - fix(plan): the unknown-state notice omits a count it did not track - ci: test:zig declares a timeout that fits every runner; coverage --check gates - fix(plan): merge never reports a cause it has not read - docs(plan): wave 15 closed complete — four landed, and §11 re-swept on the integrated tree - chore: sync plan checkboxes after merge - docs(plan): wave-15 merge — 2 landed, 2 sent back, and §11's unit 1 row deleted - docs(sim): re-count ENGINE.md's trigger figures, and fix a dead symbol - docs: the four paragraphs this change falsifies - test: Torch the Tower's rider reaches a token, and that is new - fix(sim): the proof walk holds the CR 117 seat across a trigger pick - chore: sim:coverage — HOB 155/188, LTR 102/244 - test: the controller clause, in both directions - feat: Stone of Erech, Head of the Hunt - chore(sim): retire the ability-activation kernel spec, resync COVERAGE.md - feat: graveyard rewrites keyed on the dying creature's controller - feat(sim): a whenever-you-activate-an-ability trigger event - perf(sim): bound the projection assertion on the invocation axis - docs(plan): wave-15 prep — 14 specs verified live, and two §11 rows were wrong - chore: scenes is import, not deck work - fix: the documented-script gate was red on next, and a pipe hid it - chore: bun run scc — line counts over tracked files only - chore: group the 48 scripts into three tiers, and swap lint/lint-imports - docs(plan): --remove-source-branch is unreliable in timing, not in firing - gate: wave 14 re-verifies the quarantine unchanged, and the commander exclusion was false twice - docs: re-measure the orphan-branch backlog — 10, not 15, and where five went is not established - docs: name the staged_picks arithmetic instead of implying it — 7 calls, one append, one appendSlice - docs: the wave-14 sweep — three rows were right about the population and wrong about the defect - fix: next has not parsed since 1b0a3f174 — a nested double quote in a string - fix: escape the quotes that made replay-roundtrip.ts a parse error on next - refactor: delete the narrow resolution-cast drain, dead at its only call site - test: widen the converter chain so the deferred-tier pick is load-bearing - chore: claim the last two rule-5 containers, both in cast.zig - test: pin CR 117.5 — a queued trigger choice is not the priority answer - test: the two payment walks a cost-bearing mana source used to strand - docs: the CR 608.2b notes name which card was actually in the hole - fix: a trigger-side pick is not an action taken with priority (CR 117.5) - test: pin the two guards in the block-declaration close - fix: three more places the payment walk could not see the mana it was holding - fix: block triggers at the close of the declaration, not per blocker - test: cover every TargetRef arm of the recheck's slot lookup - fix: stage a modal .choice cast's targets — three sites, not one flag - docs: a wall clock under a parallel scheduler with a deadline is a max, not a sum - docs: rule §11 unit 2, and re-anchor the queue against f81fe9a6a - fix: the CR 608.2b recheck resolves the mode and ETB specs, not just the root - fix: the payment walk's step gate priced a mana rock's activation cost against an empty pool - gate: the wave-13 quarantine reset — 30 rows over 8 causes to 20 over 1 - docs: §11 anchors that move — cite the MR and the row, not a line in a file another lane is rewriting - docs: the wave-13 post-merge sweep — fourteen §11 rows falsified, and one of them was a hypothesis - test: make the free-cast filter pin discriminate — Shock, not an X spell - test: pin the free-hand-cast grant's per-card filter against the per-player hint - fix: a resolution-cast offer may open its own CR 601.2 windows - fix: the staged-cast projection bound answered "it forks" to two questions that are not one - docs: CHARTER records the prompt path's second bound, and who the raise advice is for - feat: a scoped prompt buffer — the linear mana tail gets its own allowance - fix: an attached Aura is rechecked against CR 303.4c, not CR 601.2c - docs(skills): score a mutation by the test it names, not by the count - docs: sim:golden pins five playthroughs, and the release-facing copy said four - fix: a CR 707.10f copy token keeps its token identity on the way out - docs: the wave-13 prep sweep — 46 findings retired, and one spec had shipped - fix: the native block floor dropped every "whenever this creature blocks" trigger - gate: the leak report deduped two different leaks into one line - gate: claim state.zig's 6 and zones.zig's 4 single-appender containers - gate: rule 5's marker learns the per-seat path - docs: re-sweep §11 at the integration point — the first pass was three merges early - gate: the combined re-sweep — 30 rows, and 2 mode-scoped causes were misfiled - gate: record the valve-draw reset — 82 rows -> 78, both modes agreeing - docs: sweep §11 against the twelfth wave — six rows falsified, four by inversion - gate: reset the quarantine against the matcher fix — 82 rows -> 36, 15 causes -> 9 - test: pin the class — an omitted replay boolean is false for all nine - fix: an absent replay boolean means false, not "don't care" - gate: the stack-priority-unclear cause is fixed and deleted - chore: sync plan checkboxes after merge - fix: a replayed valve draw reproduces the draw instead of erroring - chore: refresh the coverage table - docs: the buffer comments describe the tail that exists now - test: pin the staged mana tail, and say which guard is redundant - feat: stage the mana ability's cost-object pick - gate: reset the widened quarantine against the modal staging — 5 rows, not 24 - docs(sim): triggers.zig claims the two containers its funnels own - task: the 608.2b siblings are live, and eleven containers were ten - fix: the attack declaration drains its trigger choices at the close, like native - perf: the corpus sweep runs four games at once, and the plan catches up - release: the next release is 0.22.0, not 0.24.0 — three headings that never shipped - docs: rule the 256-cap fork — a product stages, a linear tail gets an allowance - fix: stage a modal cast's CR 601.2c targets, closing #403 in the base walk - docs: file the Equipment/LoreholdAggro per-action cost, measured not estimated - docs: the roundtrip corpus now plays all 1681 pairings, and the modes disagree - feat: sim:roundtrip pairs every vault deck with every vault deck - docs: sweep the plan against wave 11's subtype and combat lanes - fix: a combat trigger answered its own pick while a taxed trigger was owed - fix: a creature that entered attacking during a combat priority window was lost - fix: the two subtype slots could not hold a second addition - docs: sweep the plan against wave 10's driver lane, and escalate the cap ruling - fix: the prompt driver's extra family was blamed on the base walk - docs: sweep the plan against wave 10's first three lanes - fix: a creature that entered attacking during the declaration triggers was unblockable - feat: four more GameState containers name the funnel that owns them - fix: an activated ability rechecked no target at resolution - refactor: fold tap, tapEach, untap and untapEach into one funnel - fix: a noncreature's lost-abilities stamp was re-read off a thinned board - refactor: the artifact/enchantment destroy ran its own sequence beside the funnel - docs: sweep the plan against the ninth wave - fix: the prompt driver's trigger queue reported a stranger's pick as its own - refactor: collapse the destroy family to one ctx verb, and give it CR 608.2h - fix: stamp last-known lost-abilities for a noncreature too - refactor: claim four more GameState containers for the leak gate's funnel rule - feat: carry an in-flight departure through both clones and the position hash - fix: card_fixture.battlefield claims a CR 613.7d entry timestamp - docs: sweep the plan against the eighth wave - fix: apiCostObjectPower reads the board before the last-known stamp - refactor: collapse the type-change ctx family onto one Becomes funnel - docs: the CR 616.1 window does not work at the callers either - fix: gauntlet and ladder dropped every degradation counter - fix: a fire-time trigger answered whichever choice was at the head of the queue - chore: name cast.zig's entry attach and pin the timestamp it takes - docs: sweep the plan against the seventh wave - refactor: collapse the attach family to one CR 701.3 funnel - fix: the CR 616.1 pick is a candidate set, and a discard no longer re-derives it - fix: capture last-known power for a whole departure event, not one at a time - fix: a no-legal-target optional trigger is removed, not prompted - docs: sweep the plan against the sixth wave - fix: a graveyard intervener dying in the same event still applies - feat: Frodo, Determined Hero - docs: name every shipped theft that reaches the CR 616.1 divergence - docs: the graveyard ladder had a rung the enum never had - fix: the grant funnel gated on creature-ness, not battlefield presence - feat: gate the container-scope append the slot count cannot see - refactor: cast.announcementRecord shares the ActionRecord copy instead of repeating it - fix: CR 616.1 gives the graveyard pick to the controller, not the owner - refactor: fold the third hand-rolled floating-effects append - docs: sweep the plan against the fifth wave, and correct three of my own claims - test: pin a graveyard intervener dying in its victim's own state-based batch - fix: the /play fire-time trigger record dropped 27 of its 33 fields - fix: state invariants rejected every open trigger-origin target window - refactor: fold the last two hand-rolled adjustment appends into the funnel - test: pin the CR 616.1 graveyard pick, and settle that the event does not migrate - docs: say where the engine's pay step leaves CR 601.2's - docs: correct four CR citations in REVIEW.md against the pinned rules - docs: sweep the plan against the fourth wave, and close the citation audit - test: exercise the choose_permanent_picks invariant arm with the window open - perf: the staged cast's projection walk stops when it has every line it can offer - refactor: collapse the adjustment family, which had been protecting only creatures - feat: the multi-pick resolution choice stages, so Miasma Demon stops filling the buffer - feat: the damage event reaches a permanent recipient - fix: a trigger choice's log record dropped the scry it committed - docs: the any-number envelope gets its CHARTER entry - fix: a plural CR heading is satisfied by its singular - feat: audit the prose docs' CR citations under their own scope - fix: five CR citations in engine comments named the wrong rule - docs: sweep the plan against the third wave, and retract my own false finding - fix: the staged trigger announcement dropped eleven of its own dimensions - fix: eleven CR citations named the wrong rule - fix: the proof pass's level allocation no longer exits uncounted - fix: a copy effect leaves the replacement-presence memo describing the wrong card - fix: the any-number envelope was a numeric coincidence, not a declaration - refactor: applyCopiedSpellTriggers collects its batch before firing it - refactor: make the trigger funnel's dispatch comptime so its hand-list checks itself - sim: pin the .life_gained condition channel, the reason the event exists - sim: fold the two life-gain flags into a .life_gained replacement event - docs: sweep the plan against the legend-rule wave, and fold it into 0.24.0 - feat: the legend rule declares one policy and runs two, so make it a choice - feat: #403's last four cast-side products stage - test(sim): pin what the priority window does when it reaches its step bound - fix(sim): the event_filter allowlist was missing six of its own dispatches - feat(sim): the citation audit reads every comment, not only declarations - fix: the combat trigger's settled commit is not a replay record either - docs: sweep the plan against the four-lane funnel wave, and cut 0.24.0 - chore(sim): the entersTapped base predicate outlived its last caller - perf: the trigger index is +9.48% on a fixed workload - docs(sim): a stream break is a gameplay break for any deck that shuffles - docs(sim): ENGINE.md said trigger firing has no funnel at the front - feat!: replay stream v8 — the settled trigger commit is gone - refactor: 31 hand-written CR 603.2d walks become one funnel call - refactor: fold "creatures your opponents control enter tapped" into the replacement family - fix: the engine's own settled trigger commit is not a replay record - feat: one indexed CR 603.2d walk behind triggers.collect - feat: plan reap --remote sweeps the unit branches left on origin - fix: plan merge reads a queued merge as a failure and skips what it owes - fix: sim:ratchet was the one honesty gate in neither CI job - chore(sim): delete the dead discard auto-pick and the entersTapped alias - docs(sim): the main phase's window is CR 505.6, not 505.1a - docs(sim): the honesty section was miscounting its own gates - docs(sim): sweep the plan against the wave that closed it - docs(sim): the step bound is a CR 104.4b approximation, not an envelope bound - docs(sim): ENGINE.md describes one priority window, and the step bound is pinned - docs: record that `plan reap` blames dirt for every worktree it keeps - docs: triage the unit-2b harvest, with the quarantine re-measured in both modes - docs: record that `plan merge` cannot see a scheduled merge - docs: triage !739's two findings, with the branch inventory re-measured - test(sim): pin the reveal the discard collapse removed - refactor(sim): the discard family is one keyword action, so it is one verb - docs: triage the discard-collapse, proof-corpora and enters-tapped findings - test: the round-trip quarantine is 9 rows over 4 live causes - feat: one priority window, two action sources — replay wire format 7 - fix: an open MR is what makes `plan start` a resume - fix: the enters-tapped decision reads CR 614.12's counterfactual - docs: triage the ReleaseFast re-measure findings - test(sim): state the Saga cadence and its sacrifice (CR 714.3c / 714.4 / 704.5s) - test(sim): prove a CR 117.1b step against the priority walk, not the seat walk - test(sim): state five more rules in the two proof corpora - fix: the roundtrip quarantine is measured in both optimize modes - docs(sim): decide where the damage_marked sibling declares itself, and sharpen the rollout-saturation measurement - docs(sim): declare the saturation ceilings, and give two comment blocks their tests back - fix(sim): the life ceiling is the counter ceiling's twin, and was equally false - fix(sim): the counter ceiling is a saturation point, not a corruption claim - docs(sim): the determinism break was a false invariant, and the diagnosis travelled three passes unchecked - chore(ci): test:ts triggers on sim scope, so the job that runs bun test sees engine changes - docs(sim): close the ladder test-graph finding, and check what it did not change - fix(sim): sim:bench walks the turn CR 117 actually opens, and a test says so - fix(sim): root ladder.zig in the test target, and fix the four cases that fall out - fix(sim): the install stamp goes to stderr, not stdout - fix(sim): every gate that reads the manatab binary now builds it - docs(sim): harvest the !731 review — the fix works, its stamp does not - docs(sim): the resampling default is decided, and ladder's tests never ran - docs(sim): harvest !728/!730, and the stale-binary false red that nearly sent both back - fix(sim): let the floor veto the interval — a binary separated from itself - docs(sim): the entry-replacement verbs carry the CR 614.12 counterfactual on their surface - fix(sim): CR 614.12 — an entering permanent's characteristics are read as they would be on the battlefield - test(sim): the unpaid half of ward on a chapter, and drop the CHARTER declaration - fix(sim): ward fires on a targeting triggered ability (CR 702.21a) - docs(sim): the aura-cooped-up hash move was a repaired fixture, not a reorder - feat(sim): make an A/B alternate by construction, and report what it cancelled - test(sim): reset the round-trip quarantine — 78 rows to 31 - fix(sim): every CR 117 priority window opens, gated by nothing - docs(sim): strike the proof pass's ~4% cost — the measurement was an order artifact - docs(sim): retire the combat-declaration story from the two docs that still told it - docs(sim): the bail enum's own comment names the helpers it actually has - feat(sim): count how each proof pass ended, not only where its nodes stopped - feat(sim): name every MCTS-solver bail, so the yield's residual is measured - docs(sim): the filter refusal is the end state, not a waypoint - feat(sim): render an ObjectQuery from its structure, and wire it into ward, sacrifice, tap-other and mirror mana - docs(sim): the merge pass repriced unit 2 and struck a census number nothing computed - feat: the pinned round-trip games cover every format the corpus does - docs(sim): a filter predicate is a Red Line, and the metric never sets the code's shape - refactor: one create verb for the six token slots, and a gate the next wave can't walk past - feat: the replay gate sweeps every vault format, not only Standard - docs(sim): prep pass — orphan branches triaged, four spec pointers settled - docs(sim): the cost-reduction spec is two cards, and says so before its body - docs(sim): sweep the plan after !712-!722 — seven rows falsified, one rewritten - fix(plan): delete the superseded local branch instead of asking glab to reset it - fix(plan): wait for GitLab's head to catch up, not just its merge status - docs(sim): narrow the StackItem hashing gap out of #1007 and file it alone - chore: sync plan checkboxes after merge - fix(sim): the tap-cost body guard needs an opponent's end step, not any end step - docs(sim): retract the solver half of the instant-activation finding - docs(sim): say why the instant-window coverage assert is wired to one caller - docs(sim): re-measure the roundtrip quarantine on the instant-activation arm - refactor(sim): drop the two TriggerKind arms TriggerRef now names - refactor(sim): StackItem names a triggered ability by TriggerRef - fix(sim): pilots activate abilities at instant speed, and a classification keeps the window honest - docs: the build command belongs in AGENTS.md, and three ENGINE.md sentences were false - docs(sim): harvest the wave — four corrections and four findings - chore: refresh the coverage table - chore: refresh the coverage table - fix: MonoGElves is a legal 60-card deck again - feat: Arcane Denial - docs: the counter-replacement ordering divergence is declared, not commutative - fix: an off-battlefield recipient is no counter-placement event - perf: the counter table runs off storage its caller sizes - feat: Vorinclex, Monstrous Raider - refactor: one staging table for every counter, with the LKI it opened with - chore: sync plan checkboxes after merge - feat: Liliana, Heretical Healer // Liliana, Defiant Necromancer - docs(sim): the library funnel's comments stop claiming CR 701.24c/d - docs(sim): file the instant-activation gap that sits under every measurement - refactor: one putOnLibrary verb for the eight library-placement slots - feat: Molten Psyche - docs: the replay twin stops asserting what the live loop no longer does - feat: Necropotence - Revert "test(ci): PLANT a text drift — Cackling Prowler's ward reads {3}, prints {2}" - test(ci): PLANT a text drift — Cackling Prowler's ward reads {3}, prints {2} - feat(sim): a mana ability's structural riders are sentences, not refusals - chore: refresh the coverage table - feat: Bolas's Citadel - ci: provision bun in the zig job until the image can be rebuilt - feat: Spelunking - ci: sim:text runs in CI, on a zig image that now carries bun - feat: Echoing Deeps - feat: Boseiju, Who Endures - test: pin the anchored error match against an echoed file - feat(sim): a new roundtrip failure is retried and says whether it held - test(sim): close the first-strike hole in CR 510.1's strictness - fix: the prior reads the world the search runs in, not the real position - feat: Otawara, Soaring City - feat: the evaluator seam, before the ML phases need it - fix(sim): the replay fixtures carry the wire format the engine reads - fix(sim): a failed round-trip keeps its replay and says what the binary saw - feat: gate untested .full cards, and sync plan files after a merge - test(sim): grow both proof corpora — five CR scenarios, two mate positions - fix: the dies-this-turn exile rider competes under CR 616.1 - docs(sim): Q8 — ObjectQuery.desc is UI-only, and the families render from structure - docs: the vault-format gap was counted by folder, and folders are not formats - fix: live priority after an activation matches the replay driver - docs: sweep the plan against the consolidation merge, and delete what landed - fix: a /play save mid-division keeps the points it was taken between - fix: drop the debug print a lane left in the replay division path - chore(sim): drop the empty rt.err a lane left in the tree - fix(sim): the forced division is CR 510.1c's second clause and nothing else - feat: sim:fields — the descriptor-doc gate, enabled at zero suppressions - feat: closed-set completeness, computed off the refusal ladders - feat: mcts_resample — a fresh world per rollout, not per search - docs: the six highest-traffic ctx verbs get their contracts written - docs: what the engine does with a card's board-wide statics - docs: what the engine does with a card's abilities - docs: what the engine derives from a printed cast mechanic - docs: what the engine does with a card's cast surface - docs: what the engine does with a card's printed characteristics - chore: data 2026.8.13 - fix: regeneration is CR 701.19, and three more citations named the wrong rule - fix: counters divided among targets land as one simultaneous action - docs: Q7 is closed by its number — perfect information is worth +49 Elo - docs(sim): declare what CR 510.1c left behind, and pin the step it rewrote - docs: the cheat delta, beside the flag that produced it - fix: /play tells a missing deck from a loading one, and takes the filename - fix: a /play save mid-blocker-order keeps the picks it was taken between - feat: combat damage follows CR 510.1c, not a rule the CR deleted - docs: harvest the citation sweep, and the index defect under it - fix: "remove all counters from it" reaches lore counters - fix: the charter's cleanup-discard citation names no rule either - fix: route build:wasm through the zig cache wrapper - feat: a fixed mana yield is a multiset, so the sequence sorts too - refactor: split counter placement into its apply and fire halves - fix: a CR section reference cannot ride inside a citation run - fix: emblems are colorless by CR 114.3, not 114.6a - fix: miracle is CR 702.94a; there is no 702.94c - fix: summoning sickness is CR 602.5a; there is no 602.5g - fix: convoke is CR 702.51a; there is no 702.51e - fix: sacrifice is CR 701.21a, not 701.16b - fix: cleanup discard is CR 514.1; there is no 514.1a - fix: sorcery-speed timing is CR 305.1 / 307.1, not 505.5a - fix: countering a trigger is CR 701.6, not 701.5 - fix: fabricate is CR 702.123, not 702.102 - fix: the citation audit missed 704.5aa and every module-level verb - fix: a spell's mandatory target is CR 601.2c, not 601.5c - fix: transform is CR 701.27, not 701.28 - fix: regenerate is CR 701.19, not 701.15 - fix: magecraft is an ability word, so it has no CR rule of its own - fix: putting a land onto the battlefield is CR 701.18a, not 505.5b - fix: evoke's sacrifice is CR 702.74a; there is no 702.74b - fix: saddle is CR 702.171, not 702.169 - fix: foretell is CR 702.143, not 702.144 - fix: echo is CR 702.30, not 702.29 - fix: sacrifice is CR 701.21, not 701.17 - fix: skulk is CR 702.118, not 702.72 - fix: meld is CR 701.42 and CR 712, not 702.83 - fix: champion is CR 702.72, not 702.71 - fix: a determinization must not redeal a card the position names - docs: record the second fan-out and schedule the next wave - ci: run sim:oracle and sim:leak beside sim:drift - docs: /play orders blockers, and the CR rule it revealed is gone - docs: the carry-over list landed, and the kernel spec is discharged - refactor(sim): the attachment settle has one departure path, not two - docs: the activation-cost family landed, and corrected its own justification - test: the /play write path crosses the kernel boundary in the app suite - docs: 0.23.0, and the gate that caught this plan lying - feat(sim): the CR 602.1b activation-cost family for sim:text - fix: /play names the decision it is asking about - chore: wire sim:leak into the merge queue - fix: drop the Aura conjunct from the entry-exile predicate - fix: the four-copy exemption is the basic supertype, not five names - test: the conformance sweep checks what it offers, and says where it went - feat: sim:leak — the engine-leak gate, measured before it gated - docs(sim): record the two structural calls the departure funnel had to make - docs: harvest the counters collapse and sim:review into the worklist - fix: /play can order blockers again - feat: sim:review — a card file beside the CR semantics of every verb it calls - fix(sim): the legend rule and meld take the departure funnel too - refactor(sim): one battlefield-departure funnel, and the two defects hiding in the retypes - feat(sim): CR 400.7a–m as one named, CR-indexed list - test(sim): pin the three contracts the counter funnel unified - refactor: collapse the 9 counters verbs into 1 vtable slot - feat: mcts_masked — the pilot denied its hidden information - docs: P4 measures closed sets, not a fraction of the pool - docs: close #403's cast side against the measurement, not a corpus - feat: replay wire format 4 — the Aura entry target stages - docs: record the damage funnel's four rules fixes in 0.22.0 - docs(sim): the damage collapse, and the gate gap it exposed - chore(sim): drop the now-dead isAuraWithExileUntilLeaves alias in actions.zig - fix: the exile family cites CR 701.13, not 701.18 - refactor: read the source facts once on the single-recipient route - test(sim): pin the three contracts the damage funnel unified - refactor: collapse the 9 damage verbs into 1 vtable slot - test(sim): pin the entry trigger's target index for Sheltered by Ghosts - docs: cut 0.22.0 for the MASTER-PLAN wave - docs(sim): the cast side of #403 was not closed, and say why nobody saw it - docs(sim): record #546's result and the /play blocker-ordering defect - fix: the ladder's half-percent sample size rounds up - perf(sim): pin Action's size exactly, and re-read the two comments it aged - docs(sim): sweep MASTER-PLAN for the wave's landed work and corrected counts - feat(sim): stage Sheltered by Ghosts' host × exile product - docs(sim): harvest the 2026-08-13 wave's findings - feat: the ladder reports how much of its rating is noise - test(sim): fail when a fixture deck stops having a golden playthrough - feat(sim): pin four golden playthroughs and the script that rewrites them - fix(sim): sim:text reads a back face's mana abilities - feat(sim): record golden playthroughs from the live loop - refactor: collapse the 18 exile verbs into 1 vtable slot - perf(sim): Action 544 B -> 292 B; the blocker order leaves the struct - feat(sim): sim:text generates mana abilities - fix: end the turn goes straight to cleanup, in all three turn drivers - feat(sim): sim:text generates kicker, multikicker and offspring -
v0.21.0
Release: v0.21.0feac7df1 · ·v0.21.0 Commits since v0.20.0: - docs(sim): harvest !704's three findings - docs: record the user-visible work the collapsed entry was missing - docs: collapse the three unreleased headings into 0.21.0 - docs(sim): close the three findings !697 served, and file two queue defects - fix(plan): the merge test gate builds the wasm it reads - docs(sim): record why !701's seam is not a home for the pip mask - docs(sim): ENGINE.md carries the closed CR 704.5 set - docs(sim): record which half of the cast-cost probe filter is load-bearing - docs(sim): sweep the worklist after !692, and correct two records it left false - fix(sim): filter the cast-cost probe back to the line the window holds - docs: record W7 in the changelog and sweep MASTER-PLAN - perf(sim): keep the pip probe off casts that owe no dimension - chore(sim): retire two kernel specs whose work landed - feat(sim): stage the rest of the cast-cost announcement - fix(sim): a green Zig gate prints nothing again - docs(sim): retire the two default-meter reds and the offspring wait - feat(sim): the proof pass is opt-in as mcts_solver, not the mcts default - chore(sim): re-measure the roundtrip quarantine on this branch - test(sim): pin that an instant-speed window ends only on an empty stack - fix(sim): an instant-speed priority window ends only on an empty stack - feat(sim): count the proof lines the state-seeded-RNG guard refuses - docs: triage the 2026-08-12 merge pass findings - docs(sim): record what the solver measured in MASTER-PLAN §7 and §11 - feat(sim): ladder --verify, the mcts_flat A/B seat, and aggregate sims/sec - feat(sim): MCTS-solver — AND-OR proof backup in the pilot - test: pin cast-mechanic at zero suppressions - fix: solve an object cost's pick and its mana as one payment - docs: the verb-family prefix has now been wrong in both directions - docs: the search family was 7 slots, as §5 predicted - docs(sim): record the closed CR 704.5 set - refactor: collapse the 7 search verbs into 1 vtable slot - docs: record W5 in the changelog and sweep MASTER-PLAN - chore: refresh the coverage table - perf(sim): reject the CR 704.5g arm on marked damage before any characteristic - docs: the graveyard-return family was 13 slots, not nine - fix(sim): keep the text verb's dash check out of the flag inventory - feat(sim): a StateBasedAction enum, one arm per CR 704.5 letter - test(sim): give the native-vs-WASM conformance matrix an X spell - refactor: collapse the 13 graveyard-return verbs into 1 vtable slot - docs: record the rules-text gate in MASTER-PLAN and AGENTS - docs: the gate list names the wrapper, not bare zig build - test(sim): the rules-text normalizer's own transform tests - fix: the repo-deck MCTS test runs every time - fix: a green Zig gate prints nothing - fix(sim): drain the whole CR 601.2 announcement in the live drivers - feat(sim): descriptor-generated rules text, diffed against pinned oracle - feat(sim): two proof corpora — CR-indexed scenarios and mate-in-N - feat(sim): bump the replay wire format to version 2 - docs: the combat damage windows are closed, and the quarantine says so - test: the hostile-input refusals name the guard that must answer - test(sim): re-measure what X shares a 601.2b announcement with - feat: the regular combat damage step opens its CR 510.3 priority window - test(sim): drive the CR 601.2b window from the card fixture - feat(sim): stage the CR 601.2b X announcement - fix(sim): name the 601.2b keyword a cast label claims - test: apply_choice hostile-input audit (MASTER-PLAN §8) - fix: the staged-choice depth bound is loud, not a rules answer - docs: the ctx verb audit's subject axis is exhausted - feat(sim): give Offspring its own cast mechanic - refactor: collapse searchLibraryToBattlefield/…For into 1 vtable slot - refactor: collapse gainLife/gainLifeFor and loseLife/loseLifeFor into 2 vtable slots - docs: answer every open decision in MASTER-PLAN §12 - feat: land .permanent_entered's representative and close its kernel spec - fix: unbreak the branch and clean up what the permanent_entered work left - docs: update MASTER-PLAN vtable count to 300 (was 261) - refactor: collapse createToken/createTokenFor and createTappedToken/createTappedTokenFor into 2 vtable slots - refactor: collapse draw/drawFor into 1 vtable slot - refactor: collapse chooseAtResolution/chooseAtResolutionFor into 1 vtable slot - feat: add .permanent_entered trigger event - docs: update stale kernel specs — exile-link and damage defects both landed - chore: remove the writing skill - docs: sweep !685 W4 target walk onto MASTER-PLAN - fix: sync Drakuseth FULL manifest + retarget wasm cost labels - docs: stop handoff — !685 W4 CI red, next tip 89f4a044 - feat(sim): stage CR 601.2c cast target walk - docs: sweep !686/!687 from MASTER-PLAN and FINDINGS - fix: gate ObjectInMultipleZones dump off WASM - diag: name object + zones on ObjectInMultipleZones - test: pin CR 509.1h block_state after all blockers leave - docs: sweep MASTER-PLAN after !681–684 - docs: mark legend-rule token cull landed in FINDINGS - docs: drop legend-rule token cull from known-red - feat: Debug event/view coherence invariant - feat: stage single-pick additional costs instead of fanning them - fix: fan as-enters choices on every cast leaf - fix: legend rule culls every token, not only copies - docs: sweep MASTER-PLAN after !675–680 - feat: view JSON bytes per prompt kind in bench --json - fix: stamp Object.blocking on every block declaration - perf: presence-gate resetPermanentForZoneChange bump - feat: one checkProposedCast gate for CR 601.2e - feat: stack must be empty at phase boundaries - refactor: classify every StagedChoice family in one meta table (#361) - docs: sweep MASTER-PLAN and FINDINGS against 16446f9a - docs: make the plan safe to hand to someone who was not here - docs: sweep after the first-strike step, and file the half it left - test: quarantine the one 818-upkeep case the first-strike window widened - docs: sweep the plan after ward and the oracle gate - feat: the first-strike damage step is a real step - docs: say what the greedy pilot does at a ward window - docs: name the oracle shape gate where the drift gate is named - fix: Shadowmage Infiltrator declares fear - feat: sim:oracle, the oracle-driven shape gate - refactor: one card-source parser and one printed-record lookup - docs: retract my own perf finding, and file the two real ones - feat: ward uses the stack - docs: sweep the plan, tenth unit landed - fix: seed the chi-square shuffle test, and correct the null it claims - refactor: route the activated 608.2b recheck through the named helper - docs: sweep the plan against the tree, and make sweeping the rule - docs: spec the ward-uses-the-stack kernel - fix: the zig CI cache stops growing without bound - fix: every ability a card prints for one event fires (CR 603.1b) - fix: name the optimize mode `build`, as bench and ladder already do - fix: the roundtrip gate states the build it measured - feat: name the CR 613 layer set in code - fix: excess damage counts deathtouch, in one place - docs: the roundtrip gate answers differently in Debug and Release - docs: my own entry was one of the things the restore falsified - fix: every leave-battlefield funnel detaches what was attached - feat: restore the worklist bodies the issue migration cut - docs: a third of the worklist was truncated on import, and it is recoverable - docs: record the measured fixpoint high-water marks - docs: trigger firing has a funnel at the back and none at the front - task: whole-EventKind boundary test + known-fail test convention - docs: a crash on three shipped cards, filed where someone will find it - fix: a fixpoint that does not converge fails loudly - docs: the plan's three worst rows, corrected against the tree - fix: a staged cast announces exactly once - docs: excess damage takes the greatest per-type amount, not the least - docs: land the engine architecture program as a map - docs: the roundtrip gate is fine, and the trap is how it was measured - chore: refresh the coverage table - chore: refresh the coverage table - feat: Goblin Plate Mail — an inline amass continuation - feat: Goblin Plate Mail - feat: Mirror of Galadriel - feat: Silvan Reveler - feat: cost reduction for activated abilities, equip included - chore: refresh the coverage table - feat: Great Gilded Boat - feat: Sound the Trumpets - feat: Patient Instructor - chore: refresh the coverage table - revert: Iron Hills Stalwart stays .partial - fix: replay a staged cast, and re-pin the quarantine it moved - test: pin the ascending floor and the completion probe by mutation - test: pin the any-number envelope against the proposal gate - fix: answer a staged window from every pilot, and probe the held line - test: drive the CR 601.2c window, and pin the offered set by size - feat: propose cast targets one slot at a time (CR 601.2c) - feat: Glamdring, Foe-hammer // Gleam of Death - feat: Thorin, Mountain-king - feat: Stir Up Trouble - feat: Iron Hills Stalwart - feat: Ragged Short Spear - feat: Thorin's Last Stand - feat: Velvetwing Butterflies // Gaze in Wonder - chore: refresh the coverage table - docs: blocked-by is not exhaustive, and the ranking is corrected for it - feat: Radagast the Brown - docs: avgSnapshotBytes cannot see a fixed-width field, and I quoted it anyway - feat: Voracious Fell Beast - feat: Tidings of War - feat: Treason of Isengard - feat: Uneasy Partings - feat: The Torment of Gollum - chore: refresh the coverage table - chore: land a-whenever-you-scry-trigger-event-carryi, delete its spec - test: CopyException's gates use the tree's one probe generator - feat: Warbeast of Gorgoroth - refactor: drop the orphaned printed-type "still legal" recheck - feat: Snowslope Hunter - fix: a token dies with the types it has, not the ones it was printed with - feat: a .scried trigger event carrying the cards looked at - refactor: one CopyException for every copy surface - feat: Wargling - feat: Théoden, King of Rohan - feat: Smaug, the Great Calamity - docs: harvest MR A's design from a handback with no code - feat: Uglúk of the White Hand - fix: free twelve HOB cards, and make the plan buckets partition - docs: the ladder crash was never the kicker fan-out - test: Shire Shirriff's enumeration test terminates on its own open window - chore: refresh the coverage table - chore: refresh the coverage table - chore: refresh the coverage table - docs: COVERAGE.md leads with the notice, the total, and the table - style: zig fmt - refactor: one SeatCursor for the APNAP seat walk, and two false docs closed - refactor: each-player sacrifice rides StagedChoice, not a queue of its own - test: pin the no-window branch on the action log, not the queue - test: pin the no-window branch and the 256-line degradation - test: pin the each-player sacrifice window - feat: each player sacrifices creatures of their own choice - chore: refresh the coverage table - feat: Troop of Ponies - feat: Vow to Erebor - feat: Stony-Voiced Goblins - docs: a prohibition sits seven lines above the helper it forbids - test: Vow to Erebor's illegal-target test ends with the sweep - refactor: the six permanent types become an enum CR 110.4 closes - test: argue expectNoTriggerChoiceFrom by mutation in both directions - feat: fixture verbs for the two claims the harness could not make - test: gate that every card test ends with the fixture sweep - feat: Fixture.done asserts no choice window is left open - chore: refresh the coverage table - feat: Troop of Ponies - feat: Vow to Erebor - feat: Stony-Voiced Goblins - docs: drop the two kernel specs this batch landed - chore: refresh the coverage table - feat: Along the Crooked Way - feat: one activation can owe both a staged cost and a target's ward tax - test: Gundabad Opportunist names why its no-action probe filters on kind - chore: refresh the coverage table - feat: Uncover the Moon-Letters - feat: Desert Were-Worm - feat: The Balrog, Flame of Udûn - feat: Mirkwood Meditator - feat: Moment of Glory - feat: Shire Shirriff - feat: CR 601.2 proposals nest, so PendingChoiceConflict stops being a rules answer - test: isolate Stew the Coneys' first target slot - feat: Reverent Howl - feat: Lake-town Toymaker - feat: The Battle of Bywater - feat: Quarrel - test: Stew the Coneys pins both target slots, not one - feat: Troop of Ponies - feat: Stew the Coneys - feat: Strider, Ranger of the North - feat: Saruman the White - feat: Gundabad Opportunist - feat: Giant's Boulder - feat: Vow to Erebor - feat: Rising of the Day - feat: Old Thrush - feat: The Mouth of Sauron - feat: Warg Rider - feat: Guardian of the Halls - feat: Long-Bodied Grey Dog - feat: Shelob's Ambush - feat: Swarming of Moria - feat: Second Breakfast - feat: Elvenking's Harper - feat: Snarling Warg - feat: Goblin-town Flunkies - feat: Stony-Voiced Goblins - feat: Quarrel's End - docs: one of two fixes to one function is pinned, the other is not - chore: refresh the coverage table - chore: refresh the coverage table - chore: refresh the coverage table - chore: refresh the coverage table - docs: the import lint tells you to run a script that does not exist - chore: sort the flag-gate test's imports - docs: census against the merged tree, and LTR's shape lines are not trustworthy - chore: refresh the coverage table - feat: Quickbeam, Upstart Ent - fix: Shagrat's attach obeys CR 301.5b/c and cites the right rules - feat: Shagrat, Loot Bearer - docs: reconcile the completion census, escalate 403, and name the real card - docs: the --help claim was false, and 0.16.1 records the fix - fix: sim:roundtrip reads the --seeds form its usage prints - test: a flag value that names a real deck is still not a deck - fix: --help reaches the help, and --seed=7 reaches the binary - fix: the usage names every verb and every flag - feat: Samwise Gamgee - feat: Fall of Cair Andros - docs: the sweep and the probe are two commands, and only one is a gate - fix: a flag value is not a deck name - fix: sim:roundtrip names its corpus, and its 36 red seeds name their causes - docs: the play wrapper eats a flag's value, and --help never worked - feat: Saruman's Trickery - feat: March from the Black Gate - feat: Dreaded Bat-Cloud - feat: Boughside Wanderers - feat: Bofur, Reliable Guardian // Concerted Care - feat: Woodland Weavemaster - feat: Wilderland Scrounger - feat: Troll Negotiations - feat: Thrór's Map - feat: Shire Terrace - test: the prompt path is pinned to refresh before a choice dispatch - feat: Oath of the Grey Host - feat: Merry, Esquire of Rohan - feat: Shire Scarecrow - docs: bun install is the fresh-worktree remedy, not svelte-kit sync - feat: Tom, Bert, and William - feat: Pippin's Bravery - feat: Rush the Room - fix: unit start bootstraps the worktree, and names what it did not do - feat: Mines of Moria - feat: Pinecone Strike - fix: Shower of Arrows carries the pilot removal hint - test: prove the shared activation prologue runs on all six arms - fix: the prompt path refreshes hand-free-cast like the other three - feat: Mirkwood Channeler - feat: Iron Hills Stalwart - feat: Revive the Shire - feat: Through the Forest Gate - test: pin the synthesize-cast declaration and its membership gate - chore: a raised ceiling keeps its rule, and three stale copies catch up - chore: raise the TriggeredSpec and StaticSpec ceilings - feat: Ioreth of the Healing House - feat: Rally at the Hornburg - refactor: name the activation proposal, and fix the arm that drifted - test: the membership gate is load-bearing at three cast-side families - feat: Lembas - feat: Thranduil's Company - feat: Magnificent End - refactor: one membership gate for the proposed action - feat: Mushroom Watchdogs - feat: Enchanted River's Grasp - feat: Shower of Arrows - feat: Oin the Brave - docs: name the leftover-worktree refusal in CONTRIBUTING - feat: Dwarven Shortsword - feat: Prince Imrahil the Fair - feat: Dwarven Provisioner - feat: Bolg's Company - feat: Attercop - feat: Lakeshore Apothecary - fix: plan refuses a unit worktree path git does not own - feat: detect one primitive claimed by two MRs - fix: the worktree registry decides what a worktree is, not existsSync - feat: Great Fierce Bee - feat: Mordor Muster - chore: a raised ceiling keeps its rule, and three stale copies catch up - refactor: one offer dispatcher, not four copies of it - feat: Ravening Warg - feat: Smaug's Fury - chore: raise the TriggeredSpec and StaticSpec ceilings - docs: harvest the wave boundary, and retract two plan-file claims - test: Haradrim Spearmaster reaches the new default through beginCombat - fix: one ResolveCtx.isLegendary, not two - chore: refresh the coverage table - chore: refresh the coverage table - chore: refresh the coverage table - chore: refresh the coverage table - chore: refresh the coverage table - feat: close the runCombat and planeswalker-loyalty doors on the same shape - feat: Faramir, Prince of Ithilien - feat: Grond, the Gatebreaker - feat: Gorbag of Minas Morgul - feat: Friendly Rivalry - feat: Horn of the Mark - feat: Grima Wormtongue - feat: Great Hall of the Citadel - feat: Galadhrim Bow - feat: Hobbit's Sting - feat: Haradrim Spearmaster - feat: Gimli's Fury - feat: The Great Goblin - feat: Old Man Willow - feat: Nimble Hobbit - feat: Legolas, Master Archer - feat: Orcish Medicine - feat: Moria Marauder - feat: Horn of Gondor - feat: Nasty End - feat: Lash of the Balrog - feat: Meriadoc Brandybuck - feat: Mirkwood Spider - feat: Protector of Gondor - docs: correct the fixture prose the new default falsifies - test: tripwires for the two harness defaults this unit changed - test: name the choice at 60-odd call sites the harness was answering - feat: the fixture holds at every queued trigger choice that is a fork - feat: Orcrist, Goblin-cleaver - feat: The Arkenstone // Seek the Heart - feat: Thranduil, Sindarin Liege // Silvan Rally - feat: Dáin, Lord of the Iron Hills - feat: Bombur, Gentle Dreamer - feat: The Lord of the Eagles - feat: The Sackville-Bagginses - feat: Well-Worn Spatula - feat: Wood Elves - feat: Bilbo's Deadly Slice - feat: The Notary Hobbits - feat: Getaway Barrel - feat: Part in Friendship - feat: Stone-Giant of High Pass - feat: The Misty Mountains Cold - docs: harvest the task-MR pass, and correct the buffer ceiling to nine - feat: Thorin Oakenshield - feat: Roll-Roll-Roll-Roll - feat: The Black Arrow - feat: Smaug the Magnificent - feat: The Master of Lake-town - feat: The Chief Warg - docs: harvest six findings from the HOB/LTR merge pass - docs: the land-play special action is CR 116.2a, not 505.5b - chore: refresh the coverage table - refactor: derive commitsEntryChoices from wasCast - chore: refresh the coverage table - fix: an entry trigger keeps its targets on a non-cast entry - chore: refresh the coverage table - fix: one payment reader for every cast-enumeration gate - chore: refresh the coverage table - docs: REVIEW.md step 1 has landed, and the file now says so - fix: plan start refuses a specless kernel, and status names dangling refs - fix: drop the worktree's zig cache, not the main clone's - docs: plan drops the main clone's zig cache, never the worktree's - ci: expire job artifacts - chore: refresh the coverage table - docs: StaticSpec is over ceiling, and Kili gets a real blocked-by - feat: raise the coverage floor to ten covered cards - feat: Smaug, Wicked Worm - docs: mark LTR's 32 phantom entries, and retract a bad detector - feat: a covered-card floor under the coverage table's ratio rule - feat: Bilbo, Luckwearer // Burglar's Plot - feat: a generated per-set coverage table - docs: Q5 answered — widen the permanent_damaged dispatch - feat: My Precious // Allure of Power - feat: Bolg of the North - feat: Beorn's Hospitality - docs: a Q5 for the human, and the fixture auto-pick is now four verbs - feat: Foray of Orcs - docs: the two meters disagreeing is the phantom-entry detector - feat: Gollum, Silent Slinker // Meager Meal - feat: Elven Farsight - feat: Elanor Gardner - feat: Settle the Wreckage - feat: Bill Ferny, Bree Swindler - feat: Éomer, Marshal of Rohan - docs: Bilbo was never unblocked, and cast provenance has no command zone - feat: Rhovanion Rampager - feat: Beorn the Fierce - feat: Galadriel, Gift-Giver - feat: Lake-town Mariners // Gone Fishing - feat: Barad-dûr - feat: Stone by Sunlight - feat: Balin, Loremaster - feat: Assault on Osgiliath - feat: Book of Mazarbul - feat: Most Decrepit Old Bird // Speak Secrets - feat: Gimli's Axe - feat: Erkenbrand, Lord of Westfold - feat: Plunder the Trollshaws - feat: Rage into the Valley - feat: Gimli, Counter of Kills - feat: Confusticate and Bebother - feat: Fíli the Pathfinder - feat: Generous Ent - feat: Escape from Orthanc - feat: Gothmog, Morgul Lieutenant - feat: Deceive the Messenger - feat: Nori, Teller of Tales - feat: Easterling Vanguard - feat: Old Fat Spider - feat: Dunland Crebain - feat: Ravenhill Flock - feat: Nasty Little Rabbit - feat: Ordinary Bear - feat: Nighthowl Pursuer - docs: classify the 49 new HOB entries - docs: record the meter's set-attribution drift across a data pin - chore: HOB adopts the 49 cards the 2026.8.7 data pin added
-
v0.20.0
Release: v0.20.0410c37f9 · ·v0.20.0 Commits since v0.17.0: - feat: the social card is Manatab's, and comes from the same drawing - docs: 0.20.0 is the new-icon release - fix: even out the caption rows, and let the chips fill their line - fix: the hero credit named itself twice, in two overlapping ways - feat: the format chip abbreviates, and carries the precon's set - feat: deck tiles wear the deck page's stat chips (#829) - feat: new site icon, redrawn from one SVG
-
v0.17.0
Release: v0.17.02a3cfee9 · ·v0.17.0 Commits since v0.16.0: - docs: 0.17.0 is the set-links release - fix: ask_user was marked quiet, which told the model never to ask - feat: Tutor can ask a question and wait for the answer - feat: set codes link everywhere, and carry a popover of the set - fix: the hero scorer's word boundaries were backspace bytes - chore: open the UX improvements branch
-
v0.16.0
Release: v0.16.0dcb4419b · ·v0.16.0 Commits since v0.15.1: - docs: 0.16.0 states The Mindskinner's kernel once - docs: 0.16.0 is the Duskmourn release - docs: DSK closes at 266/266; harvest the merge-pass findings - chore: DSK plan file records Tamiyo and Valgavoth as landed - docs: harvest the DSK merge-pass findings - chore: data 2026.8.7 - fix: a scheduled data run is never redundant, so stop cancelling it - docs: settle where damage_cant_be_prevented lands, and retire the spec - fix: the weekly data refresh could never have run - test: hexproof holds off the opponent, and damage marks instead of loyalty - test: stock your own library so the each-opponent scope can actually fail - docs: the weekly data refresh had no schedule and nothing checks that - test: the WASM prompt machine folds a ninjutsu attacker in too - docs: the clone/hash completeness gate is itself a hand-list - fix: keep the no-memo paragraph attached to cardTypesInGraveyard - test: pin "each opponent" to the replacement's controller, not the damaged seat - feat: a damage-to-a-player replacement that substitutes another effect - docs: changelog for ninjutsu and the layer-4 static type change - docs: two kernels land, and the merge queue reports two more false failures - docs: layer 4, the combat roster, and the ninjutsu constructor - test: a driver run pins the late-attacker fold-in - test: the ninjutsu activation logs CR 702.49a's reveal - test: real-state proof for ninjutsu, the layer-4 static, and the new state - feat: ninjutsu (CR 702.49) and a layer-4 static type change - test: drop an unused binding in Valgavoth's ward-count test - docs: changelog records the position-hash fix - feat: Valgavoth, Terror Eater - docs: the paragraphs this kernel falsified, and a gate for the next one - docs: drop blocked-by annotations naming specs that no longer exist - test: close the three gaps the mutation matrix found - fix: retarget labels read the pick where this kernel put it - test: mode 2 retargets a triggered ability, not only an activated one - fix: ward's choice-cost switches name the third target arm - feat: The Tale of Tamiyo - docs: the DSK merge pass records two rulings and four findings - feat: copies of exiled graveyard cards, cast during the resolution that made them - docs: ENGINE.md maps CR 603.2d, and the kernel spec retires - fix: gate each extra trigger instance separately (CR 603.3b) - docs: restore next after reviewing a merge request - test: pin the land-play, life-loss and block fire sites - docs: ward's mandatory payment becomes a named envelope approximation - test: pin saga-chapter doubling (M10 read silent) - test: pin the entry funnel's 603.2d payment (M8 read silent) - feat: Mirror Room // Fractured Realm - docs: the cast_spell announcement paragraph scopes itself to the ward path - wip: pay CR 603.2d at the remaining bare fire sites - test: the token play-permission pin says what it can and cannot prove - wip: CR 603.2d additional trigger instances + Mirror Room - docs: the kernel spec lands, and two docs it falsified - test: a replay fixture that retargets through the new action encoding - docs: the becomes-blocked paragraphs say what the code guarantees - docs: three kernels land, and six plan entries stop naming specs that are gone - feat: Untimely Malfunction - docs: the runtime target-count sources, and the kernel spec is delivered - fix: drop dead resolve_on_decline from Miasma Demon's discard choice - feat: name an activated or triggered ability on the stack - test: pin the firing-sized target lint arm - feat: a reflexive trigger's target count sized by its arming payment - chore: land the graveyard play/cast kernel, retiring its spec - docs: ward gates one DSK card, Kaito needs two primitives, and three findings land - test: the blanket graveyard permission outlives a card leaving the zone - docs: repeat-loop surface in ENGINE.md, changelog bullet, spec retired - docs: the paragraphs that carried the false premise now carry the true one - fix: drop a dead token guard from the turn-scoped graveyard replacement - test: pin the repeat batch through the rollout clone too - docs: the counter-kind checklist counts five sites, not three - test: Forgotten Cellar's exile replacement leaves tokens alone - test: pin one announcement per repeat pass, empty library included - feat: the choose-or-reveal cost arm records which half was paid - test: gate PlayerGame's scalars for clone and hash completeness - test: pin the repeat loop to exactly X passes - feat: play lands from your graveyard, and two turn-scoped graveyard permissions - docs: Card.delayed_triggers says which scopes the lint allows and which it refuses - test: pin the repeat loop's batch invariant, clone and position hash - feat: repeat a look-top window exactly N times, accumulating what it made - docs: say which callers of the activated funnel gate and which hide - test: the borrow segment hides dead lender abilities, and the stack survives it - docs: the changelog records the ward kernel and the replay-window fix - fix: a staged pick at instant-speed priority does not restart the window - docs: a change that falsifies a doc paragraph is a sendback - docs: the 2026-08-07 merge pass sends all three MRs back and harvests findings - test: the ward window announces once, replays, and survives two targets - test: hold the block close so a spurious becomes-blocked trigger is visible - fix: a ward-staged cast or activation announces itself exactly once - feat: becomes-blocked event and play-from-exile for a permanent - docs: changelog entry, and the keyword-counter spec is delivered - feat: deathtouch keyword counters; Qarsi Revenant renew places real counters - fix: the ward-cost family rejoins next's two new exhaustive ActionKind switches - docs: the DSK merge pass harvests its findings and corrects two stale specs - feat: lifelink keyword counters (CR 122.1b) and Reluctant Role Model - fix: a stack item's grant source is a distinguishing reference - test: two of your creatures dying to one sweep exile two cards - test: a land proves the borrow is creature-scoped - test: Marvin borrows a granted ability, and the name clause blocks a twin - feat: Marvin, Murderous Mimic - feat: a delayed trigger narrows by scope, and Waltz of Rage - fix: the merged arming funnel refuses a swapped chooser at compile time - docs: manifest-dread watchers reach the 0.16.0 changelog - docs: the 0.16.0 entry records the discard work - feat: fail when the committed card registry is stale - test: pin manifest dread's arm-site announcement and the gone-buried-card ruling - chore: the registry regains its Excruciator after the merge - docs: the face-down library exile spec lands with its representative - chore: release 0.16.0 — behold, gift, and gates that measure what they print - feat: detect when main has commits next never got - docs: retire 38 kernel specs no card and nothing else names - docs: a dev delivers what it took - fix: the graveyard sacrifice cost cites CR 701.21a, not Mill - docs: kernel specs for the four cards this batch skipped - feat: Last Light of Durin's Day - feat: quest counters - feat: Hobbit Hole - feat: Gollum the Abandoned - feat: a graveyard activation can pay a sacrifice cost - feat: Misty Mountains Raider - feat: Gathering of Darkness - fix: fx.attack fires the batched attackers-declared triggers - feat: Mirkwood - feat: Lake-town - feat: Elvenking's Halls - fix: the failed-search arm is tested, the header carries its reminder text - docs: the behold kernel spec is landed - feat: Elven Passage - feat: behold (CR 701.4a) - feat: a resolution choice can name the subject its continuation refers back to - fix: sim:roundtrip takes a bare deck name - fix: manatab validate reports only what it measured - fix: the gift is held on a 608.2b fizzle, and the review's citations and docs land right - docs: commit the spec DSK's plan file already points at - docs: DSK questions 1 and 2 answered — all 18, and keyword counters keep their counts - fix: the manifest sync gate compares every mirrored field - docs: the gift kernel spec is landed - feat: gift (CR 702.174), spell-to-hand, and a symmetric turn-scoped cast lock - fix: a replay fixture holds a migrated discard, and the review's minor notes clear - fix: printActionLog writes every replayable ActionRecord field - test: pin the replay fields printActionLog drops (red) - ci: run test:zig on merge request pipelines - docs: DSK phantom sweep — one spec struck, two stale claims corrected - fix: an empty hand ignores only the discard, and the subset walk counts combinations - docs: An Unexpected Party points back at the spec that gates it - docs: HOB questions 4 and 5 answered — Adventure back faces in, keyword-only cards untested - docs: a set reaching 100% coverage is a minor release - docs: retire the effect-driven discard kernel spec - feat: random discard for Hymn to Tourach; chain the each-player discards - feat: enumerated discard for the modal, two-card and tailed families - feat: enumerated discard for the opponent and effect-named families - feat: migrate the self-discard family to the enumerated pick - feat: enumerated resolution-time discard, proved on Psychic Whorl - docs: HOB architecture review — gate reach, choke-point verdict, hand-list correction - docs: the bare-action sweep closes as a measured boundary - docs: the two-piles kernel spec is landed - feat: Riddles in the Dark - fix: drop a stray debug print from the Goblin-town chapter - docs: an entry trigger loses its targets on every non-cast entry - docs: two human rulings land before the lanes reach the gate - feat: Down, Down to Goblin-town - docs: kernel specs for the two blocked HOB lane-2 cards - feat: Key to the Side-Door - docs: kernel spec for a reflexive trigger reading its arming cost object - feat: Great Ugly-Looking Goblin // Clap! Snap! - feat: Master's Councillors - docs: kernel spec for an optional target slot ahead of a mandatory one - feat: Mirkwood Nurturer - feat: Little Bear - feat: Gloin the Mighty // Easy Pickings - feat: Storied and the enduring story designation - feat: Iron Hills - feat: Large Bear - feat: Gandalf, Wandering Wizard - feat: Fearsome Goblin Pair - feat: Mirkwood Pathmaker - feat: Front Porch Sentries - docs: HOB wave prep — strike the amass authorization and three stale specs - docs: rename the architecture-review skill to arch - fix: manifest dread's comptime lint follows count_from_x onto count_source - docs: ten landed kernels release their plan entries - perf: a kernel MR stops paying for Playwright, and the pipeline learns its stages - fix: two test files leave the catalogs primed and fetch stubbed - docs: wave harvest — four live defects, two process findings, hone re-shaped - docs: sync plan checkboxes; Untimely Malfunction points at the successor spec - fix: the merge kept two copies of bear_2_2 - fix: retarget_choice picks its side in the two ActionKind authorities - chore: the last two lines still naming the old Pages host - chore: regenerate manifest - fix: wire the ward-cost staged family into next's exhaustive switches - chore: regenerate manifest - docs: a release without a changelog entry stops being possible to miss - chore: regenerate manifest - docs: the baseline guide sheds what --help and CONTRIBUTING already carry - docs: the look-top power/distinct spec lands - feat: Rip, Spawn Hunter - feat: a look-top count read off the source's power, and distinct picks - docs: the guide stops naming caches, counts, and clobbers the tree outgrew - docs: fold session memories into the agent guide - feat: a whenever-you-manifest-dread trigger, and the card that window buried - chore: the unlock-cost-reduction spec leaves the queue - docs: the new round-trip gate cannot notice it stopped testing anything - docs: the kernel queue swaps a landed spec for the one Untimely Malfunction needs - feat: Inquisitive Glimmer - feat: a cost reduction says which payment it takes off - docs: three kernel specs for this batch's skips - feat: Galion, Elvenking's Butler - docs: kernel specs for the two cards this batch skipped - feat: Entish Restoration - feat: Ent-Draught Basin - feat: Eagles of the North - feat: Dúnedain Blade - feat: Denethor, Ruling Steward - feat: Dawn of a New Age - feat: Cast into the Fire - feat: Bitter Downfall - feat: Bag End Porter - feat: Arwen's Gift - fix: the activation-count invariant test asserts the rule that replaced it - feat: Gnashing of Teeth - test: assert the candidate set, not only the pick - feat: retainsPriority and isProposalStep, the two ActionKind authorities - docs: amass lands, and 36 entries stop naming a spec that is gone - feat: Gleaming Splendor - test: pin the retarget walk against its rulings and its clone identity - feat: a search across graveyard, hand and library, and a staged multi-pick graveyard cost on an activation - docs: three promotions, one of them bought by a negative result - feat: change the target of a spell, a legality walk over somebody else's spell - fix: a play-emitted replay carries all four outcome fields - feat: Elven Raft-Steerer - feat: Errand-Rider of Gondor - feat: Erebor Flamesmith - feat: Eomer of the Riddermark - feat: Ent's Fury - feat: Eastfarthing Farmer - feat: Eagle of Deliverance - feat: Cirith Ungol Patrol - feat: Captain of Umbar - feat: Butterbur, Bree Innkeeper - feat: Brandywine Farmer - feat: Banish from Edoras - docs: kernel spec for the token-entry watcher - feat: Desolation of Smaug - feat: Eagle's Rescue - feat: Beorn, Reluctant Host - feat: Cantankerous Keepers - feat: Bard the Bowman - feat: Dancing from Dark to Dawn - feat: Dori, Bearer of Friends - feat: Iron Hills Blacksmith - docs: correct the amass inline-path rationale to CR 701.47a - docs: the exile-link retrieval spec is spent - feat: Eagle of the Great Shelf - feat: Goblin-town - docs: the SBA boundary inside a resolution gets named - feat: an exile-link retrieval reads the rest of its printed line - feat: Fateful Discovery - docs: sim:roundtrip, and the u64 trap that costs an afternoon - feat: Gigantic Big Bear - fix: a recorded activation opens its stack-priority window on replay - docs: the graveyard-arrival kernel spec is spent - test: the mill finishes before either land returns - feat: Hedge Shredder - feat: cards put into a graveyard announce one batched arrival - feat: a graveyard arrival can be declined - docs: the card-cache blocker is closed, and the wider read is recorded - fix: bun install writes the tsconfig the aliases resolve through - feat: amass (CR 701.47) and Bothersome Noisemaker - docs: the last gate consumer that still learns by exception - docs: two kernel specs name what blocks the last two HOB lane-2 cards - fix: the data stamp records what it wrote, and install re-hashes it - docs: two pool entries get verified instead of aging - docs: two gates get measured instead of trusted, and a landed kernel is cleared - feat: Down in the Valley - fix: a landfall trigger's printed condition is finally asked - chore: the creature-sourced damage sweep leaves the kernel queue - test: Nova Flame pins the source's deathtouch across the sweep - feat: Nova Flame - feat: a named creature can be the source of a damage sweep - fix: a worktree gets its card data, and an absent cache stops reading as drift - feat: The Rollercrusher Ride - test: the X-sized trigger target gate names what it refuses - chore: regenerate registry manifest for Desolation of Smaug - feat: Burn, Burn, Tree and Fern - test: an over-committed target count is refused at cast time - docs: kernel specs for the five HOB cards this batch skipped - feat: Desolation of Smaug - feat: Chief Warg's Company - feat: a permanent already on the battlefield has an X of zero - docs: the kernel spec is spent - feat: Dain's Company - feat: Duskwatch Hunter - feat: Bejeweled Warg - feat: Crude Bent Blade - feat: Dwarven Mattock - feat: Bilbo Baggins, Burglar - feat: Desolation Prowler - docs: Found Footage stops naming a kernel that landed - chore: regenerate registry manifest - feat: Dancing from Dark to Dawn - feat: Cantankerous Keepers - feat: Beorn, Reluctant Host // Till and Tend - feat: Bard the Bowman - feat: Dori, Bearer of Friends - test: the declaration gate is pinned from both sides of combat - feat: a declaration that would leave one creature attacking alone cannot close - feat: a trigger's target count reads the X its permanent was cast for - feat: Iron Apprentice and Host of the Hereafter - feat: put the counters a creature had onto another creature - docs: LTR gets read card by card, and the merge queue learns why drift died - docs: the scope answers land, and two records stop citing work the tree lacks - feat: the grant stops at the battlefield, and the spec is spent - test: the zone-change reset drops the exile facing - docs: the required shape for a closed set with more than one reader - docs: HOB's other 130 entries get shapes, and nine kernels name what gates them - chore: retire the attacks turn-limit kernel spec - fix: the four game_loop staged-action lists become one closed predicate - feat: Fear of Missing Out - feat: Doomsday Excruciator - feat: a card exiled face down is one no player can read - docs: HOB and LTR get plan files, and two kernel specs name what gates them - feat: a per-viewer grant to look at face-down permanents - fix: Heartless Act can remove every kind of counter, and two switches close - feat: one classified list of Cost arms, and both readers walk it - feat: an attacks trigger claims "the first time each turn" at the event - docs: the plan files drop three landed blockers, and findings names the branch drift - feat: a turn-scoped delayed triggered ability that watches an event - docs: record the choice-carrying ward kernel and retire its spec - feat: ward costs that carry a choice, on both payment paths - feat: add the choose-or-reveal cost arm and Monstrous Emergence
-
v0.15.1
Release: v0.15.1991e0375 · ·v0.15.1 Commits since v0.15.0: - fix: two test files leave the catalogs primed and fetch stubbed - fix: clicking a deck opens the deck, not its hero card
-
v0.15.0
Release: v0.15.07c6630b2 · ·v0.15.0 Commits since v0.14.1: - chore: declare 0.15.0, the release the morning forgot to write down - feat: the flask takes over the tab, and the nav learns the name - feat: the pane's price is a fold now, first after the rules text - feat: the card pane says what the card costs - feat: the built site gets clicked before it ships - chore: the flask sketches stay out of the tree - chore: the repo answers to manatab now, and every link says so - fix: the source menu stays on screen, and the phone pane stops taking its width from its children - feat: a card knows what it costs in money, not only in mana - fix: an empty Anthropic reply says why, and Stopped. means the user stopped it - fix: a chip that edits the deck is not offered where edits can't land - fix: install checks the tree, not just the stamp - fix: the unfurl stamp rides build:site, which is the build CI runs - fix: the stamp tool's imports sort — the gate couldn't see an untracked file - fix: og: URLs live on manatab.app now - fix: local deck pages render again, and vault unfurls move to a post-build stamp - chore: six thousand lines of narration go quiet in app/ and tools/ - feat: the orb holds water now, and the tab floats on top of it - feat: the favicon is the orb, the wave, and the way out - fix: app.html stops narrating into the page, and the markup comments go quiet - fix: a legal Commander deck stops linting as one card over - feat: the changelog is a page, and the version number is its door - fix: the scene page's Back link cannot leave the site - fix: an old local deck gains its created: line on the next save - fix: the gallery says every shipped deck is read-only, not just the vault - feat: a shared vault deck unfurls as itself - fix: a Tutor thread remembers the model that wrote it, and goes read-only under another - chore: the reshuffle the rule was owed — 26 .svelte files sorted - fix: the import linter reads indented lines, so .svelte files count
-
v0.14.1
Release: v0.14.1ca71109d · ·v0.14.1 Commits since v0.14.0: - fix: a deck with one card across several printings can select each line - feat: a deck's face is chosen by identity, not census - fix: the credit's card name is actually hoverable - fix: the name line breathes, and the key line settles at two - fix: a precon opens at once, and Back keeps the tiles' stats - feat: every deck link opens on its hero, and card names preview on hover - feat: tile card names open the deck with that card pinned, and a third key - feat: the tile's right edge earns its keep — artist, health, key cards - fix: the tile's name steps up a size, and the facts share one line - feat: the card view folds into the art tiles as a minimized stat card - fix: the reveal window survives Back - feat: precons resolve through the vault pipeline, so every view works - fix: every column header in the deck table is the same small size - fix: the gallery reveals as you scroll, and the source picker settles down - fix: a set stops paging, and card grids hold still while images arrive
-
v0.14.0
Release: v0.14.091468539 · ·v0.14.0 Commits since v0.13.0: - chore: declare 0.14.0 - feat: one card pool — Standard becomes a filter, and the wire gets compression - feat: data ships as one locked archive, and nothing generated lives in git
-
v0.13.0
Release: v0.13.0ce7166f8 · ·v0.13.0 Commits since v0.12.0: - chore: declare 0.13.0 - fix: the starred section reads as a section again, and no source means starred - feat: decks carry the day they came to exist, and the gallery can sort by it - feat: a precon says which set it came from, and "all" means all - feat: the deck gallery filters by source, and can pick several - feat: pick the art for a deck you cannot write - fix: the Karsten mark stops running into the sim dot - fix: one affordance in a search field, not two - fix: the card pane's tightest-requirement line renders its pips
-
v0.12.0
Release: v0.12.0e66c3301 · ·v0.12.0 Commits since v0.11.1: - feat: preconstructed decks, imported from MTGJSON - fix: a deck tile's backdrop image loads lazily, like the crop in front of it - docs: AGENTS.md is the operator's guide again - refactor: decks are organized by source, and answer to their names - feat: generated data moves to the package registry, pinned by hash - refactor: one card loader, so a per-card fact is stamped once
-
v0.11.1
Release: v0.11.10ea39770 · ·v0.11.1 Commits since v0.11.0: - feat: lint reports sim coverage, so nobody learns it from a refusal - fix: respelling the call mints no fresh runs, and four refusals end the turn - feat: compare_decks answers the question Gemini kept measuring at - fix: a turn that loops through refusals loses its tools - fix: the third identical call is refused, because the second changed nothing - fix: the Block union narrows again — head is its own member - fix: a heading renders as a bold line, since Gemini writes them regardless - fix: edit_deck stops answering questions, and get_card starts - fix: one flaked request no longer ends the conversation
-
v0.11.0
Release: v0.11.0e2febb73 · ·v0.11.0 Commits since v0.10.0: - fix: a billion Plains is 999 Plains at every door - perf: the palette guide loads when theming starts, not on every turn - fix: the sort keys come from the page, and the prompt says one thing once - feat: the answers render their lists, and search ranks like the browser - fix: the review's findings — a quantity cap, a scrubbed prompt, an encoded printing - docs: the changelog entry covers the release it declares - style: Appearance follows Tutor, and Save sits beside Test - fix: settings fills its column, and stops asking questions it cannot answer - fix: the theme chips show their own colors, and settings stops whispering - style: the picker is made of the composer, not the conversation - fix: the card picker ranks names the way the card browser does - feat: the card picker says what each row costs and what it is - style: the keys line reads at one step up, with air between the pairs - fix: five things about the picker and the box under it - feat: the picker floats, and shows you the card you are picking - feat: the owl looks over the top of the conversation - feat: the owl reads at the size it ships at - refactor: trim the exports nothing calls - docs: the host list correction reaches the changelog - fix: the about page names every host, and stops claiming your decks stay put - fix: the owl carries the same weight as the icons beside it - refactor: the quiet action at the end of a row is one style - feat: Tutor gets a mark of its own, a paper owl - chore: declare 0.11.0, the release where Tutor sees the page - fix: the composer trigger nearest the caret wins - fix: the card block counts artworks, and an adventure has no back - fix: a deck name means the same deck to every tool that takes one - fix: the rail's gutter is one value, so its right edge lines up - fix: the conversation list read as brackets, and hid its own timestamps - feat: $ picks a set, ! picks a format, and hydrate stops writing state - fix: one conversation for the whole app, and a list of the saved ones - refactor: tool descriptions join arrays instead of concatenating - feat: Tutor builds a deck from anywhere, and can take you to a page - docs: the rule is context per surface, tools shared - feat: every surface tells Tutor what is on it - feat: Tutor can show a card, read a set, and say which decks could run one - fix: search_cards told the model its own syntax did not exist - fix: the boot strip goes to the top of the window and says so plainly
-
v0.10.0
Release: v0.10.064c43d3d · ·v0.10.0 Commits since v0.9.0: - chore: declare 0.10.0, the release where the cards talk - fix: a short deck name was faded out to nothing - feat: hovering a named card shows it - docs: how a named card becomes a link - feat: a card that names another card now links to it
-
v0.9.0
Release: v0.9.0885ddabb · ·v0.9.0 Commits since v0.8.1: - chore: declare 0.9.0, the release where the art joins - fix: a step through search results paid for the whole search again - feat: nine LTR scenes, and the proposer credits a run split across scenes - feat: scene captions under their cards, a centered walk, and a Back that knows where - feat: the scene page shows whole cards and nothing else - feat: scenes, the art that continues across cards
-
v0.8.1
Release: v0.8.169e3ab79 · ·v0.8.1 Commits since v0.8.0: - chore: declare 0.8.1, the printing every surface means - fix: an artist search shows the art that artist drew - fix: every surface lands on the printing it showed you - fix: the card sliding in stopped a few percent short of full size
-
v0.8.0
Release: v0.8.0cfacb8f6 · ·v0.8.0 Commits since v0.7.2: - docs: the changelog entry read as a second MR body - fix: a sort the app does not have rode the URL into the walk - fix: a second touch during the handover was wiped when it landed - fix: a query that fit still faded at its end - fix: the walker's query wore a different face than the set name - fix: the deck button reads small and its icon sat off the text - fix: the centered card column sized to its content, not its track - fix: a long query in the walker pushed the card column past the page - fix: stop the walker deciding how wide the card column is - refactor: one faded end, in the design system - fix: the stepper's query pushed the page wide, and the swap flickered - refactor: drop the card pane's hover lift - refactor: the stage owns the element it moves - fix: the pane's card eased itself back on from off screen after landing - fix: the card that arrived slid back out from under its replacement - feat: a committed swipe carries the card off instead of springing back first - docs: split three paragraphs the prose linter had been undercounting - feat: walks stop at their ends, the puck is always up, and a step costs more - refactor: one stage for a card and its neighbors, wherever the list comes from - fix: a clipped neighbor with no reserved shape looks like a missing one - fix: the neighbors never moved, and the pane scrolled to a card that was not there - feat: a lint line opens its card, like every other way of asking for one - feat: the deck's card pane scrolls into view when you open it - feat: the card sticks to your thumb and the next one comes in beside it - feat: the next card comes into view as you drag toward it - fix: the wall gave back so little travel it read as a dead card - docs: the hint and what moves under the finger - feat: the swipe shows what it will do before you let go - chore: declare 0.8.0, the search walk and swipe navigation - feat: the card page walks the search you arrived on - feat: a swipe walks the list a card sits in - fix: a set's page number survives leaving the page
-
v0.7.2
Release: v0.7.23273f16c · ·v0.7.2 Commits since v0.7.1: - docs: two 0.7.2 sentences carried two ideas each - feat: sync goes both ways, and the decks page says where it stands - chore: declare 0.7.2, sync symmetry and the decks control
-
v0.7.1
Release: v0.7.12d7241b9 · ·v0.7.1 Commits since v0.7.0: - fix: drop a dead import, and clear presence on a Drive reset - docs: the 0.7.1 entry names the heads-up and the cadence - feat: a deck says when another browser has been editing it - feat: the newest edit wins, and the deck says it changed elsewhere - docs: the 0.7.1 entry reads like the rest of the file - chore: declare 0.7.1, the sync simplification