# adom-chiplinter

A Rust CLI + Hydrogen webview that detects every chip's electrical-contact
features (legs / pins / pads / balls / tabs) automatically from a 3D GLB model,
validates placement against the KiCad footprint, and bakes an annotated GLB so
downstream Adom tools can read pad positions from the scene graph.

The "north star": you point chiplinter at a chip directory containing the GLB,
KiCad footprint, datasheet PDF, and `info.json`, and it answers the question
*"are these aligned?"* — with no human override required.

## Why this exists

Every Adom flow that touches a real chip — InstaPCB previews, solder-jet
planning, heatsink-via routing, KiCad library publishing — needs to trust that
the 3D model and the footprint agree on where the pads are and which one is
pin 1. chiplinter is the linter that produces that trust.

It runs four detection stages — geometric bbox-fit, kind-aware inside-test,
material-color rescue, vision rescue — and writes a single `confidence` value
per chip that downstream tools can gate on:

| Confidence | Meaning |
|---|---|
| `verified` | Both pad geometry AND the chip's manufacturer indicator agree |
| `high` | Pad geometry uniquely fits at identity rotation (canonical case) |
| `assumed` | A non-identity rotation won uniquely; verify visually |
| `ambiguous` | Multiple rotations tie at 100% — vision is the deciding factor |
| `conflict` | Vision saw the indicator at a different quadrant than pad-1 |

## Quick start

```bash
chiplinter run path/to/chip-dir          # lint a single chip
chiplinter sweep test-cases/             # full coverage matrix
chiplinter inspect path/to/chip-dir      # interactive Babylon.js webview
```

## Inspector webview

`chiplinter inspect` serves a Hydrogen webview at `http://localhost:18420`
showing the chip GLB rendered with FP pad bboxes, raycast lines, the pin-1
marker, and a per-pad walkthrough. One-click **Bake annotated GLB** writes
`<mpn>-chiplinter.glb` with three named groups in the scene graph:

- `chiplinter_chip_pads` — chip-frame rectangle meshes parented under the
  chip's `__root__` (rotates with the chip on a PCB)
- `chiplinter_fp_pads` — KiCad footprint pads at the scene root in PCB frame
  (stays fixed when the chip rotates above)
- `chiplinter_pin1_marker` — pin-1 location with full confidence metadata

One-click **Validate pin-1** captures a top-down render with N/S/E/W compass
labels burned in, ships it to Claude vision with a structured-output schema,
compares the indicator quadrant against KiCad pad-1's expected quadrant, and
upgrades or downgrades the bake-time confidence accordingly.

## Rotational symmetry detection

For QFN/QFP/BGA/SOIC packages with N-fold symmetric pad layouts, multiple
orientations of the chip will fit the footprint at 100% coverage. chiplinter
detects ties at bake time by running the FP-projection raycast at every one
of the 24 axis-aligned rotations; if more than one rotation matches the max
hit count, the marker carries `rotational_symmetry_detected: true` and
`tied_orientations: [0, 1, 2, 3]` (or `[0, 2]` for 2-fold, etc.).

In this case bake-time confidence is `ambiguous` — the manufacturer's pin-1
indicator on the chip body is the only signal that breaks the tie. Stage 5b
vision validation is the deciding factor.

Sweep results across the staged test set:

| chip | family | tied | confidence |
|---|---|---|---|
| RP2040 | QFN-56 | [0,1,2,3] | ambiguous |
| LQFP-48 | QFP | [0,1,2,3] | ambiguous |
| LM358_DFN-8 | DFN | [0,1,2,3] | ambiguous |
| TMP102 | SOT-563 | [0,1,2,3] | ambiguous |
| Texas_DSBGA-49 | BGA | [0,1,2,3] | ambiguous |
| iCE40HX1K-TQ144 | TQFP | [0,1,2,3] | ambiguous |
| ATtiny85_SOIC-8 | SOIC | [0,2] | ambiguous |
| W25Q128JV | SOIC | [0,2] | ambiguous |
| WAGO-2601-3105 | THT | [21] | assumed |
| NE555_DIP-8 | DIP | [1] | assumed |
| USB-C-GCT-USB4085 | conn | [16] | assumed |

## Required infra

- `step2glb` — used to convert STEP → color-preserving GLB at chip-staging time
- `claude` CLI — used for Stage 5b pin-1 vision validation
- `adom-3d-viewer-babylon9` — vendored 3D viewer ESM bundle (Babylon 9.5.0 +
  Inspector v9), also published to the Adom Wiki

## 3D viewer + design-skill audit (v0.2.0)

The inspector webview uses `adom-3d-viewer-babylon9` v0.2.0. Compliance vs
the `3d-viewer-design` skill:

| Rule | Status |
|---|---|
| §1 Babylon engine, §3b gradient, §4a–4d HDRI + lights + shadows + ground | ✅ |
| §5a PBRMaterial default | ✅ |
| §6a zoom-to-mouse, §6c Shift+Alt+Click recenter, §7 ViewCube | ✅ |
| **§8a world-origin axes (default ON, R/G/B, 15% scene radius)** | ✅ **new in v0.2.0** — toolbar "Axes" button, `A` keyboard |
| **§8b mesh-local axes (default OFF, toggleable, parented to each GLB root)** | ✅ **new in v0.2.0** — toolbar "Mesh axes" button, `Shift+A` keyboard |
| **§8c screen-space corner triad (always on)** | ⚠ **deferred to v0.3.0** — second-camera-viewport rendering doesn't fire from the canonical viewer's render loop; needs `UtilityLayerRenderer` with explicit secondary `engine.render()` pass |
| §6b.i adaptive `wheelDeltaPercentage` | ⚠ open — currently constant `0.1` |
| §11 Y-up→Z-up | ✅ via `rotateYUpToZUp(scene)` exposed on the bundle global |

## Architecture

The detection pipeline is described in [SKILL.md](./SKILL.md). Source code
lives at `adom-inc/adom-chiplinter` (private repo); the canonical install
artifact is the wiki binary asset.

## Output artifacts

`chiplinter run <chip-dir>` produces:

- `chiplinter-report.json` — per-pad verdict + scoring metadata
- `chiplinter-inspector.json` — manifest for the inspector webview
- `<mpn>-chiplinter.glb` (after baking) — annotated GLB
- `<mpn>-pin1-vision.png` (after vision validation) — labeled top-down render

`chiplinter sweep` produces:

- `coverage-matrix.json` — rows=chips, cols=stages, cells=PASS|WARN|REFUSE
- `coverage.html` — visual coverage matrix
