Skip to content

fix: scope the overlap-shift oscillation guard to the bouncing net pair (closes #1102) - #1103

Open
tcsenpai wants to merge 1 commit into
tscircuit:mainfrom
tcsenpai:fix/overlap-shift-oscillation-scope
Open

fix: scope the overlap-shift oscillation guard to the bouncing net pair (closes #1102)#1103
tcsenpai wants to merge 1 commit into
tscircuit:mainfrom
tcsenpai:fix/overlap-shift-oscillation-scope

Conversation

@tcsenpai

@tcsenpai tcsenpai commented Sep 8, 2026

Copy link
Copy Markdown

Closes #1102

Problem

TraceOverlapShiftSolver used its A -> B -> A oscillation guard as a global stop condition. The first net pair that oscillated ended the entire solve, so every cross-net overlap still queued at that moment stayed in the output, even though those pairs were independent of the oscillation and would have been corrected within a few more iterations.

if (this.returnsToPreviousTraceState(nextTraceState)) {
  this.activeSubSolver = null
  this.solved = true   // ends the whole solver, not just this net pair
  return
}

Fix

Record the oscillating net pair in oscillatingNetPairKeys and skip that pair in findNextOverlapIssue, then keep stepping. The retained trace states are reset so the next pair is judged on its own history rather than the previous pair's. Nets that genuinely oscillate are still left alone, so the original non-termination guard is preserved.

Results

Reduced repro (5 chips, derived from board-1273): unresolved cross-net collinear pairs go from 2 to 1. The remaining pair is the one that actually oscillates; the independent RTS/DTR pair is now separated.

board-1273: unresolved pairs go from 6 to 1. The same 135 traces are routed, with none added or dropped, and 17 of 135 paths shift. The shift solver now runs 38 iterations instead of 27, still well under the 100 iteration cap the repro test sets.

Tests

  • New tests/repros/repro-overlap-shift-cycle-abandons-independent-overlaps.test.ts, which fails on main with the extra connectivity_net3::connectivity_net4 overlap present.
  • tests/repros/board-1273-trace-overlap-cycle.test.ts: iteration count updated 27 -> 38 and the snapshot regenerated for the intended geometry change.
  • Full suite: 344 pass, 0 fail. bun run format:check and bunx tsc --noEmit clean.

Written with AI assistance.

TraceOverlapShiftSolver stopped the whole solve the first time a net pair's
corrections bounced A -> B -> A. Every other cross-net overlap still queued
at that moment was left in the output even though those pairs are
independent and correctable.

Track the oscillating net pair instead and skip only that pair in
findNextOverlapIssue, so the remaining overlaps keep being corrected.

On the reduced repro this takes the unresolved cross-net pairs from 2 to 1
(the genuinely oscillating pair). On board-1273 it goes from 6 to 1, routing
the same 135 traces with none added or dropped.

Closes tscircuit#1102
@vercel

vercel Bot commented Sep 8, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
schematic-trace-solver Ready Ready Preview Sep 8, 2026 2:25pm UTC

Request Review

@tcsenpai

Copy link
Copy Markdown
Author

@mohan-bee @MustafaMulla29 when you have a moment, could one of you review this? It is a 26 line change in TraceOverlapShiftSolver plus a repro test; on board-1273 it takes the unresolved cross-net pairs from 6 to 1 with no trace added or dropped. Happy to adjust scope if you would rather see the oscillation guard handled differently.

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.

bug: a single oscillating net pair aborts TraceOverlapShiftSolver and leaves independent cross-net overlaps unresolved

1 participant