Files
diodeinc__pcb/crates
Lenny Khazan 36db6ff4cc ENG-1191 Improve schematic placement and minimal connectivity repair (#1119)
* Improve default schematic placement

Amp-Thread-ID: https://ampcode.com/threads/T-01a04c5e-b251-76ec-bcb7-fc965c59f1cd

* Limit inferred rotation to two-pin symbols

Amp-Thread-ID: https://ampcode.com/threads/T-01a04c5e-b251-76ec-bcb7-fc965c59f1cd

* Align schematic grids by symbol anchors

Amp-Thread-ID: https://ampcode.com/threads/T-01a04c5e-b251-76ec-bcb7-fc965c59f1cd

* Group unused schematic interface labels

Amp-Thread-ID: https://ampcode.com/threads/T-01a04c5e-b251-76ec-bcb7-fc965c59f1cd

* Place generated schematic batches on aligned shelves

Amp-Thread-ID: https://ampcode.com/threads/T-01a04c5e-b251-76ec-bcb7-fc965c59f1cd

* Grow fresh schematic pages to fit placement

Amp-Thread-ID: https://ampcode.com/threads/T-01a04c5e-b251-76ec-bcb7-fc965c59f1cd

* Fix rotated schematic field justification

Amp-Thread-ID: https://ampcode.com/threads/T-01a04c5e-b251-76ec-bcb7-fc965c59f1cd

* Match KiCad field rotation direction

Amp-Thread-ID: https://ampcode.com/threads/T-01a04c5e-b251-76ec-bcb7-fc965c59f1cd

* Fix net-symbol staircases across pin banks

Amp-Thread-ID: https://ampcode.com/threads/T-01a054b7-0376-71e9-9ceb-dd5d495bfbf1

* docs: simplify schematic placement changelog

Amp-Thread-ID: https://ampcode.com/threads/T-01a054b7-0376-71e9-9ceb-dd5d495bfbf1

* Fix schematic placement edge cases

Amp-Thread-ID: https://ampcode.com/threads/T-01a054b7-0376-71e9-9ceb-dd5d495bfbf1

* Expose symbol field autoplacement

Amp-Thread-ID: https://ampcode.com/threads/T-01a054b7-0376-71e9-9ceb-dd5d495bfbf1

* test(kicad-sch): consolidate placement coverage

Amp-Thread-ID: https://ampcode.com/threads/T-01a054b7-0376-71e9-9ceb-dd5d495bfbf1

* fix(kicad-sch): match KiCad field autoplacement

Amp-Thread-ID: https://ampcode.com/threads/T-01a054b7-0376-71e9-9ceb-dd5d495bfbf1

* feat(kicad-sch): plan selected net drivers

Amp-Thread-ID: https://ampcode.com/threads/T-01a054b7-0376-71e9-9ceb-dd5d495bfbf1

* fix(kicad-sch): separate opposing net symbol stairs

Amp-Thread-ID: https://ampcode.com/threads/T-01a054b7-0376-71e9-9ceb-dd5d495bfbf1

* refactor: simplify schematic placement internals

Amp-Thread-ID: https://ampcode.com/threads/T-01a054b7-0376-71e9-9ceb-dd5d495bfbf1

* refactor(schematic): remove editor-specific driver planning

* fix(schematic): stabilize initial placement

* feat(schematic): plan minimal short recovery cuts

* fix(schematic): complete multi-net short teardown

* fix(schematic): localize unexpected connection cuts

* feat(schematic): plan repairs as verified intents with minimum cuts

Make the repair intent the full semantic contract between PCB and an
interactive realizer. The planner now accepts forced removals (a
consumer's explicit rip-up set) and derives the nets they break, records
the issues it resolves, names the driver kind each reconnected net needs
on each page, and includes the junctions its removals orphan. A public
verify_repair judges any realization by one postcondition: selected
issues gone, no new issues, nothing outside the intent changed.
apply_edits applies removals and relocations without new geometry.

Shorts and unexpected connections are cut with a minimum node cut over
the physical adjacency graph, verified through the reducer, replacing
the bounded exact search that fell back to whole-island teardown past
sixteen candidates. Duplicate and overlapping wires no longer defeat it.

Net-symbol re-drive checks its stub against geometry outside the net and
steps along the stair before falling back to a local label, so a repair
can no longer reintroduce a short through its own driver.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(schematic): let a realizer keep an item the intent would remove

Orphaned-junction removal is cleanup, not semantics. A realizer that
reroutes through the same point re-establishes the tee, and with a stable
junction id that read to the verifier as keeping an item the intent
removes. Verification now only rejects such an item if it changed; the
issue checks already judge whether the removal mattered.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* refactor(schematic): simplify the repair intent boundary

Drop the standalone removal applier and the intermediate net-symbol driver
type, derive driver kinds once in the public planner, share item matching
and segment tests between the planner and composer, and trim redundant
repair-planning tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(changelog): summarize schematic placement and repair work

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(kicad-sch): address review findings on fit, drivers, and repair verification

- Judge generated-batch fit against the page's real occupancy (title
  block, hierarchy sheets, preserved items) and place with that same
  packer, so a batch that fits never lands on preserved work and a fresh
  page grows instead of overlapping.
- Number upright side net-symbol stairs across pin banks so two banks
  cannot stack distinct power nets on one body-corner point.
- When no stair is free, fall back to a label in the power symbol's own
  scope (global for global power symbols), and count the drivers already
  added for a net as its own geometry rather than as collisions.
- Join a net's interface-only hierarchical labels with a wire so several
  interface names form one island.
- Plan a hierarchical driver on pages that expose a net only through
  their module interface.
- Verify repairs against the whole document: no added, removed, or
  reordered pages, unchanged page metadata, preserved library
  definitions and uninterpreted items, and relocated symbols that differ
  only by their offset.
- Count sheet pins as junction contacts when pruning orphaned junctions.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(kicad-sch): rank viable grid shapes, guard forced removals, align driver kinds

- Rank only the component-grid shapes that fit around the page's preserved
  items, so a batch that fits in another column count no longer aborts an
  incremental apply and a fresh page no longer grows when another shape
  fits the current paper.
- Reject a forced removal of any symbol that is not a name driver in the
  inspected connectivity; deleting a component symbol would produce an
  intent no verification can accept.
- Plan a global driver for an island cut off from its net on another page,
  the rule PCB's own realizer applies, so a consumer following the intent
  lands on the same label kind.
- Count only the current page's pins as safe geometry when checking a net
  symbol stub for collisions; a matching coordinate on another page is
  foreign here.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(kicad-sch): make symbol definitions order-stable so apply converges

A derived (`extends`) library symbol was flattened through a HashMap, so
its child order -- and with it the position of `(embedded_fonts no)` --
changed on every `pcb build`. `pcb apply schematic` then rewrote the
`lib_symbols` definition on every run and never reported `schematic
unchanged`.

- pcb-eda: keep a derived symbol's own items in source order while
  merging them over the parent, instead of iterating a HashMap.
- pcb-kicad-sch: canonicalize every symbol definition to KiCad's own
  order (header attributes, properties sorted by name, unit sub-symbols,
  `embedded_fonts`) so a definition compares and serializes the same
  however its source ordered the children.

Verified on a 31-page migrated legacy schematic: the second and third
`pcb apply schematic` now report `schematic unchanged` with no file
changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(changelog): summarize schematic placement and repair work

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-02 14:49:47 -04:00
..
2026-09-01 20:20:01 -04:00