@protoboardai/ext-hardware 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +13 -0
  3. package/checks/evidence.ts +63 -0
  4. package/evals/compose-probe-cable/case.json +160 -0
  5. package/evals/e2e-desk-rover/case.json +62 -0
  6. package/evals/e2e-desk-rover/fixture/AGENTS.md +9 -0
  7. package/evals/e2e-desk-rover/fixture/docs/brief.md +28 -0
  8. package/evals/e2e-desk-rover/fixture/docs/decisions.md +3 -0
  9. package/evals/e2e-desk-rover/fixture/package.json +1 -0
  10. package/evals/e2e-desk-rover/fixture/protoboard.config.ts +12 -0
  11. package/evals/e2e-desk-rover/fixture/src/.gitkeep +0 -0
  12. package/evals/e2e-desk-rover/solution/decisions.md +26 -0
  13. package/evals/e2e-desk-rover/solution/desk-rover.uhd.ts +60 -0
  14. package/evals/find-reversed-cell-leads/case.json +78 -0
  15. package/evals/fix-gnss-uart-swap/case.json +32 -0
  16. package/evals/fix-two-wiring-faults/case.json +97 -0
  17. package/evals/rough-draft-is-concept/case.json +36 -0
  18. package/evals/rough-draft-is-concept/fixture/AGENTS.md +9 -0
  19. package/evals/rough-draft-is-concept/fixture/docs/brief.md +8 -0
  20. package/evals/rough-draft-is-concept/fixture/docs/decisions.md +3 -0
  21. package/evals/rough-draft-is-concept/fixture/package.json +1 -0
  22. package/evals/rough-draft-is-concept/fixture/protoboard.config.ts +11 -0
  23. package/evals/rough-draft-is-concept/fixture/src/.gitkeep +0 -0
  24. package/evals/rough-draft-is-concept/solution/trail-light.uhd.ts +40 -0
  25. package/evals/tidy-the-diagram/case.json +30 -0
  26. package/evals/tidy-the-diagram/fixture/.protoboard/display.json +20 -0
  27. package/evals/tidy-the-diagram/fixture/AGENTS.md +9 -0
  28. package/evals/tidy-the-diagram/fixture/docs/brief.md +5 -0
  29. package/evals/tidy-the-diagram/fixture/package.json +1 -0
  30. package/evals/tidy-the-diagram/fixture/protoboard.config.ts +12 -0
  31. package/evals/tidy-the-diagram/fixture/src/bike-computer.uhd.ts +63 -0
  32. package/ops/bom.ts +22 -0
  33. package/package.json +30 -4
  34. package/protoboard-extension.json +65 -0
  35. package/skills/build-a-project/SKILL.md +562 -0
  36. package/skills/harness-author/SKILL.md +232 -0
  37. package/skills/harness-author/references/stack-up.md +70 -0
  38. package/skills/harness-author/references/wire-harnesses.md +35 -0
  39. package/skills/harness-author/scripts/stackup.ts +104 -0
  40. package/skills/harness-verify/SKILL.md +112 -0
  41. package/skills/system-compose/SKILL.md +269 -0
  42. package/skills/system-compose/references/diagnostic-codes.md +292 -0
  43. package/skills/system-compose/scripts/scenarios.ts +82 -0
  44. package/skills/system-review/SKILL.md +145 -0
  45. package/skills/test-and-measure/SKILL.md +181 -0
  46. package/skills/test-and-measure/references/procedure-template.md +45 -0
  47. package/skills/test-and-measure/references/test-plan.md +35 -0
  48. package/skills/test-and-measure/scripts/test-data.ts +94 -0
  49. package/README.md +0 -3
@@ -0,0 +1,562 @@
1
+ ---
2
+ name: build-a-project
3
+ description: The top-level SOP for taking a Protoboard hardware project from an idea or a written brief to a release and its Manufacturing Package, one level of detail at a time (concept, blocks, parts, definitions verified, schematic and PCB), asking before each level deeper — a rough draft or concept is 3 to 6 capability blocks, nothing more — then brief and requirements, sourcing, parts by tier (cloud catalog via parts search/add, project-researched via the part skills, publish), system composition and harnesses, custom boards (circuit capability), enclosures and structures (cad capability), harness CAD, checks and fault scenarios, firmware configuration, documents, `protoboard release` by package units, and evals — delegating each stage to the extension SOP that owns it. Use when starting a project from an idea or a brief, when asked for a rough draft, a concept or a block diagram, when resuming a project and deciding what to do next, or when asked "build this" end to end.
4
+ ---
5
+
6
+ # Build a project
7
+
8
+ ```
9
+ brief ─► requirements ─► sourcing ─► parts (catalog │ project-researched) ─► system + harnesses
10
+ │
11
+ evals ◄─ release (Manufacturing Package) ◄─ documents ◄─ firmware ◄─ checks ◄─ boards ─► enclosures/structures ─► harness CAD
12
+
13
+ how far, one level at a time, asking before each:
14
+ concept (3–6 blocks) ─► blocks ─► parts ─► definitions verified ─► schematic and PCB
15
+ ```
16
+
17
+ This SOP owns the order of work and the hand-offs. Each stage is done by the
18
+ SOP named in it; this one says when to start a stage, what must be true
19
+ before moving on, and where to go back to when something fails. The UHD model
20
+ is the design record throughout: every stage reads it, and every finding is
21
+ fixed in the model or in a provider's config, never in a generated file.
22
+
23
+ Worked example: `examples/quadcopter-5in` (purchased modules, a custom frame
24
+ and top plate, ten routed cables, Betaflight configuration, datasheet and
25
+ assembly guide). Its `AGENTS.md` and `docs/harnesses-and-cad.md` show the
26
+ standard the result should meet.
27
+
28
+ ## Purpose
29
+
30
+ Take an agent from a brief to a release that someone could order, make,
31
+ assemble and check from, without skipping the evidence each stage needs. Use
32
+ it when starting a project from a brief, when picking up a project and
33
+ deciding what comes next (run the stage checks in **Verification** to find
34
+ the first stage that is not done), or when asked to build something end to
35
+ end. For one stage alone, go straight to that stage's SOP.
36
+
37
+ It does not run to the end by itself. The work goes down a ladder of five
38
+ levels of detail (step 0), it starts at the level the person asked for (a
39
+ "rough draft" or a "concept" is the first: three to six blocks), and it asks
40
+ before going a level deeper.
41
+
42
+ It stops at manufacturing-ready files. It never orders, uploads, prints,
43
+ creates accounts or runs cloud services, and physical tests are prepared for
44
+ a person, not performed.
45
+
46
+ ## Inputs
47
+
48
+ | Input | Where | From |
49
+ | --- | --- | --- |
50
+ | The brief | `docs/brief.md` (purpose, operating envelope, constraints, acceptance targets) | the person asking; write it with them if it does not exist |
51
+ | How far to go | one of the five levels in step 0 | the person asking; concept when they did not say |
52
+ | A project | `protoboard.config.ts` at the project root; the top-level module under `src/` | `npx protoboard init <dir>` (step 0) |
53
+ | The extensions the project needs | `extensions` in `protoboard.config.ts`; the Protoboard installed on the machine carries them | step 0 |
54
+ | Earlier work to build on | another project's research, where the person says it is | the person asking (step 0) |
55
+ | Tool runtimes | `.protoboard/tools/` (`npx protoboard doctor`) | `npx protoboard tools install cad` / `circuit` |
56
+ | The parts service, for catalog parts | `PROTOBOARD_CLOUD_URL` or `cloud.url` in the config (default `http://localhost:8787`) | the operator; only `parts` commands use it |
57
+
58
+ ## Steps
59
+
60
+ ### 0. Look, ask, agree how far to go, set up
61
+
62
+ **Look first.** When a project already exists, read its real state before
63
+ you say anything about it:
64
+
65
+ ```bash
66
+ npx protoboard inspect # what the project holds now: instances, definitions by tier, links
67
+ npx protoboard check # what the rules find
68
+ npx protoboard doctor # extensions, tools, skills, the sign-in
69
+ ```
70
+
71
+ With Protoboard's MCP server connected, `project_status` first. Describe
72
+ what these report. Never answer "what is in this project" from memory, from
73
+ an earlier session or from the template's description: a project that
74
+ started empty may hold a whole system by now.
75
+
76
+ **Ask, in plain words.** Before modelling, ask the few questions whose
77
+ answers change the work, in one short list, and wait for the answers:
78
+
79
+ 1. What is it, in one sentence, and who uses it?
80
+ 2. What must it do? The three or four things it cannot do without.
81
+ 3. What is already fixed? A size, a battery, a part that must be used, a price.
82
+ 4. How far should this go now? Offer the levels below by what the person
83
+ gets from each, with the concept as the default.
84
+ 5. Is there earlier work to build on, such as another project's research?
85
+
86
+ How to ask:
87
+
88
+ - Everyday words. Spell out every abbreviation the first time: "UV-C
89
+ (ultraviolet light that disinfects)", "BLE (Bluetooth Low Energy)", "DRC
90
+ (design rule check)".
91
+ - No labels from your own notes, no codenames, no marketing words
92
+ ("positioning", "parity with model X"). Ask the question the label stands
93
+ for: "Should it do everything the earlier model does, or only clean the
94
+ water?"
95
+ - Say what each choice leads to, in a few words.
96
+ - **A free-text answer is always possible.** When your host shows questions
97
+ as a card with options, add "something else: I will type it" to every
98
+ question, and accept an answer typed in the chat in place of the card.
99
+ Options are a convenience, never the only way to answer.
100
+ - At most five questions at once. When one stays unanswered, say which
101
+ assumption you will work with and go on at the concept level: do not
102
+ block the conversation on a card.
103
+
104
+ **Agree how far to go.** Five levels; each is complete and useful by itself.
105
+
106
+ | Level | People say | You build | You do not build yet | Done when |
107
+ | --- | --- | --- | --- | --- |
108
+ | 1. Concept | "rough draft", "concept", "sketch", "block diagram", "just the big pieces" | 3 to 6 top-level capability blocks (for example power, control, sensing, output, user controls, housing) as children of the top-level module, each with a name, one line saying what it is for, and only the interfaces that join it to the other blocks; the links between them. All in the top-level module's own file under `src/` | no circuit boards, no blank part for each board or component, no file or folder per board (`src/boards/…`), no provider configs, no sourcing, no harness modules, no CAD | `check` has 0 errors, the diagram shows 3 to 6 nodes, and the person has looked at it |
109
+ | 2. Blocks | "break it down", "what is inside each block" | each capability block opened into its functional blocks, still without part numbers ("microcontroller", "charger", "level sensor"): the interfaces carry their protocols and voltages, the links follow the functions, and each block is marked bought or designed here (**Decision points**) | no real parts, no board nets, no provider configs | every requirement of the brief lands on a block (stage 1); `check` has 0 errors |
110
+ | 3. Parts | "pick the parts", "a real bill of materials" | a real part behind every block (stages 2 and 3), each custom board as a module with its components as children in `src/boards/<name>/`, the harnesses (stage 4) | no PCB layout, no enclosure or cable CAD, no documents | no `PB_UNRESOLVED_DEFINITION`; `check` has 0 errors; `npx protoboard bom` prices it |
111
+ | 4. Definitions verified | "make sure it is right", "review it" | every researched part verified against its sources, the sourcing audited, the fault scenarios, the independent reviews (stage 8) | nothing generated for manufacture | stage 8's exit check |
112
+ | 5. Schematic and PCB | "make the board", "ready to build" | stages 5 to 11: boards, enclosures and structures, harness CAD, firmware configuration, documents, the release | | stage 11's exit check |
113
+
114
+ - Start at level 1 unless the person named a deeper one. "Rough draft",
115
+ "concept", "first pass" and "just show me the idea" all mean level 1.
116
+ - A block without a part behind it is a blank part: name it for what it
117
+ does, not for a part you have in mind, and say in its description that no
118
+ part is chosen yet. At levels 1 and 2 the blocks live in the files that
119
+ hold their parent; they get files of their own at level 3.
120
+ - At the end of a level, stop: show the diagram, say in two or three
121
+ sentences what is there and what is assumed, and ask whether to go a
122
+ level deeper. Do not go deeper unasked: a multi-board design in answer to
123
+ "a rough draft" costs the person an hour to undo.
124
+ - When the request itself names the end ("down to parts", "to a release"),
125
+ that is the level: say so at the start and work down to it, still
126
+ finishing each level's check on the way.
127
+ - Going back up is allowed: a level-3 project can get a new block at level
128
+ 1 detail. Say which parts of the system are at which level.
129
+
130
+ **A project made from another.** When the new project builds on another
131
+ project's research (datasheets, teardowns, notes, part evidence), ask which
132
+ the person wants:
133
+
134
+ - **Link it**: the research stays where it is and is read from there.
135
+ Nothing is duplicated; the new project depends on that folder staying
136
+ put. Record every linked path in the new project's `AGENTS.md`, under a
137
+ heading `## Linked research`, one line each: the path, what it holds, the
138
+ date. Read from it; never edit the other project's files.
139
+ - **Carry it over**: copy it into the new project (`docs/research/<source
140
+ project>/`, part evidence into `parts/evidence/`). The project stands
141
+ alone; the copy can go stale. Record where it came from and when in
142
+ `docs/decisions.md`.
143
+ - **Neither**: start clean, and say that the earlier findings are not used.
144
+
145
+ Do not decide this silently: a new project that lacks the earlier research
146
+ looks finished and is not.
147
+
148
+ **Set up the project.** A folder is a project when it has a
149
+ `protoboard.config.ts`. When there is none, ask whether to start one now and
150
+ from which template, then:
151
+
152
+ ```bash
153
+ npx protoboard init --list # the templates and what each starts from
154
+ npx protoboard init <dir> --template <id> # without --template: an empty project
155
+ ```
156
+
157
+ The project uses the Protoboard installed on the machine, which is the
158
+ default: there is no install step in the project, and you never tell the
159
+ person to run npm there. A copy of the stack inside the project
160
+ (`npx protoboard init <dir> --stack project`) is the exception: ask before you do
161
+ it, and say that it needs Node.js with npm and access to the package
162
+ registry. The top-level module lives under `src/` (`root` in
163
+ `protoboard.config.ts` names its file); keep it there. When the new project
164
+ opens in VS Code, VS Code asks whether the person trusts the folder: tell
165
+ them to expect that and to choose **Yes, I trust the authors**, because the
166
+ Protoboard views stay off until they do.
167
+
168
+ List the extensions in `protoboard.config.ts`. A project that designs its
169
+ own boards, enclosures or cables needs their providers; one that only
170
+ composes purchased modules does not.
171
+
172
+ | Extension | For |
173
+ | --- | --- |
174
+ | `@protoboardai/ext-hardware` | this SOP, system composition, harnesses, tests, BOM |
175
+ | `@protoboardai/ext-release` | `protoboard release` and the Manufacturing Package (**release**) |
176
+ | `@protoboardai/ext-sourcing`, `@protoboardai/ext-parts` | sourcing and the project-researched part tier |
177
+ | `@protoboardai/ext-tscircuit` | custom PCBs (`circuit`; selected by a board's `circuit.config.ts`) |
178
+ | `@protoboardai/ext-enclosure-cad`, `@protoboardai/ext-frame-cad`, `@protoboardai/ext-harness-cad` | enclosures, plates and frames, routed cables (`cad`) |
179
+ | `@protoboardai/ext-zephyr`, `@protoboardai/ext-esp-idf` | firmware configuration of a board's controller (`firmware`; selected by a board's `firmware.config.ts`): Zephyr board definition (nRF52840), ESP-IDF pins header and `sdkconfig.defaults` (ESP32-C3) |
180
+ | `@protoboardai/ext-drone` | flight-controller configuration (Betaflight CLI) |
181
+ | `@protoboardai/ext-docs` | datasheet and assembly guide |
182
+
183
+ ```bash
184
+ npx protoboard doctor # extensions ✓, tools ✓/✗ with install hints, skills found
185
+ npx protoboard tools install cad # if a cad provider is used: the shared Python runtime (~1 GB, once per checkout)
186
+ npx protoboard skills export --host all # only when .claude/skills/ is missing: put every SOP where the agent host finds it
187
+ ```
188
+
189
+ Look at `doctor`'s Tools: every tool a stage needs must be ✓ before that
190
+ stage, or the stage's operations are refused (`run`) and its checks skipped
191
+ (`check`), which is unknown, not passed.
192
+
193
+ ### 1. Brief and requirements
194
+
195
+ **system-compose** step 1: turn `docs/brief.md` into checkable requirements,
196
+ each mapped to how it will be shown (a UHD rule, an assembly check, a
197
+ document value, or a test), state the product in `docs/product.json`
198
+ (summary, features, functions, requirements: the documents' first page),
199
+ and start `docs/decisions.md`. Decide which
200
+ functions are bought and which are designed here (**Decision points**).
201
+
202
+ ### 2. Sourcing
203
+
204
+ For every function the brief needs, find the part before modelling it:
205
+
206
+ 1. Look in the project and the catalog first:
207
+
208
+ ```bash
209
+ npx protoboard inspect # what the project already has
210
+ npx protoboard parts search <words> --format json # catalog; --protocol, --domain, --tag narrow it
211
+ ```
212
+
213
+ 2. Not there, or not right: **part-search** (requirement first, lanes,
214
+ `docs/sourcing/<need>.md`), then **datasheet-extract** for every value
215
+ that matters, **supplier-compare** and **lifecycle-alternates** for the
216
+ chosen part, and **sourcing-verify** before authoring.
217
+
218
+ Record each selection in `docs/decisions.md` with the requirement it meets.
219
+
220
+ ### 3. Parts, by tier
221
+
222
+ | Tier | How |
223
+ | --- | --- |
224
+ | Cloud catalog | `npx protoboard parts add <id>` (or `<id>@<rev>`): the revision, its closure and files into `parts/catalog/`, with its `.uhd.ts` source in `parts/catalog/<id>/` (`--compiled`: JSON only), pinned in `parts/origins.json` |
225
+ | Project-researched | **part-handoff** → **uhd-part-research** → **uhd-part-author** ↻ **uhd-part-verify**: `parts/local/<id>.uhd.ts`, evidence in `parts/evidence/<id>/`, verification recorded with `npx protoboard run part-verification --input part=<id>` |
226
+ | Project-specific | designed in `src/` in the next stages (system, boards, enclosures, structures, harnesses) |
227
+
228
+ ```bash
229
+ npx protoboard parts add <id> --format json # results[].status: added, unchanged, restored, conflict
230
+ npx protoboard run part-verify --input part=<id> # stage 1 of uhd-part-verify, for a parts/local part
231
+ npx protoboard check --severity info # HW_* (evidence) and SRC_* (sourcing) findings
232
+ ```
233
+
234
+ A verified project-researched part may be offered to the catalog once
235
+ someone with the publish token agrees (**part-handoff** step 5):
236
+
237
+ ```bash
238
+ npx protoboard parts publish parts/local/<id>.uhd.ts --dry-run
239
+ ```
240
+
241
+ ### 4. System composition and harnesses
242
+
243
+ **system-compose** steps 2 to 5: the root system's instances, links,
244
+ sub-assemblies and mates, then the fault scenarios. **harness-author**: a
245
+ harness for every physical carrier (cables with connector ends and
246
+ conductors, soldered ends as compositions, fastener stacks for mechanical
247
+ joints).
248
+
249
+ ```bash
250
+ npx protoboard check --format json
251
+ npx tsx node_modules/@protoboardai/ext-hardware/skills/system-compose/scripts/scenarios.ts
252
+ npx tsx node_modules/@protoboardai/ext-hardware/skills/harness-author/scripts/stackup.ts
253
+ # in an npm workspace (the stack's examples) node_modules is the workspace's: ../../node_modules/@protoboardai/...
254
+ npx protoboard dev --open # the system diagram and 3D view, live while you edit
255
+ ```
256
+
257
+ Look at `checks[]` (every validator `ran`) and `diagnostics[]` (fix errors
258
+ in the order **system-compose** step 5 gives). Then look at the diagram as
259
+ the person will: lay it out so that it reads (the project's `AGENTS.md`,
260
+ "The diagram's layout": you may write `.protoboard/display.json`), and check
261
+ the result in the viewer before you call the level done. Stop the `dev` server
262
+ (`Ctrl+C`) when you no longer need it.
263
+
264
+ ### 5. Boards (circuit capability)
265
+
266
+ For each custom PCB, **circuit-board**: the board as a UHD module in
267
+ `src/boards/<module>/` (components as children, nets as links), a
268
+ `circuit.config.ts` naming the provider and constraints, then:
269
+
270
+ ```bash
271
+ npx protoboard capabilities # the board is bound to its provider ✓
272
+ npx protoboard run circuit:generate --module <board>
273
+ npx protoboard run circuit:export --module <board> # out/: Gerber, drill, BOM, PnP, GLB, STEP, manifest, netlist
274
+ npx protoboard run circuit:extract --module <board> --format json # frames of connectors and buttons for the enclosure
275
+ npx protoboard run circuit:check --module <board> --format json
276
+ ```
277
+
278
+ Boards come before enclosures: the enclosure is fitted around
279
+ `out/board.glb` and aligned to the frames in `out/board.manifest.json`.
280
+
281
+ A board is done when the person can see it in the viewer, not when the
282
+ commands pass. Its outputs reach the viewer by themselves (the provider's
283
+ artifacts); check that every tab draws:
284
+
285
+ ```bash
286
+ npx protoboard views check --module <board> # Diagram, 3D, Schematic, PCB and BOM each draw; exit 1 on an empty or erroring tab
287
+ ```
288
+
289
+ Then the hand finish, when the person wants one: a KiCad preview with
290
+ `circuit:kicad` at any time, and the handoff to KiCad with `circuit:lock`
291
+ only when the person decides (**circuit-board** step 8), reviewed with
292
+ **kicad-layout-review**.
293
+
294
+ Before any change to a board, say where the fix belongs: the UHD model
295
+ first, then the tscircuit stage (placement, widths, rules,
296
+ `circuit.config.ts`), then the stack (a converter or provider bug to report,
297
+ never to hand-patch), and KiCad only for the hand finish. A locked board is
298
+ not fixed in place: for a change upstream, propose unlocking and re-locking,
299
+ and say which KiCad work it would lose. **circuit-board** step 0 has the whole rule, with mistakes and design choices and post-lock
300
+ steps.
301
+
302
+ ### 6. Enclosures and structures (cad capability)
303
+
304
+ Each custom mechanical module gets a `cad.config.ts` naming its provider:
305
+
306
+ | Module | SOP | Provider |
307
+ | --- | --- | --- |
308
+ | Case, cap, back cover around a board | **enclosure-cad** | `@protoboardai/ext-enclosure-cad` (`process: print` or `machine`) |
309
+ | Plate, frame, bracket from bolt patterns | **frame-cad**, then **frame-cad-verify** | `@protoboardai/ext-frame-cad` (`process: cut` or `machine`) |
310
+ | Bought screw, nut, spacer or standoff researched in the project | **frame-cad** step 6 | `@protoboardai/ext-frame-cad` (no process: bought) |
311
+ | Body of another researched part, drawn from its drawing | **uhd-part-author** (In a project) | `@protoboardai/ext-parts`, running the part's own script (no process) |
312
+
313
+ ```bash
314
+ npx protoboard run cad:generate --module <module>
315
+ npx protoboard run cad:export --module <module>
316
+ npx protoboard check
317
+ ```
318
+
319
+ Every CAD body goes through the capability, a bought part's too: a script
320
+ run by hand is not traced by the release, which refuses a module whose
321
+ `out/` has no `cad:export` record. The aliases (`frame-cad`,
322
+ `hardware-cad`, `harness-cad`) run the capability for each module and leave
323
+ each its own `cad:generate` and `cad:export` record. After a structure changes, re-derive the
324
+ fastener stacks on its faces (**harness-author** step 3).
325
+
326
+ ### 7. Harness CAD
327
+
328
+ **harness-cad** for every wire harness: a `cad.config.ts` per cable, then
329
+ the routes through the assembled model.
330
+
331
+ ```bash
332
+ npx protoboard run harness-cad # every cable, in the system's routing order
333
+ npx protoboard check # HARNESS_* findings, ends still meet their parts
334
+ ```
335
+
336
+ Set a cut-to-length cable's `length_mm` from the route it reports, then
337
+ regenerate.
338
+
339
+ ### 8. Checks and fault scenarios
340
+
341
+ The whole project, with nothing stale:
342
+
343
+ ```bash
344
+ npx protoboard check --severity info --format json
345
+ npx tsx node_modules/@protoboardai/ext-hardware/skills/system-compose/scripts/scenarios.ts --json
346
+ npx protoboard build # .protoboard/build/resolved.json and the UHD bundle
347
+ ```
348
+
349
+ 0 errors; every warning dispositioned in `docs/decisions.md`; every
350
+ scenario `caught`; no `*_STALE`, `PB_OUTPUT_*` or `HARNESS_*_STALE` finding.
351
+ Then the independent reviews, each by a fresh agent: **system-review**,
352
+ **harness-verify**, **frame-cad-verify** (if plates), **sourcing-verify**
353
+ (if sourced parts).
354
+
355
+ ### 9. Firmware configuration
356
+
357
+ The configuration is derived from the model's links and part facts, every
358
+ line cited. Two kinds:
359
+
360
+ - **A board you design** (a microcontroller on your own PCB): a `firmware`
361
+ capability provider, chosen in the board's `firmware.config.ts`
362
+ (`@protoboardai/ext-zephyr` for nRF52840, `@protoboardai/ext-esp-idf` for
363
+ ESP32-C3; **firmware-config-zephyr**, **firmware-config-esp-idf**). The
364
+ config holds only what the model cannot state (wake sources, a driver
365
+ property, the board name).
366
+
367
+ ```bash
368
+ npx protoboard run firmware:generate --module <board> # src/boards/<board>/zephyr/ or esp-idf/ (provider-owned)
369
+ npx protoboard run firmware:export --module <board> # src/boards/<board>/out/config/ + out/firmware.manifest.json
370
+ npx protoboard check # includes firmware:check: FW_* findings, drift from the model
371
+ ```
372
+
373
+ `out/config/` is what the firmware build and the release read: a Zephyr
374
+ board definition and Kconfig fragment, or an ESP-IDF `board_pins.h` and
375
+ `sdkconfig.defaults`. `firmware.manifest.json` lists every file with its
376
+ digest and the UHD facts each setting line cites. Re-run generate and
377
+ export after any change to the board's nets or parts (`FW_*_STALE`).
378
+ - **A bought flight controller** (**firmware-config**, @protoboardai/ext-drone):
379
+
380
+ ```bash
381
+ npx protoboard run betaflight-cli # firmware/betaflight/cli.txt, every hardware UART set
382
+ ```
383
+
384
+ **firmware-verify** is a bench step a person performs.
385
+
386
+ ### 10. Documents, BOM and test plan
387
+
388
+ ```bash
389
+ npx protoboard run bom # docs/bom.md and docs/bom.json
390
+ npx protoboard run tech-docs # datasheet and assembly guide (uhd-tech-docs)
391
+ npx protoboard run tech-docs-verify # then the visual review (uhd-tech-docs-verify)
392
+ ```
393
+
394
+ **test-and-measure** writes `docs/test-plan.md` from the requirements, the
395
+ warnings and the stand-in data: inspection, bring-up (rails, current against
396
+ the budget, programming, bus scans), functional checks per requirement.
397
+
398
+ ### 11. Release and the Manufacturing Package
399
+
400
+ Choose the package units (**Decision points**) and name them in
401
+ `protoboard.config.ts` (or `release.config.ts`):
402
+
403
+ ```ts
404
+ release: { units: ["<sub-assembly instance or module id>", "<board>", "<enclosure>"] }, // the root is always a unit
405
+ ```
406
+
407
+ Then follow **release** (`@protoboardai/ext-release`):
408
+
409
+ ```bash
410
+ npx protoboard release --check # the preconditions only; writes nothing
411
+ npx protoboard release [--version <v>] # default version: the root module's `version`
412
+ ```
413
+
414
+ `--version <v>` is the release version; `npx protoboard --version` alone
415
+ still prints the CLI's. The command refuses to run while `check` reports
416
+ errors, any generated output is stale or edited, or the tree has
417
+ uncommitted changes (`--allow-dirty` only for a trial package nobody builds
418
+ from), and writes `release/<v>/`: `index.html`, `manifest.json`,
419
+ `00-overview.pdf`, `ordering-list.csv`, `system/` and `units/<unit>/` (spec
420
+ sheet, BOM, work order, assembly guide, test plan, `files/`).
421
+
422
+ `release --check` passing does not make the package buildable. Read every
423
+ unit's work order and test plan end to end, in build order, as the person
424
+ who will use them: nothing done in a sub-unit is undone or repeated at
425
+ final assembly (an enclosure unit that closes its lid, inserts set twice),
426
+ every bring-up row is a real measurement on this board (its design values,
427
+ its programming port, each bus device), and every hold or deviation the
428
+ project knows (unverified land patterns, a missed requirement) is stated
429
+ where the reader acts on it (`fab_notes`, docs/decisions.md).
430
+
431
+ ### 12. Evals
432
+
433
+ `npx protoboard evals` runs the eval cases the installed extensions ship in
434
+ `evals/` on scratch copies of their fixtures and writes a scorecard to
435
+ `.protoboard/evals/<run>/` (`--list` shows the cases; the default scripted
436
+ host replays each case's known-good solution; `--host claude-code` runs an
437
+ agent). Run it when the project is used as a reference or a fixture for
438
+ agent quality; it is not a gate for a release.
439
+
440
+ ## Decision points
441
+
442
+ | Decision | Rule |
443
+ | --- | --- |
444
+ | How far to go | The level the person asked for; level 1 (concept) when they did not say or said "rough draft". Ask before each level deeper (step 0). |
445
+ | Research from another project | The person chooses: link (paths recorded in `AGENTS.md` under `## Linked research`), carry over, or neither (step 0). |
446
+ | Machine-wide or project-local install | Machine-wide, the default. Project-local only when the person asks for it or agrees to it. |
447
+ | Buy or design a function | Buy a module when one meets the requirement and fits the envelope (**part-search**). Design a board only when no module fits (size, connector placement, power, cost at the build quantity) and record why in `docs/decisions.md`. |
448
+ | Which part tier | Catalog first (`parts search`); project-researched (`parts/local/`) when the catalog lacks it or holds the wrong variant; never edit `parts/catalog/`. A local variant of a catalog part gets its own id. |
449
+ | Publish a researched part | Only after **uhd-part-verify** accepted it, `check` is clean, and someone holding the publish token agrees. The project keeps its local copy until it re-adds the catalog revision. |
450
+ | Which `cad` provider | Plates and frames from bolt patterns: ext-frame-cad. Cases around boards and parts: ext-enclosure-cad. Cables: ext-harness-cad. One config per module. |
451
+ | When to move to the next stage | Its exit check (**Verification**) passes. A stage that cannot pass (a missing tool, an unconfirmable part identity, a risk only a person can accept) stops the procedure: report what is missing and what would resolve it. |
452
+ | Order when something changes | Re-run every stage downstream of the change: a part change → system checks → boards → enclosures → harness routes → documents → release. `*_STALE` findings show which outputs are behind. |
453
+ | Package units | Each subsystem built or bought as one thing gets a unit (a sub-assembly, each custom board, each enclosure). A module that is not a unit folds into the nearest unit above it. A small project has only the root. |
454
+ | Long processes | Before one (hand-routing, a regroup of many parts, a sweep of several builds, a large search): say what it will do and roughly how long it takes; ask when it is optional. Do not over-optimise a small area before asking whether it needs doing at all. |
455
+ | Where the work happens | In Protoboard: the modules own the data, and the build steps write each tool's files. Do not manage KiCad or tscircuit libraries, symbols, footprints or models directly, unless the job needs something Protoboard cannot do (a SPICE model, for example); then say so first, as the fallback rule asks. |
456
+ | What needs a person | Accepting a sourcing risk, signing off a weak or drawing-only datasheet value, publishing to the catalog, every physical step (bench, flight, assembly), and any order. |
457
+
458
+ ## Outputs
459
+
460
+ | Output | Where |
461
+ | --- | --- |
462
+ | Brief, product statement, requirements trace, decisions | `docs/brief.md`, `docs/product.json`, `docs/decisions.md`, `docs/sourcing/` |
463
+ | Linked research, when the person chose to link | `## Linked research` in `AGENTS.md` (paths, what each holds, the date) |
464
+ | Parts | `parts/catalog/` + `parts/origins.json`; `parts/local/` + `parts/evidence/` |
465
+ | The system and designed modules | `src/` (the top-level module, sub-assemblies, boards, enclosures, structures, harnesses), each designed module with its `*.config.ts`, native folder and `out/` |
466
+ | Fault scenarios | `src/scenarios.ts` |
467
+ | Diagram layout and display placements | `.protoboard/display.json` |
468
+ | Firmware configuration | a designed board's `src/boards/<board>/firmware.config.ts`, provider folder (`zephyr/`, `esp-idf/`) and `out/config/` + `out/firmware.manifest.json`; a bought flight controller's `firmware/betaflight/cli.txt` |
469
+ | BOM, documents, test plan | `docs/bom.*`, `docs/<system>-datasheet.*`, `docs/<system>-assembly-guide.*`, `docs/test-plan.md`, `docs/test-data/` |
470
+ | Reviews | `docs/reviews/` |
471
+ | Release | `release/<version>/` (the Manufacturing Package and manifest) |
472
+ | Operation records | `operations/` (commit them with the outputs they describe) |
473
+
474
+ ## Verification
475
+
476
+ Run these in order; the first that fails is the stage to work on.
477
+
478
+ | Stage | Done when |
479
+ | --- | --- |
480
+ | 0 | the level is agreed; `npx protoboard doctor` exits 0 with every tool that level needs ✓ |
481
+ | Level 1 (concept) | `check` has 0 errors; the top-level module has 3 to 6 children and no `src/boards/`; the person has seen the diagram and was asked about level 2 |
482
+ | 1 | every requirement has a "shown by" entry; `docs/product.json` states the summary, features and functions (`protoboard release --check` has no `REL_PRODUCT_NOT_STATED`) |
483
+ | 2–3 | `npx protoboard check --severity info` has no `PB_UNRESOLVED_DEFINITION`, `HW_*` error or warning, or unaccepted `SRC_*` warning; every `parts/local` part has `verification.json` |
484
+ | 4 | `check` has 0 errors; `scenarios.ts` prints every scenario `caught`; `stackup.ts` exits 0; **system-review** and **harness-verify** files exist with no open blocker |
485
+ | 5–7 | `npx protoboard capabilities` shows every designed module ✓; `check` has no `PB_OUTPUT_*`, `PB_VIEW_UNREACHABLE`, `*_STALE`, `CIRCUIT_*`, `ENCLOSURE_*` or `HARNESS_*` error or warning; `npx protoboard views check` exits 0 (every tab of every level draws) and the person can see each board in the viewer |
486
+ | 8 | the full `check` is clean as above; every warning dispositioned |
487
+ | 9 | every board with a `firmware.config.ts` exported (`firmware:export`) with `check` showing no `FW_*` error or `*_STALE` finding; `firmware/betaflight/cli.txt` regenerated from the current model; open items listed |
488
+ | 10 | `tech-docs-verify` succeeds and the visual review is recorded |
489
+ | 11 | `release/<version>/manifest.json` exists; rebuilding in a clean clone gives the same digests |
490
+
491
+ ## Failure handling
492
+
493
+ | Code or symptom | Means | Do |
494
+ | --- | --- | --- |
495
+ | `PB_EXTENSION_NOT_INSTALLED`, a `doctor` tool ✗ | The stage's extension or tool is missing | List the extension in `extensions` (the machine's Protoboard carries every extension; in a project with its own copy, ask the person before installing a package); `npx protoboard tools install <cad\|circuit>`; re-run `doctor` |
496
+ | The person asked for a rough draft and got boards, or cannot answer a question card | The level was not agreed, or the questions were not plain | Go back to step 0: cut the model back to the level asked for, ask again in plain words, accept a typed answer |
497
+ | An answer about the project turns out wrong ("it is still empty") | It was given from memory | `npx protoboard inspect`, then correct what was said |
498
+ | `PB_UNRESOLVED_DEFINITION` | A part the system uses is not in the project | stage 3: `parts add`, or author it in `parts/local/` |
499
+ | `PB_INVALID_ENDPOINT`, `UHD_LINK_STATE` error | The system is wired wrong, or a part fact is wrong | stage 4 (**system-compose** step 5) |
500
+ | `HW_NO_SOURCES`, `HW_VERIFICATION_WRONG`, `SRC_*` warnings | Part evidence missing or wrong | stages 2–3 |
501
+ | `PB_CAPABILITY_*`, `PB_PROVIDER_*` | A designed module's config is wrong or its provider missing | the module's SOP (**circuit-board**, **enclosure-cad**, **frame-cad**, **harness-cad**) |
502
+ | `*_STALE`, `PB_OUTPUT_NOT_EXPORTED` | Outputs behind the model | regenerate in stage order (boards, enclosures and structures, harnesses), then documents |
503
+ | A check `skipped` in `checks[]` | Unknown, not passed (a tool missing, an upstream error) | fix the reason it gives, re-run |
504
+ | `protoboard release` refuses | errors in `check`, stale or edited outputs, uncommitted changes | `release --check` names each; stage 8 or commit, then retry |
505
+ | `protoboard release` / `evals` not in `--help` | An older CLI, or `@protoboardai/ext-release` not installed | update the CLI or install the extension (`npx protoboard doctor`); otherwise skip and say so |
506
+ | A part's identity cannot be confirmed, or a risk needs accepting | Only a person can decide | stop and report, with the closest documented alternative |
507
+
508
+ Every other code: **system-compose** [diagnostic codes](../system-compose/references/diagnostic-codes.md).
509
+
510
+ ## Hard rules
511
+
512
+ 1. Follow the stage order; going back is normal, skipping a stage's exit
513
+ check is not.
514
+ 2. Fix findings in the model or a provider's config, never in generated
515
+ files (`out/`, native folders, `firmware/`, generated documents).
516
+ 3. Every number traces to a source, a recorded decision, or an `assumption`
517
+ trait. A passing check validates the model, not the hardware.
518
+ 4. No orders, uploads, prints, accounts or credentials; physical steps are
519
+ for a person.
520
+ 5. Work at the level asked for. A rough draft is the concept: 3 to 6
521
+ blocks. Ask before going a level deeper.
522
+ 6. Describe a project from what `inspect` and `check` report now, never
523
+ from memory.
524
+ 7. Never tell the person to run npm in a project. Ask before a
525
+ project-local install.
526
+ 8. Never make placeholder CAD or 3D models from datasheets while the part's
527
+ UHD artifacts or its JLC/LCSC source has one; when none does, ask first.
528
+ 9. A board change goes where it belongs (the model, the tscircuit stage, a
529
+ stack bug, then KiCad), said before the edit; a locked board is unlocked
530
+ and re-locked for an upstream change, by the person's decision.
531
+
532
+ ## Diagram layout
533
+
534
+ The diagram is the first thing the person looks at, at every level of
535
+ detail. A level is not done until its diagram reads. At the end of
536
+ every level (concept, blocks, parts) and after any change that adds or
537
+ removes modules:
538
+
539
+ 1. **Lay it out by function.** The module most things connect to (the
540
+ processor, the flight controller, the power stage) in the middle; what
541
+ feeds it (connectors, power) on the left; what it drives (sensors,
542
+ outputs) on the right; parts that work together side by side. Compact and
543
+ about the shape of a screen: never a long row or column of parts. Parts
544
+ linked to nothing (seals, pads, consumables) go together below the rest.
545
+ 2. **Measure it.** `npx protoboard layout` (`project_layout` on the MCP
546
+ server) reports each level as the viewer draws it: line crossings,
547
+ overlapping cards, the longest row or column of cards (a strip), the
548
+ aspect ratio, lines under cards, and what to fix.
549
+ 3. **Fix what it reports.** `npx protoboard layout <level> --apply` lays a
550
+ level out afresh; `--tidy` keeps your arrangement and fixes it; `--pin
551
+ <card>` keeps a card you placed on purpose. Or move cards in
552
+ `.protoboard/display.json` (the project's `AGENTS.md`, "The diagram's
553
+ layout") and measure again. Two tries per level: if it still does not
554
+ pass, say what is left and show it, rather than going round again.
555
+ 4. **Look at it** in the viewer (`npx protoboard dev`, or VS Code) as the
556
+ person will, then report the numbers with the level. `check` lists a
557
+ level of modules that still needs work as `PB_DIAGRAM_LAYOUT` (info).
558
+
559
+ A board's own sheet is laid out as a schematic. When a board of dozens of
560
+ parts reports a strip or many crossings, the fix is in the model, not the
561
+ file: group its parts into sub-modules by function (power, processor,
562
+ sensors, outputs), each a level of its own.