## drandyhaas/KiCadRoutingTools — v0.22.0…v0.22.1

_508+ commits._

### Features
- **#961: verifier round 1 -- sum the body over its sides, no new conjunct; untested branches pinned** (b7c6014)

### Fixes
- **Fix the suite's two standing failures: re-record #703 for #958, anonymise three board names** (f0838d2)
- **Merge pull request #969 from edgehero/fix/966-unset-clearance** (6116e7c)
- **Merge pull request #968 from edgehero/fix/967-resolved-edge-clearance** (bc6ab92)
- **Document three independent bug reviews and final placement evidence** (3bbd5a5)
- **Fix unset Default clearance resolution in routing dialog** (a29856f)
- **Merge pull request #957 from edgehero/fix/seed-gate-sees-its-own-shorts** (5a7fbcb)
- **Merge pull request #954 from edgehero/fix/seed-gate-pad-conflicts** (ce5f9b2)
- **Merge branch 'fix/958-smoother-prefers-fewer-segments': #958 smoother prefers fewer segments at equal length** (9fcb659)
- **Merge pull request #953 from edgehero/fix/seed-gate-grades-its-own-work** (c44f623)
- **Merge pull request #949 from edgehero/fix/oob-exemption-and-body-seat** (740cf1c)
- **Merge pull request #948 from edgehero/fix/writer-text-angles-on-rotation** (36ea693)
- **Merge pull request #947 from edgehero/fix/908-graphic-width-rows** (a56de4a)

### Backend
- **v0.22.1: the release triple** (023d3f7)
- **run the obstacle ref-count release gate on Modal, per-step by default** (57037aa)
- **gui-parity ledger: audit a633f898..96912901 (16 commits), no gap, eight gates green** (b30b724)
- **the fanout fronts honour --clearance-ceiling instead of accepting and ignoring it** (9691290)
- **Merge PR #981: place_seed reports its declared connector requirements in JSON_SUMMARY** (84bc32c)
- **#974: fact-check round -- the counts are not all per-pad** (6b74a30)
- **#974: pre-push review -- the battery runs its gate unmutated first** (cb112d8)
- **#974: record the battery's measured result** (601ef4f)
- **#974: overhang_evidence is a projection, so the summary line stays bounded** (6fc6022)
- **#974: delta verifier round -- rc 1 and re-seat unseating in the exit-code row** (a998c64)
- **#974: drop the along-edge guard the battery measured inert** (b82fce7)
- **#974: verifier round P2 -- acceptance 2 on an arm the band alone decides** (7245088)
- **#974: verifier rounds P1b and P3 -- one entry's row, and six false doc sentences** (3ddaa15)
- **#974: the mutation battery -- does anything notice when the report lies** (c35555b)
- **#974: verifier round P1 -- a vacuous band never hides skipped copper** (4c9c23f)
- **#974: document connector_requirements, and gate the doc against real output** (774642a)
- **#974: place_seed carries connector_requirements on every JSON_SUMMARY** (91d775a)
- **#974: floorplan.connector_requirements -- the declared connector requirements, reported** (d90eb10)
- **gui-parity ledger: audit f4fb38ed..a633f898 (58 commits), no gap, eight gates green** (98243e8)
- **Merge PR #976: provenance rows chain on a pose digest, and copy/rename deliveries are recorded** (a633f89)
- **Merge PR #971: grade a declared connector overhang on the drawn body, not a clearance shortfall** (7ff774c)
- **Merge PR #970: record place_pose provenance at the promote, against the delivered path** (e4e7054)
- **#961: the AUDIO1 correction missed the code comment it also lived in** (b9879b8)
- **#961: make the certification test reach the exemption it asserts** (f919912)
- **#961: verifier round 5 -- never certify a pad the grader cannot model, and stop keying on prose** (077f623)
- **#961: make the pad-box matrix vary y, so a sign error in the centre transform dies** (0815f64)
- **#961: verifier round 4 -- pads the edge grader cannot model, and the extent maths nothing pinned** (68d7e06)
- **#961: verifier round 4 -- say why the copper rule is body-scoped, and correct three numbers** (9314d84)
- **#961: verifier round 3 -- the seat predicate sees pad copper too, and the branches its battery reached** (79c199e)
- **#961: verifier round 3 -- the copper conjunct in the docs, and rows for the five branches that had only tests** (907205d)
- **#961: verifier round 2 -- pad copper past the outline stays a defect; a marker is not a body** (77cd3f1)
- **#961: grade the declared overhang band on the drawn body, not a clearance shortfall** (498af62)
- **#960: record the mutate_892 battery for the five promote/ledger rows** (d8126bc)
- **#960: test the ledger-failure rollback; state the pending-leak risk exactly** (baad562)
- **#960: record place_pose provenance at the promote, against the delivered path** (365c3b8)
- **test_973: compare delivered paths by realpath, not abspath** (50e1bd3)
- **the staged board minimum must not outrank a pad's own declared clearance** (dfa7ddb)
- **Merge PR #979: a footprint's pose is its own (at ...), in any number spelling KiCad writes** (b028358)
- **Merge PR #978: project siblings reach every routed and delivered board, and in place is not a crash** (c923a6d)
- **say which floor a KiCad grade was taken at, so two arms can be compared** (ace794f)
- **a footprint segment bridging two nets is not free space for either** (5e48a3d)
- **a read-only step is not the producer of the board it reads** (ce75d3c)
- **#713: register py_tools/repo_metrics.py's clock, with what it actually does** (d96877f)
- **P and N are different nets, so price the intra-pair gap pairwise** (cc0109e)
- **#958's fine-pitch field is decided by what fits between the pads, not by 0.8mm** (e5c7a76)
- **the strip derivation must not delete copper no pass may prune** (2f5974e)
- **a via-suppression bridge is a joint between two barrels, not a disc** (7b2837e)
- **Merge #977: one lifter per obstacle map, so there is no marker to keep honest** (8706545)
- **#977: one lifter per obstacle map, so there is no marker to keep honest** (f2cfbc5)
- **the shipped file must be the engine's own answer, not the strip list's memory** (b195582)
- **--force-reroute must not restore copper on top of what replaced it (#134)** (46881ca)
- **a net name with a backslash is one net, not two -- at every site that resolves one** (b271473)
- **#521: a PARTIALLY routed pair still carries coupled copper, so protect it** (8ca103b)
- **detect_bga_pitch returns a PITCH, not the smallest gap on the package** (125eeaf)
- **invariant E on the route.py front, measured free of endpoint exemptions** (40caf3f)
- **obstacle map: every copper commit tells the map (#806 on the route.py front)** (d7c805a)
- **donate: a Ko-fi button on the About tab, the README and the PCM metadata** (61bd0f9)
- **footprint (at): the verifier's findings -- three untested paths, a spaced node, a silent drop** (a280cd6)
- **test_sibling_copies: pin samefile over a path compare; say what is skipped; clean up** (750188d)
- **A footprint's pose is its own (at ...), in any number spelling KiCad writes** (96d2e76)
- **Project siblings reach every routed and delivered board, and in place is not a crash** (4214ff1)
- **#972/#973: the fact-checker's test gaps** (86ffeb8)
- **#972/#973: the pre-push review's findings** (00a8055)
- **#972: the rename-onto-another-pose case lands on the pose exactly** (94cee58)
- **#972/#973: the delta verifier's findings** (3f8eb78)
- **#973: the undeclared loop case can see siblings copied before the refusal** (f10a138)
- **#973: the Phase 3-5 verifier's findings** (33d5747)
- **#972: the Phase 2 verifier's findings** (5cee5bd)
- **#972/#973: the audit's prose says what it now checks** (8290944)
- **#972: the Phase 1 verifier's findings** (cfe3efe)
- **#973: deliveries by copy or rename are recorded against the output** (593b949)
- **#972: the audit walks a pose lineage from the staged board** (cf9679a)
- **#972: a pose digest on every engine row** (c11a140)
- **gui-parity ledger: re-point the SHAs after main's history rewrite** (223e46b)
- **metrics: the archive moves to an orphan branch, so main stops collecting bot commits** (d23e90b)
- **gui-parity ledger: audit c44f623f..009a8cf0 (71 commits), no gap, eight gates green** (f30304b)
- **#703: re-record the esp_prog rows for the #958 fine-pitch tie guard** (f4fb38e)
- **#958: an equal-length collapse does not rearrange copper in a fine-pitch field** (4e6f858)
- **Revert "#958: an equal-length collapse must not take a waiting pad's escape room"** (cda2e93)
- **#521/#906: half a pair is not a protected pair** (ba9a25f)
- **#441: a ring-uncovered plated drill is a hole to the copper-MOVERS too** (0b9acf9)
- **#958: an equal-length collapse must not take a waiting pad's escape room** (74579cf)
- **#703: re-record the three esp_prog rows for #908's Phase 3 own-pad lift** (06922ab)
- **#448/#536: an NPTH slot is board edge to the passes that MOVE copper, too** (bd930fd)
- **#874: a stub layer-swap via is shipped copper, so the sync must keep it** (18d5f16)
- **Revert "Same-net via keep-out reaches the small fab rung" -- it buys connectivity with shorts** (0c12cb3)
- **watchy EN/BTN3: an intact restore outranks partial copper that connects nothing** (90929b3)
- **A diff pair whose own members short is not written (icepi_zero /USB/D1)** (7ecc63b)
- **Same-net via keep-out reaches the small fab rung (mod_bme280's overlapping drills)** (377b8c6)
- **#908: cparti_fpga's tie nets ROUTE -- the short gate counted the tie as foreign** (41b8cc6)
- **#908: the bake marker is per-MAP, Phase 3 gets the lift, and a gate that pins it** (0f23e2c)
- **#908: the own-pad lift could never remove anything -- #422 stamps the base STATIC** (2b463a0)
- **#908: the own-pad lift covers only the TRACK stamp, never the via keep-out** (e17f87d)
- **#908: a net tie's own copper is the tie, not foreign copper (PARTIAL)** (897bebd)
- **README: link the metrics page** (a7581a8)
- **Chart labels are HTML, so they stay readable at any page width** (b6d89ba)
- **The PCM headline follows the release PCM is SERVING, not the biggest pile** (1a37562)
- **Stop tracking the generated site; commit only the archive** (7cd8786)
- **Collect daily, and immediately on every release** (668f2c6)
- **Spread the release downloads over time instead of stacking them into spikes** (06fe4c3)
- **Site: a downloads chart, and /metrics as a subpage under a landing root** (dcd0348)
- **Audit METRICS_TOKEN by asking it what it can do** (9561a29)
- **The first CI run's two findings: an un-paginated read, and an exit that buried its own disclosure** (00bf139)
- **Merge feat/reach-metrics-pages: weekly reach snapshot, archived in git and published to Pages** (e1b984d)
- **Weekly clone/view rollup, with the partial week marked rather than compared** (c3c8f7d)
- **Clone character: an automation index, because a human count does not exist** (087e27d)
- **Weekly reach snapshot, archived in git and published to Pages** (05af694)
- **#966: a Default net-class clearance of 0 is UNSET, not a floor, on the WRITE side too** (b6f5a4e)
- **#966: drop the evidence dumps from the repository** (f9f441a)
- **#967: drop the evidence dumps from the repository** (5dd9273)
- **Clarify command evidence versus identity metadata** (cbc819b)
- **Placement: resolve independent geometry, rule and output review findings** (ad156f2)
- **Record fresh independent verification and bounded issue scope** (58c3689)
- **Disclose simplified pad and unevaluated edge coverage** (64c6368)
- **Record independent clearance reproduction and final native verification** (acbcfa8)
- **Preserve omitted placement clearance across the fanout boundary** (e568142)
- **Record independent edge-floor reproduction and verification** (9df83aa)
- **Qualify custom copper coverage and retain mutation checks** (39d91f2)
- **Enforce resolved placement edge floors with separate pad evidence (#967)** (1f84d36)
- **Merge pull request #956 from edgehero/docs/skill-tool-index** (5756044)
- **Merge pull request #955 from edgehero/feat/seed-the-residue-not-the-decisions** (07b6761)
- **place_seed: the refusal line names the channel that actually fired** (05c7cf6)
- **set29: 12 boards mined from awesome-kicad-projects, +1 monster** (6b74f00)
- **#958: the smoother prefers fewer segments at equal length, in a second greedy phase** (2fe97a3)
- **place_seed: the gate looks at the copper it just arranged** (e40e995)
- **Placement driver: `must_lock` is not a pin, and the gate said it was** (d961929)
- **Placement skill: "Which tool, when" -- a decision table, gated both ways against the #937 registry** (2f90497)
- **Seeder: the review's three findings on the stage-1 seat check** (ced30ac)
- **Placement: the seeder places the RESIDUE, and P1 refuses to let it choose a connector's pose** (93cbc78)
- **Seeder: stage 1 seats a declared edge connector CLEAR of the parts already placed** (93e58d0)
- **gui-parity-checked: audit head c44f623f (a65194fb..HEAD, 272 commits)** (c38b3f5)
- **Merge pull request #952 from edgehero/feat/driver-zone-plan-guard** (64d6ac5)
- **Merge pull request #951 from edgehero/feat/seed-rotate-by-facing** (96165d0)
- **Merge pull request #950 from edgehero/feat/edge-facing-term** (ba9fade)
- **#908 follow-up: the THIRD consumer -- the relaxation banner's census counted outlines too** (8c44b06)
- **place_seed: the gate grades the seed's own work; an error on a part it was told not to move is set aside, named** (eb7b4fc)
- **Seeder: the OFF path gets its whole-board sweep back; the review's four other findings** (284007f)

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