Skip to content

12 — Decisions and risks

Part of the TraceMaker plan. Start at ../PLAN.md.

Decisions

Every decision has its own record in decisions/: what was decided, the alternatives, the reason and, where it was replaced, the decision that replaced it. The records are the source; the table below is generated from them. To add one, run scripts/decisions.py new "Short title" --docs 05 and fill in the file it prints (D134). Records D1–D131 were converted from the rows of this table on 2026-10-21; their text is unchanged.

# Decision Status
D1 Engine in C++20 and CUDA, viewer in TypeScript accepted
D2 Placement in scope with four optimality levels accepted
D3 Analytic placement, then annealing, then exact windows accepted
D4 Octilinear lattice routing first, gridless later accepted
D5 GPU never makes the final legality decision accepted
D6 Four-tier failure memory accepted
D7 Native .kicad_pcb I/O, DSN for benchmarks only accepted
D8 KiCad DRC is the benchmark judge accepted
D9 Integer fixed-point costs accepted
D10 Browser viewer served by the engine accepted
D11 Own CUDA kernels, no PyTorch or DREAMPlace runtime accepted
D12 FLUTE for Steiner trees accepted
D13 Courtyard gap fallbacks in full placement accepted
D14 SimPL spreading instead of electrostatic density accepted
D15 New placement kept only if it routes as well accepted
D16 Double-pitch portfolio variants on large boards accepted
D17 CLI, Python module and plugin share one route function accepted
D18 Position-independent build when bindings are on accepted
D19 PCM package without a bundled engine by default superseded by D121
D20 Annealed replica exchange for parallel tempering accepted
D21 RUDY overflow and pin density as routability term accepted
D22 Router as a callback in router-in-the-loop placement accepted
D23 Exact windows by own branch and bound, not CP-SAT accepted
D24 --route-check restores a rejected placement by copying the input accepted
D25 Decoupling capacitor affinity pseudo-nets accepted
D26 Component-rule catalogue in YAML, embedded as generated JSON accepted
D27 lib_id detectors match the footprint name only accepted
D28 Component proximity rules reuse affinity pseudo-nets accepted
D29 Generated keep-outs for crystals and switching inductors accepted
D30 Per-net coupled routing for detected USB pairs accepted
D31 --component-rules off by default for placement and routing superseded by D52
D32 Escape planning v1 as reserved corridors accepted
D33 Escape planning in two of eight portfolio variants accepted
D34 Escalation rung necks vias down to board minimum accepted
D35 Escape feasibility reported beside the clean pass accepted
D36 Impedance rules computed and reported only superseded by D58
D37 Closed-form impedance models from the papers accepted
D38 Adjacent copper layer as the assumed reference plane accepted
D39 Differential pairs solved for width at the class gap accepted
D40 User rule override file in strictly checked JSON accepted
D41 ETH-05 magnetics keep-out like XTAL-04 accepted
D42 Opt-in connector edge attraction by axis anchor accepted
D43 Two-stage component-rule pulls in full placement accepted
D44 Flood-fill reachability pre-check before strict searches accepted
D45 Replay logs as zstd-compressed JSON lines accepted
D46 Evidence code D for rules with TraceMaker default values accepted
D47 Portfolio variant set independent of thread count accepted
D48 Opt-in side assignment by annealer flip moves accepted
D49 Opt-in min-cost-flow escape planning v2 accepted
D50 Differential pairs searched as one object accepted
D51 DRC follows KiCad 10 connectivity on broken boards accepted
D52 tracemaker-place defaults to --component-rules soft accepted
D53 Global congestion map off, global router v2 deferred superseded by D56
D54 Connection planning by copper gap, group re-route removed accepted
D55 DRC zone-fill edge index instead of GPU broad-phase accepted
D56 Global router v2 kept off and M6 closed accepted
D57 M8 closed with its gate not met accepted
D58 Impedance and width rules as synthetic net classes accepted
D59 Restart-based successive halving stays off accepted
D60 Plugin refills zones only on request or after moves accepted
D61 JSON protocol kept, FlatBuffers dropped accepted
D62 M9 closed with two items unbuilt accepted
D63 Half-pitch variant for small boards, no gridless arm accepted
D64 Coupled pairs may twist at layer changes accepted
D65 Rule areas block tracks and vias by own flags accepted
D66 Opt-in soft zone fills as via targets accepted
D67 Vias kept off SMD pads narrower than 2 mm accepted
D68 Via in pad at the board minimum via, opt-in accepted
D69 --first-nets routes named nets first and protects them accepted
D70 Native macOS with an optional Metal backend accepted
D71 Metal cost-to-go field by segmented prefix-min scan accepted
D72 Router enforces net- and layer-only custom disallow rules accepted
D73 Router hot-path optimisations accepted
D74 Footprints clear of the outline are unplaced parts accepted
D75 Opt-in minimal repair of illegal input placements accepted
D76 Opt-in layer limits: --no-tracks-on and --layer-cost accepted
D77 Coupled-pair work counts every leg check accepted
D78 Router zone-fill probes through the DRC edge index accepted
D79 Plane targets exclude teardrops and unreachable fills accepted
D80 Custom-rule conditions follow observed KiCad item sets accepted
D81 Named regression board sets with work budgets accepted
D82 Router applies positional disallow rules accepted
D83 tracemaker escape analyses outstanding pins under router rules accepted
D84 Board-prep and route guidance as agent skills accepted
D85 In-engine exact zone refill for judging accepted
D86 Reported route time covers the whole job accepted
D87 (reserved) reserved by PR #21 (probe sealed BGA targets first), not merged
D88 Per-phase work counters and route CPU time accepted
D89 Terminal options screen and options file accepted
D90 Simple Route JSON supported at the edge only accepted
D91 Bus routing inside the existing search accepted
D92 After-route passes: widen power, stitch vias, style metric accepted
D93 Options screen with global, project and file scopes accepted
D94 Higher rip and pass limits, extra seeded variants accepted
D95 Unhelpful options kept as hidden flags accepted
D96 SRJ fan-out import options for fanout31 accepted
D97 M14 plan as measured outcomes, not a build order accepted
D98 Automatic preferred directions on breakout boards accepted
D99 Negotiation as transactions with annealing acceptance accepted
D100 Breakout profile reach-check and field caching accepted
D101 Breakout portfolio with warm-started rounds accepted
D102 Portfolio search state saved and resumable accepted
D103 Clearance continuation ramp with warm starts accepted
D104 Relax, route, legalise accepted
D105 Layerless legacy fills inherit the zone's sole layer accepted
D106 Benchmark gates compare violation multisets accepted
D107 Fixture preparation by native conversion and ID repair accepted
D108 KiCad 10 defaults and legacy migration precedence for rules accepted
D109 Engine never talks to a model; advice files accepted
D110 Advised attempts as extra portfolio variants accepted
D111 Advice regions as in-memory rule areas and rules accepted
D112 Stuck report as part of the route accepted
D113 failure event explains what rejected the path accepted
D114 Read-only reference-return audit accepted
D115 Footprint check against trusted datasheet references accepted
D116 Viewer binds loopback by default, token elsewhere accepted
D117 JLCPCB routing rules as opt-in options accepted
D118 Milestones M17 to M21 follow the owner's answers accepted
D119 Agent board session over MCP and JSON lines accepted
D120 Per-shape zero edge clearance as in KiCad 10.0.6 accepted
D121 Release as Linux tarball and KiCad plugin package accepted
D122 PCBWorld D3 run as PCBench boards with Freerouting rerun accepted
D123 One project brand, the trace logo accepted
D124 Rule relaxation spent on signals, not power nets accepted
D125 Legalisation may subdivide long tracks accepted
D126 Four opt-in escape features from the EtherCAT review accepted
D127 Soft mask and copper graphics, fine-lattice finish accepted
D128 --first-nets-ordered routes first nets in list order accepted
D129 --bundle-escape river escapes on dense packages accepted
D130 --supply-first routes dense-package supply nets first accepted
D131 --package-tunnels under dense packages accepted
D132 KiCad-measured shapes and net-less arcs in the judge accepted
D133 Viewer framing for named pages (--view-embed) accepted
D134 Documentation site: MkDocs, Diátaxis, decision records, Doxygen accepted
D135 macOS 15: floating-point parsing without std::from_chars accepted

Risks

Risk Likelihood Mitigation
nvcc 12.4 does not accept GCC 15 as host compiler Confirmed Use -ccbin g++-12 (installed; builds for sm_60/sm_70; ran on the P100). Stay on CUDA 12.x because CUDA 13 drops Pascal and Volta
GPUs are shared with other workloads (llama-server held almost all GPU memory on 2026-10-02) Confirmed Memory admission control, batch shrinking, CPU fallback with identical results (doc 07 §4)
DRC parity with KiCad drifts across KiCad versions Medium Pin a KiCad version per release; parity tests in CI
Lattice routing misses tight gaps Medium Pin-access points, half-pitch last-gasp windows, gridless cleanup, tile-plane arm
Placement quality judged subjectively by users (mechanical, thermal intent not in netlist) High refine/eco modes by default for placed boards; rule areas and locks honoured; full mode opt-in
Negotiation oscillates Medium History decay, α scaling, reroute caps, best-board keeping
Learned components overfit the benchmark Medium Held-out board sets; learned arms only via bandit, never mandatory
Viewer slows the engine Low Lock-free rings, coalescing, drop-frontier policy
Scope (placement + routing + GPU + viewer) is very large High Milestones each deliver a usable tool; GPU and learning are additive to working CPU paths