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

_129 commits._

### Fixes
- **tests: repoint the schema rows, fix the CRLF anchor break, pin the declared gate** (5604654)
- **#792: the battery row the review's own fix invalidated, re-anchored** (4a4bf34)
- **#700/#798: the pre-push review's findings -- a 40x perf regression I shipped,** (ff56f35)
- **perf: capsule keep-outs as SPANS -- 11.4% of a glasgow route** (c9e32f0)
- **perf: capsule spans for block_segment (11x), vectorized clears() (21x)** (4d56635)
- **perf: batch the two PAD stamping loops the 2026-08-14 FFI pass missed** (0d11212)

### Backend
- **Release v0.21.5** (7db2b91)
- **parity audit 31004f43..166255d0: no gap; six gates green, corpus sets 1-5 screened** (b2b489c)
- **Merge PR #824: test(#797): re-anchor the mutation row that #706 and #797 landing together moved** (166255d)
- **Merge PR #823: #797: the seat search refuses a stranger the intent reserved a region for** (f348455)
- **Merge PR #822: #711/#712/#706: a board can DECLARE what it is for, say where along an edge a connector sits, and be seated to it** (beea34c)
- **Merge PR #821: #705/#792/#794: the decap rule measures the wrong thing, on a set it disagrees about, inside a horizon that hides the worst case** (0c12880)
- **Merge PR #820: #700/#798: the layer count reaches the placement stack, and the via row is what actually binds** (96ec4df)
- **Merge PR #819: #709/#459: the pocket census can say EMPTY, and a region becomes nameable** (052287a)
- **Merge PR #813: #793/#799: an allow glob that matches nothing strands the part it was drawn around, and a zone a keep-out leaves no pose in is accepted** (867b3ed)
- **#797: re-record the AFTER arm at the branch tip** (67a26c4)
- **#797: the fact-check's corrections -- three stale line refs and three false claims** (00f1ff9)
- **#797: the corpus measurement, before and after, committed** (f816df4)
- **tests: the measured battery table, 35 rows / 34 killed / 1 recorded survivor** (d502700)
- **#797: a second blind review, and the guard that was only half a guard** (e8d30d6)
- **tests: assert the CENTRE, not the tolerance -- the bound was the answer twice** (12d595a)
- **review round 2: four defects in the FIXES, including one my own correction created** (8bb3b15)
- **#797: the post-polish repair was moving KiCad-LOCKED parts, and this branch made it reach two** (8b11bab)
- **routing (#816): the tie epsilon reaches every float-centre disc -- a source census found a FOURTH drill-h2h mirror still deciding boundary cells by float rounding** (6eb2a45)
- **#711: guard the two plugin sibling imports, and assert the fallbacks cannot drift** (e125ac2)
- **#797: six defects a blind review found in my own work, and the two it found in the engine** (4e40600)
- **tests: the measured battery table, 35 rows / 33 killed / 2 recorded survivors** (9b3a52a)
- **tests: the combined stage-1 row now actually disables both paths** (7e7d7d6)
- **tests: a combined stage-1 row, because each path alone is redundant** (0d692f7)
- **tests: two stage-1 rows, because the declaration is carried twice** (fa40735)
- **tests: repoint the six anchors the _seat_edge restructure moved, single-line** (194f9c4)
- **review: five statements of mine that were not true, and two defects behind them** (10cc540)
- **#797: the two seat paths that bypass `pose_ok`, and the column that went stale** (48ab6f6)
- **#797: the seat search refuses a stranger the intent reserved a region for** (11baa9f)
- **tests: the measured mutation table, 33 rows and 33 killed -- and what it took** (cebc7a3)
- **tests: close the four holes the mutation battery found, and stop it poisoning itself** (7b51ca6)
- **tests(#711/#712/#706): three files, and the two defects they found in this branch** (9559b40)
- **#706: the seat and the grade now speak the same currency, and the ladder can search a declared window** (408b373)
- **#706: _seat_edge aims at the declaration instead of the pose it inherited** (9d4dfc1)
- **#711: check_floorplan reads the brief -- merges it on emit, reports DRIFT on grade** (a3619dc)
- **#711: one sibling list, imported everywhere, and a lint that refuses a tenth** (e55efd5)
- **#711: a board can carry a DECLARED design brief, and it compiles into the existing intent** (4073979)
- **#712: edge_connectors can say WHERE ALONG the edge, and the span comes from the ring** (b812d63)
- **#700: read the board's design rules ONCE per ledger** (5318a74)
- **#705/#792/#794: the battery table, from the run** (f59e63a)
- **#705/#792/#794: the pre-push review's findings, fixed and pinned** (bc8e9a8)
- **#705/#792/#794: five holes the battery found in my tests, and a second silent path** (57c4444)
- **#792: the seeding rows, and the two things they found that I had asserted** (543c562)
- **#705/#792/#794: the mutation battery and the seeding measurement, before either is run** (e053807)
- **#700: the items 1-2 verifier's findings, fixed -- including two of mine that** (036127f)
- **#705: the two doc numbers my previous commit claimed to have fixed** (384ec35)
- **#705/#792/#794: the docs, including three sentences that were false before this PR** (492ab42)
- **#792: the first tests stage 2.5 has ever had, and two they did not test at first** (049d23d)
- **#792: the seeder stops evicting caps it can never seat, and says so when it declines** (a36c96f)
- **#705: two arms my own deletion probe passed, and the controls that close them** (d10e86b)
- **#705: the pin rule's tests, and what they refuse to let a clean arm mean** (7237945)
- **routing (#815/#818/#816): grid keep-out boundaries stop depending on board position, and the capsule memo stops thrashing** (a405511)
- **#705: grade the decoupling cap to the PIN, on evidence the grade records** (a22a968)
- **#700 item 3: the demand-derived halo, measured and declined** (61feec5)
- **#794: a cap past the 5mm horizon is reported, and the census stops understating the worst one** (a956bc0)
- **#700 item 2: the escape ledger gains a layer term, and supply does not move** (4c545a9)
- **#700 item 1: the fab-floor bucketing is visible, so add_layers stops** (b3a654a)
- **#792/#794: one election for the decap tethers, and the pin predicate stops being unreachable** (cd30793)
- **#700 phase 1: the verifier's findings on my own guard, fixed** (c9610f2)
- **#798: resolve a registrar per FUNCTION, and the published flag sets become exact** (ce25527)
- **#793/#799: a skill script may not name a specific board** (670ab46)
- **#793/#799: the battery table re-recorded from the 22-row run** (5e3abe5)
- **#799: two battery rows for the guards the review exposed** (7d309e5)
- **#793/#799: the pre-push review's findings, fixed and pinned** (dc5ba1a)
- **#799: the agreement sweep, its committed numbers, and two proxies it caught** (a71ff60)
- **#799: the agreement sweep builds one QuenchState per board, not per case** (30b552f)
- **#793/#799: the measured mutation table, and the docs section for the widened check** (3ad6490)
- **#799: four things the battery caught in my own tests, three of them real** (8cec69a)
- **#793/#799: the battery's selftest probe could not tell its mutants apart** (8761f56)
- **#793/#799: the mutation battery, before it is run** (010274a)
- **#799: a zone a keep-out leaves no room in is refused, not only one it covers** (5d2ae40)
- **#793: an allow glob that matches nothing is reported, at both reach points** (9d9cfd6)
- **board_score: `blocking` counts ERROR-severity floorplan violations, not every one** (b5ef0d7)
- **#799: one local-bounds chain and one zone-origin algebra, shared before anything uses them** (729981a)
- **#700 phase 1: one via centre-to-centre rule, reachable without the router** (75e7ff5)
- **writer (#817): resolve strip-matcher net tokens PER BLOCK, either dialect -- on a mixed-dialect board every numeric copper block evaded the stale-input strip, shipping ripped copper that crosses the net routed into its corridor (the "same-call shorts" class)** (5e8aa39)
- **#800: add_allowed_rect -- one Python->Rust crossing per exemption block** (f249827)
- **tests: re-record five stale baselines, each with its cause BISECTED first** (cc8d5c2)
- **#709: the free-area guard is redundant, and the battery now says so on purpose** (ceb9567)
- **#709: the last surviving mutation, and why a count could never have caught it** (4ab0a59)
- **#709: the census's headline output was a command that lifts nothing, on every board** (e37a004)
- **#459: the empty-region shortcut skipped the board, the summary and the repair** (5abd819)
- **#459: the last surviving mutation -- a rectangle with nothing on its boundary proves nothing** (bb1d266)
- **#709: the pocket census gets predictor columns, so the question is answerable** (abbead3)
- **#709: document the census, and register it where a consumer can find it** (58d2bc1)
- **#459: place_seed --reseat-region -- naming a reseat scope by geometry** (d58c9c0)
- **#709: the verifier found the guard was excluded from --fast, and my order claim was overstated** (34da8fe)
- **#709: the mutation battery found four holes, one of them in the census itself** (bfa5d21)
- **#709: the tests, and the fourth bucket the first one of them found** (b11156f)
- **#709: the census enumerates in-outline windows, ranks cold regions, and joins mass to demand** (33d1873)
- **#709: congestion_bins can report a bin nothing demands** (dd247b8)
- **#811: merge collinear track pieces -- a straight track ships as ONE segment** (661c88b)
- **Merge PR #809: #788/#789 -- the L2 gate names the census it reads, and rule 1's crossings clause meets its exit criterion** (3244726)
- **Merge PR #808: #803/#552/#742 -- the cited authority, the analysis contract, and --default-via-size** (6d49042)
- **#742: --default-via-size gets its own GUI control, on its own key** (7dfb470)
- **#552: grant the dispatch tool, state the contract once, and stop overclaiming it** (5ddeb7c)
- **#803: the authority those eleven citations point at, committed** (74c10d2)
- **#789: three battery anchors, repointed at the code the review fixes moved** (6db38bc)
- **#789: the pre-push code review's findings, fixed and pinned** (faf419f)
- **#789: the pre-push fact-check's findings, fixed and pinned** (131be35)
- **#789: the mutation battery -- 16 rows, 16 killed, and the two it caught first** (1c408eb)
- **#788/#789: the doctrine stops saying crossings has never been correlated with routed blocking** (f0b9f0e)
- **#789: the six-board slate run, and what it settled** (1ee2a89)
- **#789: rule 1's crossings clause is withdrawn, on the criterion it pre-registered** (2841d5c)
- **#789: the tau carries how many candidates it was computed over** (ae66deb)
- **#789: two defects the instrument's own guards found on its first run** (031606e)
- **#789: pre-register the tau criterion, BEFORE any tau exists** (82a49ce)
- **#789: the slate study, and the circularity position it takes** (a206e8e)
- **#789: the arithmetic -- Kendall tau-b in rank_stats, and its self-test** (89bd8a2)
- **#788: the clearance-graze channel does not earn a gate at L2, and why** (f160018)
- **#788: the L2 gate names the census it actually reads, and the two are measured** (7dfe567)
- **#788 prep: the study's own numbers -- 120 rows over six boards, not 87 over four** (d3101c0)

### Tests
- **test(#797): re-anchor the edge-slide row that #706 and #797 landing together moved** (fb91b85)
- **test(#797): the measured table, at 31 rows, and a note about why it drifts** (387ac31)
- **test(#797): the ghost-member fixture, and the row that needed it** (db9f5d1)
- **test(#797): the mutation battery, and the two rows the run corrected** (721deb9)
- **test(#799): the blame claim is verified, not asserted** (96f0bb1)
- **test(#789): the null rate is checked where a reader sees it** (06b3b06)
- **test(#789): the slate analysis, on synthesized rows, with no wk/ and no routing** (61fa0c1)
- **test(#788): fourteen rows of the study, committed as literals** (366b493)
- **test(#788): the corrected claim is pinned in both directions** (4d48923)

### Docs
- **docs(stress): cloud grading is the SAME grader now, so --no-local-regrade is the fast path on a KiCad wave** (c5f9668)
- **docs(stress): the cloud image HAS carried KiCad since 2026-08-23 -- three places still said it does not, one of them as a rule's justification** (472545a)
- **docs(#711): the design-brief reference, board_brief's structured section, and a caller** (ec2b760)

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