Skip to content

Don't route net-label-only nets as wire traces (#79)#307

Open
s300169140 wants to merge 1 commit into
tscircuit:mainfrom
s300169140:fix/79-net-only-skip-msp
Open

Don't route net-label-only nets as wire traces (#79)#307
s300169140 wants to merge 1 commit into
tscircuit:mainfrom
s300169140:fix/79-net-only-skip-msp

Conversation

@s300169140
Copy link
Copy Markdown

Closes #79.

Summary

Two related root causes produced spurious wire traces between pins that share only a net label:

1. Shared-state in getConnectivityMapsFromInputProblemnew ConnectivityMap(directConnMap.netMap) retained a reference to the underlying netMap, so subsequent netConnMap.addConnections(...) calls mutated directConnMap.netMap too. Pins added via netConnections appeared to be in the direct-wire connectivity. Fixed by deep-cloning before seeding.

2. MspConnectionPairSolver iterated every net, not just direct onesqueuedDcNetIds = Object.keys(netConnMap.netMap) queued every net for MSP pair creation, including net-label-only ones. The README documents the intended behavior: "Net connections will not be routed, net labels are placed instead." This change brings the code in line with that contract by queuing only direct-connection nets and reading pins from dcConnMap.

Relationship to #275

This builds on the same root-cause analysis as #275 (h/t @chengyixu) but goes further. #275 addresses the mixed case (one pin in a directConnection, another only in a netConnection) — but the pure net-label-only case (two pins sharing a net name with no direct wire between them) still produces MSP pairs and therefore visible traces.

Verified on the #275 branch:

// Two caps, GND on top pins, VCC on bottom pins, no direct wires.
directConnections: [],
netConnections: [
  { netId: "GND", pinIds: ["C1.1", "C2.1"] },
  { netId: "VCC", pinIds: ["C1.2", "C2.2"] },
],

On #275 main:

MSP pairs: 2          ← spurious
Lines solver paths: 2 ← visible traces still drawn

On this branch:

MSP pairs: 0          ← correct

This is the repro61 scenario from tscircuit/core PR #1503 — and the one I think is the actual subject of this bounty issue.

Tests

Adds tests/solvers/MspConnectionPairSolver/MspConnectionPairSolver_repro79.test.ts covering both:

Updates MspConnectionPairSolver_repro1.test.ts from expect(4) to expect(2) with a comment explaining why — the previous expectation was capturing the buggy behavior (creating MST pairs for the GND netConnection).

Snapshot impact

11 example snapshots updated. I spot-checked example12 and example21 — every change is removal of spurious same-net trace lines, no unrelated drift. Happy to walk through any specific example if the diff is hard to read.

Verification

  • bun test — 59 pass / 0 fail / 4 skip (was 47 pass / 12 fail before snapshot update)
  • bunx tsc --noEmit — clean
  • bun run format:check — clean

closes tscircuit#79

Two related issues caused spurious wire traces between pins that share
only a net label (no direct wire):

1. **Shared-state bug in `getConnectivityMapsFromInputProblem`** —
   `new ConnectivityMap(directConnMap.netMap)` retained a reference to
   the underlying netMap, so the subsequent `netConnMap.addConnections`
   calls mutated `directConnMap.netMap` too. Pins added via
   netConnections then appeared to be in the direct-wire connectivity.
   Fixed by deep-cloning before passing to the netConnMap constructor.

2. **`MspConnectionPairSolver` iterated all nets, not just direct** —
   `this.queuedDcNetIds = Object.keys(netConnMap.netMap)` queued every
   net for MSP pair creation, then used `globalConnMap.getIdsConnectedToNet`
   to expand. Net-label-only nets (e.g. two capacitors both labeled GND)
   thus produced MSP pairs which became visible traces. Fixed by queuing
   only direct-connection nets and reading pins from `dcConnMap`.

The README documents the intended behavior: "Net connections will not be
routed, net labels are placed instead." This change brings the code in
line with that contract.

Adds `MspConnectionPairSolver_repro79.test.ts` covering both:
- the mixed case (one pin direct, another only net-labeled)
- the pure case (two pins joined only via net label, no direct wire) —
  this is the repro61 scenario from tscircuit/core PR #1503

Updates 11 example snapshots that previously rendered spurious traces;
spot-checked example12 and example21 visually — the changes are
strictly *removal* of unwanted same-net trace lines, not unrelated drift.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
schematic-trace-solver Ready Ready Preview, Comment May 11, 2026 5:51pm

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix extra net label in repro61, or remove trace

1 participant