## drandyhaas/KiCadRoutingTools — v0.21.3…v0.21.4

_357+ commits._

### Features
- **#554: register the new tests in the placement README** (937f289)

### Fixes
- **Merge pull request #804 from edgehero/fix/554-bounded-block-relocation** (d4ce14e)
- **Merge pull request #802 from edgehero/fix/553-diagnosis-target-select** (e2a57a2)
- **Merge pull request #801 from edgehero/fix/698-reseat-acceptance** (dc2d365)
- **#698: the re-verification found a regression in the previous fix wave** (efdccd7)
- **Merge pull request #796 from edgehero/fix/702-intent-in-quench** (8959f2a)
- **Merge pull request #790 from edgehero/fix/701-704-intent-keepouts** (6f785c1)
- **Merge pull request #785 from edgehero/fix/703-complete-table** (29eb93b)

### Backend
- **Release v0.21.4** (56e2da2)
- **#805: parity ledger to 31004f43 -- victim-restore default re-checked** (05b2f64)
- **#622: ship victim-priority restore ON by default** (31004f4)
- **#805: parity ledger to 66e60fb2 -- one real gap found and fixed** (a110116)
- **#805: quote the PCBData annotations -- eager annotations broke GUI routing on KiCad python** (66e60fb)
- **#671: drill hole-to-hole is not net-aware -- two guards treated it as if it were** (82b8063)
- **#622 port: pocket-stuck rip targeting, OPT-IN (from bus622-take2 947698d6)** (caadfb6)
- **#671: ride an existing same-net via instead of drilling one 71um away** (58f5721)
- **#805: correct the #796 mislabel on the trim ghost-via work** (3c3047f)
- **#805: two debugging instruments -- cell watch and via birth watch** (59245b1)
- **#309: give every obstacle-cache object a stable identity, never id()** (217d10d)
- **#309: the obstacle ledger wiped the net-ids it needed to report** (83ce220)
- **#805: five missing-stamp / stale-cache fixes from the obstacle-bookkeeping audit** (dfc725c)
- **#666 port: decline a bare-ball rescue escape that would short routed copper** (f210087)
- **#622 port: victim-priority restore, OPT-IN (from bus622-take2 a693919b)** (bab4218)
- **#622 port: verdict-integrity merge (from bus622-take2 947698d6)** (1c00671)
- **#554: the fact-check found my own dose table stale, in the feature's favour** (e780d51)
- **#805: commit the #189 unblock via to pcb_data when it is kept** (9919613)
- **#805: release gate for obstacle ref-count integrity, on a board that reproduces** (d00032d)
- **#554: the routed A/B ran, and it is UNDERPOWERED with the incumbent ahead** (d3a3f47)
- **#554: the routed study's regen test, explicit about the half it cannot re-derive** (f9613ed)
- **#554: the second audit found ten defects; the worst was my own headline** (59bf7ca)
- **#554: the study reports where the incumbent loop beats the relocation** (8462f08)
- **#554: relocate only among blocks this round's failure implicates** (9982420)
- **#554: the routed study, and the pairing arithmetic it got wrong on its first cell** (fd17dfb)
- **#554: the docs, the correction the audit forced, and the rules recorded before the routed study** (2bfbae5)
- **#554: the battery table, from the run** (4600f63)
- **#554: the two same-unit guards are each other's redundancy** (7051966)
- **#554: battery rows for the guards that carry, survivors recorded for the ones that do not** (e95fb04)
- **#554: three battery rows that survived, and the tests that now reach them** (364c8f9)
- **#554: the audit found the graph is not conservative, and a regen test that wasn't** (2073c5f)
- **#554: the solve, and the two gates that refuse the incumbent board** (4dc5fd8)
- **#554: the mechanism claim, measured before the solver was worth writing** (0d65887)
- **#553: the recall study came back NULL once it had a control, and that is what ships** (902e97d)
- **#553: the fact-check found a crash on a real board, and two claims that lied** (76844fa)
- **#553: the docs, and the two rules that say what has NOT been measured** (8c3c2b4)
- **#553: the recall study, and the first version of it that measured nothing** (fbb039f)
- **#553: a diagnosis wholly inside --lock was ending the run, and reporting success** (1666f89)
- **#553: re-record the battery table -- 21 rows, 18 killed, 0 broken** (22f184b)
- **#553: two battery anchors went stale, and the battery said BROKEN** (a5e3e2c)
- **#553: nine defects a refutation pass found in the ranking module** (913e65b)
- **#553: the battery left a stale .pyc, and every later import used it** (86c2987)
- **#553: --target-select, defaulted to pins, and the proof that changed nothing** (1b51757)
- **#553: record the battery's measured table, including the row it cannot kill** (45f219f)
- **#553: the pool-claim row now kills by assertion, not by crashing** (b2e1ba4)
- **#553: the battery's first run found the fixture testing its own tie-break** (269293e)
- **#553: the verifier found a second implementation, and I removed it** (080e999)
- **#553: the mover ranking, and the three things it refuses to combine** (a6af4ac)
- **#553: the loop may carry the blocker cell counts, and by default does not** (6726d63)
- **#805: the stub-swap rescue never removed the old cache from the working map** (d67ab6e)
- **#805: three copper caches keyed on counts alone, broken by any pass that REMOVES copper** (c15fcde)
- **#698: record the battery's third round** (6c6484b)
- **#698: single-line mutation anchors, and the two checks they needed** (8cc56a4)
- **#698: record the battery's second round in the test header** (743018e)
- **#698: the battery caught my own fixes' tests being vacuous** (e4cef03)
- **#698: the pre-push review's findings, fixed and pinned** (6abbc1f)
- **#698: the mutation battery -- 32 rows, 30 killed, 2 recorded survivors** (7a82cea)
- **#698: three arms the mutation battery said were missing** (43692cd)
- **#698: the arm test -- 76 checks, every accepting arm with a control** (a75db96)
- **#698: the prune sweep stops undoing a seat a declared claim justifies** (f78b4c3)
- **#698: an explicit re-seat is judged on what the operator asked about** (f562253)
- **#698 prep: the declared-claim measurement leaves the state that enforces it** (c7bef8d)
- **#796: the stub-debris trim frees a via the writer still emits** (176f932)
- **tests: the suite reaches zero failures, and two of the three were real bugs** (cc0a809)
- **#702: nine more defects, one of them a red test I had reported as green** (16434cc)
- **#702: the docs say which rules the search can see, and the probe can reach them** (7f90ada)
- **#702: the tests, the mutation battery, and what they caught in my own work** (6098707)
- **#702: --intent reaches the quench from all four call sites** (d0b9ba1)
- **#702: the quench refuses a move that breaks a declared claim** (44f88c3)
- **#702: one measurement for "outside its zone", shared with the grade** (7024ede)
- **#702 prep: the A/B harness graded its own fixture as unresolved** (556a931)
- **predictor_study: a ONE-row rows.jsonl is one row, not zero (#703)** (0d66263)
- **gui-parity: audit aaa60331..722ea1cc -- no gap, fourteen gates green** (91a19df)
- **#795: KiCad's own board iteration, on a SWIG that dropped next()** (722ea1c)
- **#701: three things an adversarial verifier broke, and a mutation it invented** (648f03a)
- **#704: a decap limit read off the board, and a census that says what it cannot see** (c1b66f8)
- **#701: the polish walks a part into a keep-out; the self-check walks it back** (f80a4dc)
- **#701: a keep-out that strands a part is a NAMED verdict, not a silent refusal** (309fe73)
- **#701: the edge seat is refused by a keep-out too, and says which one** (35e1be8)
- **#701: the seat predicate reads the keep-outs off the state** (5f50b41)
- **#701: one keep-out hit test, and the grader stops owning a second copy** (09bc225)
- **predictor_study: the complete table -- 6 boards, 120 placements (#703)** (7ea9b0d)
- **predictor_study: a fifth board, and every exclusion removed (#703)** (ab4e3d0)
- **#703: what predicts routed blocking, measured within board (#784)** (2c84c01)
- **#703: drop the committed rows, implement the flag that did nothing** (acad9c0)
- **#703: two stale "measured" numbers, and the guard that could not see them** (f6e1906)
- **#782: the fanout tab clamps the net classes its cap pass priced at the ceiling** (f9039d4)
- **#780: the INLINE cap pass gets the #768 netclass ceiling too (#783)** (00d4f56)
- **#779: the seed half of the via disclosure grades seed BARREL positions (#781)** (967aaff)
- **#772: an optimize_caps step's cap params reach the engine, on the cap knob (#778)** (d9ddec3)
- **#775: the per-cap via prune has ONE spelling, and the post-nudge refresh uses it (#777)** (2917832)
- **#735: the via-nudger's connectors honour the board's track-scoped .kicad_dru rules (#776)** (b9e0160)
- **portfolio: the crossings contradiction, disclosed and left unchanged (#703)** (2c3de0e)
- **predictor_study: the measured table over 4 boards, and a doc that cannot drift (#703)** (f4c78fd)
- **#703: a sign rule that one board could not clear alone** (e4498b9)
- **predictor_study: freeze the argv ONCE in the parent, and survive the Windows replace (#703)** (3b8edc1)
- **predictor_study: portfolio candidates are jitter-only, measured (#703)** (8d7d298)
- **predictor_study: wrong_side is an UNDOSED kind, measured (#703)** (1ff5bac)
- **predictor_study: an ARGV.json race, and a resume that skipped a crash (#703)** (2912ea6)
- **predictor_study: three doses that are three placements, and the duplicate guard (#703)** (cb9e4e4)
- **predictor_study: the rig, its frozen argv and its independent re-parse (#703)** (0684511)
- **#703: the LEDGER is the terminal authority, not RUN_STATE** (ed843e8)
- **predictor_study: the harvester, and the terminal score that is not score.json (#703)** (27b336a)
- **#703: the NaN-truth arm nothing was attacking, and a guard that crashed** (dcb2157)
- **#703: the anti-pooling guard is EXECUTED, not documented** (99f0722)
- **predictor_study: the statistics kernel, before any row exists (#703)** (a9d3319)
- **#780: what the inline ceiling does NOT do, next to the line that does it** (e0c1ec9)
- **#780: a fanout step that switches the cap pass on obeys #768's OMITTED rule too** (824110e)
- **fanout_gui: the INLINE cap pass gets the netclass ceiling too (#780)** (c9a381c)
- **fanout_clearance: the seed half of the via disclosure grades seed BARRELS (#779)** (f1bfee4)
- **#772: the leak an adversarial review found still open, and five weaker things** (7edc406)
- **#772: the fanout step reaches its option panels too, like the reset already did** (0998ef3)

### Tests
- **test(#704): pin the sortedness the census claims, and the README says keep-outs are enforced** (f86f5f8)
- **test(#704): the censoring guard was asserted by NOTHING** (7af4e5a)
- **test(#704): the emission battery, and the two traps it caught in my own work** (5c57066)
- **test(#701): the zone-less repair arm, which the S9 mutation survived** (f924351)
- **test(#701): the shared-implementation battery, and three of my own tests that passed in both directions** (c3b5c53)
- **test(#703): the battery table gets a MEASURED external-only column** (0583f89)
- **test(#703): repair the two rows a heredoc mangled** (a2c14db)
- **test(#703): the battery's re-measured table, with external-only attribution** (c2c19f9)
- **test(#703): external checks for the two rows only the self-test could kill** (353100c)
- **test(#703): the stale anchor the LOO rename left behind** (11c6e57)
- **test(#703): the battery's measured table** (5c45c4f)
- **test(#703): the self-test runs LAST, so it cannot mask the checks below it** (f96a3d4)
- **test(#703): the mutation battery, before its counts are recorded** (39b2fab)
- **test(#703): the kernel's arms, before the battery's counts are recorded** (358f01c)
- **test(#768): the battery's measured table, re-derived rather than adjusted** (95bbe74)
- **test(#768): re-anchor the plan row the widened guard left matching nothing** (8bcc13b)
- **test(#768): the STANDALONE section drives run_cap_optimization too (#780)** (37e344a)
- **test(#768): the #780 line made one battery row BROKEN and one arm vacuous** (d3c603f)
- **test(#768): the inline arm reads the config the inline path BUILDS (#780)** (40dc432)
- **test(#779): the battery's re-measured table after the behavioural arm** (63e93fa)
- **test(#779): the end-to-end arm I said was unavailable, and five more review findings** (97ee7ee)
- **test(#779): the battery's measured table** (9d19520)
- **test(#779): the mutation battery, before its counts are recorded** (14b1f0b)
- **test(#779): the arms, before the battery's counts are recorded** (63ef3e5)
- **test(#775): four numbers a third review found, one of them my own arm's doing** (83b3309)
- **test(#733): re-point the arm the #772 rename broke, and say how it got past me** (4e505df)
- **test(#772): the no-wx gate learns which OWNER a param has to resolve on** (3a19ede)
- **test(#772): the gate that reads what the cap engine is handed, not what the plan says** (070cca6)

### Docs
- **docs(#703): every r-value says which variable it was measured against** (9948c0e)
- **docs(#772): the cap-param delivery gate in the gui_parity README** (a30e86c)

_Recap by [Repo Wrapped](https://repowrapped.com/gh/drandyhaas/KiCadRoutingTools?utm_source=github-action)._