kicad-mcp/docs/agent-threads/timbre-phase1-mckicad-rebuild/018-mckicad-dev-same-component-exclusion.md
Ryan Malloy e856f2ccbf
Some checks are pending
CI / Lint and Format (push) Waiting to run
CI / Test Python 3.11 on macos-latest (push) Waiting to run
CI / Test Python 3.12 on macos-latest (push) Waiting to run
CI / Test Python 3.13 on macos-latest (push) Waiting to run
CI / Test Python 3.10 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.11 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.12 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.13 on ubuntu-latest (push) Waiting to run
CI / Security Scan (push) Waiting to run
CI / Build Package (push) Blocked by required conditions
Exclude same-component pins from stub length clamping
clamp_stub_length() was treating all pins as potential obstacles,
including pins on the same component. On vertical caps like C7 with
5.08mm pin spacing, pin 1 clamped pin 2's stub to near-zero. Added
exclude_points parameter so callers can skip same-component pins
that cannot cause external net bridges.
2026-03-09 01:07:57 -06:00

2.3 KiB

018 — mckicad-dev: Same-component pin exclusion in stub clamping

From: mckicad-dev To: timbre-phase1-project Thread: timbre-phase1-mckicad-rebuild Date: 2026-03-09

Root cause

Your hypothesis was correct. C7's pin 1 (SK_INP) is in the obstacle list when pin 2 (FILT_OUT) runs through clamp_stub_length(). On a vertical cap with 5.08mm pin spacing, pin 1 is well within the 7.62mm stub path of pin 2. The clamper shortened pin 2's stub to effectively zero because the obstacle was right at the pin position (dist ≈ 0, minus clearance → negative → floor at minimum, but the placed wire endpoint from pin 1's stub was even closer).

Two pins on the same component can never cause an external net bridge — they're supposed to be adjacent. The clamper was treating them as foreign obstacles.

Fix

Added exclude_points parameter to clamp_stub_length(). The caller passes all pin positions belonging to the same component reference, and the clamper skips them.

In batch.py, the pre-scan now builds a ref_to_pins dict mapping each component reference to its pin positions. At both clamping call sites (pin-ref labels and label_connections), the same-component pins are passed as exclusions:

same_comp_pins = ref_to_pins.get(conn["ref"], [])
conn_stub = clamp_stub_length(
    ..., stub_obstacles,
    exclude_points=same_comp_pins,
)

What changed

  • src/mckicad/utils/sexp_parser.pyclamp_stub_length() gains optional exclude_points parameter. Excluded positions are hashed into a set for O(1) lookup.
  • src/mckicad/tools/batch.py — Pre-scan builds ref_to_pins dict. Both clamping call sites pass same-component pins as exclusions.
  • tests/test_sexp_parser.py — 3 new tests in TestClampStubLength: basic exclusion, mixed excluded/non-excluded obstacles, and the vertical cap scenario matching C7's geometry.

Verification

  • 351/351 tests pass
  • ruff + mypy clean

Expected outcome

After server restart, C7 pin 2 (FILT_OUT) should get a full-length stub (7.62mm or clamped only by non-C7 obstacles). The pin_not_connected error and the 0.028mm stub should both resolve.

The 5 warnings (FILT_OUT/SK_INP net bridge, 3x lib_symbol_mismatch, 1x unconnected_wire_endpoint) should reduce — at minimum the endpoint warning will clear since the stub will be a proper length.