← Commit history
Cargo.lock+10−10
@@ -4,7 +4,7 @@ version = 4  [[package]] name = "adom-aiflow"-version = "0.1.45"+version = "0.1.46" dependencies = [  "aiflow-analyze",  "aiflow-board",@@ -24,7 +24,7 @@ dependencies = [  [[package]] name = "aiflow-analyze"-version = "0.1.45"+version = "0.1.46" dependencies = [  "serde",  "serde_json",@@ -33,7 +33,7 @@ dependencies = [  [[package]] name = "aiflow-board"-version = "0.1.45"+version = "0.1.46" dependencies = [  "serde",  "serde_json",@@ -41,7 +41,7 @@ dependencies = [  [[package]] name = "aiflow-bridge"-version = "0.1.45"+version = "0.1.46" dependencies = [  "aiflow-board",  "serde",@@ -50,7 +50,7 @@ dependencies = [  [[package]] name = "aiflow-copper"-version = "0.1.45"+version = "0.1.46" dependencies = [  "aiflow-board",  "aiflow-grid",@@ -60,7 +60,7 @@ dependencies = [  [[package]] name = "aiflow-grid"-version = "0.1.45"+version = "0.1.46" dependencies = [  "aiflow-board",  "serde",@@ -69,7 +69,7 @@ dependencies = [  [[package]] name = "aiflow-place"-version = "0.1.45"+version = "0.1.46" dependencies = [  "aiflow-board",  "serde",@@ -78,7 +78,7 @@ dependencies = [  [[package]] name = "aiflow-pours"-version = "0.1.45"+version = "0.1.46" dependencies = [  "aiflow-board",  "aiflow-copper",@@ -88,7 +88,7 @@ dependencies = [  [[package]] name = "aiflow-router"-version = "0.1.45"+version = "0.1.46" dependencies = [  "aiflow-board",  "aiflow-grid",@@ -98,7 +98,7 @@ dependencies = [  [[package]] name = "aiflow-run"-version = "0.1.45"+version = "0.1.46" dependencies = [  "serde",  "serde_json",
Cargo.toml+1−1
@@ -14,7 +14,7 @@ members = [ ]  [workspace.package]-version = "0.1.45"+version = "0.1.46" edition = "2021" license = "MIT" repository = "https://wiki.adom.inc/adom/adom-aiflow"
bin/adom-aiflow
⋯ 1 unchanged line ⋯
crates/adom-aiflow/src/checks.rs+1−1
@@ -269,7 +269,7 @@ pub fn molecule_check(b: &Board, spec: &Value, before: Option<&Board>) -> Findin             let inside = geom::point_in_poly(fp.x, fp.y, &b.outline);             let n = b.outline.len();             let d = (0..n).map(|k| { let (a, c) = (b.outline[k], b.outline[(k + 1) % n]); geom::seg_distance(fp.x, fp.y, a.0, a.1, c.0, c.1) }).fold(f64::INFINITY, f64::min);-            if !inside || d < margin - 0.01 {+            if !inside || d < margin - 0.02 {   // 0.02: rounded corners are read as chords, a hair inside the true arc                 f.error(format!("{r} centre is {}{d:.2} mm from the board edge; the molecule edge margin is {margin} mm", if inside { "" } else { "OUTSIDE the outline, " }), &format!("Keep every machine pin and contact centre {margin} mm inside the outline (spec.molecule.edgeMarginMm): grow the outline or move the part inward on the grid."));             }         }
docs/release-0.1.46.mdadded+8
@@ -0,0 +1,8 @@+# AI Flow 0.1.46++From John's review of the buck molecule (2026-10-01):++- **Schematics people can read.** aiflow-schematic-to-board no longer says "pin stubs and net labels, no wires between parts", which produced a grid of labelled parts. It now asks for a datasheet-style sheet (flow left to right, supplies up, GND down, real wires, sheet-local power symbols, junction dots, section titles), proven equal to netlist.json net by net, rendered and looked at, plus ten generator mechanics learned from the cleanup.+- **Adom-style IC symbols by default.** Every IC's symbol comes from adom-symbol, with the white 3D-chip outline and lasered name in the body; offer it to the IC's wiki page owner when the page lacks it.+- **Rounded molecule corners.** aiflow-molecule suggests an outline with corners of radius = the edge margin, centred on the corner pins, instead of 45 degree chamfers; the molecule edge-margin check tolerates the chords arcs are read as.+- **New skill: aiflow-process-video.** What to capture during the run (the prompt being typed, the token cost, the final GLB), how to compose (motion in every scene, narration that matches the frame, smooth frame-by-frame 3D instead of a filmed KiCad viewer, only this board's parts), per-clip review in video-post's storyboard before assembly, and publishing on the project page with a how-it-was-made sub-readme. The board flow's intake and finish steps now prompt for the prompt clip and the cost.
flows/board.json+3−3
@@ -7,7 +7,7 @@       "name": "intake",       "who": "ai",       "does": "read the board and the spec, write the spec from the schematic if it is missing, plan; offer the optional Hydrogen progress widget (default off; enable when requested), reusing saved milestone images without extra AI calls",-      "record": "nothing on screen yet: the clip is the board opening on the test box (capture open) and the spec being read",+      "record": "FIRST, the prompt: film the human's prompt being typed into the AI's input on the screen where it is typed (or, if it was typed before the run, save its exact text in run.json for a labelled re-enactment). The prompt states the design goal (part, input, output, current, molecule), never 'copy this video'. Then the board opening on the test box (capture open) and the spec being read. Skill aiflow-process-video.",       "workflow": [         "After EVERY board or model update, refresh and verify BOTH the native 2D editor and its linked 3D viewer before showing/reporting completion. Check exact saved board revision and actual rendered changes in both windows. Reload cached models; if reopening is required preserve unsaved user work, close only task-owned stale windows and retain one current editor/viewer pair. Never overwrite a newer disk edit from a stale editor. Use native bridge controls and keep foreground preferences."       ]@@ -208,7 +208,7 @@         "finish",         "deliver"       ],-      "record": "the finish line passing (0 unconnected, 0 new errors), then the cut video and the delivery message"+      "record": "the finish line passing (0 unconnected, 0 new errors), then the cut video and the delivery message. Before delivering, record the run's cost for the process video: model calls and tokens (input, cache reads, cache writes, output) from the AI's own session logs inside the run's clock window, sub-agents included; plan-limit percentages are not a cost. Then build the process video per skill aiflow-process-video: every scene loaded into video-post's storyboard for per-clip review before assembly."     }   ],   "returns": "any step may send the AI back to any earlier step: step <name> --back --why \"...\"",@@ -240,4 +240,4 @@   ],   "clips": "every `step <name>` stops the previous step's clip and starts a new window recording tagged with the step, when the board is open on a test box; run.json captures[] carries one entry per clip with its step, start, stop and file, and deliver lists them; the final video is cut from these clips, one segment per step, so two engines' videos line up step for step; a return (step <name> --back --why) is a new visit and gets its own clip, tagged <step>-<visit> with the reason, so the rework is on camera and the final cut can show the loop",   "screenshots": "every step visit gets two background screenshots of the editor window, at its start and at its end (shot-<step>-<visit>-start.png, shot-<step>-<visit>-end.png), logged as artifacts, so a run's own README has a picture for every step without anyone taking one"-}\ No newline at end of file+}
package.json+1−1
@@ -1,7 +1,7 @@ {   "slug": "adom-aiflow",   "type": "app",-  "version": "0.1.45",+  "version": "0.1.46",   "title": "AI Flow",   "description": "Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board. One Rust binary with a crate per step (placement helpers, a grid router with Kelvin taps, pours with keepouts, KiCad's DRC gate, live landing through the KiCad Bridge, copper measurement, current and thermal analysis) and a finish line that refuses an unfinished board. Every command answers with hints for the AI; every turn, its thinking time and every rework loop go into run.jsonl, so Claude, Codex and any other engine are compared on the same flow. KiCad today; Altium, Fusion and Adom's own web apps next.",   "summary": "Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board. The AI thinks its way from placement through routing, pours, current and thermal analysis to a delivered video; the binary does the fast, deterministic parts of every step, hands back hints, and keeps a ledger of every turn, every return to an earlier step, and the clock from the prompt to done.",
page.json+1−1
@@ -1,7 +1,7 @@ {   "slug": "adom-aiflow",   "type": "app",-  "version": "0.1.45",+  "version": "0.1.46",   "title": "AI Flow",   "description": "Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board. One Rust binary with a crate per step (placement helpers, a grid router with Kelvin taps, pours with keepouts, KiCad's DRC gate, live landing through the KiCad Bridge, copper measurement, current and thermal analysis) and a finish line that refuses an unfinished board. Every command answers with hints for the AI; every turn, its thinking time and every rework loop go into run.jsonl, so Claude, Codex and any other engine are compared on the same flow. KiCad today; Altium, Fusion and Adom's own web apps next.",   "summary": "Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board. The AI thinks its way from placement through routing, pours, current and thermal analysis to a delivered video; the binary does the fast, deterministic parts of every step, hands back hints, and keeps a ledger of every turn, every return to an earlier step, and the clock from the prompt to done.",
skills/aiflow-molecule/SKILL.md+2−2
@@ -18,7 +18,7 @@ A molecule is a small board whose machine pins seat it on a scaffold and whose c | Contacts | footprint `MachineContactMedium`: 1.3 mm pad, 0.78 mm drill, one per signal the Control Panel wires to | | Library | the Adom KiCad Library 1.2.3 (KiCad plugin manager); copy the footprints and their STEP models into the project (`lib/Molecule.pretty`, `3d/`) so the project travels | | Markers | MP1 to MP4 are the anchoring markers the step2glb molecule conversion reads; keep those exact references and the library's 3D models on them |-| Outline | pin span plus an edge margin all round (24 x 16 mm span + 2 mm = 28 x 20 mm here) |+| Outline | pin span plus an edge margin all round (24 x 16 mm span + 2 mm = 28 x 20 mm here), with **rounded corners**: an arc of radius = the edge margin, centred on each corner pin, so the edge stays the same distance from the pin all the way round (2 mm here; the 1.6 mm pin pad then clears the edge by 1.2 mm). Suggest this by default; never 45 degree chamfers, which read as unfinished. | | Scaffold fit | medium-pin molecules mount on a LrgMed user scaffold: a 4 mm medium contact grid, with its large pins on a 32 mm base grid. Keep the pin span on 4 mm multiples so every corner pin lands on a scaffold hole |  Put the interface in netlist.json as `fixed` positions (aiflow-schematic-to-board) and in the aiflow spec as `fixedRefs` with a `fixedRefsNote`, so placement never moves them.@@ -48,7 +48,7 @@ The DRC gate uses the board's own `.kicad_dru`, so the fab's limits must be in i  - MP1 to MP4 present, references exact, `MachinePinMediumShort`, at the four corners of the span, all on GND. - Every contact is `MachineContactMedium`, on the 2 mm grid from MP1.-- Pin span on 4 mm multiples; outline = span + margin; board origin on MP1.+- Pin span on 4 mm multiples; outline = span + margin with rounded corners (radius = margin, centred on the corner pins); board origin on MP1. - All interface parts locked and in `fixedRefs`. - Every pin and contact has its STEP model bound (`adom-aiflow models`). 
skills/aiflow-process-video/SKILL.mdadded+67
@@ -0,0 +1,67 @@+---+name: aiflow-process-video+description: >+  Make the "how this board was built" video for an adom-aiflow project: what to capture during the run+  so the video can be made at all (the prompt being typed, the token cost, smooth 3D), how to compose+  it (motion in every scene, narration that matches the frame, per-clip review in video-post before+  assembly), and where it lives (the project page README, explained in a sub-readme). Written from John's+  review of the first one (buck molecule, 2026-10-01). Trigger words: process video, build video, video of+  the whole process, make a video of the board, narrated video, prompt clip, token cost clip, clip review,+  storyboard, video-post, voice-over, re-cut the video, choppy 3D, video feedback.+---++# The process video++The video tells one board's story start to finish: the prompt, the circuit, the simulation, the layout,+the analysis and the rework it caused, the silkscreen, the part models, the board on its scaffold, and+what it cost. It is made from footage the run captured, so most of this skill is about **capturing the+right things while the run happens**. You cannot film the past.++## Capture during the run (do this, or the video can't be made)++| moment | capture | why |+|---|---|---|+| intake, before any work | **the prompt being typed** into the AI's input, recorded on the screen where it is typed, and the prompt text saved in `run.json` | the video opens on the human asking. The prompt states the design goal ("a 12 V to 5 V, 1 A buck converter using the TI TPS54202"), never "copy this video" or "reproduce X". If the typing was not filmed, re-enact it from the saved text and say so in the sub-readme |+| every step | the step clip (`capture start` / `stop`), as the board flow already does | the body of the video |+| simulation | the dashboard run itself (adom-spice in a background pup window), not screenshots | three engines agreeing is a scene |+| finish | **token usage per run**: input, cache reads, cache writes, output, and the number of model calls, from the AI's own session logs within the run's clock window (prompt time to delivery), sub-agents included | the cost scene. aiflow's `usage` block only records plan-limit percentages, which are not a cost |+| finish | the molecule GLB with the final models (etched, coloured, datasheet heights) | the smooth 3D shots are rendered from it, not filmed |++## Compose++- **Motion in every scene.** No held still frames: an eased camera move (crop, push-in, pan) over every+  recording and every still, and long recordings sped up to their action. A scene is exactly as long as its+  narration plus a short lead-in and tail.+- **Say only what the frame shows, while it shows it.** If the narration names a detail ("the LED's marking+  is on its side"), the camera is on that detail at that moment, from the side where it is visible. Check+  each named detail against the frames before rendering the voice.+- **Only this board's story.** Every part, page or tool on screen belongs to this board: show the parts that are on it, labelled with their references (L1, C1, D1...). Work done along the way for other parts (a library pass, other pages) is not in this video.+- **3D must be smooth.** Never use a filmed KiCad 3D-viewer tour for a hero shot: it steps between view+  commands and the recorder only writes frames on change, so it is choppy. Render the board's own GLB frame+  by frame in a headless browser (eased orbit, studio light, soft shadow, no cursor, no browser chrome) at+  30 fps or more. Close-ups aim at a part by raycasting its board position onto the surface.+- **No cursor, no browser chrome, no pup window label** in any frame. Prefer headless renders; crop when a+  recording must be used.+- **The prompt clip** is its own scene: the prompt typed character by character in a terminal-style input,+  the design goal only.+- **The cost scene** ends the video: tokens per run (output, input, cache reads), model calls, wall-clock+  time from prompt to finished board, and a plain note on how they were counted. No LTspice or PSpice run+  times anywhere (licence).+- Narration: adom-tts, one file per scene, part numbers and units written out the way they are spoken.+  Subtitles in the written form, brand fonts (gang-takes helpers in adom/adom-video-post), wrapped.++## Review every clip before assembling++Load every scene as its own clip into **video-post's storyboard** (`adom-video-post manifest add` with a+title, a one-line description of what the clip should show, and its narration text, then+`adom-video-post storyboard <manifest>`), give the human the link, and wait for per-clip feedback. Fix+the clips they call out, re-render only those, and assemble only when every clip is approved. Never hand+over a finished video that skipped this.++## Publish++On the project's own wiki page: the player on the main README, and a sub-readme+(`docs/process-video.md`) that explains how it was made: each scene's source clips, the full voice-over+script, the tools. **Never a separate wiki page for the video**: that is wiki bloat. The web copy stays+under 15 MB with a keyframe every second; the 1080p copy is a download link (the wiki refuses files over+about 100 MB).
skills/aiflow-schematic-to-board/SKILL.md+15−1
@@ -37,7 +37,21 @@ The KiCad Bridge has no "update PCB from schematic" verb. So do not draw a schem Write the `.kicad_sch` directly as s-expressions (a small reader/writer, `sexp.py`, is enough).  - **Embed the symbols** in `lib_symbols`. A symbol that `extends` another must be flattened (copy the base body, merge the child's properties, rename the unit sub-symbols); KiCad will not resolve `extends` inside a schematic.-- **Pin stubs and labels.** Every connected pin gets a short wire stub and a net label at its end; no hand-drawn wires between parts. The schematic's netlist then equals netlist.json by construction.+- **A schematic people can read: prettiness matters.** A grid of parts joined only by net labels is correct and unreadable, and it is the first thing a reviewer judges the design by. Lay it out as a datasheet would: signal and power flow left to right (input connector and input caps, the IC with its bootstrap, the switch node and inductor, the output caps), supplies up and GND down, the feedback divider and Cff under the output, the enable divider next to EN, then indicator, monitor, test points and connectors in a tidy block. Real wires for the power path and local connections, power symbols (VIN, the output rail, GND) where that is the convention, net labels only where a wire would cross the sheet, junction dots, every coordinate on the 1.27 mm grid, no wire through a symbol or text, no overlapping text, short section titles (Input, Converter, Output and feedback, Enable, Indicator and monitor, Connectors). Generate it from a layout description in the generator, never by hand-placing coordinates.+- **IC symbols in the Adom style, by default.** Every IC (regulators, MCUs, drivers; anything with a package worth recognising) gets its symbol from **adom-symbol**, whose `render` composites the white 3D-chip outline and lasered part name into the middle of the body, and adom-lbr carries it into the Fusion/EAGLE library. Do not use KiCad's generic box for an IC. Pins grouped by function (inputs and enable one side, outputs and switch nodes the other, GND at the bottom), names and numbers exactly as the footprint. When the IC's wiki component page lacks this symbol, say so and offer it to the page owner.+- **Prove it equals the netlist.** Export the schematic's netlist and compare it with netlist.json net by net (same refs, pins, net names); run ERC. A pretty schematic that changes one connection is worse than an ugly one.+- **Generator mechanics that make it clean** (from the buck molecule cleanup, 2026-10-01; reference generator: john/buck-12v5v-molecule `kicad/gen_schematic_v2.py`):+  1. Lay out in 100 mil units, coordinates in multiples of 0.5, converted to mm in one function, so everything lands on the 50 mil grid.+  2. Split a wire automatically wherever a pin or another wire end lands on it, and add a junction dot wherever three or more connections meet.+  3. KiCad's standard power symbols rename nets (power symbols outrank labels: "/GND" becomes "GND"). To keep the netlist.json names, use sheet-local power symbols (`(power local)`) from a project library listed in sym-lib-table.+  4. Every named net needs a label or power symbol carrying that name, or KiCad invents "Net-(R1-Pad2)".+  5. On a symbol rotated 90 degrees, give its value and reference text a 90 degree angle and swap the justification; KiCad mirrors it otherwise and text lands on the body.+  6. Keep an approximate box for every text, symbol body and section frame, and have the generator report overlaps, wires through text or bodies, frames cutting text, dangling wire ends and off-grid points. Ship only when it reports none.+  7. Shunt parts hang off a straight horizontal rail (wire down, the part, wire down, GND), about 6.5 units apart so a long value never reaches the next part; route feedback under everything, at an x clear of the BOOT jog.+  8. Snap symbols made by tools (adom-symbol) onto the grid before use, and keep their footprint filter and keywords so the swap changes nothing else.+  9. Compare the run-time board check against the schematic for the OLD and NEW sheets with each other, not against zero: pre-existing items (net-name prefixes, missing MPN fields) are not regressions.+  10. Pull a wiki clone before copying files into it: `repo pull` overwrites local edits silently.+- **Render it and look**, full sheet and each section zoomed, before the board step; suggest a cleanup pass to the human whenever the sheet does not read at a glance. - **PWR_FLAG** on each rail that arrives from off-board (VIN, GND), or ERC reports "power input not driven". - Deterministic UUIDs (`uuid5` of design + ref + pin), 1.27 mm grid snapping, and a design note read from calcs.json.