← All Pull Requests

Make native library assembly and component tours explicit early steps #9

Merged opened by John Lauer 2026-09-16

The early flow mentioned library work and a tour in prose, but still left libraries in the future-steps list and told the model step there was nothing to film. Make the review sequence explicit: components → libraries → models → library-tour → placement.

The new AI-owned visits require native symbol-to-pad/model binding, selected plain/marked variant parity, and separate detailed and approximately five-second overview clips. The final overview shares the overall 120-second limit. Global reusable CAD remains on component pages; board mappings remain on the board page. No automated geometry qualification or released compose integration is claimed.

Rebuilt the isolated release binary and passed the real 149-reference ESC integration test, including the new plan order, review-note preservation, marking preference, stale-source invalidation and malformed-register preservation. This additive flow/docs/test patch requires PR #6, and coexists with widget client PR #8. Issue #16 still blocks wiring into the complete released composer; the installed production binary is untouched.

Diff Skip to comments

--- a/flows/board.json+++ b/flows/board.json@@ -1,162 +1,208 @@ {   "name": "board",   "title": "The board flow: parts placement to a qualified board",-  "scope": "Starts at the 3D models and parts placement on a board whose schematic, libraries and part choices already exist. Ends when the board is 100 percent routed, DRC-clean, poured, its copper measured, its current and thermal analyses passed, its nets and its 3D view walked through on camera, and the AI has delivered the video.",+  "scope": "Starts with component identity, reusable CAD review and native library assembly for an existing schematic/board. Reviews the selected model variants on camera before placement, then routes, pours, analyzes and delivers a bounded final video.",   "steps": [     {       "name": "intake",       "who": "ai",-      "does": "read the board and the spec, write the spec from the schematic if it is missing, plan",+      "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"     },     {+      "name": "components",+      "who": "ai",+      "does": "Audit wiki component identity, reusable CAD quality and redistribution evidence before placement; offer cached optional MPN-marked variants.",+      "binary": [+        "components"+      ],+      "workflow": [+        "Inventory every reference from the actual board and schematic: manufacturer, MPN, supplier code, package, value and ratings; group repeated exact parts and record their references. Do not invent an MPN or silently substitute a similar value/package. Distinguish populated parts, DNP parts and bare copper/mechanical features; a bare test pad needs no purchased component or fictitious 3D body.",+        "Search the wiki FIRST for each exact manufacturer/MPN and supplier code; reuse the matching component page and inspect its symbol, footprint and STEP/WRL assets. A page existing is not proof its CAD bundle is complete. Record the page URL and missing assets per reference.",+        "For missing identities or assets, use adom-parts-search next, then original manufacturer and distributor websites. Use Pup to navigate and download through the automated browser when curl/fetch is blocked or the site requires JavaScript; do not treat a blocked fetch as proof the part is unavailable. Read the relevant parts-search and Pup skills for current commands.",+        "Verify manufacturer, exact ordering code, package dimensions, pin numbering and required electrical ratings against source evidence before accepting CAD or a candidate part. Preserve source URLs and provenance. Label generated or approximate models as such; never present an approximate body as a verified vendor model.",+        "Global component pages are shared resources for ALL ADOM USERS, never a board-specific BOM dump. Create one only for a distinct reusable manufacturer part or independently specified reusable custom component, after searching for duplicates. Write a part-focused page with portable verified assets and provenance, and improve existing pages. Keep board references, unresolved identities, one-off land patterns, bare copper test pads and project-only assemblies inside the board project wiki page; do not create catalog placeholders or rename a one-off feature to make it appear global.",+        "Use portable project/library model paths, preserve placement and routing, rerun kicad_model_check and inspect the saved board in native KiCad 3D. Report reference coverage, reused/created page URLs, unresolved identities and missing CAD separately. A successful download or wiki publication alone does not close a missing-model finding.",+        "Judge quality per component, not per board screenshot: publish a linked visual register with top, bottom and oblique views. Check dimensions, units, terminal count and pitch, pin-1/polarity, body/pad alignment, standoff, materials and visible details. File resolution alone is not quality. Record pass, needs-work, reference-only or unknown with evidence and limits.",+        "Prefer manufacturer CAD when the source permits the intended redistribution. Keep third-party/Ultra Librarian downloads as private reference-only inputs unless redistribution is explicitly permitted. Compare independently generated models against manufacturer drawings and permitted reference views; retain dimensional deviations and source hashes. Converting, extracting, recoloring, or etching a restricted model does not make it independently authored or license-cleared.",+        "Offer optional MPN marking using adom/adom-chip-laser or the current adom-step2glb laser-etch service. Ask whether to enable it; default to unmarked models until the user chooses. Check the shared page cache first. Preserve the plain STEP and publish an additional marked STEP, derived GLB and reviewed thumbnails only for assets eligible for redistribution. Keep the mark clear of pin-1, polarity, terminals and optical/mechanical features. Marking is an identification aid, not evidence of actual factory top-marking, especially on tiny passives.",+        "Cache reviewed artifacts on the existing global component page: source/plain STEP, optional MPN STEP, GLB, thumbnails and machine-readable provenance. Record input hash, generator/tool version, parameters, units, transforms, marking text/mode, reference evidence and review results. Cache keys must change when geometry, text or generator parameters change. Keep board-only transforms and mappings in the board project. Never claim cross-EDA parity without rendering the variant in the named native viewers.",+        "When publishing or improving a component page, make per-file provenance mandatory even though creating a new page is optional. Record original source URL/file and revision, retrieval date, source and output SHA-256, authoring classification (manufacturer-supplied, source-derived, AI-created, or unknown), generator/version and parameters, units/transforms, redistribution evidence and limitations. For AI-created geometry cite the actual datasheet page/figure/table and dimensions used, list simplifications and reference comparisons, and never present copied/extracted CAD as independent work. State which checks ran and which remain unverified; retain plain and marked variant lineage. Put a readable provenance section on the page plus a machine-readable asset record and a link to that component's issue tracker. Unknown provenance stays unknown, not a fabricated source. Reuse/improve existing pages first; offer new global-page publication only for reusable components, keeping board-specific records in the project.",+        "For optional MPN marking, fit the text along the longest usable top-face direction with the largest legible size, respecting pin-1 and mechanical features. Compare both orientations and retain the package coordinate frame. Cache and identify the marked variant explicitly.",+        "Offer the optional Hydrogen progress widget. If enabled, reuse saved component, marked-model, symbol and later board/analysis thumbnails via widget event; do not generate extra screenshots or call a model solely for the widget. Respect widget disable immediately."+      ]+    },+    {+      "name": "libraries",+      "who": "ai",+      "does": "Assemble and validate the reviewed symbols, footprints and selected model variants in the chosen EDA before placement.",+      "workflow": [+        "Use the components register to build a portable project library for the actual EDA (KiCad, Altium or Fusion). Verify symbol pin numbers against footprint pads, package dimensions and pin-1/polarity; resolve model transforms and selected plain or marked STEP paths. Record native tool/version and evidence per part.",+        "Keep board reference mappings and native project transforms in the board project, while reusable source CAD and provenance remain on their existing global component pages. Do not claim native EDA support from a GLB gallery or a file extension alone.",+        "Return to components with --back --why when identity, rights or geometry cannot be resolved; preserve honest unknowns and report the affected references."+      ],+      "record": "Native library review with the selected symbol, footprint and model; saved verification evidence belongs with the library register."+    },+    {       "name": "models",       "who": "ai",-      "does": "every footprint on the board has its 3D model resolved (kicad_model_check): fetch the vendor STEP, build one, or fix the path, so the board renders as it will be built; a bare footprint in the 3D view is a missing model",+      "does": "Check native board model resolution and inspect the selected library variants in the chosen EDA; use the component register for unresolved assets.",       "binary": [         "models"       ],-      "record": "nothing to film: the model check's list and the fixes; the 3D walkthrough later is the proof"+      "record": "Native board 3D inspection and model-check evidence; the separate library-tour step reviews each selected component.",+      "workflow": [+        "Use the components register and its reviewed plain or explicitly selected marked variants; fix portable model paths, run kicad_model_check, then inspect the native board render. Do not substitute a model merely to make the missing-file gate pass."+      ]     },     {+      "name": "library-tour",+      "who": "ai",+      "does": "Review each selected component model in motion and produce a separate short library overview for the final video.",+      "workflow": [+        "Use tools/library-tour.py with the reviewed library.json, --run and --ai-thread. The manifest must identify the same plain or explicitly chosen marked variants and hashes that the native board uses. A marking choice does not authorize silent plain-model fallback.",+        "Inspect the detailed orbit tour and the moving overview in a rendered browser. Reject blank, clipped, wrong-variant or static clips; retain raw recordings and contact sheets. The detailed tour stays separately linked for component review.",+        "Budget approximately five seconds for the moving overview within the entire final video limit of 120 seconds. Do not insert the whole BOM walkthrough or one wiki-page shot per part into the final video. Optional scrolling wiki-page clips belong in the separate detailed review.",+        "Automatic overview selection in released compose requires the complete maintained release source (issue #16); until integrated, report that limitation explicitly and keep the reviewed clips and selection manifest available for integration."+      ],+      "record": "Two separate raw clips: a detailed component orbit tour and a roughly five-second moving overview. No title pages or baked captions; the final composer supplies its own overlays."+    },+    {       "name": "placement",       "who": "ai",       "does": "place the parts for routability, current and heat; the binary packs, checks courtyards and lands moves",⋯ 104 unchanged lines ⋯   "returns": "any step may send the AI back to any earlier step: step <name> --back --why \"...\"",   "later": [     {-      "name": "components",+      "name": "part-selection",       "does": "choose the parts from the requirements; SPICE may send the AI back here"     },     {-      "name": "libraries",-      "does": "symbols, footprints, 3D chips for every part"-    },-    {       "name": "schematic",       "does": "the schematic, and the spec that falls out of it"     },⋯ 17 unchanged lines ⋯   "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" }+--- a/docs/library-tours.md+++ b/docs/library-tours.md@@ -0,0 +1,18 @@+# Component library tours++Review the library early, before placement, in the actual EDA selected by the user. Match symbols, footprints and model paths in that EDA; a GLB gallery alone is not native library validation.++Use one reviewed manifest (`library.json`) to select every component's exact STEP and GLB hashes and its plain or optional MPN-marked variant. If marking is on, a missing marked asset must be resolved or the user must explicitly change that choice. Never silently show plain models in the tour when the board is expected to use marked ones. Preserve the original package frame, and fit marking along the longest usable top-face direction, with pin-1 clearance.++The additive `tools/library-tour.py` helper builds an interactive Adom 3D viewer from that manifest, then records two distinct clips: a two-second orbit per component and a five-second moving overview. Preview bodies are normalized in size for visibility; source CAD is unchanged. Keep the long walkthrough as a separate review artifact. The final video should include only the short overview by default and remain at most two minutes. Optional brief scrolling component wiki shots belong in a separate library tour when a large BOM would otherwise dominate the final cut.++`build --manifest library.json --out library-tour`, `serve --out library-tour --port 8878`, `record --out library-tour --port 8878`, then inspect both contact sheets and play the clips. Supply your run and thread to the helper. Hash/GLB validation and successful loading are not enough: reject blank, clipped, wrong-variant or motionless clips. `clips.json` deliberately leaves visual review pending. Register approved clips only after native EDA binding and visible review.++Release integration note: the published source snapshot lacks the installed release's compose and tour implementations (issue #16). This helper is independently runnable; wiring its approved overview into released compose must occur in the complete maintained release tree. Do not replace the installed production binary with the incomplete snapshot or claim that integration is already released.++The early plan now exposes `components → libraries → models → library-tour → placement`+as distinct visits. `libraries` covers native symbol/pad/model binding; `models`+checks the board's actual selected models; `library-tour` records their visual review.+An existing schematic's library repair is different from later requirements-driven+part selection. These are AI-owned steps, not new automated qualification gates.+--- a/tests/component-workflow.py+++ b/tests/component-workflow.py@@ -0,0 +1,27 @@+"""Exercise early component inventory, optional marking and review-note preservation."""+import pathlib,subprocess,tempfile,sys,json+binary,board,spec=map(lambda p:str(pathlib.Path(p).resolve()),sys.argv[1:])+with tempfile.TemporaryDirectory(prefix='aiflow-components-') as d:+ base=[binary,'--ai-thread','ESC AI Flow Astra','--run',d]+ subprocess.run(base+['start','--board',board,'--spec',spec,'--engine','component-workflow-test'],check=True,capture_output=True,text=True)+ text=subprocess.run(base+['plan'],check=True,capture_output=True,text=True).stdout+ assert text.index('step components') < text.index('step libraries') < text.index('step models') < text.index('step library-tour') < text.index('step placement')+ assert text.index('Search the wiki FIRST')<text.index('use adom-parts-search next')+ for phrase in ['ALL ADOM USERS','private reference-only','optional MPN marking','Cache keys','per-file provenance mandatory','datasheet page/figure/table','Unknown provenance stays unknown']:+  assert phrase in text,phrase+ result=subprocess.run(base+['components'],check=True,capture_output=True,text=True)+ p=pathlib.Path(d)/'components.json';v=json.load(open(p));assert len(v['components'])==149;assert v['mpnMarking']=='ask'+ assert all('assetProvenance' in r['review'] for r in v['components'])+ refs=[r['reference'] for r in v['components']];assert len(set(refs))==149+ v['components'][0]['review']['notes']='Preserve this independent review';p.write_text(json.dumps(v))+ subprocess.run(base+['components','--etch','on'],check=True,capture_output=True,text=True)+ v=json.load(open(p));assert v['mpnMarking']=='on';assert v['components'][0]['review']['notes']=='Preserve this independent review'+ subprocess.run(base+['components'],check=True,capture_output=True,text=True);assert json.load(open(p))['mpnMarking']=='on'+ subprocess.run(base+['components','--etch','off'],check=True,capture_output=True,text=True);assert json.load(open(p))['mpnMarking']=='off'+ v=json.load(open(p));v['components'][0]['properties']['Value']='deliberately stale source value';v['components'][0]['review']['status']='pass';p.write_text(json.dumps(v))+ subprocess.run(base+['components'],check=True,capture_output=True,text=True)+ v=json.load(open(p));assert v['components'][0]['review']['status']=='stale';assert v['components'][0]['review']['notes']=='Preserve this independent review'+ p.write_text('{invalid');r=subprocess.run(base+['components'],capture_output=True,text=True);assert r.returncode!=0;assert p.read_text()=='{invalid'+ print(result.stdout)+ print('PASS: early plan order, 149 references, explicit marking preference, preserved review notes, stale source invalidation, malformed register untouched.')+

Comments

No comments yet.

Log in to comment.