hrithik18k/metal-touch-panel

A PCB autorouting wrapper that corrects footprint-trace obstacle dimensions, solves routes with a preloaded trace-graph solver, and reports completed traces or routing errors.

Version
1.0.0
License
unset
Stars
0

HIGH_PRIORITY_ISSUES.md

# High-priority tscircuit issues found building Metal Touch Rev A

Date: 2026-09-25. These are local, reproducible findings, not submitted GitHub issues. Severity is proposed. This report distinguishes the autorouter from its core integration; not every routing problem belongs in the autorouter repository.

Environment: Windows, Bun 1.3.14; tscircuit 0.0.2646; @tscircuit/core 0.0.1971; @tscircuit/props 0.0.666; @tscircuit/capacity-autorouter 0.0.919; @tscircuit/cli 0.1.2158; circuit-json 0.0.499. Exact dependencies are in bun.lock. Run commands from this project directory with `bun node_modules/tscircuit/cli.mjs`.

## P1: Footprint copper obstacles discard physical width and end caps

Primary owner: https://github.com/tscircuit/core ; integration with https://github.com/tscircuit/tscircuit-autorouter .

Actual: `getObstaclesFromRoute` in core generates a 0.1 mm thickness regardless of the route's real width. Segment extents also omit round end caps. The installed source explicitly contains `// TODO use route width` for both dimensions. Our 0.20 mm winding becomes a 0.10 mm obstacle. This permits routes violating physical copper clearance even though the routing pipeline reports success.

Evidence: `evidence/first-route/phase-0.input.simple-route.json`, `phase-0.output.traces.json`, `raw.circuit.json`, `coil-clearance.json`; `evidence/08-orthogonal-build.log`. For pcb_trace_2, the horizontal segment centered at (-18,6) is width 18, height 0.1; physical winding width is 0.2. The generated route source_trace_8__source_trace_10_mst1_0 approaches the winding at (-26.585,5.95). The raw build has zero recorded errors, yet the independent geometry audit finds physical contact with the winding outside its designated terminal.

Reproduce: run `node scripts/audit-coil-clearance.mjs evidence/first-route/raw.circuit.json`; inspect the saved SRJ and rendered copper. The audit also reports near-terminal contacts, so do not interpret its entire count as independent bugs.

Expected: obstacles cover actual copper width, layer transitions, and end caps, including variable-width segments. Preserve terminal access without allowing arbitrary contact along the winding.

Suggested fix: derive obstacles from swept copper geometry, with explicit terminal access. Add tests for 0.1/0.2/0.5 mm pre-existing copper, orthogonal and diagonal paths, verifying actual edge clearance after routing. Do not repair by deleting or simplifying sensor geometry.

Local mitigation: `coil-aware-router.ts` corrects obstacle thickness/end extents for the four known winding paths. Extended external terminals keep approach routing away from the winding. This narrowly scoped workaround is not an upstream fix.

## P1: Pipeline 9 outputs a power via with insufficient clearance to another-net QFN pad

Primary owner to investigate: https://github.com/tscircuit/tscircuit-autorouter . Core's final DRC correctly detects this failure.

Evidence: `evidence/repro-via-clearance/` contains source, input SRJ, routed output, result JSON and build log. The saved raw SRJ can be replayed with AutoroutingPipelineSolver9_PreloadedTraceGraph; the project's custom adapter only enlarges footprint winding obstacles. The pad/via conflict is in the QFN region, away from those winding obstacles.

Actual: V3V3 via pcb_via_0 at (-0.6348087671605677,-2.54004), diameter 0.6 mm, nearly touches the bottom-layer U1 GND pad. Core reports approximately 0.0000013 mm gap against a 0.1 mm minimum. Solver returns 33 routes, errors=0. The board-level build then correctly fails DRC. Earlier placement with 0.3 mm via diameter also produced 0.09 mm clearance, below 0.1 mm.

Expected: respect via edge-to-pad edge clearance against every foreign-net pad through routing and final simplification. Return failure or retry if final copper is invalid.

Suggested investigation: terminal fanout, via insertion, and final route postprocessing; verify actual via radius, rectangular pad bounds and bottom-layer transforms. Root cause inside the pipeline has not been isolated, so do not claim a specific solver stage is proven defective.

Acceptance test: replay saved input, compare via disks against foreign-net rectangular pads, require at least the declared clearance, and ensure all connections remain complete. Retain a post-route DRC failure signal.

Local mitigation: reposition and rotate C5 to face its supply terminal toward U1, reducing the need for a via near GND. Final validation is in the `evidence/final-*` files.

## P1 for printed passive support: Source-associated footprint windings are replaced during routing

Primary owner: https://github.com/tscircuit/core ; investigate fixed-trace handling with the autorouter maintainers.

Actual: associating each footprint pcbtrace with its corresponding source_trace_id before autorouting results in zero preserved 50-point winding paths in the output. The winding graphics disappear and four missing-connection errors are emitted. `check shorts` says no shorts because the coils are missing; that result alone is not a valid board acceptance check.

Evidence: `evidence/associated-route/source.tsx`, `result.json`, `evidence/10-associated-build.log`, `11-associated-shorts.log`, and `12-coil-clearance.json`. The source uses source_trace_0,4,8,12 for the four windings in that exact declaration order. Those IDs must be verified rather than reused after changes.

Expected: preserve authored footprint copper exactly, or expose explicit printed-passive/internal-copper semantics that do not treat its geometry as replaceable interconnect. A winding is not an ordinary wire eligible for shortening.

Acceptance test: associate footprint copper with a source net, autoroute external wiring, assert every winding vertex and width remains unchanged, test exported Gerbers, and verify terminal connectivity.

Local mitigation: route with anonymous footprint copper; associate source ownership AFTER routing using `scripts/associate-coil-copper.mjs`. That script changes metadata only. Do not reroute the normalized output. Independent winding count, geometry, connection and shorts checks remain necessary.

## Additional reproducible blockers (P2, not inflated to P1)

### Diagonal footprint trace aborts autorouting

Owner: core. `getObstaclesFromRoute` throws on any diagonal rather than supplying a rotated obstacle. Saved source/JSON: `evidence/repro-diagonal/`; log: `evidence/07-routed-build.log`. Segment (13.4,-19.2) to (14.4,-18.6) triggers the failure before the autorouter receives SRJ. Reproduce by placing the saved source at the project root (its relative import expects imports/) and building it. Expected: conservative rotated/swept copper obstacles. Workaround: right-angle lead-in. Test at 45 degrees and arbitrary angles, including variable widths.

### Public pcbtrace props disagree with core runtime

Owners: core and https://github.com/tscircuit/props . Public props/skill example accepts `layer`, `thickness`, and `route=[{x,y},...]`; runtime PcbTrace instead requires circuit-json wire points with `route_type`, `width`, and `layer` per point. Evidence: `evidence/04-unrouted-build.log`. Working syntax is in CoilFootprint. Unify the contract and test a documented example end-to-end, including JSX typechecking and runtime.

### Node invocation fails before CLI starts

Owner: CLI/dependency packaging. `node node_modules/tscircuit/cli.mjs ...` under installed Node 23.3.0 throws ERR_UNSUPPORTED_DIR_IMPORT for calculate-elbow/lib. See `evidence/node-cli-startup-failure.log`. Bun works; the current executable explicitly uses a Bun shebang, so this is a compatibility/documentation finding, not a proven supported-runtime P1 regression.

## Scope and reporting limits

No issues were posted publicly. Existing issue search was not exhaustive; check duplicates before filing. The reference project is an untested hardware prototype. The successful final design does not establish the generic solver bugs are fixed. Saved failure artifacts are retained independently of final layout changes. Avoid running unqualified build over evidence folders; use the explicit `index.circuit.tsx` entrypoint.

## Rechecked 2026-09-30 — current status

All six recorded failure **behaviours** remain reproducible; none was demonstrated fixed in this recheck. This does not establish that all six deserve the original severity labels.

Tests used a fresh isolated install, without changing the board project's pinned dependencies or fabrication files:

- Latest tscircuit bundle: **0.0.2683**, resolving core **0.0.2018**, props **0.0.670**, autorouter **0.0.941**, CLI **0.1.2197**, circuit-json **0.0.507**.
- Additional tests used the newer standalone releases: core **0.0.2020** and autorouter **0.0.945**.
- Bun 1.3.14 and Node 23.3.0 on Windows. Versions are scoped to this check, not a claim about every future upstream build.

| Finding | Recheck result | Evidence / qualification |
| --- | --- | --- |
| Footprint obstacle width/end caps | **Still present, confirmed in latest core 0.0.2020** | Running the installed conversion function on a 0.5 mm-wide, 10 mm-long segment returns a 10 x 0.1 mm rectangle. Copper thickness and rounded end extents remain omitted. |
| Power via to foreign-net QFN pad clearance | **Still present, confirmed in latest autorouter 0.0.945** | Saved SRJ replay with the original winding-obstacle correction returns solved=true, failed=false; power via at (-0.6348087672,-2.54004) has approximately **0.0000013 mm** edge clearance to U1 GND, versus **0.1 mm** minimum. The same location appears on two connected route records, representing one physical violation, not two independent bugs. Also reproduced on bundled 0.0.941. |
| Source-associated winding loss | **Behaviour still present on latest bundle; P1 classification needs qualification** | Replay leaves **zero preserved long winding traces** and emits the same four missing-INxA-connection errors. The source hardcodes internal source_trace_id values for external connections while the winding spans an inductor's two different source nets. This is not a clean proof that a correctly modelled ordinary fixed trace is discarded. Maintainer review/minimal valid printed-passive representation is needed before presenting it as an unconditional P1 autorouter defect. |
| Diagonal footprint trace abort | **Still present** | Original board reproduction throws at (13.4,-19.2) -> (14.4,-18.6). Direct test of latest standalone core 0.0.2020 also throws for (0,0) -> (1,1). |
| pcbtrace props/runtime disagreement | **Still present** | Current bundle rejects the documented layer/thickness/XY-only route with missing route_type/width/layer errors. Public props still expose that format; standalone core 0.0.2020 still uses a different route-point schema. |
| Node CLI startup failure | **Still present in the tested Node environment** | CLI 0.1.2197 fails before --version with ERR_UNSUPPORTED_DIR_IMPORT for calculate-elbow/lib on Node 23.3.0. Bun works. This does not prove failure on a supported Node LTS version, and the Bun shebang remains relevant. |

### New evidence and reproduction commands

Evidence lives in `evidence/recheck-2026-09-30/`. It contains the isolated manifests/lockfiles, input fixtures, logs, outputs, and scripts. Reinstall dependencies inside that folder with `bun install --frozen-lockfile` before replaying. The original board project remains unchanged apart from this report and added evidence.

```powershell
# From evidence/recheck-2026-09-30
bun node_modules/tscircuit/cli.mjs build props.circuit.tsx
bun node_modules/tscircuit/cli.mjs build diagonal.circuit.tsx --autorouter-timeout 45s
bun node_modules/tscircuit/cli.mjs build associated.circuit.tsx --autorouter-timeout 120s
node node_modules/tscircuit/cli.mjs --version
bun replay-via.mjs

# From its latest-packages subdirectory, after bun install --frozen-lockfile
node check-obstacles.mjs
bun replay-via.mjs
```

Key evidence: `versions.json`, `props.log`, `diagonal.log`, `node-startup.log`, `associated-retry.log`, `associated-result.json`, `latest-packages/obstacle-tests.json`, and `latest-packages/via-replay-result.json`. The first association replay timed out at 45 seconds; the 120-second retry completed and reproduced the winding-loss behaviour. Treat the completed retry as the deciding result.

Current upstream source inspection agrees with the obstacle and runtime-contract findings:
- https://github.com/tscircuit/core/blob/main/lib/utils/obstacles/getObstaclesFromRoute.ts
- https://github.com/tscircuit/core/blob/main/lib/components/primitive-components/PcbTrace.ts

**Filing recommendation:** prioritize the independently confirmed obstacle-geometry and via-clearance defects. Keep the winding-loss item qualified; do not equate unsupported/misassigned internal net metadata with a proven generic fixed-copper regression. No GitHub issues were posted, and duplicate-issue review was not exhaustive.

---