Summary
On a real board's SimpleRouteJson, AutoroutingPipelineSolver7_MultiGraph completes with solved: true and no error, but its output contains a same-layer crossing between two different connections — i.e. an invalid routing that becomes a physical copper short. The affected connections are the two pins of a 32.768 kHz crystal (XL1/OSC1 vs XL2/OSC2 of an nRF52810), which shipped as a shorted crystal on tscircuit/nrf52810.
Reproduces on v0.0.710 (the version currently bundled into tsci via eval/cli) and on latest v0.0.754. The crossing is deterministic, at the same coordinate as in the full tsci build:
source_trace_52__source_trace_55 x source_trace_51__source_trace_53
at (-1.862, 5.518) layer=top
Repro
Files: https://gist.github.com/seveibar/74108f17b558700a42b417c0a742054c
srj-input.json — the phase-0 SRJ dumped by tsci build --autorouter-debug --autorouter-dump-srj all on tscircuit/nrf52810 (26 connections, 119 obstacles, 2 layers). The input is well-formed: source_trace_51/53 (OSC1 net) and source_trace_52/55 (OSC2 net) are separate connections with distinct endpoints; the solver itself merges them per-net into source_trace_51__source_trace_53 and source_trace_52__source_trace_55, then crosses one over the other.
repro.ts — runs the solver and scans the output for same-layer segment intersections between traces of different connections.
bun add @tscircuit/capacity-autorouter@0.0.754
bun run repro.ts
Output on 0.0.754:
AutoroutingPipelineSolver7_MultiGraph: solved=true, 1 different-connection same-layer crossings
SHORT: source_trace_52__source_trace_55 x source_trace_51__source_trace_53 at (-1.862,5.518) layer=top
AutoroutingPipelineSolver4: solved=true, 0 different-connection same-layer crossings
AutoroutingPipelineSolver8: failed=true, error=Ok ran out of iterations
Observations
| Solver |
v0.0.710 |
v0.0.754 |
AutoroutingPipelineSolver7_MultiGraph |
solved=true, 1 crossing |
solved=true, 1 crossing (23.5s) |
AutoroutingPipelineSolver4 |
solved=true, clean (8.3s) |
solved=true, clean (89.5s) |
AutoroutingPipelineSolver8 |
fails: ran out of iterations |
fails: ran out of iterations (6.6s) |
AutoroutingPipelineSolver5 |
fails: HdCache ran out of iterations |
— |
AutoroutingPipelineSolver6 |
fails: 2 poly nodes |
— |
Two issues worth separating:
- Correctness (primary): Solver7_MultiGraph should never report success with intersecting different-net traces — either untangle them or fail/report an error so downstream can react. (Until core#3024, a separate core bug also mis-attributed these traces'
source_trace_id, which blinded the DRC and tsci check shorts to the crossing — that's fixed, so these will now at least surface as DRC errors, but the router shouldn't emit them at all.)
- Regression (secondary):
AutoroutingPipelineSolver8 — the current default in core — cannot solve this SRJ at all ("ran out of iterations"), while Solver4 solves it cleanly. When eval/cli re-bundle with ^0.0.750, this board goes from "routes with a hidden short" to "fails to route".
Happy to split #2 into its own issue if that's preferred.
🤖 Generated with Claude Code
Summary
On a real board's SimpleRouteJson,
AutoroutingPipelineSolver7_MultiGraphcompletes withsolved: trueand no error, but its output contains a same-layer crossing between two different connections — i.e. an invalid routing that becomes a physical copper short. The affected connections are the two pins of a 32.768 kHz crystal (XL1/OSC1vsXL2/OSC2of an nRF52810), which shipped as a shorted crystal on tscircuit/nrf52810.Reproduces on v0.0.710 (the version currently bundled into
tscivia eval/cli) and on latest v0.0.754. The crossing is deterministic, at the same coordinate as in the fulltsci build:Repro
Files: https://gist.github.com/seveibar/74108f17b558700a42b417c0a742054c
srj-input.json— the phase-0 SRJ dumped bytsci build --autorouter-debug --autorouter-dump-srj allon tscircuit/nrf52810 (26 connections, 119 obstacles, 2 layers). The input is well-formed:source_trace_51/53(OSC1 net) andsource_trace_52/55(OSC2 net) are separate connections with distinct endpoints; the solver itself merges them per-net intosource_trace_51__source_trace_53andsource_trace_52__source_trace_55, then crosses one over the other.repro.ts— runs the solver and scans the output for same-layer segment intersections between traces of different connections.Output on 0.0.754:
Observations
AutoroutingPipelineSolver7_MultiGraphAutoroutingPipelineSolver4AutoroutingPipelineSolver8AutoroutingPipelineSolver5AutoroutingPipelineSolver6Two issues worth separating:
source_trace_id, which blinded the DRC andtsci check shortsto the crossing — that's fixed, so these will now at least surface as DRC errors, but the router shouldn't emit them at all.)AutoroutingPipelineSolver8— the current default in core — cannot solve this SRJ at all ("ran out of iterations"), while Solver4 solves it cleanly. When eval/cli re-bundle with ^0.0.750, this board goes from "routes with a hidden short" to "fails to route".Happy to split #2 into its own issue if that's preferred.
🤖 Generated with Claude Code