Skip to content

Releases: seunghyukchoe/copper-mcp

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 01 Sep 19:03
eeef3a9

What's Changed

Documentation and maintenance

Other changes

Full Changelog: v0.11.0...v0.12.0

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 28 Aug 10:53
479bd4c

What's Changed

Documentation and maintenance

Other changes

Full Changelog: v0.10.0...v0.11.0

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 27 Aug 12:16
2bf32ef

What's Changed

Documentation and maintenance

Other changes

Full Changelog: v0.9.0...v0.10.0

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 16 Aug 08:43
c9d39a0

What's Changed

Documentation and maintenance

Other changes

Full Changelog: v0.8.0...v0.9.0

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 13 Aug 18:47
0bc72da

What's Changed

Documentation and maintenance

Other changes

  • fix(board-ir): copper text has no derivable envelope, and refuses saying so (#141) by @seunghyukchoe in #148
  • feat(board-ir): convert an edge-connector pad as SMD, and count the token it discards by @seunghyukchoe in #149
  • fix(board-ir): a pad refusal names its field, and seven fabrication properties convert (ADR-0099, D-189, R-144, SEC-140, B-103) by @seunghyukchoe in #157
  • fix(board-ir): a custom pad refuses by name, and the name says why (#153) by @seunghyukchoe in #158
  • fix(routing): close #63 as delivered, and gate the single-layer fill shrink like the layered one by @seunghyukchoe in #162
  • fix(routing): a candidate replays under the model that produced it (#163) by @seunghyukchoe in #169
  • docs(release): the 0.8.0 migration note, and a changelog audited rather than moved by @seunghyukchoe in #171

Full Changelog: v0.7.0...v0.8.0

v0.7.0

Choose a tag to compare

@seunghyukchoe seunghyukchoe released this 12 Aug 08:57
da51f7d

Real boards, and the refusals that stop them.

Upgrading from 0.6.0: read the 0.7.0 migration notes first. Five changes break something a working 0.6.0 deployment can depend on.

Highlights

ROUTER_VERSION moves to astar-grid/0.7.0. Every held candidate_id and bundle_id stops reproducing. No path geometry moved — this is the one change in the release that invalidates stored data, and it has its own migration section.

One obstacle budget was metering three different populations. 61 of 93 route refusals were the routed net's own copper charged to a budget named for copper it must avoid — a category error, not a capacity problem. Split into three discriminated budgets, with the obstacle model scoped to a routing region and the search confined to the same region, which is what makes the scoping sound rather than merely cheaper.

A locked (group …) now refuses instead of silently unlocking its members. BOARD_ITEM::IsLocked() derives lock from the parent group, so a locked group locks every member transitively with nothing in the member's own s-expression saying so. Members would have converted at locked=False past three authorization gates.

Pad zone_connect overrides that attach are accepted; the one that detaches still refuses. Accepting 0 could have made Board IR assert attachment over a deliberately isolated pad. Along the way: seven named pad refusals turned out to be unreachable dead code behind a generic allowlist check, so the message the original issue quoted was one the adapter could not emit.

Net-tie copper converts as a netless obstacle — something to route around, never a connection. The two deliberately shorted nets are never reported as connected.

Off-grid refusals now carry evidence: the pad, the lattice pitch, the signed per-axis miss in nanometres, and the largest representable step. The measurement that produced it refuted the hypothesis it was meant to confirm — re-previewing all 18 real-board off-grid refusals at exactly their own representable step, with the node budget at its ceiling, routed none of them. The lattice is where the refusal is reported, not where the constraint is.

Our own DRC payload failed our own published schema, and the schema then failed the other way too: clean: true beside a nonzero finding count validated. Both derived flags are now enforced in both directions, so a schema-only consumer cannot accept what the runtime refuses.

Honest numbers

Board IR converts 11 of the 12 boards in the #116 survey set, which is 11 of all 17 boards in that corpus as saved today. Six typed refusals across three constructs, each tracked: edge-connector pads (#138), root board properties on four saves (#140), a root copper graphic (#141).

Route preview routes 0 of 385 previews on that corpus today. An earlier 0 → 14 figure was measured on the corpus as it stood on 2026-08-07; those boards have since changed. An old-code/new-code differential on today's boards returns byte-identical verdicts across all seven codes, so nothing here regressed routing — the corpus moved, not the code.

Route preview runs one net at a time on F.Cu against the unrouted snapshot, so candidates are not mutually compatible and this is not a whole-board completion result. Placement preview ran without rules, so a clean verdict means legal-as-found, not placement quality. Neither surface makes an electrical, thermal, signal-integrity or manufacturing claim.

Gates

2,518 tests, 1 skipped, 760 subtests locally including the real-KiCad nodes; 2,438 passed with 81 environment skips across Python 3.11, 3.12 and 3.13 on hosted runners. Ruff, strict mypy over 97 source files, four repository checkers, CodeQL, dependency and secret audit, and OpenSSF Scorecard — all green on the exact source commit. The full evidence, including the one gate that could not run locally, is in the release ledger.

One thing the release build caught

The default source distribution was 124 MB across 20,452 files — it had swept in twenty-eight agent worktrees, because hatchling reads .gitignore and this repository excludes them through .git/info/exclude. The sdist now ships an explicit allowlist rather than an exclusion list: 717 files, 4.8 MB.

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 05 Aug 23:15

What's Changed

Documentation and maintenance

Other changes

  • fix(placement): refuse non-orthogonal saved poses with a typed diagnostic by @seunghyukchoe in #79
  • test: pin golden identities for every content-addressed surface by @seunghyukchoe in #84

Full Changelog: v0.5.0...v0.6.0

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 05 Aug 13:42

What's Changed

Features

  • feat: serialize replayed candidates to disposable KiCad snapshots by @seunghyukchoe in #25

Research and performance

Documentation and maintenance

Other changes

  • feat: add bounded deterministic two-pin A* baseline by @seunghyukchoe in #23
  • feat: bind route candidates to authoritative KiCad DRC by @seunghyukchoe in #27
  • feat: expose a bounded non-mutating route preview by @seunghyukchoe in #28
  • feat: add read-only Board IR inspection over a shared request boundary by @seunghyukchoe in #30
  • feat: route around existing copper instead of rejecting it by @seunghyukchoe in #31
  • feat: treat through vias as obstacles instead of a board-level veto by @seunghyukchoe in #33
  • feat: via-aware cross-layer connectivity recognition by @seunghyukchoe in #36
  • feat: Circuit Scene IR v0.1 — typed board observation for agents by @seunghyukchoe in #39
  • feat: Scene IR slice 2 — deterministic digest-bound renders by @seunghyukchoe in #40
  • fix: absolute pad rotation + six scene observation hardening fixes by @seunghyukchoe in #41
  • feat: placement intent and deterministic legalizer (M4 core) by @seunghyukchoe in #42
  • feat: preview_placement surface (M4 placement preview complete) by @seunghyukchoe in #43
  • feat: CST splice layer and pure apply engine (M3 slices 1-2) by @seunghyukchoe in #45
  • feat: apply_candidate — the first mutating surface (M3 slices 3-5) by @seunghyukchoe in #46

Full Changelog: v0.1.0...v0.5.0

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 03 Aug 18:04

What's Changed

Features

  • feat: serialize replayed candidates to disposable KiCad snapshots by @seunghyukchoe in #25

Research and performance

Documentation and maintenance

Other changes

  • feat: add bounded deterministic two-pin A* baseline by @seunghyukchoe in #23
  • feat: bind route candidates to authoritative KiCad DRC by @seunghyukchoe in #27
  • feat: expose a bounded non-mutating route preview by @seunghyukchoe in #28
  • feat: add read-only Board IR inspection over a shared request boundary by @seunghyukchoe in #30
  • feat: route around existing copper instead of rejecting it by @seunghyukchoe in #31
  • feat: treat through vias as obstacles instead of a board-level veto by @seunghyukchoe in #33
  • feat: via-aware cross-layer connectivity recognition by @seunghyukchoe in #36
  • feat: Circuit Scene IR v0.1 — typed board observation for agents by @seunghyukchoe in #39
  • feat: Scene IR slice 2 — deterministic digest-bound renders by @seunghyukchoe in #40
  • fix: absolute pad rotation + six scene observation hardening fixes by @seunghyukchoe in #41
  • feat: placement intent and deterministic legalizer (M4 core) by @seunghyukchoe in #42
  • feat: preview_placement surface (M4 placement preview complete) by @seunghyukchoe in #43

Full Changelog: v0.1.0...v0.4.0

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 03 Aug 15:21

What's Changed

Features

  • feat: serialize replayed candidates to disposable KiCad snapshots by @seunghyukchoe in #25

Research and performance

Documentation and maintenance

Other changes

Full Changelog: v0.1.0...v0.3.0