Skip to content

test: pin different-net trace crossings per bug report - #718

Open
DPS0340 wants to merge 3 commits into
tscircuit:mainfrom
DPS0340:test/pin-trace-crossings
Open

test: pin different-net trace crossings per bug report#718
DPS0340 wants to merge 3 commits into
tscircuit:mainfrom
DPS0340:test/pin-trace-crossings

Conversation

@DPS0340

@DPS0340 DPS0340 commented Jul 25, 2026

Copy link
Copy Markdown

Why

Nearly every bug report in tests/bug-reports/ is verified by an SVG snapshot. That catches change, but not quality — a trace crossing that appears or disappears is a handful of pixels in a large regenerated SVG, and easy to approve without noticing.

Different-net crossings are the thing several of these reports are actually about, so I measured them across every imported board:

crossings segments board
11 149 bug-report-20260706T213649Z
6 199 bug-report-20260706T220324Z
5 168 bug-report-20260721T221026Z
4 52 bug-report-20260716T144856Z
3 38 bug-report-20260717T022934Z
3 67 bug-report-20260707T134549Z
2 20 bug-report-20260708T055430Z
2 154 bug-report-20260707T092615Z
2 28 bug-report-20260707T230831Z
1 80 bug-report-20260707T140410Z
1 22 bug-report-20260707T020342Z
0 (8 further boards)

40 crossings across 19 boards. None of that was visible from CI before.

What this adds

  • tests/fixtures/traceCrossings.tsgetTraceCrossings(traces), mirroring the shape of the existing getTraceLabelCollisions helper next to it. Counts only proper crossings between segments on different nets; shared endpoints on the same net are excluded, since traces legitimately meet there.
  • tests/different-net-trace-crossings.test.ts — pins the count per board, one named test each.

These numbers are the current state, not a target. Several of these boards are open bugs and the counts should come down. The value is that they can't quietly go up: a routing or cleanup change that makes a board worse now fails an assertion that names the board, instead of sliding into a regenerated snapshot.

There's also a guard test asserting the pinned set matches what's on disk, so a newly imported bug report can't go unmeasured.

Verification

  • The guard actually bites. Changed the expected count for bug-report-20260706T213649Z from 11 to 10 and got Expected: 10, Received: 11. A pinning test that can't fail is worse than no test.
  • Full suite: 164 pass / 0 fail / 4 skip (was 144 before, +20 from this file).
  • tsc --noEmit clean, biome clean.

One implementation note: I initially read traces from netLabelNetLabelCollisionSolver, the last pipeline step — but its getOutput() returns only netLabelPlacements. tsc caught it. Final trace geometry comes from traceCleanupSolver2, which is what this reads now.

Follow-up

If this is useful, the natural next step is fixing the worst boards and lowering the numbers in the same PR. bug-report-20260706T213649Z at 11 is the obvious first target — happy to take that on.

Diff: 2 new files, no existing file touched.

@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
schematic-trace-solver Ready Ready Preview, Comment Jul 26, 2026 6:13am

Request Review

DPS0340 added 2 commits July 26, 2026 12:47
Adds a helper that counts places where traces on different nets properly
cross, and a test that pins the current count for every imported bug
report.

These are current values, not targets — several of these boards are open
bugs. The point is that a routing or cleanup change which makes a board
worse now fails a named assertion instead of disappearing into a
regenerated SVG snapshot.

Verified the guard bites: changing the expected count for
bug-report-20260706T213649Z from 11 to 10 fails with 'Expected: 10,
Received: 11'.
tscircuit#727 (TraceOverlapShiftSolver) fixed the RP2040 USB-C overlap and moved
bug-report-20260707T092615Z from 2 different-net crossings to 3. Measured
either side of that merge:

  ca7e80c (before)  TOTAL 40, this board 2
  be20aa7 (tscircuit#727)    TOTAL 41, this board 3

Pinned at the current value with a comment recording the change, and
reported it on tscircuit#727 so the trade is visible rather than absorbed.
A crossings-only count is one-sided: two nets that cross can always be
made to stop crossing by running them along each other instead, which
reads as a single line and hides a connection. Counting only crossings
scores that as an improvement.

tscircuit#727 is the concrete case. On bug-report-20260707T092615Z it moved the
board from 2 crossings / 1 overlap to 3 crossings / 0 overlaps, and both
numbers involve the same pair of segments (C_SENSE.2-C1.2 and
available-net-orientation-13-BAT_POS) — it separated two nets drawn on
top of each other across a 0.141 span and left them crossing at a point.
That is a trade in the right direction, but a crossings-only guard flags
it as a regression.

Pinning both quantities makes the trade visible instead of scoring it.
@DPS0340

DPS0340 commented Jul 26, 2026

Copy link
Copy Markdown
Author

Updated this to pin overlaps as well as crossings, because I found the one-sided version scoring a good change as a bad one.

I had used the earlier version of this counter to report a "regression" from #727. It was not a regression. Counting different-net collinear overlaps too:

                        crossings   overlaps
ca7e80c (before #727)       40          1
be20aa7 (#727 merged)       41          0

Same pair of segments on both sides, on the single board that moved:

bug-report-20260707T092615Z
before:  overlap   C_SENSE.2-C1.2  ||  available-net-orientation-13-BAT_POS  (vertical, span 0.141)
after:   crossing  C_SENSE.2-C1.2  ×   available-net-orientation-13-BAT_POS  (x=-9.809, y=-1.764)

#727 separated two nets that had been drawn on top of each other and left them crossing at a point instead — the right trade, since an overlap looks like one trace and hides that two nets are there.

That is the argument for pinning both. A crossings-only guard is gameable in one specific direction: any crossing can be eliminated by making the two nets run along each other, and a one-sided counter reads that as an improvement. Pinning both makes the trade explicit — a PR that moves a board from 2/1 to 3/0 has to say so, rather than passing or failing depending on which quantity happened to be measured.

Still measurement-only — no lib/ changes:

  • getTraceOverlaps added next to getTraceCrossings in tests/fixtures/traceCrossings.ts. Shared endpoints are excluded, since traces meeting at a point is normal; only a shared span counts.
  • the per-board table now pins { crossings, overlaps }.

Verification, since a guard that cannot fail is worth nothing:

  • checked out ca7e80c with the new fixture → 092615Z fails on overlaps: 1, the other 19 pass. The counter detects the real state the crossings-only version missed.
  • current main → all 20 boards pass.
  • full suite 167 pass, 4 skip, 0 fail; bun run format:check clean; bunx tsc --noEmit exits 0.

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.

1 participant