Skip to content

Repository files navigation

image

pcbFork

pcbFork is an experiment in AI-assisted component placement for low-noise biosignal PCBs. It asks a narrow question: can a language model, treated as an untrusted proposal generator, improve the physical placement of components on an EEG/BCI front-end when its output is constrained, validated, and scored deterministically in the browser?

It is not an EDA tool and it is not a design authority. It is a harness for studying that question on real KiCad boards, entirely client-side.


How it works

The tool separates two things that are usually conflated when people talk about "AI PCB design":

  1. Proposal — a stochastic step that suggests where components could go. This is the language model's only job. It is assumed to be unreliable.
  2. Judgement — deterministic, inspectable code that decides whether a proposal is structurally valid and whether it is geometrically better or worse than the original.

The model never edits the board directly. It returns a placement patch (a list of ref x y [rot] moves), which is applied textually to the original KiCad source. Nets, pads, tracks, and zones are preserved by construction, so the model cannot silently corrupt connectivity regardless of board size. Everything the model produces is then re-parsed, validated, and re-scored by the same code path that judges the original.

KiCad .kicad_pcb → parse → summarise → model proposes placement patch
                 → apply patch → re-parse → validate → score → compare → iterate

What is measured

All metrics are geometric heuristics computed from placement and routing geometry. They are proxies for electrical behaviour, not measurements of it. They exist to (a) give the optimisation loop a differentiable-enough objective and (b) let a human compare two layouts on the same axes.

BCIAnalyzer locates the analog front-end (ADS1299 / ADS129x / RHD families, by value/footprint markers) and derives, among others:

Metric Definition Proxy for
AFE↔radio distance mm from AFE to nearest radio component RF ingress into analog inputs
Decoupling proximity mean/max distance from AFE power-pad decoupling caps to the AFE supply loop area / bypass effectiveness
Channel symmetry 0–1 regularity of the differential input channel layout matched channel behaviour
Analog/digital separation mean gap between analog and digital-categorised parts digital noise coupling
Vias on sensitive nets count of vias on IN*, CH*, SRB*, BIAS, REF nets impedance discontinuity / stub pickup on high-impedance inputs
Analog input track length total routed length on sensitive-input nets antenna length / noise pickup

Net classification is name-based (e.g. IN1P, AIN3, SRB1, BIAS → sensitive; SCLK, MOSI, DRDY → digital; AVDD, DGND, 3V3 → power). This is a heuristic and will misclassify boards that use unconventional net names.


Scoring

BoardScorer maps the heuristic metrics to a transparent 0–100 score with a per-axis breakdown. Every sub-score exposes the number that produced it and the reason (e.g. "AFE↔radio 18.4 mm (target ≥ 25 mm)"). Sub-score weights are set by the user's optimisation-priority sliders (signal integrity, separation, compactness, routing simplicity, symmetry, manufacturability).

Structural validity is a hard gate: a board that fails deterministic validation has its score multiplied by 0.3, so an invalid layout can never outrank a valid one on aggregate.

The score is a relative comparison instrument, not an absolute quality rating. A score of 82 means "better on these weighted geometric axes than a board that scores 74," nothing more.


Deterministic validation

Before a candidate is scored it passes BoardValidator, a browser-side preflight that catches regressions detectable without KiCad itself:

  • balanced parentheses and a (kicad_pcb …) root
  • component / net / pad preservation against the original
  • duplicate reference designators
  • changed footprints, added/removed components
  • out-of-bounds placement and bounding-box overlap approximations

This is not DRC/ERC. It cannot check clearances, impedance, or electrical rules. It only rejects proposals that are structurally broken or that mutate more than placement.


Adversarial evaluation (src/redblue/)

A separate, fully deterministic red-team / blue-team layer tests whether the geometric metrics are sensitive enough to notice a deliberate regression. No language model is involved.

  • Red injects one plausible physical-design defect into a parsed board and records hidden ground truth. Defect families: extra via on a sensitive net, degraded decoupling loop, radio moved into the analog keep-out, clock routed parallel to an input, differential-pair length imbalance, lengthened sensitive route.
  • Blue independently recomputes metrics, detects and localises the regression to a component or net, explains the mechanism via a causal interference graph (aggressor → coupling → victim), attempts a minimal-intervention repair, and re-scores to demonstrate the effect.
  • Counterfactual search finds the smallest change (|ΔPCB|) that improves the score by at least a margin, ranked by improvement per unit change.
  • Benchmark runs Red against Blue across all applicable defects and reports detection rate, localisation rate, and repair recovery.

Known limitation: the repair "proof" only closes for defects the current BoardScorer actually measures (vias, radio distance). Coupling and small route-length changes are detected and localised but are not yet reflected in the aggregate score, so their repairs cannot be numerically proven by this harness.


Autonomous loop (src/agent/)

An optional closed-loop mode that runs generation → validation → adversarial testing → counterfactual critique → improvement until it converges. All control logic is client-side; the model is called only for the propose and improve steps.

  1. Objective parsing — natural-language goal → structured config (weights, constraints, robustness threshold, generation budget, convergence delta, batch size) via the model, with schema validation.
  2. Generation — N candidates per generation, each validated and scored.
  3. Robustness — top candidates undergo Red/Blue testing; the loop records detection rate and specific vulnerabilities.
  4. Counterfactual critique — the best candidate's minimal-intervention opportunities are turned into concrete instructions ("move C5 3.2 mm closer to U1 for +4.5 pts") rather than vague feedback.
  5. Improvement — the model refines the best candidate using that concrete critique.
  6. Convergence — stops on score plateau (avg Δ over 3 generations below threshold), constraint + robustness satisfaction, or budget exhaustion.

The loop reports total AI calls, candidates generated, wall-clock time, and a rough cost estimate.


Limitations

This section is the point of the tool, not a disclaimer.

  • Heuristics are not electrical signoff. Every metric is geometry. None model impedance, current return paths, coupling coefficients, stackup, or noise numerically. A layout that scores well can still be electrically wrong.
  • Net classification is name-based and will misread boards with unconventional naming.
  • The preview is a legibility aid, not a rendering of the real board. The authoritative artifact is always the KiCad source.
  • No DRC/ERC. The browser preflight does not replace KiCad's rule checks.
  • The AFE detector is marker-based and targets ADS129x / RHD-class parts; other front-ends may not be recognised.
  • Every generated design requires human review and a full KiCad DRC/ERC before fabrication.

Data flow and secrets

  • The app runs entirely in the browser. There is no backend, no account, and no server-side storage.
  • PCB contents leave the browser only in the request you explicitly send to the AI provider you configured.
  • API keys are persisted in browser localStorage for convenience (key pcbFork:credentials). They are never logged and never included in any exported artifact. Use Clear credentials in the UI, or clear site data, to remove them.
  • No CORS bypass. If a provider blocks direct browser access, the app surfaces a clear message rather than attempting to work around it. Providers are pluggable: OpenAI-compatible, Anthropic-compatible, or a custom endpoint behind one callAI() interface.

Running

npm install
npm run dev      # http://localhost:5173 (or next free port)

A bundled ADS1299 demo board loads automatically, so parsing, metrics, preview, and scoring are explorable with no API key. Additional real open-hardware boards ship under public/boards/ (VolksEEG, an OpenBCI-style 8-channel AFE, and ADS1299-based designs).

To generate candidates:

  1. Open AI Connection, pick a provider, set endpoint/model, paste your API key, and test the connection.
  2. Write an objective (optionally set constraints and priority sliders).
  3. Generate 1 / 3 / 5 candidates.
  4. Select a candidate to compare against the original, then Improve to iterate or Download to export.
npm run build    # tsc + vite build → docs/ (static, host anywhere)
npm run preview  # preview the production build

Type-checking must pass clean: npx tsc --noEmit.


Architecture

Everything is client-side. The analysis, scoring, validation, and AI modules are pure and never touch the DOM; AppController is the only module that does.

src/
  parser/
    sexpr.ts            S-expression tokenizer/parser + tree queries
    KiCadParser.ts      .kicad_pcb → Board (components, nets, tracks, vias, zones, bounds)
    placementPatch.ts   parse + apply `ref x y [rot]` patches onto original source
  analysis/
    geometry.ts         distance / stats / bbox helpers
    BoardAnalyzer.ts    semantic categorisation (analog/digital/power/radio/…)
    BCIAnalyzer.ts      biosignal placement heuristics + derived metrics
  scoring/
    BoardScorer.ts      transparent 0–100 score, slider-weighted
  validation/
    BoardValidator.ts   deterministic browser preflight
  ai/
    AIProvider.ts       provider adapters behind one callAI(); live model listing
    PromptBuilder.ts    system + user + critique prompt construction
  candidates/
    CandidateManager.ts patch → parse → analyse → validate → score, keeps history
  redblue/
    RedTeam.ts          defect injectors with hidden ground truth
    BlueTeam.ts         detect → localise → explain → repair → re-score
    CausalGraph.ts      aggressor → coupling → victim hypotheses
    Counterfactual.ts   minimal-intervention (|ΔPCB|) search
    Benchmark.ts        Red vs Blue harness + summary
    boardOps.ts         board clone + mutation primitives
    netClasses.ts       net taxonomy (sensitive/clock/digital/power)
  agent/
    AgentOrchestrator.ts  autonomous loop controller
    ObjectiveParser.ts    natural language → structured config
    RobustnessScorer.ts   Red/Blue batch testing
    CounterfactualCritique.ts  repair-instruction builder
    ConvergenceDetector.ts  stopping criteria
  render/
    BoardRenderer.ts    SVG preview + overlays + selection
  diff/
    DiffViewer.ts       LCS line diff
  app/
    AppController.ts    UI state + orchestration
    shell.ts            static HTML shell
    dom.ts / report.ts  helpers + JSON report builder
  demo/
    demoBoard.ts        bundled ADS1299 sample board + real-board manifest
  types.ts              shared data model

The AI contract

The model must return only the components it wants to move, never a whole board. Echoing a full .kicad_pcb does not scale — a large board exceeds the model's output-token budget and returns truncated (corrupted). The expected response is exactly:

<reasoning_summary>
brief engineering rationale
</reasoning_summary>
<placement>
U1 84.30 62.10 90
C3 78.00 55.50
</placement>

Each placement line is ref x y [rot] (absolute mm; rotation optional). A full <kicad_pcb> board is still accepted as a fallback. Candidates that cannot be parsed are rejected; structural failures hard-cap the score.


Stack

Vite · TypeScript · vanilla DOM · SVG. No server, no database, no framework. Geometric heuristics only — no numerical field solver, no DRC engine, no persistence of secrets beyond the localStorage credential entry described above.

About

A browser sandbox testing if LLMs can optimize KiCad board layouts by treating the AI as an untrusted proposal generator for low-noise biosignal PCBs

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages