Skip to content

Project template — one repo per product, rules baked in

Status: task #150 completed and closed, 2026-11-04. PR #49 merged as a40e7041; latest master is installed in ~/kicad-lib. The PCB design rules reference owns the current nine classes and three profiles. SOP-021 v1.21 owns the process/release gate. The numerical profiles are corrected and natively verified; actual products retain their own DRC, stackup calculation and matching fab-order requirements.

The September comparison below is historical research. Its six-class description, “safe everywhere” guarantee and 0.25 mm “annular ring” are superseded.

Manufacturer rule inquiries — 2026-11-04

Task #352 records the manufacturer inquiry batch: JLCPCB, PCBWay, NextPCB, ALLPCB, Elecrow, Seeed Fusion, Eurocircuits, PCB Train/Newbury Electronics, Sierra Circuits and AdvancedPCB. Angel sent the inquiries; Gmail Sent readback on 2026-11-04 confirms all ten recipients (11 messages, PCB Train twice in the same thread), 07:30–07:32 America/New_York. Delivery is not established. The closed preparation task holds the sent-message links and official contact/technical sources. No automated reply monitoring or follow-up is configured. Questions seek versioned KiCad rules and process-specific stackup/impedance guidance; no new fabrication limits were adopted. Task #150 remains closed; any later manufacturer response must be checked against its actual service/build before changing KiCad rules.

Reply review, 2026-11-04: JLCPCB and AdvancedPCB replied; full evidence and unresolved questions are recorded on task #352. JLCPCB's capability screenshots confirm the distinction between via pad diameter and annular-ring width and link the impedance calculator, but do not approve a stackup or finish the hole/clearance answers. AdvancedPCB supplies facility-dependent guidance and requires sales/manual quoting for controlled dielectric; its reply misreads our lead-free HASL option as leaded solder, so that quote conclusion needs clarification. Neither reply supplies a KiCad rule file or an approved USB/RF geometry. No new fabrication limits adopted and no email sent during review.

Historical plan and research (September 2026)

Historical decision: approved 2026-09-15 (Angel, task 150): safe-everywhere rule set as the template default, six net classes kept, a JLCPCB-only .kicad_dru for boards needing finer geometry. The two JLCPCB numbers (0.25 mm figure, USB 90 Ω width/gap) are checked when the dru files are written. Plan started 2026-09-13.

Historical question to Engineering (resolved by task #150): adopt the safe-everywhere design-rule set as the KiCad template default (0.20/0.20 track/space, 0.30 drill, 0.15 annular ring, 0.30 copper-to-edge, 0.15 silk, 0.10 mask dam, 1 oz, no impedance assumed) so any board can go to any of six fabs unchanged, keep the six existing net classes, and add a second JLCPCB-only .kicad_dru for boards that need finer geometry. Numbers and sources are in "Fab capabilities" below; two items still need an engineer's eye (JLCPCB's 0.25 mm figure, and the USB 90 Ω width/gap from JLCPCB's impedance calculator). Approve, amend the table, or reject on the home page. Angel's ask: a template KiCad repo carrying our rules (net classes, trace widths, clearances), an SOP for starting a new PCB, and an answer to the harder question — a product is not just a board. It has an enclosure, firmware, an app, labels, artwork. How is that captured?

What the Real Cow teaches

The Real Cow exists across five repos: Cow_Robot_Board, Cow_Remote, Cow_LCD, The_Real_Cow_Flasher, The_Real_Cow_Configurator. Each is sensible alone. Together they have no front door: nothing says what the product is, which board revision ships with which firmware, or where the enclosure lives. Answering "what did we ship?" means knowing the history.

What it got right, and the template should keep: Cow_Robot_Board already holds hardware/, firmware/, FreeCad/ and Solidworks/ side by side. The shop's instinct was already one-repo-per-thing-you-build. The drift was the remote, the LCD and the two apps becoming their own islands.

The decision: one repo per product

At two people, the coordination cost of five repos beats the coupling cost of one — badly. A product gets one repo, with a fixed shape:

product.yml            the manifest — what this is, and where every piece lives
hardware/<board>/      one KiCad project per board, from the template
firmware/<target>/     one per MCU
app/                   configurator, mobile, whatever the customer touches
mechanical/            enclosure, CAD source and exported STEP/STL
artwork/               labels, silkscreen art, packaging, the printed insert
test/                  fixtures, test plans, and the Universal Tester plan (TOML)
docs/                  the datasheet, the manual, compliance evidence
.github/workflows/     the checks

Where a piece genuinely must live elsewhere — a public configurator, a fork of somebody else's flasher — it stays where it is and product.yml points at it. The manifest is what makes a product findable even when it is not all in one place. That is the whole trick, and it is why the manifest matters more than the folder layout.

product.yml

The one file that makes a scattered product coherent, and the thing the engineering portal reads (engineering-portal):

product: The Real Cow
ipn: EE-P-0007              # the ERP part number — the ERP owns the number (SOP-001)
status: shipping            # concept | prototype | shipping | retired
revision: C                 # the PRODUCT revision, not the board's
boards:
  - name: Robot Cow
    path: hardware/robot-cow
    revision: 004B
    ipn: EE-A-0031
firmware:
  - target: STM32G0
    path: firmware/robot-cow
    builds_for: [Robot Cow 004B]
mechanical: mechanical/enclosure-v3
artwork: artwork/
external:
  - what: Configurator (public, browser)
    repo: EmbeddedEra/The_Real_Cow_Configurator
compliance: docs/compliance/     # FCC IDs, UN38.3, RoHS — see embeddedera-business

Why a manifest rather than a README: a person reads a README; the portal, the audit and the ERP sync read a manifest. It is checkable — "every board has an IPN", "status shipping implies compliance evidence exists" become audit rules the same way SOP checks are.

The KiCad template, with the rules in it

hardware/<board>/ starts as a copy of the template already in the KiCad repo (template/EmbeddedEra_Project), extended so a new board is correct by default rather than correct if you remember:

  • Net classes — Default, Power, HV, USB (90 Ω differential), RF (50 Ω), and a documented trace width, clearance and via size for each.
  • A .kicad_dru custom rules file for the things net classes cannot say: annular ring minimums, edge clearance, courtyard overlap, silkscreen over pad.
  • A stackup that matches what we order — JLCPCB 2- and 4-layer are already separate templates; keep that and name the fab in the template's name, because the rules are the fab's, not ours.
  • Sheet template and title block already filled with the shop's details.
  • The ERC/DRC severities we mean, saved in the project, so the checks in CI and the checks in the editor agree.

Where the numbers come from: whatever JLCPCB's capability page says for the process we actually buy, not folklore. Writing this down is part of the work, and it is the part that needs an engineer rather than me.

SOPs

  • SOP-021 New PCB Design — start from the template, name and number it (SOP-001), the net classes and when to deviate, when a review happens, what "done" means (ERC and DRC clean, BOM resolves to real IPNs, fab files generated by CI not by hand).
  • SOP-022 Product Records — what a product repo must contain, product.yml, how a revision is cut, and what evidence a shipping product must carry.

Both cross-reference SOP-008 KiCad Library and SOP-001 Part Numbering instead of restating them.

Order

  1. Write the rules down (net classes, widths, clearances) — needs the fab's capabilities.
  2. Extend the KiCad project template with those rules and the DRU file.
  3. Create EmbeddedEra/Project_Template with the folder shape, product.yml, and the checks workflow already wired.
  4. SOP-021, then SOP-022. (018 Content Publishing, 019 Cloudflare Changes and 020 Credentials were written on 2026-09-14 — numbers are sequential and never reused.)
  5. Backfill product.yml for the Real Cow across its five repos — the test of whether the manifest idea actually works is whether it can describe the messy real case.
  6. The portal reads the manifests (engineering-portal).

Related: KiCad, engineering-portal, task-board, universal-tester-product.

Fab capabilities (research, 2026-09-14)

Scouted from the fabs' own capability pages by a research agent; every number carries its URL below. Cells marked unverified were not on an official page. Not yet checked by an engineer — that check is task 150. Two known weak spots to verify first: the agent labelled JLCPCB's 0.25 mm figure "annular ring" but it is more likely the minimum via pad diameter (0.15 drill + 0.05 ring each side), and it did not find JLCPCB's impedance calculator (it exists at jlcpcb.com/pcb-impedance-calculator; the stackup codes such as JLC04161H-7628 are shown there, not on the capabilities page).

Fab Track/Space 2L Track/Space 4L Min drill Annular ring Hole-to-Cu Hole-to-hole Cu-to-edge Silk width Mask dam Thickness Copper ENIG Impedance
JLCPCB 0.10/0.10 0.09/0.09 0.15 0.25 (see note) ~0.2 unverified ≥0.2 ≥0.15 0.10 0.4–2.0 1–4.5 oz out, 0.5–2 in yes ±10 %, 4+ layers
PCBWay 0.10/0.10 0.10/0.10 0.15 0.15 ~0.1 unverified 0.25 0.15 0.05 0.2–3.2 1–8 oz out, 1–4 in yes ±10 %
NextPCB 0.08/0.08 0.08/0.08 0.15 ≥0.1 ~0.1 unverified ≥0.2 ≥0.12 ≥0.04 0.6–3.2 1–2 oz out, 0.5–2 in unverified ±10 %
Seeed Fusion 0.15/0.15 0.15/0.15 0.3 unverified unverified unverified unverified unverified 0.1 0.8–2.0 1 oz out yes (+$10) unverified
Elecrow 0.20/0.20 0.20/0.20 0.3 0.15 0.3 0.45 unverified 0.15 unverified unverified 1 oz all unverified no
ALLPCB 0.10/0.10 0.10/0.10 0.2 ≥0.153 unverified unverified ≥0.3 ≥0.15 unverified 0.4–3.2 1–2 oz out, 0.5–2 in yes yes, details unverified
Safe everywhere 0.20/0.20 0.20/0.20 0.30 0.15 0.30 0.45 0.30 0.15 0.10 0.8–2.0 1 oz yes do not assume

All mm. "Safe everywhere" is the tightest rule set that passes every fab listed; it is also, not by accident, almost exactly what the KiCad template already uses (0.20 track, 0.20 clearance, 0.60/0.30 via, 0.5 edge). The design-rule decision is therefore: ship the safe set as the template default (a board can go to any of six fabs unchanged) and keep a JLCPCB .kicad_dru for the boards that need the headroom (USB-C, fine-pitch BGA).

Assembly: JLCPCB in-house library + consigned, 0201 yes, BGA 0.35 mm, 2–3 days; PCBWay 0201 risky, BGA 0.25 mm with X-ray, 8–48 h; NextPCB BGA 0.5 mm; Seeed 0402 minimum, 4–6 days; Elecrow 0201 claimed. Price bands were not found on official pages (unverified).

Sources: JLCPCB https://jlcpcb.com/capabilities/pcb-capabilities and https://jlcpcb.com/capabilities/pcb-assembly-capabilities · PCBWay https://www.pcbway.com/capabilities.html, https://m.pcbway.com/assembly-capabilities.html · NextPCB https://www.nextpcb.com/pcb-capabilities · Seeed https://wiki.seeedstudio.com/Service_for_Fusion_PCB/ · Elecrow https://www.elecrow.com/blog/a-complete-guide-from-kicad-design-to-pcb-prototyping-order.html · ALLPCB https://www.allpcb.com/standard_pcb_manufacturing_capability.html

Rule files to fork (no fab publishes an official .kicad_dru): Cimos/KiCad-CustomDesignRules (JLCPCB + PCBWay, KiCad 8), labtroll/KiCad-DesignRules (JLCPCB, KiCad 7), Huaqiu-Electronics/NextPCB-Manufacturing-Rules (NextPCB).

Build plan for task 151 (2026-09-14)

What already exists, checked before planning (Hard Rule 1):

  • The KiCad template already carries six net classes (kicad-lib/template/EmbeddedEra_Project: Default 0.20, Signal_Robust 0.25, Power_500mA 0.40, Power_1A 0.60, Power_2A 1.00, USB2 0.20 pair) plus naming conventions, README and AGENTS.md — the Universal Tester 003 repo's EMBEDDEDERA_TEMPLATE_UPDATE_PLAN.md did that work and marks it complete. Task 150 is therefore smaller than it reads: not "invent the classes" but "confirm the fab minimums and write them into a .kicad_dru". UT003's PCB_NET_CONSTRAINTS_PLAN.md already used JLCPCB-derived values (0.1375 mm clearance, 0.20 mm min track, 0.60/0.30 via) and is the best starting point.
  • Universal_Tester_003 is already the target shape (hardware/kicad, hardware/enclosure, firmware/, host/, docs/, README with a layout table). The template should look like UT003 tidied up, not like something new; Cow_Robot_Board (hardware/<rev>/, firmware/, FreeCad/, Solidworks/) is the second reference.
  • EmbeddedEra-products/templates/product-template + new_product.py is a different idea (the modular-ECU merge workspace with fusion/modules submodules). Leave it alone; it is not a per-product repo template and its copy-and-rename script is replaced by GitHub's own template feature below.
  • CI: kicad-lib/.github/workflows/kicad-checks.yml (KiCad 10.0.5 container + kicad-cli, written 2026-09-13, not yet pushed — task 100) is the check to reuse verbatim. Community alternatives were checked: KiBot (739★, community default, but KiCad 10 support limited as of v1.9.1) and actions-for-kicad/kicad-actions (25★, KiCad 10 ok). Neither is needed: kicad-cli already exports gerbers, drill, BOM and position files, so fab outputs are a second job in the same workflow, no extra tool. Revisit KiBot only if we want the PDF/3D render set.
  • Manifest: Open Know-How (OKH v1, iop-alliance, active) is the published standard for describing open hardware, but it models one design, not "board X rev 4.0.1 ships with firmware Y". Decision: keep product.yml, but use OKH's field names wherever they overlap (title, version, license, repo, documentation-home, bom) so an OKH export is a mapping, not a rewrite. CycloneDX HBOM is for supply-chain SBOMs, not this.
  • Design-rule files: labtroll/KiCad-DesignRules (362★, JLCPCB, KiCad 7 syntax) and tinfever/KiCAD-Custom-DRC-Rules-for-JLCPCB-with-Unit-Tests (4-layer, with test boards) are the references to fork; .kicad_dru is native in KiCad 10 with a graphical editor, so the file ports.

Steps

  1. Task 150 — design rules (engineer, ~1 h, blocks the rest). Open JLCPCB's capability page for the 2-layer 1 oz and 4-layer processes we buy and fill one table: min track/space, min annular ring, min drill, min hole-to-copper, edge clearance, silkscreen minimums, USB 90 Ω width/gap for each stackup (JLC's impedance calculator, JLC04161H-7628 for 4-layer). Decide whether the six existing classes stay. Output: the table in this note. Claude then writes EmbeddedEra_JLCPCB_2L.kicad_dru and _4L.kicad_dru from labtroll/tinfever as the base, sets the board minimums in the two template .kicad_pro files, and runs kicad-check on the template to prove it is DRC-clean out of the box.
  2. Create EmbeddedEra/Project_Template (Claude, no engineer needed). Private repo, marked a GitHub template repository (gh repo edit --template), so a product starts with gh repo create EmbeddedEra/<Product> --template EmbeddedEra/Project_Template --private and the copy-rename script goes away. Contents:
  3. product.yml with every field present and a # required / # optional comment, plus docs/product-yml.md documenting each field.
  4. hardware/board-1/ = a copy of the KiCad template (post step 1); firmware/, app/, mechanical/, artwork/, test/, docs/ each with a one-paragraph README saying what goes there and what must not (no generated fab files, no backups, no .DS_Store).
  5. .gitignore and .gitattributes merged from UT003 and kicad-lib (KiCad backups, -cache, fp-info-cache, *.bak, STEP exports as LFS).
  6. .github/workflows/kicad-checks.yml copied from kicad-lib, with the library tables step changed to clone EmbeddedEra/KiCad at a pinned tag (a product repo has no libraries of its own); a second job fab-outputs that on a tag hw/<board>/<rev> runs kicad-cli pcb export gerbers|drill|pos and sch export bom, zips them, attaches them to the GitHub release.
  7. .github/workflows/manifest-check.yml: a 40-line Python check that product.yml parses, every boards[].path exists and contains a .kicad_pro, every board has an ipn, and status: shipping implies docs/compliance/ is non-empty. This is what makes the manifest auditable (SOP-022 later cites this check).
  8. AGENTS.md from the KiCad template, extended with the repo shape.
  9. README with the layout table (UT003 style) and the "start a product" steps.
  10. Prove it on a fresh clone: create a throwaway repo from the template, push, watch both workflows go green, delete the throwaway. Then push task 100's workflow to kicad-lib the same day so the two repos run the same checks.
  11. SOP-021 New PCB Design, SOP-022 Product Records (task 152) — written against the real template, not before it. SOP-021 is mostly "use the template; deviate from a net class only with a comment in the schematic"; SOP-022 is the product.yml contract and the revision cut (tag hw/<board>/<rev> = fab outputs frozen).
  12. Real Cow backfill (task 153): one product.yml in Cow_Robot_Board pointing at the other four repos through external:. If the manifest cannot describe it, the schema is wrong and gets fixed before SOP-022 is published. Second test: Universal_Tester_003, which should need only the manifest and a workflow.
  13. Add a tile for the engineering portal reading manifests later (engineering-portal).

What needs Angel

  • Task #150's generic rule decision is complete. Product-specific calculation/fabrication review is part of each product's release, not a pending owner decision on this template task.

Open

Log

  • 2026-11-04 close-out after owner explicitly requested completion: task #150 closed in Engineering/Done. PR #49 merged as a40e7041 and pulled into the main KiCad checkout. Three generic profiles now separate PTH/via rings and hole spacing, enforce NPTH/pad/edge coverage, and keep the stronger PTH floor on mixed PTH/via pairs. Older stricter JLCPCB values were retained; Hellen source boards/class presets were not changed. The generic USB requirement is resolved by a documented process decision: no manufacturer-controlled impedance claim for the generic 2L option; a product needing controlled USB/RF selects a supported stackup and retains a calculation plus matching fab control requirement before release. No universal width/result or real-board approval was invented. Evidence: vendor manufacturing guide and stackup reference in the repo doc. Stock KiCad10.0.7 passed seven bad/good pairs, a layer-specific ring check and 5mm active-parser probe for each profile. Original-profile negative control failed; the mixed-pair regression failed before correction and passed after. 80 checker tests passed; local native gate zero blockers; final hosted gate passed (run41826410300, 2m28s) on b2700b63; master tree matches that checked tree. SOP-021v1.21 published at https://3d92a78f.embeddedera-sop.pages.dev and built page verified. Read-only GPT-6.1Sol agents handled research (medium), final review (high) and corrective review (medium); the review blocker was reproduced and fixed. Codex allowance observations:4% before,5% after (app-server observations1793792170/1793793372; shared usage, not precise attribution); CLI dollar estimate unavailable. No paid API route or reset credit used.

  • 2026-11-04, task #150: pulled KiCad master to ae5ca35d (large Hellen/quality-gate update). Nine net classes and three rule profiles already ship; added canonical docs/PCB-DESIGN-RULES.md and linked repo/template/tool entry points in commit e159fe73, draft PR #49. Source comparison by tool-disabled Claude Sonnet 5.5 (CLI list-price estimate $0.1212 on the subscription, not an API charge); independently matched all nine class rows and three profile rows to actual files; links resolve; repository metadata check zero blockers. Documented Hellen module-outline exception, complete blocks being schematic-only, and current JLCPCB process gaps (PTH rings, PTH track spacing, hole spacing, V-cut edge). Numerical rules/boards unchanged. SOP-021 1.20 corrects automatic power-class and “safe everywhere” claims and points to the repository reference. Task remains open for a verified 90 Ω calculator export and board-specific fab-rule sign-off; current browser host unavailable, so no production width/gap invented.

  • 2026-09-13: written, after looking at how the Real Cow is spread across five repos.
  • 2026-09-14: build plan for task 151 written after checking existing work (KiCad template already has the net classes; UT003 is the reference shape; GitHub template repos replace the copy script; OKH field names, not OKH itself; kicad-cli, not KiBot, for CI).
  • 2026-09-14: fab capability table added from a research pass over six Asian fabs; the safe-everywhere set matches the template's current numbers. Engineer check pending (task 150).
  • 2026-09-15: design rules approved by Angel as proposed; build (task 151 chain) to follow when there is time.
  • 2026-09-15: step 2 done — template/EmbeddedEra_Project/EmbeddedEra_Project.kicad_dru (safe-everywhere, the default) and EmbeddedEra_JLCPCB.kicad_dru (JLCPCB-only, ported from labtroll) written; board minimums in the .kicad_pro set to the safe set; template DRC clean; pushed to EmbeddedEra/KiCad. Two JLCPCB numbers still marked to confirm by eye (via pad figure, USB 90 Ω width/gap).
  • 2026-09-15: step 3 done — EmbeddedEra/Project_Template exists (private, template). Smoke test proved manifest-check; kicad-checks needs a read token for the private library (KICAD_LIB_TOKEN). Step 4 (SOP-021/022) drafted. Step 5 (Real Cow) is next.
  • 2026-09-15: fab pack added to CI. Any hw/<board>/<rev> tag now attaches <board>-<rev>-fab.zip (gerbers, drill, BOM, CPL, assembly PDFs, top/bottom/iso renders, REQUIREMENTS.md rendered from hardware/<board>/fab.yml). Proven on a throwaway tag, then deleted. Release upload uses softprops/action-gh-release because the KiCad image has no gh. Copied to Dashcam_Drive. SOP-021 v1.1.
  • 2026-09-15: Robot Cow pilot of the alternates decision done. ERP: EE-A-0002-A Robot Cow (pk 181), EE-P-0002-A PCB, 11 new components EE-C-0169…0179, 25 BOM lines, 4 substitutes. Schematic IPNs on branch erp-ipn of Cow_Robot_Board (not merged). erp-bom-export <assembly IPN> writes the order BOM with alternates. Open: R29–R31 value 1k vs MPN 330R; 8 lines have no MPN yet (D1, D10, D14, FB1, J10, J11, RT1, U5).
  • 2026-10-15: Template review before a hand-started board. Measured: renaming pro/sch/pcb without the .kicad_dru silently drops every custom rule (probe track flagged with the matching name, not with a mismatched one); both rule files load. Fixed in KiCad repo: USB_D+/USB_D- now auto-assign to USB2 (checked with pcbnew GetEffectiveNetClass), Revision defaults to A, README lists all 9 classes. SOP-021 v1.15. Schematic fixes left as an Open item.

  • 2026-10-15: Logo on the board: EmbeddedEra_Logo_Mark_5mm/8mm and _Lockup_15mm/25mm silkscreen footprints (board-only, out of BOM/CPL) built from the approved v1 lockup SVG with svg2mod + scripting/pcb/make_logo_footprints.py; template board has the 5 mm mark beside its name text, DRC 0. Trap: giving svg2mod an SVG with mm width/height scaled x and y differently (aspect 1.34 vs 1.63); feed it untouched. Sub-0.15 mm loss measured at 0.2-1.2% (corners only).

  • 2026-10-16: Template fixed and split by function (KiCad commits 9692994, a9a6012): symbols refreshed (pins proven identical), ERP IPNs on every part, C2 1u 50V, rail +3V3, worksheet 004 CUSTOMER, PCB title, root overview + Power/MCU/Controls with global interface labels. Netlist identical (47 nets) apart from the rail rename; tidy-check 0 overlaps. Review page: projects/kicad-template-review.md. Trap: local labels become /Sheet/NAME after a split, so net-class patterns stop matching; cross-sheet nets must be global labels.
  • 2026-10-16: Logo v2 (design/logo-v2) put in the KiCad template at the owner's request: worksheet 004 wordmark and the four silkscreen logo footprints (KiCad 76a9375). Owner set aside the J1 inactive-IPN and passive-library IPN items.
  • 2026-10-16: Title block rebuilt as worksheet 005 by scripting/pcb/make_title_block.py (caption over value, one grid); review fields drive SOP-021 v1.16 steps 2 and 12; notice grammar fixed with the owner (same meaning).
  • 2026-10-16: Title-block logo fixed (5aedc4e): v2 hex mark + wordmark on a transparent PNG; the opaque wordmark had printed as a white box. Handoff: template work done and pushed; review page https://notebook.embeddedera.com/projects/kicad-template-review/. Waiting on the owner: OK on the reworded confidentiality notice (else restore the old wording in scripting/pcb/make_title_block.py and regenerate 005). Open to-dos stay in this note's Open section (title block in assembly PDFs, release check).
  • 2026-10-30: Title block 006 adopted (owner). KiCad template project -> 006: PR EmbeddedEra/KiCad#6 (title-block-006, 16961dc). Project_Template PR #2 now 006 (8894427, renamed "Title block 006 + CI ..."). Released boards (GDA rev A etc.) keep the block they were released with.
  • 2026-10-16: Title block 006 added as an alternative to 005 (KiCad 697547b), after the owner said the CUSTOMER and TITLE cells left a lot of empty space. 006: stacked logo (mark over wordmark) in a two-row cell, TITLE a two-row cell with a 3.4 mm value, STATUS over a large REV in their own column, CUSTOMER moved beside DESCRIPTION, values 1.8 mm. make_title_block.py <pngs> <out> 006; 005 output proven unchanged. Preview: assets/kicad-template/title-block-006.png (approximate render, no KiCad in the cloud). Decided 2026-10-30: owner picked 006 ("go with the latest").

Audit follow-up — 2026-09-16

  • Repair ordinary branch-push triggers; distribute missing checker/manifest files to Cow repos; make tool/report failures fail CI, fix report artifact paths, and require checks before fab release. Evidence and priorities: engineering-workflow-audit-2026-09-16.
  • Title block / release gate are in Project_Template (9e12bef, 2026-10-16). Still open from the audit: roll the same workflow into Cow_Robot_Board, Cow_Remote and Dashcam_Drive; refresh Project_Template's own hardware/board-1 (still worksheet 003, Costumer, Designer AGD, no Status/Checker/Approver/Release_Date, so it fails the new gate by design); needs: erc-drc on fab-outputs, branch push trigger and report path from the audit P1s. See engineering-workflow-audit-2026-09-16.
  • Reconcile legacy revision labels with controlled release revisions, strengthen manifest validation, pin shared inputs and record release provenance. See engineering-workflow-audit-2026-09-16.

  • 2026-09-16: Audit confirmed missing Cow checker scripts, tag-only KiCad push triggers, releases succeeding despite check failure, starter title-block placeholders, production revision mismatch, and assembly PDFs without title blocks. Report engineering-workflow-audit-2026-09-16 includes reproduced evidence and rollout acceptance checks; no templates or pipelines changed.

  • 2026-09-16: Robot Cow production board moved to hardware/Robot-Cow-004B (was mistakenly hardware/Robot Cow 4.0.1). ERP (EE-A-0002-A, pk 181): description updated, BOM rebuilt to 004B (29 lines: dropped D11/D12/R25/R26 line refs and the SOD-123 zener line; added C5/C6, D3/D4, R7/R8, U7 to existing part lines; new parts EE-C-0180 4.7K, EE-C-0181 220R, EE-C-0182 ZMM5V1 MiniMELF; swapped D13/D15 LED colour lines). Schematic: IPN hidden property added to all 65 fitted symbols in Robot-Cow-004B.kicad_sch (ERC unchanged, 4 errors/276 warnings). fab.yml moved from the retired 4.0.1 board to 004B. product.yml: EE-P-0002-A now on 004B, 4.0.1's ipn set null. Released hw/Robot-Cow-004B/A (fab-outputs job green, Robot-Cow-004B-A-fab.zip); old hw/Robot_Cow_4.0.1/A release and tag deleted.
  • 2026-09-16: Cow Remote entered the ERP: assembly EE-A-0004-A (pk 199), bare PCB EE-P-0004-A (pk 200); 10 finished, bagged units counted into Finished goods as stock item 31 (SOP-023) and a 2×1.5 in stock label with the quantity printed on the Zebra. product.yml updated. The 006 BOM is not in the ERP yet (same pilot flow as the Robot Cow when needed).
  • 2026-10-16: Project_Template kicad-checks.yml: assembly PDFs now use --include-border-title (top and bottom checked on the template board, title block upright on the mirrored bottom page); new .github/scripts/release_check.py blocks a hw/ tag unless Status is RELEASED, Designer/Checker/Approver/Release_Date are set, Revision equals the tag revision and Part_Number is an EE-P IPN (positive and negative cases run). SOP-021 v1.17.