app
Adom Fields
Public Made by Adomby adom
Adom Fields: where the current and the heat go on your board.
← Commit history
0.10.1: the skill's topics as installable sub-skills
17 files changed
+529−35
Cargo.lock+1−1Cargo.toml+1−1SKILL.md+23−10docs/release-0.10.0.md+3−1install.sh+13−7package.json+2−2page.json+2−2skills/adom-fields-emc/SKILL.md+67skills/adom-fields-noise-rf/SKILL.md+33skills/adom-fields-pdn/SKILL.md+31skills/adom-fields-review/SKILL.md+52skills/adom-fields-si/SKILL.md+39skills/adom-fields-spec/SKILL.md+58skills/adom-fields-verify/SKILL.md+66skills/adom-fields-views/SKILL.md+112skills/adom-fields/SKILL.md+23−10uninstall.sh+3−1Cargo.lock+1−1@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "adom-fields"-version = "0.10.0"+version = "0.10.1" dependencies = [ "clap", "png",
Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "adom-fields"-version = "0.10.0"+version = "0.10.1" edition = "2021" license = "MIT" description = "Adom Fields: where the current and the heat go on your board. Current density, copper heat flow and board temperature from the board file itself, in 3D, for the AI to drive and the human to explore."
SKILL.md+23−10@@ -26,13 +26,13 @@ Save the board with its zones filled first (the filled polygons are the copper). ``` - `loads`: each net's current (`maxDropMv`, `maxRiseC`, `draws`, explicit `terminals` optional). `hot`: each dissipating part's watts (`tabNet` for an exposed pad, `tabPad`, `tjMaxC`, `thetaJcKPerW`). Without `hot` the temperature is only the copper's own loss, and the output says so.-- A few seconds for a small board, one to five minutes for a dense 65 × 75 mm four-layer one at the default 0.2 mm cell. Every other key (stackup, solids, package cooling, fans, transients, terminals, Fusion boards): [spec.md](spec.md).+- A few seconds for a small board, one to five minutes for a dense 65 × 75 mm four-layer one at the default 0.2 mm cell. Every other key (stackup, solids, package cooling, fans, transients, terminals, Fusion boards): the `adom-fields-spec` skill. ## Read the result - **The printed lines** (`OK:` then `Hint:`): peak density and rises, the top findings, the review, the inputs it had to assume, the first fix-plan steps, then **`Not run:` lines**, one per optional module this board may need, each with the reason found on this board and what the module adds. - **`fields/fields.json`** (lean, made for you to read): `nets` (peak A/mm² and where), `chips` (each hot part's rise still and moving air, and where its heat goes), `heat`, `issues`, `fixPlan`, `review` (the numbers behind the findings), `review.inputs` (each assumed input with the datasheet field that replaces it and `specPatch` to fill), `modules` (what ran, what did not and why it may matter).-- **`issues`**: `severity`, `kind`, `what`, `at`, `net`, `reference`, `fix`, and an `action` to carry out (`widen`, `add-vias`, `move`, `add-part`, `add-copper`, `reroute`, `review`). Three or more low findings of one kind come as one finding whose action is `{"type": "group", "items": [...]}` with every item's own action; per-via barrel warnings come as one per net. Every kind and its module: [review.md](review.md).+- **`issues`**: `severity`, `kind`, `what`, `at`, `net`, `reference`, `fix`, and an `action` to carry out (`widen`, `add-vias`, `move`, `add-part`, `add-copper`, `reroute`, `review`). Three or more low findings of one kind come as one finding whose action is `{"type": "group", "items": [...]}` with every item's own action; per-via barrel warnings come as one per net. Every kind and its module: the `adom-fields-review` skill. - `detail.json` holds the bulk the app draws (river data, per-via currents, mode grids, PDN curves, parts): you never need to read it. ## Optional modules: when to turn them on@@ -41,12 +41,12 @@ The core always runs: current, heat, necks and ampacity, hot tabs and thermal vi | Module | Turn it on when | It adds | On by itself when the spec has | |---|---|---|---|-| `emc` | a switching converter, clocks or cables, and the product will be FCC/CISPR tested | hot-loop and cable (common-mode) radiated emissions, conducted emissions, return paths and stitching, a compliance prediction with the cheapest fixes by dB and a bench plan ([emc.md](emc.md)) | `emcLimit`, `emcLimits`, `cables`, `measurements` |-| `esd` | a connector faces the outside world (user cable, hot-plugged lead) | a TVS within 3 mm and a filter for each outside-facing pin; list those connectors in `external` ([emc.md](emc.md)) | `external` |-| `pdn` | a rail feeds an MCU, FPGA, RF chip or anything with fast current edges; a converter input; a connector-fed rail | each rail's impedance against its target, the cheapest decoupling set, hot-plug overshoot, input-filter stability ([pdn.md](pdn.md)) | `pdn` |-| `si` | differential pairs (USB, Ethernet, LVDS, MIPI), clocks or fast buses, traces over about 50 mm | trace impedance from a 2-D field solve, TDR and overshoot with the series resistor, length matching, via stubs, reference planes ([si.md](si.md)) | `impedance`, `tdr`, `lengthGroups` |-| `noise` | a switch node or clock near quiet or sensitive nets; power pours over ground | plane-cavity resonances against the harmonics, crosstalk into quiet nets ([noise-rf.md](noise-rf.md)) | `crosstalkMv`, `victimBudgetsMv` |-| `rf` | a receiver: antenna, oscillator, mixer, IF | LO leak out of the antenna (FCC 15.111), stage isolation, in-band tones ([noise-rf.md](noise-rf.md)) | `rf`, `bands`, `sensitiveNets` |+| `emc` | a switching converter, clocks or cables, and the product will be FCC/CISPR tested | hot-loop and cable (common-mode) radiated emissions, conducted emissions, return paths and stitching, a compliance prediction with the cheapest fixes by dB and a bench plan (the `adom-fields-emc` skill) | `emcLimit`, `emcLimits`, `cables`, `measurements` |+| `esd` | a connector faces the outside world (user cable, hot-plugged lead) | a TVS within 3 mm and a filter for each outside-facing pin; list those connectors in `external` (the `adom-fields-emc` skill) | `external` |+| `pdn` | a rail feeds an MCU, FPGA, RF chip or anything with fast current edges; a converter input; a connector-fed rail | each rail's impedance against its target, the cheapest decoupling set, hot-plug overshoot, input-filter stability (the `adom-fields-pdn` skill) | `pdn` |+| `si` | differential pairs (USB, Ethernet, LVDS, MIPI), clocks or fast buses, traces over about 50 mm | trace impedance from a 2-D field solve, TDR and overshoot with the series resistor, length matching, via stubs, reference planes (the `adom-fields-si` skill) | `impedance`, `tdr`, `lengthGroups` |+| `noise` | a switch node or clock near quiet or sensitive nets; power pours over ground | plane-cavity resonances against the harmonics, crosstalk into quiet nets (the `adom-fields-noise-rf` skill) | `crosstalkMv`, `victimBudgetsMv` |+| `rf` | a receiver: antenna, oscillator, mixer, IF | LO leak out of the antenna (FCC 15.111), stage isolation, in-band tones (the `adom-fields-noise-rf` skill) | `rf`, `bands`, `sensitiveNets` | How to decide: - Run the core first. Then read the `Not run:` lines: they name what on this board points to each module (the converter and its frequency, the connectors, the rails and their chips, the pairs, the RF nets). If the reason applies to this product, rerun with that module.@@ -56,7 +56,7 @@ How to decide: ## Fix it 1. Work down `fixPlan` (worst first, concrete edits before reviews). Fill `review.inputs.specPatch` from the parts' datasheets when it lists inputs that matter.-2. Copper edits can be applied and proven for you: `adom-fields verify --board b.kicad_pcb --spec s.json --step 1,3 --refill --out verify` adds the vias and widens the traces on a copy, has KiCad refill and DRC it, re-solves and reports what moved. Part, move and reroute steps are yours to make in the layout; then `analyze` again. [verify-report.md](verify-report.md)+2. Copper edits can be applied and proven for you: `adom-fields verify --board b.kicad_pcb --spec s.json --step 1,3 --refill --out verify` adds the vias and widens the traces on a copy, has KiCad refill and DRC it, re-solves and reports what moved. Part, move and reroute steps are yours to make in the layout; then `analyze` again. the `adom-fields-verify` skill 3. `adom-fields probe --fields fields --from J1.1 --to U1.3` reads the IR drop between two pads without re-solving. 4. `adom-fields report --fields fields [--safety <adom-safety out>] [--mechanics <adom-mechanics out>]` writes a readiness report: each area ready, needs work, blocked or not checked. @@ -68,7 +68,20 @@ adom-fields ui view --quantity current|heat|temperature|emc|pdn|... [--net X] [- adom-fields tour # the walkthrough, for a video ``` -The views (flow, river, energy, cycle, charge, magnetic, ground, noise, PDN) are for people and videos; they add no findings. Everything about them: [views.md](views.md).+The views (flow, river, energy, cycle, charge, magnetic, ground, noise, PDN) are for people and videos; they add no findings. Everything about them: the `adom-fields-views` skill.++## The sub-skills (load when the topic comes up)++| Skill | For |+|---|---|+| `adom-fields-review` | every finding kind and its module, grouped findings, the fix plan, the IR-drop probe |+| `adom-fields-spec` | every spec key: terminals, hot parts, stackup, solids, package cooling, fans, transients, Fusion boards |+| `adom-fields-emc` | `--with emc` and `--with esd`: emissions, compliance, bench calibration, connector protection |+| `adom-fields-pdn` | `--with pdn`: rail impedance, decoupling, hot-plug, input-filter stability |+| `adom-fields-si` | `--with si`: trace impedance, TDR, termination, length matching, via stubs |+| `adom-fields-noise-rf` | `--with noise` and `--with rf`: cavities, crosstalk, receivers |+| `adom-fields-verify` | `verify`, `report`, and the inputs assumed |+| `adom-fields-views` | `serve`, `ui`, `tour`: the 3D app and its views | ## Honest limits
docs/release-0.10.0.md+3−1@@ -1,4 +1,4 @@-# adom-fields 0.10.0: lean by default, more when the board needs it+# adom-fields 0.10.0 and 0.10.1: lean by default, more when the board needs it - **Optional modules.** - **The core always runs:** current and IR drop, heat, necks and ampacity, hot tabs and thermal vias, part and capacitor temperatures, ground offset, decoupling, the converter's hot loop and ripple, and the inputs assumed.@@ -29,3 +29,5 @@ - **The app:** the Power and Noise views say which module to run when the solve has none. Across four real boards (buck, ESC, e-load, AM/FM), the default run gives 12 to 50 findings where 0.9.8 gave 12 to 155. The 52 high and medium findings with a concrete edit are all still there. `fields.json` is 24 KB to 240 KB where it was 0.3 MB to 5.1 MB.++0.10.1 ships the topic files as sub-skills, each its own skill that installs with the package: `adom-fields-review`, `-spec`, `-emc`, `-pdn`, `-si`, `-noise-rf`, `-verify` and `-views`. Asking about emissions, impedance or decoupling loads the one that says which module to turn on.
install.sh+13−7@@ -1,12 +1,18 @@ #!/bin/bash set -e HERE="$(cd "$(dirname "$0")" && pwd)"-mkdir -p "$HOME/.local/bin" "$HOME/.claude/skills/adom-fields"+mkdir -p "$HOME/.local/bin" install -m 755 "$HERE/bin/adom-fields" "$HOME/.local/bin/.adom-fields-new" mv -f "$HOME/.local/bin/.adom-fields-new" "$HOME/.local/bin/adom-fields"-# the skill is SKILL.md plus its topic files (read on demand): copy the whole folder-cp "$HERE"/skills/adom-fields/*.md "$HOME/.claude/skills/adom-fields/"-echo "OK: adom-fields installed at ~/.local/bin/adom-fields. Run 'adom-fields --version'."--mkdir -p "$HOME/.codex/skills/adom-fields"-cp "$HERE"/skills/adom-fields/*.md "$HOME/.codex/skills/adom-fields/"+# the core skill and its sub-skills, each its own folder (Claude Code and Codex)+install_skill() { for d in "$HOME/.claude/skills" "$HOME/.codex/skills"; do mkdir -p "$d/$1"; cp "$HERE/$2" "$d/$1/SKILL.md"; done; }+install_skill adom-fields skills/adom-fields/SKILL.md+install_skill adom-fields-views skills/adom-fields-views/SKILL.md+install_skill adom-fields-spec skills/adom-fields-spec/SKILL.md+install_skill adom-fields-review skills/adom-fields-review/SKILL.md+install_skill adom-fields-emc skills/adom-fields-emc/SKILL.md+install_skill adom-fields-pdn skills/adom-fields-pdn/SKILL.md+install_skill adom-fields-si skills/adom-fields-si/SKILL.md+install_skill adom-fields-noise-rf skills/adom-fields-noise-rf/SKILL.md+install_skill adom-fields-verify skills/adom-fields-verify/SKILL.md+echo "OK: adom-fields installed at ~/.local/bin/adom-fields with its skill and 8 sub-skills. Run 'adom-fields --version'."
package.json+2−2@@ -1,8 +1,8 @@ { "slug": "adom-fields", "type": "app",- "version": "0.10.0",- "changelog": "0.10.0: lean by default: the core always runs, six optional modules (emc, esd, pdn, si, noise, rf) run with --with and the output says when each matters on this board; grouped findings, a lean fields.json with detail.json for the app, faster heat passes, and the skill split into a short core plus topic files.",+ "version": "0.10.1",+ "changelog": "0.10.1: the skill's topics install as sub-skills (adom-fields-review, -spec, -emc, -pdn, -si, -noise-rf, -verify, -views); 0.10.0: lean by default with optional modules the output says when to turn on.", "title": "Adom Fields", "brief": "Adom Fields: where the current and the heat go on your board.", "summary": "Current density on the copper, heat flow through the pours and the vias, and the temperature over the board, solved from the board file itself and shown on the board in 3D. The AI does the analysis and drives the view; the human orbits, zooms, hovers for the number under the cursor, and reads the nets by what they carry and the issues by what to fix. A step in Adom's AI Flow: the walkthrough goes into the video.",
page.json+2−2@@ -1,8 +1,8 @@ { "slug": "adom-fields", "type": "app",- "version": "0.10.0",- "changelog": "0.10.0: lean by default: the core always runs, six optional modules (emc, esd, pdn, si, noise, rf) run with --with and the output says when each matters on this board; grouped findings, a lean fields.json with detail.json for the app, faster heat passes, and the skill split into a short core plus topic files.",+ "version": "0.10.1",+ "changelog": "0.10.1: the skill's topics install as sub-skills (adom-fields-review, -spec, -emc, -pdn, -si, -noise-rf, -verify, -views); 0.10.0: lean by default with optional modules the output says when to turn on.", "title": "Adom Fields", "brief": "Adom Fields: where the current and the heat go on your board.", "summary": "Current density on the copper, heat flow through the pours and the vias, and the temperature over the board, solved from the board file itself and shown on the board in 3D. The AI does the analysis and drives the view; the human orbits, zooms, hovers for the number under the cursor, and reads the nets by what they carry and the issues by what to fix. A step in Adom's AI Flow: the walkthrough goes into the video.",
skills/adom-fields-emc/SKILL.mdadded+67@@ -0,0 +1,67 @@+---+name: adom-fields-emc+description: >-+ Adom Fields EMC, compliance and ESD modules (--with emc, --with esd): hot-loop and cable common-mode radiated emissions, conducted emissions through a LISN, FCC/CISPR limit sets, a compliance prediction with uncertainty bands, the cheapest fixes by dB, a bench plan and bench calibration, connector ESD/TVS checks. Use when asked about EMI, EMC, FCC or CISPR risk, "will it pass the chamber", "radiated emissions", "conducted emissions", "common mode cable", "pre-compliance", "ESD protection", "TVS".+---++Parent skill: **adom-fields**++# Adom Fields: EMC, compliance and ESD (`--with emc`, `--with esd`)++Turn on `emc` when the board has a switching converter, clocks or cables and the product will face FCC/CISPR testing; `esd` when a connector faces the outside world (name those connectors in spec `external`).++## The EMC screen (0.7.5)++`ui view --quantity emc` on a board with a modelled switching converter (see the energy cycle): three checks drawn on the board.+- **The hot loop**: input capacitor → the switch's input pin → its ground pin → back to the capacitor, for every input capacitor; the smallest (fastest-edged) capacitor's loop is the red patch, pulsing with the switching, drawn over the parts; a green dashed outline is the smallest loop the switch allows (a capacitor straight across its pins). Areas in mm², in the board's plane between the pads.+- **The reference plane**: copper of the loaded and switching nets on the top layer, green where ground copper lies on the next layer, red where it does not (the return current has to detour); the share and mm² per net in the panel.+- **Radiated emissions**: the hot loop as a small loop antenna (Ott: E = 1.316·10⁻¹⁴ f² A I / r), its current's harmonics from the trapezoid (duty from the cycle, edge time from the spec's `switching.<net>.riseNs`, 8 ns by default), 30 MHz to 1 GHz at 3 m against the FCC Part 15 class B limit, with the worst margin and what the smallest loop would gain.+A screen, not a chamber: differential mode only; cables (common mode), which often dominate, are not modelled.++## Compliance prediction and bench calibration (0.9.5)++`fields.json` `review.compliance` puts every emission source the review models into one table against the chosen limit set (`emcLimit`):+- **The sources:** the switching hot loop (`loop`), each connector's cable (`cable:J2`), an oscillator's copper (`lo:<net>`), a receiver's oscillator leaking out of its antenna port (`lo-leak:<net>`, FCC 15.111), and the conducted emissions (`conducted`).+- **What each row carries:** level, limit, margin, an uncertainty band from the model's own error, and the basis:+ - loop ±6 dB;+ - cable 0 to +20 dB, because the common-mode model is an upper bound;+ - conducted ±4 dB;+ - antenna port ±3 dB.+- **Verdicts per test (`radiated`, `conducted`, `antenna`):** `likely fail` (even the band's best case is over), `at risk` (the band crosses the limit), `likely pass, thin margin` (under 6 dB), `likely pass`.+- **`fixes`, each with the dB it buys per source:**+ - slower switch edge (computed from the edge's envelope at each source's frequency);+ - spread spectrum (from the dither width over the receiver bandwidth: 9 kHz conducted, 120 kHz radiated);+ - a smaller hot loop (from the area ratio);+ - per cable: a clip-on ferrite (about 200 Ω), a board common-mode choke (about 1 kΩ), and moving the connector's ground to the converter's input-capacitor ground;+ - an input filter (sized to 6 dB);+ - for receivers: an RF amplifier's reverse isolation, or weaker LO coupling;+ - a shield can.+- **`toSixDb`:** the cheapest set of those fixes that gets every source to 6 dB of margin, found by searching every combination (free and cable fixes cost less than layout and parts), with the margins after it.+- **`benchPlan`:** how to measure each prediction, cheapest first:+ - conducted: LISN and analyzer, 150 kHz to 30 MHz;+ - each cable: a current clamp, with the predicted current and the current that puts the cable on the limit;+ - the hot loop: an H-field probe, which ranks sources and shows a fix working but gives no dBµV/m;+ - the antenna port: an analyzer.+ - Each step says what to expect and gives the `measurements` record to fill in.+- **Bench calibration:** spec `measurements: [{source, fMHz, value, unit}]`, with unit `dBuV` (LISN), `dBuA` (clamp), `dBuVm` (chamber or pre-scan at 3 m) or `dBm` (antenna port).+ - The source moves onto the reading, keeping the model's spectral shape and taking the bench's level. Its band narrows to ±2 dB at the measured frequency (±3 dB elsewhere).+ - A cable reading also moves the cables not measured by the same offset, ±4 dB.+ - `calibration` says what was used, by how much, and why a reading was not used.+- `analyze` prints a `Hint: Compliance` line: each verdict with its worst source and band, and the cheapest set.++On the TPS54202 buck (12 V to 5 V, 1 A, 1 m cables, FCC B):+- **Radiated** is at risk: J2's cable is −7.1 to +12.9 dB, while the loop itself is 55 dB under.+- **Conducted** is a likely fail: −33.5 dB with no input filter.+- **The cheapest fix set:** an input filter, spread spectrum and a 16 ns edge, which gets every source to 6 dB or more.+- **With a clamp reading** of 9 dBµA on J2 (9 dB under the bound), radiated becomes "likely pass, thin margin", and the set drops to the input filter plus spread spectrum.++## Also in this area++- **Conducted emissions** (0.9.2, `review.conductedEmissions`, `conducted-emissions`).+ - The converter's trapezoid input current split between its input capacitors (at bias) and any input filter into a LISN (50 Ω ∥ 50 µH), against CISPR 32 / FCC 15.107 class B (or A with `emcLimit` *-a), 150 kHz to 30 MHz.+ - The fix sizes the input-filter inductor for the attenuation needed.+ - Differential mode only.+- **Emission limits** (0.9.0): spec `emcLimit` picks the set the issues use: `fcc-b` (default), `fcc-a`, `cispr32-b`, `cispr32-a`, or a custom name. Spec `emcLimits` adds lines (CISPR 25, MIL-STD-461 RE102, a customer's) as {name, distanceM, points [[MHz, dBµV/m]]}. Every emission estimate also reports its margin against every set.+- **Cable emissions** (0.9.0, `review.cableEmissions`, `cable-emissions`): common mode, the usual chamber failure.+ - The switching loop's harmonic current across the ground copper's inductance between the loop and each connector's ground pin (μ0·h × the solved squares) drives that connector's cable (spec `cables` {J1: metres}, 1 m) as a monopole.+ - It is an upper bound with no ferrite.
skills/adom-fields-noise-rf/SKILL.mdadded+33@@ -0,0 +1,33 @@+---+name: adom-fields-noise-rf+description: >-+ Adom Fields noise and receiver modules (--with noise, --with rf): plane-cavity resonances, crosstalk into quiet nets, frequency plan and in-band tones, LO leak out of the antenna (FCC 15.111), stage isolation, oscillator emission. Use when asked about crosstalk, "plane resonance", "switching noise coupling", "receiver", "LO leakage", "antenna", "in-band spur", "radio board".+---++Parent skill: **adom-fields**++# Adom Fields: noise and receivers (`--with noise`, `--with rf`)++Turn on `noise` when a switch node or a clock runs near quiet or sensitive nets, or power pours face the ground plane (cavities). Turn on `rf` on a receiver: an antenna, an oscillator, a mixer, an IF.++## Noise: plane resonance and crosstalk (0.7.8)++`analyze` also screens noise couplings, each finding with an action:+- **Cavities**: every power or switching pour facing the ground plane is a parallel-plate cavity; its lowest modes are solved on the real overlap (the Neumann Laplacian's eigenpairs by Lanczos with full reorthogonalisation, then Jacobi; f = c·k/(2π√εr); checked against the rectangle's c/(2a√εr) in the tests). A mode within 5 % of a strong tone (the switching harmonics up to ten times the edge's knee, `clocks` from the spec: a crystal or an LC oscillator no chip drives counts to its 5th harmonic, a logic clock further) is `cavity-resonance`, with an `add-part` capacitor at the mode's loudest point.+- **Crosstalk**: each quiet net (not a rail, not loaded, not tied to the aggressor through a capacitor, like a bootstrap) next to a switching node or a clock: closest approach, run within 1 mm, side and overlap capacitance, and the coupled step ΔV·Cm/(Cm+Cg). Over `crosstalkMv` (50) is `crosstalk`, with a `reroute` action (spacing, or a ground guard).+- `review.noise` holds the cavities' modes, the tones and the crosstalk table; `noise.json` holds the mode shapes for the app.++`ui view --quantity noise`: the largest cavity rings in 3D (its real modes, red and blue phases, white nodal lines), the switching copper pulses, and quiet nets glow by the millivolts they pick up, with arcs at the closest approach.++`ui view --quantity signals` (the Signals button pulls the layers apart): each `signals.capacitance` check lights its real overlap on both layers as two glowing plates with the electric field crossing between them as sparks, one check at a time (seven seconds each, or the one picked in the panel), tagged with its picofarads, overlap and dielectric; differential pairs glow red and blue, tagged with skew and impedance. The via barrels hide so the plates read.++## The copper stack, receivers and RF (0.7.16)++- Boards of two, four or six copper layers; plated pads only on real copper. `stackupMm` is one dielectric per real gap (else the board's stackup, else its thickness); `epsilonR` when the stackup has none. fields.json: `board.copperLayers`, `board.dielectricMm`, `board.stackupFrom`.+- `hot.<part>.tabNet` is optional: a leaded part's watts go through all its leads by pad area. With no `hot`, the temperature is only copper I²R and the output says it is not a thermal pass.+- `clocks`: `{net: Hz}` or `{net: {hz | minHz, maxHz, harmonics, amplitudeV}}` (a tuned LO). `bands`: `{name: {minHz, maxHz, ifHz, lowSideLo}}` for the frequency plan (`tone-in-band`, the band and its image). `sensitiveNets`: nets an oscillator must not reach (`circuit-path` issues with the parts on the way). `victimBudgetsMv`: a budget per victim net (µV for RF/IF inputs).+- Crosstalk is in the victim's impedance (its capacitors and resistors to ground or rails), sine for oscillators, step for switch nodes. Return path (`no-reference`) for every non-rail net on every layer: over ground, a supply plane or nothing. `antenna-ground-loop`, `stage-feed-unbypassed`, `solve-unconverged` are new kinds; `review.stageFeeds`, `review.noise.frequencyPlan`, `review.noise.circuitPaths`.++## Also in this area++- **Receiver screens** (0.8.8, `review.rf`): the LO level at the antenna (each circuit path from a `clocks` oscillator to a `sensitiveNets` net, solved as an AC network with transistors as their junction capacitances, cross-checked in ngspice, against FCC 15.111's -57 dBm: `lo-leak`), isolation between stages through a shared rail at the oscillator's frequency (`stage-isolation`, target 40 dB), the LO's own radiated emission against FCC class B at 3 m (`lo-emission`), and USB edge and FM IF-limiter odd harmonics in the frequency plan (`tone-in-band`). Tune with spec `rf`: `cbcPf`, `cbePf`, `antennaOhm`, `loLeakLimitDbm`, `stageIsolationDb`, `usbHighSpeed`, `limiter`. Screening estimates, not measurements.
skills/adom-fields-pdn/SKILL.mdadded+31@@ -0,0 +1,31 @@+---+name: adom-fields-pdn+description: >-+ Adom Fields power-delivery module (--with pdn): each rail's impedance from its load pin against a target, capacitor DC-bias derating, the cheapest decoupling set, hot-plug overshoot, input-filter stability (Middlebrook), ngspice cross-check. Use when asked about PDN, power integrity, rail impedance, "decoupling", "bypass capacitors", "target impedance", "hot plug", "input filter stability".+---++Parent skill: **adom-fields**++# Adom Fields: power delivery (`--with pdn`)++Turn on `pdn` when a rail feeds a digital or RF chip with fast current edges, or the board has a converter input or a connector-fed rail (hot-plug overshoot, input-filter stability).++## Power delivery: rail impedance (0.7.9)++`analyze` also checks each rail's impedance seen from its load pin (a pin of the chip with the most pins on the rail, else an outgoing connector; `pdn.<net>.load` names another), 1 kHz to 1 GHz. What feeds the rail comes from the spec's `sources`, the modelled converter, an on-board regulator (named like one: TLV7…, LDO, AMS1117…, bridging the rail and a higher one), a chip whose pin on the rail is named as an output (VOUT, OUT: KiCad's pin function), or the connector the solve found the current entering by; a rail with none of these is listed `skipped` with the reason, never guessed:+- **The model**: branches in parallel at the load pin. The source: a modelled converter's output is flat (5 mΩ) below its loop crossover (fsw/10, `crossoverHz`), then an inductance that resonates with the output capacitors there, damped to Q 1 (about a 50° phase margin), fading out a decade above; a linear regulator the same with a 100 kHz crossover; a connector-fed rail is about a metre of supply leads (30 mΩ, 0.7 µH; `sourceOhm`, `sourceNh`). Each capacitor: its board value (nominal, no DC-bias derating), ESR by type, body inductance from its pad span, and the mounting inductance of a microstrip over the plane from it to the load pin. The rail's copper over ground as a plate capacitor.+- **The target**: V·tolPct/100 / stepA (5 %; the step is half the rail's spec load, or the converter's output current on its input rail), over a band: up to the switching edge's knee on a converter input, 100 MHz at a chip pin, 1 MHz at a connector (`fminHz`, `fmaxHz`, or `targetOhm` outright).+- **The fix**: a peak over the target is `pdn-impedance`, with an `add-part` capacitor (value, package, pin) chosen by re-solving with each candidate, up to three, each with the ratio it reaches; still over after three is a `pour` action (a plane pair). A converter's input rail also gets Middlebrook's check: under 10 dB below the converter's negative input resistance V²/P is `input-filter-stability`, with a damping capacitor and its ESR.+- **Capacitors as they sit on the rail** (0.7.13, `src/caps.rs`, used by the PDN check and the converter's ripple): the technology comes from the Value, the MPN and the footprint (EEE-F…/CP_Elec_… electrolytic, ECAS…/EEF-…/APX… polymer, T520/T530 polymer tantalum, CP_Tantalum_… tantalum, else ceramic; C0G/NP0 by Value or vendor code), with ESR by technology. Class-II ceramics are taken at the rail's DC bias: from a measured curve when one matches the MPN (a folder of Murata SimSurfing JSON, spec `capCurves` or ADOM_FIELDS_CAP_CURVES: C at the bias, ESR at self-resonance, ESL from |Z| a decade above), else an estimate, retained = 1/(1+(V/V0)^1.6), V0 = 9.1 V·(case mm³ / µF)^0.38 (a fit to Murata's 0603 to 1206 X5R/X7R curves, about ±0.05). Each branch reports `uF`, `uFAtBias`, `type` and `biasModel`; new ceramics in the fix search are derated too, and polymer bulk parts are candidates. Ripple adds each side's ESR term.+- **Hot-plug** (0.7.14): on a connector-fed rail, the supply leads (R, L; `pdn.<net>.sourceOhm`/`sourceNh`, default 30 mΩ and 0.7 µH) are switched onto every capacitor branch at its rail bias and solved in time (backward Euler, ESL ignored), with the same step run in ngspice as a cross-check (`hotPlug.spicePeakV`). The peak is checked against the lowest voltage rating on the rail (a "35V" in a Value, or Murata's code in an ECAS/GRM MPN). Over that rating is high, over 50 % overshoot is medium: `hot-plug-overshoot`, whose action is a damping bulk capacitor (value, ESR) or a TVS. It catches a low-ESR bulk part with no damping, which an impedance peak under its target does not show.+- **Filtered rails** (0.7.15): a rail fed through a ferrite, fuse, OR-ing diode, resistor or transistor switch from another rail is followed up to its connector or regulator (by pin function or part number) and modelled as one source branch; the upstream rails' capacitors are left out (conservative at high frequency).+- `review.pdn` holds each rail's branches, |Z(f)| (`fHz` is shared), the target and band, the fixes and the curve after them; `pdn-<net>.cir` is the same circuit as an ngspice deck, run as a cross-check when ngspice is installed (`spice.maxErrPct`).++`ui view --quantity pdn` (the Power button): the frequency sweeps; each branch stands a column at its place, its height its share of the load's current (over 100 % is two branches ringing); arcs carry the shares to the load pin; at the load pin |Z| stands in a glass sleeve, the target (green under the rim, red over, steel blue outside the band); the panel draws |Z(f)| per rail with its target, band and fix curve, and a frequency slider.++## Also in this area++- **Decoupling optimiser** (0.9.2, PDN rail `decapPlan`).+ - A beam search over sets of up to six new capacitors at the load pin (MLCC values in 0402/0603/0805 at their DC bias, polymer) for the cheapest set by estimated cost, then area, that meets the rail's target (`cheapest`, `optionsMeetingTarget`).+ - When none can, the lowest-|Z| set (`bestPossible`).+ - On a rail that already passes, the existing capacitors it can lose (`removable`; never the converter's own input or output capacitors).
skills/adom-fields-review/SKILL.mdadded+52@@ -0,0 +1,52 @@+---+name: adom-fields-review+description: >-+ Every Adom Fields finding kind, which module produces it, grouped findings, the review blocks and the fix plan, budgets and the IR-drop probe. Use when reading adom-fields issues or fixPlan, "what does this finding mean", "current-neck", "decoupling-far", "group action", "fixPlan", "review block", "ir drop probe".+---++Parent skill: **adom-fields**++# Adom Fields: the findings, the review and the fix plan++Every finding kind, which module it comes from (`core` always runs; the rest need `--with <module>`), and the review blocks behind them.++## Finding kinds by module++`core` always runs; the others need `--with <module>` (or the spec keys listed in SKILL.md). Kinds not listed are core: `current-neck`, `current-barrel`, `ampacity`, `ir-drop`, `pour-fragmented`, `tab-rise`, `thermal-vias`, `junction-temperature`, `capacitor-temperature`, `electro-thermal`, `ground-offset`, `ground-island`, `decoupling-far`, `decoupling-missing`, `hot-loop`, `inductor-ripple`, `output-ripple`, `solve-unconverged`, `load-unsolved`.++| Module | Kinds |+|---|---|+| `emc` | `emissions`, `cable-emissions`, `conducted-emissions`, `stitching-gap`, `ground-loop-risk`, `no-reference`, `clock-outer-layer`, `clock-near-connector`, `edge-signal`, `input-filter-cutoff` |+| `esd` | `esd-unprotected`, `io-unfiltered` |+| `pdn` | `pdn-impedance`, `input-filter-stability`, `hot-plug-overshoot`, `regulator` |+| `si` | `impedance`, `diff-impedance`, `reflection`, `length-skew`, `via-stub`, `stackup-adjacent-signals`, `stackup-far-reference`, `plane` |+| `noise` | `cavity-resonance`, `crosstalk`, `tone-in-band` |+| `rf` | `lo-leak`, `stage-isolation`, `lo-emission`, `stage-feed-unbypassed`, `circuit-path`, `antenna-ground-loop` |++Grouping: three or more low findings of one kind become one finding (`action.type: group`, every item with its own action in `action.items`); per-via `current-barrel` warnings become one per net; `ampacity` on a net that already has a `current-neck` folds into it. `verify` carries out a group's items one by one. With spec `external: ["J1", ...]`, `esd-unprotected` and `io-unfiltered` cover only those connectors.++## For the AI that called the solve: the review and the fix plan (0.7.6)++`analyze` reviews the design as well as solving it, and says what to change, without anyone looking at the app:+- **`fields.json` `issues`**: every finding with `severity`, `kind`, `what`, `at` (board mm), `net`, `reference`, a plain `fix`, and an **`action`** to carry out: `move` (`ref`, `toPins`, `targetMm2`), `add-vias` (`net`, `points` or `at`, `pitchMm`), `widen` (`net`, `at`), `pour` (`net`, `layer`, `under`, `at`), `add-copper`, `add-part`, `review`. Kinds: `current-neck`, `tab-rise`, `thermal-vias` (the solve's own), and from the review `hot-loop`, `emissions`, `no-reference`, `ground-offset`, `ground-island`, `stitching-gap`, `ground-loop-risk`, `ir-drop` (over `dropPct` of the rail, or over the net's own `loads.<net>.maxDropMv`), `pour-fragmented` (a poured net's fill on one layer broke into pieces: the nearest gap, the pad in it, and a `move` (`reference`, `orRotateDeg`, `byMm`) or `reroute` action; `fields.json` `fragments` lists every pour's pieces per layer), `inductor-ripple`, `output-ripple`, `decoupling-far`, `decoupling-missing` (each chip power pin's nearest small capacitor: over 3 mm moves it, none adds a 100 nF), `cavity-resonance`, `crosstalk`, `esd-unprotected` (a connector pin with no diode to ground: add a TVS within 3 mm if it faces the outside).+- **`fields.json` `fixPlan`**: the actions, worst first and concrete edits before reviews, numbered for the caller to work down. `analyze` prints the first five as a `Hint: Fix plan` line and the review as a `Hint: Review` line.+- **`fields.json` `review`**: the numbers behind them: `converter` (duty, ripple, hot loops per input capacitor and the best possible, the emissions margin), `reference` (each net's copper with no ground under it), `ground` (offset, connectors to the outside, islands, the stitching fence and its gaps), `rails` (IR drop per rail), `decoupling` (pin, cap, distance, loop), `esd` (each connector pin and what protects it).+- **IR-drop probe**: `adom-fields probe --fields <dir> --from J1.1 --to U1.3` (or `--to <net>` for its farthest point, `--json` for the record) reads the drop between two pads from the solve, no re-solve; `adom-fields ui probe --from J1.1 --to U1.3` shows it in the running app's river view with a toast.+- Budgets in the spec: `groundOffsetMv` (10), `dropPct` (1 % of the rail), `loads.<net>.maxDropMv` (none; `review.drops` lists every loaded net's drop and its two ends), `emcFmaxHz` (1 GHz, for the stitching pitch), `switching.<net>.riseNs` (8).++After applying a step, run `analyze` again: the issue goes away or says how far it still is. In the app, clicking an issue opens the view that shows it (EMC, Ground, River, Cycle).++## Hot parts read at their tab (0.9.8)++A hot part with a tab net is read at its tab: the pad named in `hot.<ref>.tabPad` (the exposed pad's number, e.g. `"29"`), else the largest tab-net pad, so an exposed pad wins over corner pins that share its net. `vias` counts the tab net's vias near every tab-net pad, including a footprint's own thermal-via holes. The watts are still spread over all tab-net pads by area.++## Also in this area++- **Board checks** (0.9.0, `review.checks`), on the solved fields where one exists:+ - `ampacity`: each loaded net's narrowest neck against IPC-2221's 10 °C rating, beside the solved rise there.+ - `junctions` / `junction-temperature`: ambient (spec `ambientC`, 25) + the solved rise (+ `hot.<ref>.thetaJcKPerW`·W) against `hot.<ref>.tjMaxC` (125).+ - `capacitors` / `capacitor-temperature`: each capacitor's solved temperature against its type's rating (read from value or part number; electrolytic life by the 10 °C rule; ceramics with only an assumed rating grouped into one finding).+ - `emcRules`: `clock-outer-layer`, `clock-near-connector`, `edge-signal`, `io-unfiltered`, `input-filter-cutoff` (a converter's input LC against fsw/10).+ - `stackup`: which layers are planes, plus `stackup-far-reference`, `stackup-adjacent-signals` and plane-pair pF/cm².+ - `viaStubs` / `via-stub`: the quarter-wave resonance of each signal via's unused barrel against its clock.+ - `lengthGroups` / `length-skew`: spec `lengthGroups` {name: {nets, maxSkewPs | maxSkewMm | protocol: usb2|usb3|pcie|ethernet|ddr|hdmi|mipi}}.
skills/adom-fields-si/SKILL.mdadded+39@@ -0,0 +1,39 @@+---+name: adom-fields-si+description: >-+ Adom Fields signal-integrity module (--with si): trace and differential-pair impedance from a 2-D field solve, TDR and overshoot in ngspice with the series termination, length matching, via stubs, stackup reference planes, signal capacitance screens. Use when asked about trace impedance, "50 ohm", "90 ohm USB", "differential pair", "TDR", "reflections", "ringing", "series termination", "length matching", "skew".+---++Parent skill: **adom-fields**++# Adom Fields: signal integrity (`--with si`)++Turn on `si` when the board has differential pairs (USB, Ethernet, LVDS, MIPI), clocks or fast buses (SPI, SDIO, QSPI), traces over about 50 mm, or impedance targets.++## Reflections and TDR (0.9.6)++`review.reflections` checks the nets where edges matter: spec `impedance` targets, `clocks`, `lengthGroups` members, and any net in spec `tdr: {net: {driverOhm, riseNs, loadPf, from, to}}`.+- **The model:**+ - **The path:** the net's copper is walked from the driver pad (`from`, else the first IC pin) to the receiver (`to`, else the farthest pad), segment by segment and through vias.+ - **The line:** each segment is a lossless line with the cross-section solve's Z0 and delay, and each via adds its pad capacitance (Johnson & Graham).+ - **What is not modelled:** branches off the path are counted, not simulated.+- **Two ngspice runs:**+ - **TDR:** a 50 Ω, 35 ps step gives `tdr.points` (ps, Ω), the impedance profile along the path.+ - **In use:** the real driver (25 Ω and 1 ns by default; a clock's edge is 7 % of its period) into a 3 pF receiver gives `inUse`: overshoot, undershoot, settling time, and the series termination (line Z0 less the driver's resistance).+- **Short nets:** a path shorter than a sixth of its edge is `electricallyShort` and only says so.+- **Issues:** overshoot over 15 % raises a `reflection` issue, with an `add-part` action for the series resistor at the driver pin.+- **On the ESC's SWD clock** (73 mm, 449 ps of 58 Ω line, a 0.5 ns edge from 20 Ω): 40 % overshoot, fixed by a 38 Ω series resistor. The DShot input (2 ns edge) is electrically short.+- `impedance` segments' `psPerMm` is now in ps/mm (it read a million times too high before 0.9.6).++## Conducting blocks and signals (0.4.0)++Read `docs/heatsinks-and-signals.md` in the package before specifying these models. Use measured conductivity/contact resistance for `heatsinks`; contact is to the board face, not an automatically modeled chip lid. Never add a fictitious heatsink to make a gate pass. Inspect both air conditions and mesh sensitivity.++For signal screening, provide `signals.capacitance` or `signals.differentialPairs`, explicit consistent `stackupMm`, and justified epsilonR. Inspect Signals with `adom-fields ui --port 8874 view --quantity signals`. Unsupported geometry must stay unsupported; do not replace null estimates with guessed numbers. This is outer-layer microstrip and adjacent-layer overlap screening, not high-frequency signoff. The summary records assumptions and primary references.++## Also in this area++- **Trace impedance** (0.9.0, `review.impedance`): a 2-D Laplace field solve of every signal net's cross-section on its own layer (microstrip or stripline, solder mask unless `rf.noSolderMask`).+ - It gives Z0, εeff, ps/mm, pF/m and nH/m, plus Zodd, Zeven and Zdiff for pairs found by name (_P/_N, +/-, DP/DM).+ - Targets come from spec `impedance` {net: Ω, "P/N": Ω differential} or by protocol (USB 90, PCIe 85, Ethernet/LVDS/HDMI/MIPI 100).+ - It is validated within about 2 % of Hammerstad-Jensen and Cohn.
skills/adom-fields-spec/SKILL.mdadded+58@@ -0,0 +1,58 @@+---+name: adom-fields-spec+description: >-+ The full Adom Fields spec and solver reference: loads and explicit terminals, hot parts (tabNet, tabPad, tjMaxC, thetaJcKPerW), voltages, sources, switching, stackup, copper, epsilonR, solid bodies, package cooling, heatsinks, fan levels, transients, electro-thermal, plated holes, Fusion boards, evidence identity. Use when writing or debugging an adom-fields spec, "spec key", "terminals", "solids", "packageCooling", "fanLevels", "transient", "stackupMm".+---++Parent skill: **adom-fields**++# Adom Fields: the spec and the solver, in full++Every spec key and what the solver does with it. The core keys are in SKILL.md; read this for terminals, solids, package cooling, fans, transients, stackups and Fusion boards.++## What a solve writes++```+adom-fields analyze --board <board.kicad_pcb | board.brd from Fusion> --spec <spec.json> --out fields+```++The board must be saved with its zones filled (the filled polygons are the copper). The spec is the AI Flow spec: `loads` (net: amps, maxRiseC, maxDropMv, draws: {part: amps}), `sources` (net: [the parts that feed it]), `hot` (ref: watts, tabNet, maxRiseC: that part's own limit, else hotMaxRiseC), `copperUm`, `hotMaxRiseC`, `thermalVias` (pad, count), optional `stackupMm` (three dielectric thicknesses). About two minutes for a 65 x 75 mm four-layer board at the default 0.2 mm cell; `--pitch 0.1` is four times longer and sharper.++What comes out, in `fields/fields.json` and `fields/tex/`:+- `nets`, ordered by amps then by peak density: peak A/mm² and where, the layers, the copper mm², the Joule loss, the vias.+- `chips`, hottest first: the rise at the tab in still and moving air, and where its watts go within 3 mm (along its layer, down its vias, through the bare dielectric, to the air), with how many vias the spec asked for.+- `issues`: `current-neck` (a loaded net over 60 A/mm², about what IPC-2221 allows at 35 µm for 10 °C), `tab-rise` (over the budget), `thermal-vias` (fewer than the spec asks), each with `at`, `layer`, `net`, `reference` and a `fix`.+- textures per layer: `J-<layer>.png` (all nets), `J-<net>-<layer>.png`, `q-<layer>.png` (heat flow, W/mm), `T-<layer>.png` and `Tm-<layer>.png` (rise, still and moving air), `copper-<layer>.png`, plus `.raw.png` 16-bit values for the readout.++Terminals per net: the wire pads and connectors (MC*, J*, P*) on one side; on the other the spec's hot parts on the net (a FET's tab and its source pins both count), else the Q and U parts, else the parts with real pads, each part's share by its pad area. A net with neither is skipped and says so.++## Honest limits (0.1)++DC only (no skin effect, no switching loss on the copper); per-layer thickness when copperUmByLayer is supplied; the 1.6 mm stack is 0.2 / 1.065 / 0.2 mm unless `stackupMm` says otherwise; convection is a flat coefficient on both faces (10 or 25 W/m²K), optional specified rectangular conducting blocks; no fins, enclosure or radiation; the tab watts come from the spec, not from a switching model. It is a screen that finds the necks and the starved tabs, and shows them; it is not a datasheet number.++## Evidence identity++Each solve records SHA-256 identities of the board and spec in `fields.json.inputIdentity`, plus the solver version. If an input changes while solving, analysis refuses to publish the summary. AI Flow uses these identities to reject stale field screens, and requires every positive load and hot part to be represented. Existing summaries without these identities must be re-solved, not manually stamped. The identities establish which inputs were used; they do not establish the accuracy of assumed terminals, losses, materials or convection.++## Fusion boards (0.6.0+)++A Fusion Electronics board works as `--board <board>.brd` (EAGLE source: `fusion_export_eagle_source`+on the Fusion bridge). Run RATSNEST in Fusion first so the pours are filled: the reader then uses+Fusion's own fill. Put the parts' STEP files, named by MPN, in a folder and pass `--models-dir` so the+chips sit over the fields.++## The solver: holes, terminals, heat models, fans, transients++- **Plated holes** (PR 5, 9): every via and plated through-hole pad barrel joins its copper layers in the electrical and thermal models (25 µm plating, circular or slotted, `platedPads` counted apart from vias). Drill holes are voids on every layer; each barrel's conductance is spread around its plated wall on cells with copper on both faces, and a wall the mesh does not resolve falls back to the nearest such cells, so a plated hole never disconnects a net. `nets[].platedConnections` gives each hole's current and mean barrel density. Blind, buried and micro vias are refused; Fusion boards read their declared `layerSetup`. See docs/plated-wall-coupling.md.+- **Explicit pin currents** (PR 6, 10): `loads.<net>.terminals: [{reference, pad, amps, at?}]`, positive into the copper, negative out, each side summing to `amps`; `at: [x, y]` picks one physical land where a pin number repeats. Wrong-net, missing, duplicate and unbalanced pins are refused; a loaded net the spec names that cannot be solved fails the run instead of publishing a partial report. `terminalAssignments` says explicit or heuristic per net.+- **Peak current density is the modeled maximum** (PR 8), before the display texture's 99.5th-percentile clip and unrounded (`peakJDefinition`).+- **`dcMaxIterations`** (PR 5, default 20000, at most 100000) bounds each net's solve; the target is unchanged.+- **Electro-thermal** (0.9.1, `review.electroThermal`). Copper's resistance rises 0.393 %/°C, so every run reports the first-order extra Joule heat at the solved temperatures, and an `electro-thermal` issue when it is over 10 %. With spec `electroThermal: true`, a second full pass solves the current and heat with each copper cell at its solved temperature. On the ESC: +33 % Joule, peak rise 109 → 119 °C.+- **Heating transient** (0.9.1, `transient`). Spec `transient` {durationS, steps (24), powerScale (1; a stall or surge at 3× is 3), fromSteady}: implicit Euler on the still-air heat system with copper, FR4 and the solid bodies' heat capacities.+ - It gives the board peak and each hot part's rise over time, and each part's time constant (`t63S`, to 63 % of its steady rise).+ - On the buck: U1 about 2 min, L1 about 3 min.+- **Terminals** (0.8.1): without explicit `loads.<net>.terminals`, the solve picks them. The named `sources` feed the net, and every other connector and part on it is a sink, so a board-to-board connector that a rail feeds counts as a load. Otherwise connectors feed and parts draw. A part listed in `loads.<net>.draws` carries its own amps, the rest share what is left (sinks by pad area, sources evenly), and each part's share splits evenly over its pins. A pin with no copper near it is left out and its share goes to the other pins on its side, so the injection always balances. Every net in fields.json lists `terminalCurrents` (pin, amps, + into the copper) and `terminalBasis`, so a reviewer can check them.+- **Solid bodies off the board** (0.8.0): `solids: {pitchMm, bodies: [{name, boxesMm: [[x0,y0,z0,x1,y1,z1]], conductivityWMk, watts | heatOf: "<hot ref>", hStillWM2k, hMovingWM2k, boardContactM2kW?, provenance}], contacts: [{bodies: [a, b], resistanceM2kW}], boardLinks: [{body, at, layer, resistanceKPerW, pad}], assumptions}`. Boxes are in board mm (x and y as KiCad, z up from the top copper). The bodies are voxelized and solved in the same heat system as the board, so the heat runs from the die through the tab, the pad and the heatsink fins to the air, and down the leads into the copper, in one energy balance. Bodies may touch only through a declared contact (0 means ideal), and they may not overlap. `fields.json` `solids` gives each body's peak rise, heat to air and to board, and peak flux. `solids.json` has every cell's temperature and flux vector, and the viewer paints them in the Heat and Temperature views. Calibrate a sink's h to its vendor rating rather than trusting a textbook h. See docs/solids.md.+- **Fan levels** (0.8.0): `fanLevels: [0, 0.25, 0.5, 0.75, 1]` solves each level fully. h on every exposed face (board, bodies, a packageCooling sink) follows (h_still³ + (h_forced·sⁿ)³)^⅓, where s is the fraction of full speed, s = 1 gives the moving-air h, and n is `fanExponent` (0.5). `fields.json` `airStates` gives each level's h, chip rises and bodies. The viewer's Fan control (Off, 25, 50, 75, 100 %) switches the board and the bodies together, on one colour scale, so the levels compare by eye. `ui view --air fan50` drives it.+- **Package cooling** (PR 11): `packageCooling: [{reference, junctionCaseKPerW, caseSinkKPerW, sinkAmbientStillKPerW, sinkAmbientMovingKPerW, boardLinks, provenance}]` puts a hot part's watts at its junction and lets them split through the supplied case, sink and board links; junction, case and sink rises per air state and an energy balance in `packageCooling`. See docs/package-cooling.md.+- **`adom-fields thermal3d --spec --out`** (PR 12): axis-aligned 3D solids with explicit materials, contacts and convection for an off-board package and finned sink, with a GLB of the surface temperatures. Not CFD. See docs/thermal3d.md.
skills/adom-fields-verify/SKILL.mdadded+66@@ -0,0 +1,66 @@+---+name: adom-fields-verify+description: >-+ Adom Fields fix-and-verify, the readiness report and the inputs assumed: apply fix-plan copper edits (vias, wider traces) to a copy with KiCad refill and DRC and report what moved; a certification-readiness report with Adom Safety and Adom Mechanics; the datasheet fields each assumed input needs. Use when asked to apply and check a fix, "verify the fix", "is it ready for the lab", "readiness report", "what did it assume", "specPatch".+---++Parent skill: **adom-fields**++# Adom Fields: fix and verify, the readiness report, the inputs assumed++## Fix and verify (0.9.3)++`adom-fields verify --board b.kicad_pcb --spec s.json [--step 1,3] [--refill] [--fields <solve>] --out verify` carries out fix-plan steps on a copy of the board, solves the copy, and says what the fix did:+- **Steps it applies (copper edits only):**+ - `add-vias`: a through via, at the board's most common via size, at each point of the action (else `count` of them near `at`). A via is placed only where it lands on the net's own copper on two or more layers and keeps 0.2 mm from other nets. A blocked point moves up to 1 mm (2.5 mm around `at`) to the nearest spot that fits, and `movedMm` says how far.+ - `widen`: the net's segments within 2.5 mm of `at` (on `layer` when given) go to `toMm` (else twice as wide), each only as far as 0.2 mm clearance allows; `short: true` marks one that could not reach the goal.+ - **Each edit sees the earlier ones**, so two neighbouring nets widened in one run keep their clearance to each other.+- **Steps it refuses**, with the reason: `add-part`, `move`, `reroute`, `pour`, `add-copper`, `review`, an impedance width change, and a neck inside a pour (that needs the pour reshaped). Make those in the layout, then `verify` (or `analyze`) the edited file.+- **`--refill`:** KiCad refills the zones and runs DRC (errors only) on both the original and the fixed copy, through `kicad-cli` (service-kicad, else KiCad on the desktop through Adom Bridge). With it:+ - other nets' pours retreat from new copper, as a real refill would;+ - both solves start from refilled boards, so they differ only by the fix;+ - `drc.new` lists the errors the fix introduced.+ - Without `--refill`, other nets' fills count as fixed copper and the copy keeps the fills as saved.+- **Output:**+ - `verify/<board>.kicad_pcb`: the fixed board.+ - `before/` and `after/`: the two solves.+ - `verify.json`: per step, what was applied or why not, and `issueCleared`. Also the issues cleared and new, the metrics that moved (each net's peak density and Joule loss, peak rise still and moving air, each part's rise, ground offset, edge stitching, hot-loop, cable and conducted emissions margins) with `better` true or false, and the DRC result.+- **Reading it:**+ - A peak current density is one cell: widening can move it to a new corner where wide meets narrow. The Joule loss, temperatures and drops are the robust measures.+ - A step can be applied and its issue still be there (a neck at 300 A/mm² against a 60 A/mm² threshold). Read the numbers: they say how far it moved.+ - `--fields <dir>` reuses an existing solve of the same board for the plan and its step numbers.+- **Adopting it:** with `--refill` and no `drc.new`, the fixed board is clean to open in KiCad and save over the original. Without `--refill`, refill and run DRC in KiCad first.++## Certification readiness report (0.9.5)++`adom-fields report --fields <solve> [--safety <adom-safety out>] [--mechanics <adom-mechanics out>] --out readiness.md` writes one readiness report as Markdown, plus the same as `readiness.json`:+- **Areas:** thermal; current and copper; power delivery; signal integrity; EMC and ESD (with the compliance verdicts and the cheapest fix set); electrical safety (from Adom Safety); mechanical reliability (from Adom Mechanics).+- **Each area gets a status** with its key numbers and its first five findings:+ - **blocked:** a high finding, a likely-fail emission test, or a safety distance not met;+ - **needs work:** a medium finding, an at-risk test, no heat sources, or safety nets left on default voltages;+ - **ready:** low findings only;+ - **not checked:** that tool's output was not given, and the report says the command to run.+- **The overall status** is the worst area's.+- **The report also carries:**+ - what it does not cover: measurements, immunity, materials and flammability, DFM;+ - the evidence: tool versions and the board and spec hashes.+- **"Ready" is not "certified".** It means nothing found stands in the way of booking the lab.++## The inputs a solve assumed (0.9.6)++`review.inputs` lists every default or estimate the results lean on, most important first (`matters`: high, medium, low). Each item gives:+- `what` and `used`;+- `from`: default, estimate or missing;+- `part`: its ref and MPN;+- `datasheetField`: the exact datasheet entry that replaces it;+- `specKey`: where the number goes;+- `affects`: what moves, with a sensitivity where one can be computed. For example: "half the edge time costs 6 dB on cable:J2".++The items covered:+- **The converter:** the switch edge and frequency, each capacitor's capacitance at its DC bias and an electrolytic's ESR.+- **Heat:** junction or operating temperature limits, θJC (asked for semiconductors only), and dissipating parts with no watts.+- **Components:** capacitor temperature ratings, and a TDR driver's output resistance and edge.+- **The board:** stackup, laminate Dk, copper weight.+- **The product's world:** ambient, cable lengths, PDN load steps, and a receiver's transistor capacitances.++`specPatch` is the spec fragment to fill in, each value a placeholder naming its source (`<TPS54202DDCR datasheet: switch-node rise time, ns>`). An AI reads the datasheets (the MPN tells it which), fills the patch, and re-runs; an item leaves the list once the spec gives it. `analyze` prints a `Hint: Inputs assumed` line with the high ones.
skills/adom-fields-views/SKILL.mdadded+112@@ -0,0 +1,112 @@+---+name: adom-fields-views+description: >-+ Adom Fields app and its 3D views: serve the solved board, drive the view (current, heat, temperature, flow, river, energy, light, cycle, charge, magnetic, ground, noise, pdn), parts and silkscreen, narration, the tour for a video. Use when asked to show the board in 3D, open the fields app, drive the view, make a walkthrough video, "show me the current", "explode the stack", "river view", "magnetic view", "energy view", "adom-fields tour".+---++Parent skill: **adom-fields**++# Adom Fields: the app and its views++Read this when you show the board to a person or make a video. None of it changes a finding: the views draw what `analyze` solved.++## Serve and show++```+adom-fields serve --fields fields --port 8874 &+```++Open `https://<slug>.adom.cloud/proxy/8874/` in pup, the browser, or a Hydrogen webview (never localhost from outside the container). The app: a 44 px header, the board in 3D on the canonical Adom 3D viewer (adom/adom-3d-viewer, embedded; ViewCube, studio lighting, zoom to the cursor), the field painted on the picked layer with the other layers faded, the vias as dots, the hot parts labelled with their rise, the legend, the readout under the cursor, the nets and hot parts on the left, the issues and the method on the right. Phone: the two side panels open from the header buttons.++## Drive it (the AI's wheel)++```+adom-fields ui view --quantity current|heat|temperature|signals|flow|river|energy|light|cycle|charge|magnetic|emc|ground|noise|pdn [--explode 0..1] [--probe mm] [--speed 1] [--layer F.Cu|In1.Cu|In2.Cu|B.Cu] [--camera top|iso|bottom|fit|zoom --at x,y] [--air still|moving] [--parts auto|ghost|solid|off]+adom-fields ui select --net +VBAT # one net lit alone (current)+adom-fields ui select --chip Q3 # fly to a hot part, heat view+adom-fields ui issue --index 0 # fly to an issue+adom-fields ui toast "20 A through a 1.5 mm neck"+adom-fields ui state | console+adom-fields tour --pause-ms 20000 # the scripted walkthrough: nets by relevance, each field, the hot parts, the issues+```++The server: `GET /state`, `GET /console` (the UI's log), `GET /events` (SSE), `GET /fields.json`, `POST /ui/view|select|issue|toast`. State lives on the server; the UI, the CLI and the AI see the same view.++## The parts over the fields (0.5.0)++`analyze` now also places every footprint's own 3D model on the board, so the chip stands in its hot zone and the cause of a hot spot is plain. The models come from the board file: each footprint's `(model ...)` entries, resolved as KiCad does (`${KIPRJMOD}`, `${KICAD*_3DMODEL_DIR}`, then `--models-dir <folder>` by file name, then a stock KiCad library model fetched by name), converted once to GLB on the Adom STEP service (`step2glb`) and cached by content in `~/.cache/adom-fields/models/`. They land in `<out>/parts/` and the `parts` block of fields.json. A footprint with no model gets a 1 mm box from its courtyard; test points and board-only footprints stay bare copper. A failed conversion never fails the solve: it is logged and the part becomes a box.++On a Fusion board (`.brd`) the parts are found by name, since Fusion binds its 3D packages by cloud urn: each element's MPN, then its deviceset, then its package, as `<name>.step` in the `--models-dir` folders, then in `3d/` or `3dmodels/` beside the board. AI Flow's `fusion library` writes the checked Z-up models to `<run>/3d/<MPN>.step`, so a solve of `<run>/board-live.brd` finds them with no flag. The conversion needs `step2glb` on the PATH (a declared dependency since 0.6.1; `adom-wiki pkg install adom/adom-step2glb`); without it every model is logged as a failure and the parts stay bare.++```+adom-fields analyze --board run/board-2.kicad_pcb --spec spec.json --out fields --models-dir kicad/3d # a snapshot outside the project folder+adom-fields parts --board board.kicad_pcb --fields fields # add or refresh the parts of an existing solve+adom-fields ui view --parts ghost|solid|off|auto # auto: see-through on every field but signals+adom-fields analyze ... --no-parts # skip them (no STEP service needed)+```++`ghost` draws the bodies see-through so the field glows through them; `solid` is the plain assembly; the header's cube button cycles them. The hot-part labels ride on top of their part.++## Calmer motion (0.5.0)++Every camera move and the idle sway run at half the 0.4 speed (the sway period is about 40 s), because the flow plays the clip ten times faster. `tour --pause-ms` defaults to 20000 so a beat settles before the next. For frame-exact video, the page exposes `window.fieldsCapture.begin(1/30)` and `.step()` (one frame of page time per call; the live loop stops and the orbit pivot marker hides); `ui view --camera zoom --at x,y` flies to any board point.++## In the AI Flow video++Record the pup window (Adom Bridge `desktop_record_window_start` on it) while `adom-fields tour` runs: the clip is the fields step, the toasts are the captions, the AI's own analysis on the board in 3D.++## Flow, river and the exploded stack (0.7.0)++`analyze` also writes `flow.bin` (the signed current, the voltage and the owning net of every cell) and `fields.json` `flow` (each net's rail, sense, drop, terminals as source or sink, and the current down each barrel). Two views use it:++- `ui view --quantity flow`: the current as charge, streaks whose speed and glow follow |J|, dropping through the barrels by their solved share. `--explode 1` pulls the layers apart (0 puts them back); the camera backs off to keep the stack in frame.+- `ui view --quantity river`: each net lifted to its voltage, water over it, loads as waterfalls, sources as fountains, a switching node as a slowed tide. Signs give each net's voltage and drop; the readout gives the volts under the cursor.+- `--speed 0.1..4` slows or quickens both. The badge states the scale and the exaggeration; say it when you narrate.++Tell the solve the voltages it cannot read from names, in the spec:++```json+"voltages": {"VIN": 12, "VOUT": 5},+"sources": {"VOUT": ["L1"], "SW": ["U1"]},+"switching": {"SW": {"highV": 12, "lowV": 0, "freqHz": 500000}}+```++Names give GND/PGND/AGND/VSS 0, 3V3 3.3, +12V 12, 5V_AUX 5; SW, LX and PH are switching nodes between the highest rail and 0 unless the spec says otherwise. Default sense: a supply flows from its connector to its parts, a ground from its parts back to its connector; `sources` flips a net whose feed is a part (a regulator or inductor output). A net with no rail stays at its drop and says "rail not given". The voltages are DC: the rail plus the solved IR drop. Copper the pinned terminal cannot reach (a floating island) sits still at the rail.++Developing the page: `ADOM_FIELDS_UI_DIR=<repo>/src/ui adom-fields serve ...` serves index.html, app.js and flow.js from disk, so a reload shows a change without a rebuild.++## Energy and light++**Energy** (`ui view --quantity energy --explode 0.6`) shows where the energy really travels: pink particles in the board material between the copper layers, along the Poynting vector S = E × H. Between two layers a gap h apart, E is (V_top − V_bottom)/h and the two current sheets give H, so S = ½ (V_top − V_bottom)/h · (K_top − K_bottom) in W/mm²; over a supply and its return that integrates to V × I. Pink rising into a part is that part taking its energy. The blue dots are the electrons in the copper at their real drift speed (J / n e, 0.073 mm/s per A/mm²), moving against the current. DC, inside the board only: part of the energy travels in the air around it.++**Light** (`ui view --quantity light`) colours each piece of copper by how fast a change travels in its field, as a % of the speed of light: 1/√εr_eff, all FR4 between planes (about 48 %), Hammerstad's εr_eff for a trace over a plane (wider is slower), mostly air with no plane under it. A switch-on front sweeps out from each fed net's source, and each load is tagged with its arrival time in picoseconds (the fastest path, the sum of length over speed along the way). εr comes from the spec's signals epsilonR, else 4.3. A switching node's DC average (`switching.SW.meanV`) sets its level in the energy view.++## Explained out loud (0.7.1)++Every view can explain itself by voice: the speaker button in the header, `adom-fields ui explain [--quantity q]` (`--stop` silences it), or automatically. The left panel's "Explain each view out loud" sets the rule per viewer: **First time** (the default: each kind of view speaks once, the first time this viewer opens it, so a newcomer hears what they are looking at), **Always**, or **On ask**. The page writes each explanation from a template with this board's own numbers (the peak density and its net, the hottest part, the rails, the electrons' speed, the arrival times), so no AI tokens are spent; the server voices it with adom-tts and keeps the mp3 under `<fields>/narration/`, named by the text's hash, so it is voiced once. A one-line subtitle follows the voice, sentence by sentence, sitting above the legend and readout so neither is covered. Without adom-tts, a toast says so.++## The energy cycle (0.7.2)++`ui view --quantity cycle`: one switching period of a buck converter, slowed about a million times (the meter states the factor). Pink energy packets run from the input capacitors through the switch into the inductor while the switch is on, and from the inductor to the output capacitors and the load all the time; blue particles ride the inductor's magnetic field lines, brightening and swelling as its current and stored energy grow, collapsing on the off-time; red arches over each capacitor brighten as its stored energy rises; orange heat leaves the switch and the inductor. A meter (bottom left, click its title to fold) gives the switch state, the inductor current waveform with a cursor, each store's voltage or current and energy, the heat and the energy delivered per cycle.++The model is the ideal continuous-conduction buck solved exactly: D = Vout/Vin, inductor ripple ΔI = (Vin − Vout)·D·T/L, the capacitor charge integrated over the period. It finds the converter from the solve: the switching node, the inductor on it (L*), the switch (the node's source), the input rail (the switch's highest rail), the output (the inductor's other net), the input and output capacitors (C* between each rail and ground). L and C come from the parts' values on the board (KiCad Value, Fusion element value; `fields.json` `partValues`), fsw from the spec's `switching.freqHz`, the load from the output net's amps, the heat from the hot parts' watts. A board it cannot model says why.++## The silkscreen (0.7.2)++`analyze` exports the board's F.SilkS and B.SilkS with kicad-cli as SVG (`silk-front.svg`, `silk-back.svg`, fields.json `silk`); `adom-fields silk --board <pcb> --fields <dir>` adds them to an existing solve. The page draws each once into a texture on one plane per side (two quads, no geometry), riding its copper layer and the exploded stack, each side shown only from its own side of the board, hidden in the river. The header's T button or `ui view --silk on|off` toggles it. `--no-silk` skips it; a Fusion board has none yet.++## Charge: the board as capacitors (0.7.3)++`ui view --quantity charge` (the Charge button pulls the layers apart): wherever copper at different voltages faces copper across the board material, it is a capacitor. Each face holds σ = ε0·εr·ΔV/h, red on the higher voltage, blue on the lower, brighter for more charge; particles cross the gap from the + face to the − face along the field; a switching node's copper charges and empties with its tide every cycle (the stray capacitance switching noise couples through). A panel compares the copper's own capacitance between net pairs (pF, pC) with the capacitor parts (µF, µC, the energy ½CV²); the readout gives the charge per mm² and the field under the cursor. Parallel plates only: fringing and the air above are not counted.++## Magnetic: the field of every current (0.7.4)++`ui view --quantity magnetic [--probe 2]`: the Biot–Savart field of the solved currents (every copper cell's current summed onto a half-millimetre grid of current elements, plus the current down each via). Glowing blue field lines loop around the current paths, brightest where the field is strongest, their dashes running the way the field points; a sheet at `--probe` mm above the top copper (the slider beside the view buttons, 0.5 to 15 mm) glows where the field is strong, with a white ring at every tenfold step, the way a near-field probe would see it. The readout gives µT, the share of Earth's field (about 50 µT) and H in A/m. DC: the switching field comes with the EMC loop views.++## The ground view (0.7.6)++`ui view --quantity ground`: the ground copper lifted by its solved millivolts (rings every step), each part's ground pin tagged with its offset, dashed arcs for the possible loops through the ground connectors' cables, floating ground islands in red, and the stitching fence: a ring per ground via (λ/40 reach) with the uncovered stretches of the edge in red.++## Also in this area++- **Field views frame themselves** (0.8.6): entering Energy (stack open 0.8, parts off, low front camera), Flow (0.6, parts ghosted, low side) or Magnetic (parts off, low side) sets the stack, parts and camera so the field shows; values the command sets win, `ui view --keep-camera` keeps everything as it is, and leaving for another view restores what was there. Camera presets: top, iso, front, low, bottom, fit, zoom.
skills/adom-fields/SKILL.md+23−10@@ -26,13 +26,13 @@ Save the board with its zones filled first (the filled polygons are the copper). ``` - `loads`: each net's current (`maxDropMv`, `maxRiseC`, `draws`, explicit `terminals` optional). `hot`: each dissipating part's watts (`tabNet` for an exposed pad, `tabPad`, `tjMaxC`, `thetaJcKPerW`). Without `hot` the temperature is only the copper's own loss, and the output says so.-- A few seconds for a small board, one to five minutes for a dense 65 × 75 mm four-layer one at the default 0.2 mm cell. Every other key (stackup, solids, package cooling, fans, transients, terminals, Fusion boards): [spec.md](spec.md).+- A few seconds for a small board, one to five minutes for a dense 65 × 75 mm four-layer one at the default 0.2 mm cell. Every other key (stackup, solids, package cooling, fans, transients, terminals, Fusion boards): the `adom-fields-spec` skill. ## Read the result - **The printed lines** (`OK:` then `Hint:`): peak density and rises, the top findings, the review, the inputs it had to assume, the first fix-plan steps, then **`Not run:` lines**, one per optional module this board may need, each with the reason found on this board and what the module adds. - **`fields/fields.json`** (lean, made for you to read): `nets` (peak A/mm² and where), `chips` (each hot part's rise still and moving air, and where its heat goes), `heat`, `issues`, `fixPlan`, `review` (the numbers behind the findings), `review.inputs` (each assumed input with the datasheet field that replaces it and `specPatch` to fill), `modules` (what ran, what did not and why it may matter).-- **`issues`**: `severity`, `kind`, `what`, `at`, `net`, `reference`, `fix`, and an `action` to carry out (`widen`, `add-vias`, `move`, `add-part`, `add-copper`, `reroute`, `review`). Three or more low findings of one kind come as one finding whose action is `{"type": "group", "items": [...]}` with every item's own action; per-via barrel warnings come as one per net. Every kind and its module: [review.md](review.md).+- **`issues`**: `severity`, `kind`, `what`, `at`, `net`, `reference`, `fix`, and an `action` to carry out (`widen`, `add-vias`, `move`, `add-part`, `add-copper`, `reroute`, `review`). Three or more low findings of one kind come as one finding whose action is `{"type": "group", "items": [...]}` with every item's own action; per-via barrel warnings come as one per net. Every kind and its module: the `adom-fields-review` skill. - `detail.json` holds the bulk the app draws (river data, per-via currents, mode grids, PDN curves, parts): you never need to read it. ## Optional modules: when to turn them on@@ -41,12 +41,12 @@ The core always runs: current, heat, necks and ampacity, hot tabs and thermal vi | Module | Turn it on when | It adds | On by itself when the spec has | |---|---|---|---|-| `emc` | a switching converter, clocks or cables, and the product will be FCC/CISPR tested | hot-loop and cable (common-mode) radiated emissions, conducted emissions, return paths and stitching, a compliance prediction with the cheapest fixes by dB and a bench plan ([emc.md](emc.md)) | `emcLimit`, `emcLimits`, `cables`, `measurements` |-| `esd` | a connector faces the outside world (user cable, hot-plugged lead) | a TVS within 3 mm and a filter for each outside-facing pin; list those connectors in `external` ([emc.md](emc.md)) | `external` |-| `pdn` | a rail feeds an MCU, FPGA, RF chip or anything with fast current edges; a converter input; a connector-fed rail | each rail's impedance against its target, the cheapest decoupling set, hot-plug overshoot, input-filter stability ([pdn.md](pdn.md)) | `pdn` |-| `si` | differential pairs (USB, Ethernet, LVDS, MIPI), clocks or fast buses, traces over about 50 mm | trace impedance from a 2-D field solve, TDR and overshoot with the series resistor, length matching, via stubs, reference planes ([si.md](si.md)) | `impedance`, `tdr`, `lengthGroups` |-| `noise` | a switch node or clock near quiet or sensitive nets; power pours over ground | plane-cavity resonances against the harmonics, crosstalk into quiet nets ([noise-rf.md](noise-rf.md)) | `crosstalkMv`, `victimBudgetsMv` |-| `rf` | a receiver: antenna, oscillator, mixer, IF | LO leak out of the antenna (FCC 15.111), stage isolation, in-band tones ([noise-rf.md](noise-rf.md)) | `rf`, `bands`, `sensitiveNets` |+| `emc` | a switching converter, clocks or cables, and the product will be FCC/CISPR tested | hot-loop and cable (common-mode) radiated emissions, conducted emissions, return paths and stitching, a compliance prediction with the cheapest fixes by dB and a bench plan (the `adom-fields-emc` skill) | `emcLimit`, `emcLimits`, `cables`, `measurements` |+| `esd` | a connector faces the outside world (user cable, hot-plugged lead) | a TVS within 3 mm and a filter for each outside-facing pin; list those connectors in `external` (the `adom-fields-emc` skill) | `external` |+| `pdn` | a rail feeds an MCU, FPGA, RF chip or anything with fast current edges; a converter input; a connector-fed rail | each rail's impedance against its target, the cheapest decoupling set, hot-plug overshoot, input-filter stability (the `adom-fields-pdn` skill) | `pdn` |+| `si` | differential pairs (USB, Ethernet, LVDS, MIPI), clocks or fast buses, traces over about 50 mm | trace impedance from a 2-D field solve, TDR and overshoot with the series resistor, length matching, via stubs, reference planes (the `adom-fields-si` skill) | `impedance`, `tdr`, `lengthGroups` |+| `noise` | a switch node or clock near quiet or sensitive nets; power pours over ground | plane-cavity resonances against the harmonics, crosstalk into quiet nets (the `adom-fields-noise-rf` skill) | `crosstalkMv`, `victimBudgetsMv` |+| `rf` | a receiver: antenna, oscillator, mixer, IF | LO leak out of the antenna (FCC 15.111), stage isolation, in-band tones (the `adom-fields-noise-rf` skill) | `rf`, `bands`, `sensitiveNets` | How to decide: - Run the core first. Then read the `Not run:` lines: they name what on this board points to each module (the converter and its frequency, the connectors, the rails and their chips, the pairs, the RF nets). If the reason applies to this product, rerun with that module.@@ -56,7 +56,7 @@ How to decide: ## Fix it 1. Work down `fixPlan` (worst first, concrete edits before reviews). Fill `review.inputs.specPatch` from the parts' datasheets when it lists inputs that matter.-2. Copper edits can be applied and proven for you: `adom-fields verify --board b.kicad_pcb --spec s.json --step 1,3 --refill --out verify` adds the vias and widens the traces on a copy, has KiCad refill and DRC it, re-solves and reports what moved. Part, move and reroute steps are yours to make in the layout; then `analyze` again. [verify-report.md](verify-report.md)+2. Copper edits can be applied and proven for you: `adom-fields verify --board b.kicad_pcb --spec s.json --step 1,3 --refill --out verify` adds the vias and widens the traces on a copy, has KiCad refill and DRC it, re-solves and reports what moved. Part, move and reroute steps are yours to make in the layout; then `analyze` again. the `adom-fields-verify` skill 3. `adom-fields probe --fields fields --from J1.1 --to U1.3` reads the IR drop between two pads without re-solving. 4. `adom-fields report --fields fields [--safety <adom-safety out>] [--mechanics <adom-mechanics out>]` writes a readiness report: each area ready, needs work, blocked or not checked. @@ -68,7 +68,20 @@ adom-fields ui view --quantity current|heat|temperature|emc|pdn|... [--net X] [- adom-fields tour # the walkthrough, for a video ``` -The views (flow, river, energy, cycle, charge, magnetic, ground, noise, PDN) are for people and videos; they add no findings. Everything about them: [views.md](views.md).+The views (flow, river, energy, cycle, charge, magnetic, ground, noise, PDN) are for people and videos; they add no findings. Everything about them: the `adom-fields-views` skill.++## The sub-skills (load when the topic comes up)++| Skill | For |+|---|---|+| `adom-fields-review` | every finding kind and its module, grouped findings, the fix plan, the IR-drop probe |+| `adom-fields-spec` | every spec key: terminals, hot parts, stackup, solids, package cooling, fans, transients, Fusion boards |+| `adom-fields-emc` | `--with emc` and `--with esd`: emissions, compliance, bench calibration, connector protection |+| `adom-fields-pdn` | `--with pdn`: rail impedance, decoupling, hot-plug, input-filter stability |+| `adom-fields-si` | `--with si`: trace impedance, TDR, termination, length matching, via stubs |+| `adom-fields-noise-rf` | `--with noise` and `--with rf`: cavities, crosstalk, receivers |+| `adom-fields-verify` | `verify`, `report`, and the inputs assumed |+| `adom-fields-views` | `serve`, `ui`, `tour`: the 3D app and its views | ## Honest limits
uninstall.sh+3−1@@ -1,2 +1,4 @@ #!/bin/bash-rm -f "$HOME/.local/bin/adom-fields"; rm -rf "$HOME/.claude/skills/adom-fields"; echo "OK: adom-fields removed"+rm -f "$HOME/.local/bin/adom-fields"+for n in adom-fields adom-fields-views adom-fields-spec adom-fields-review adom-fields-emc adom-fields-pdn adom-fields-si adom-fields-noise-rf adom-fields-verify; do rm -rf "$HOME/.claude/skills/$n" "$HOME/.codex/skills/$n"; done+echo "OK: adom-fields removed"