@hybridlabor-api/bdb-hardware-pcb 0.1.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 (192) hide show
  1. package/README.md +116 -0
  2. package/config/mcp/antigravity.json +22 -0
  3. package/config/mcp/claude.json +22 -0
  4. package/config/mcp/codex.toml +25 -0
  5. package/docs/adr/ADR-001-KICAD-OPENSCAD-MCP-STRATEGY.md +334 -0
  6. package/docs/review_documentation.md +121 -0
  7. package/installer.js +358 -0
  8. package/mcp_servers/kicad-mcp-server/.env.example +22 -0
  9. package/mcp_servers/kicad-mcp-server/.github/workflows/ci.yml +36 -0
  10. package/mcp_servers/kicad-mcp-server/CLAUDE.md +487 -0
  11. package/mcp_servers/kicad-mcp-server/README.md +316 -0
  12. package/mcp_servers/kicad-mcp-server/docs/DEVICE_TREE.md +416 -0
  13. package/mcp_servers/kicad-mcp-server/docs/INSTALLATION.md +332 -0
  14. package/mcp_servers/kicad-mcp-server/docs/PIN_ANALYSIS.md +332 -0
  15. package/mcp_servers/kicad-mcp-server/docs/README.md +240 -0
  16. package/mcp_servers/kicad-mcp-server/docs/TESTING.md +613 -0
  17. package/mcp_servers/kicad-mcp-server/docs/VALIDATION.md +268 -0
  18. package/mcp_servers/kicad-mcp-server/pyproject.toml +96 -0
  19. package/mcp_servers/kicad-mcp-server/requirements-dev.txt +16 -0
  20. package/mcp_servers/kicad-mcp-server/requirements-test.txt +24 -0
  21. package/mcp_servers/kicad-mcp-server/requirements.txt +13 -0
  22. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__init__.py +3 -0
  23. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__main__.py +17 -0
  24. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/config.py +46 -0
  25. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/__init__.py +1 -0
  26. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/types.py +87 -0
  27. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/__init__.py +1 -0
  28. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/netlist_parser.py +234 -0
  29. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser.py +375 -0
  30. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser_kicad.py +327 -0
  31. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/schematic_parser.py +902 -0
  32. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/server.py +71 -0
  33. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/__init__.py +1 -0
  34. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/arduino/connectivity_test.cpp.j2 +189 -0
  35. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/atmega.dts.j2 +77 -0
  36. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/esp32.dts.j2 +77 -0
  37. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/nrf52.dts.j2 +77 -0
  38. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/stm32f4.dts.j2 +89 -0
  39. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/esp_idf/test_suite.c.j2 +340 -0
  40. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/pytest/test_connectivity.py.j2 +147 -0
  41. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/st_hal/hal_test.c.j2 +313 -0
  42. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_gpio_test.py.j2 +99 -0
  43. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_i2c_test.py.j2 +117 -0
  44. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_pinmux_test.py.j2 +43 -0
  45. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_spi_test.py.j2 +94 -0
  46. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_gpio_test.c.j2 +113 -0
  47. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_i2c_test.c.j2 +101 -0
  48. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_spi_test.c.j2 +94 -0
  49. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/unittest/test_schematic.py.j2 +172 -0
  50. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/__init__.py +36 -0
  51. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/device_tree.py +1187 -0
  52. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/hierarchical_analysis.py +211 -0
  53. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/netlist.py +320 -0
  54. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/parts_registry.py +142 -0
  55. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb.py +955 -0
  56. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb_layout.py +308 -0
  57. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pin_analysis.py +765 -0
  58. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/project.py +196 -0
  59. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic.py +319 -0
  60. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_editor.py +674 -0
  61. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_search.py +158 -0
  62. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/validation.py +866 -0
  63. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/visualization.py +225 -0
  64. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/__init__.py +1 -0
  65. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/file_handlers.py +65 -0
  66. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_cli.py +103 -0
  67. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_version.py +103 -0
  68. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/parts_registry.py +197 -0
  69. package/mcp_servers/kicad-mcp-server/tests/__init__.py +1 -0
  70. package/mcp_servers/kicad-mcp-server/tests/examples/ESP32S3_TEST.md +219 -0
  71. package/mcp_servers/kicad-mcp-server/tests/fixtures/README.md +65 -0
  72. package/mcp_servers/kicad-mcp-server/tests/fixtures/__init__.py +1 -0
  73. package/mcp_servers/kicad-mcp-server/tests/fixtures/example_pcb.kicad_pcb +177 -0
  74. package/mcp_servers/kicad-mcp-server/tests/fixtures/example_schematic.kicad_sch +145 -0
  75. package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/child.kicad_sch +24 -0
  76. package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/root.kicad_sch +38 -0
  77. package/mcp_servers/kicad-mcp-server/tests/test_tools/__init__.py +1 -0
  78. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_hierarchical_labels.py +195 -0
  79. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_kicad_cli.py +116 -0
  80. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_netlist_cache_path.py +29 -0
  81. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic.py +189 -0
  82. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic_hierarchy.py +69 -0
  83. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_visualization.py +136 -0
  84. package/mcp_servers/kicad-mcp-server/uv.lock +2873 -0
  85. package/mcp_servers/openscad-mcp-server/.dockerignore +9 -0
  86. package/mcp_servers/openscad-mcp-server/.github/workflows/test.yml +40 -0
  87. package/mcp_servers/openscad-mcp-server/Dockerfile +29 -0
  88. package/mcp_servers/openscad-mcp-server/LICENSE +21 -0
  89. package/mcp_servers/openscad-mcp-server/README.md +154 -0
  90. package/mcp_servers/openscad-mcp-server/docs/audit.md +56 -0
  91. package/mcp_servers/openscad-mcp-server/docs/docker.md +66 -0
  92. package/mcp_servers/openscad-mcp-server/docs/issue-followup.md +19 -0
  93. package/mcp_servers/openscad-mcp-server/docs/jetson.md +17 -0
  94. package/mcp_servers/openscad-mcp-server/glama.json +4 -0
  95. package/mcp_servers/openscad-mcp-server/legacy/README.md +15 -0
  96. package/mcp_servers/openscad-mcp-server/legacy/README.original.md +294 -0
  97. package/mcp_servers/openscad-mcp-server/legacy/implementation_plan.md +100 -0
  98. package/mcp_servers/openscad-mcp-server/legacy/old/download_sam2_checkpoint.py +115 -0
  99. package/mcp_servers/openscad-mcp-server/legacy/old/src/ai/sam_segmentation.py +209 -0
  100. package/mcp_servers/openscad-mcp-server/legacy/old/src/models/threestudio_generator.py +231 -0
  101. package/mcp_servers/openscad-mcp-server/legacy/old/src/workflow/image_to_model_pipeline.py +260 -0
  102. package/mcp_servers/openscad-mcp-server/legacy/old/test_sam2_segmentation.py +96 -0
  103. package/mcp_servers/openscad-mcp-server/legacy/requirements.txt +57 -0
  104. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/README.md +39 -0
  105. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/ai-driven-code-generation.md +122 -0
  106. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/export-formats.md +76 -0
  107. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/ai/ai_service.py.md +51 -0
  108. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/main.py.md +63 -0
  109. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/models/code_generator.py.md +63 -0
  110. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/nlp/parameter_extractor.py.md +63 -0
  111. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/ai/natural-language-processing.md +78 -0
  112. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/nlp/parameter-extraction.md +173 -0
  113. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/export-formats.md +91 -0
  114. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/openscad-basics.md +66 -0
  115. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/primitive-testing.md +79 -0
  116. package/mcp_servers/openscad-mcp-server/legacy/src/__init__.py +0 -0
  117. package/mcp_servers/openscad-mcp-server/legacy/src/ai/ai_service.py +257 -0
  118. package/mcp_servers/openscad-mcp-server/legacy/src/ai/gemini_api.py +161 -0
  119. package/mcp_servers/openscad-mcp-server/legacy/src/ai/venice_api.py +203 -0
  120. package/mcp_servers/openscad-mcp-server/legacy/src/config.py +121 -0
  121. package/mcp_servers/openscad-mcp-server/legacy/src/main.py +1456 -0
  122. package/mcp_servers/openscad-mcp-server/legacy/src/main.py.new +404 -0
  123. package/mcp_servers/openscad-mcp-server/legacy/src/main_remote.py +401 -0
  124. package/mcp_servers/openscad-mcp-server/legacy/src/models/__init__.py +0 -0
  125. package/mcp_servers/openscad-mcp-server/legacy/src/models/code_generator.py +321 -0
  126. package/mcp_servers/openscad-mcp-server/legacy/src/models/cuda_mvs.py +209 -0
  127. package/mcp_servers/openscad-mcp-server/legacy/src/models/scad_templates/basic_shapes.scad +144 -0
  128. package/mcp_servers/openscad-mcp-server/legacy/src/nlp/__init__.py +0 -0
  129. package/mcp_servers/openscad-mcp-server/legacy/src/nlp/parameter_extractor.py +388 -0
  130. package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/__init__.py +0 -0
  131. package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/wrapper.py +418 -0
  132. package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/__init__.py +1 -0
  133. package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/printer_discovery.py +471 -0
  134. package/mcp_servers/openscad-mcp-server/legacy/src/remote/connection_manager.py +537 -0
  135. package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_client.py +435 -0
  136. package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_server.py +787 -0
  137. package/mcp_servers/openscad-mcp-server/legacy/src/remote/error_handling.py +415 -0
  138. package/mcp_servers/openscad-mcp-server/legacy/src/testing/__init__.py +0 -0
  139. package/mcp_servers/openscad-mcp-server/legacy/src/testing/primitive_tester.py +203 -0
  140. package/mcp_servers/openscad-mcp-server/legacy/src/testing/test_primitives.py +98 -0
  141. package/mcp_servers/openscad-mcp-server/legacy/src/utils/__init__.py +1 -0
  142. package/mcp_servers/openscad-mcp-server/legacy/src/utils/cad_exporter.py +241 -0
  143. package/mcp_servers/openscad-mcp-server/legacy/src/utils/format_validator.py +206 -0
  144. package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_exporter.py +140 -0
  145. package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_repair.py +91 -0
  146. package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_validator.py +123 -0
  147. package/mcp_servers/openscad-mcp-server/legacy/src/visualization/__init__.py +0 -0
  148. package/mcp_servers/openscad-mcp-server/legacy/src/visualization/headless_renderer.py +52 -0
  149. package/mcp_servers/openscad-mcp-server/legacy/src/visualization/renderer.py +177 -0
  150. package/mcp_servers/openscad-mcp-server/legacy/src/visualization/web_interface.py +639 -0
  151. package/mcp_servers/openscad-mcp-server/legacy/src/workflow/image_approval.py +148 -0
  152. package/mcp_servers/openscad-mcp-server/legacy/src/workflow/multi_view_to_model_pipeline.py +338 -0
  153. package/mcp_servers/openscad-mcp-server/legacy/test_complete_workflow.py +374 -0
  154. package/mcp_servers/openscad-mcp-server/legacy/test_cuda_mvs.py +191 -0
  155. package/mcp_servers/openscad-mcp-server/legacy/test_gemini_api.py +168 -0
  156. package/mcp_servers/openscad-mcp-server/legacy/test_image_approval.py +192 -0
  157. package/mcp_servers/openscad-mcp-server/legacy/test_image_approval_workflow.py +251 -0
  158. package/mcp_servers/openscad-mcp-server/legacy/test_image_to_model_pipeline.py +145 -0
  159. package/mcp_servers/openscad-mcp-server/legacy/test_model_selection.py +41 -0
  160. package/mcp_servers/openscad-mcp-server/legacy/test_multi_view_pipeline.py +290 -0
  161. package/mcp_servers/openscad-mcp-server/legacy/test_primitives.sh +13 -0
  162. package/mcp_servers/openscad-mcp-server/legacy/test_rabbit_direct.py +71 -0
  163. package/mcp_servers/openscad-mcp-server/legacy/test_remote_cuda_mvs.py +283 -0
  164. package/mcp_servers/openscad-mcp-server/legacy/test_venice_example.py +69 -0
  165. package/mcp_servers/openscad-mcp-server/pyproject.toml +33 -0
  166. package/mcp_servers/openscad-mcp-server/requirements.txt +2 -0
  167. package/mcp_servers/openscad-mcp-server/scad/simple_cube.scad +2 -0
  168. package/mcp_servers/openscad-mcp-server/scripts/test_docker.py +220 -0
  169. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__init__.py +3 -0
  170. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__main__.py +3 -0
  171. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/engine.py +94 -0
  172. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/geometry.py +242 -0
  173. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/server.py +245 -0
  174. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/service.py +190 -0
  175. package/mcp_servers/openscad-mcp-server/tests/conftest.py +17 -0
  176. package/mcp_servers/openscad-mcp-server/tests/test_engine.py +37 -0
  177. package/mcp_servers/openscad-mcp-server/tests/test_geometry.py +106 -0
  178. package/mcp_servers/openscad-mcp-server/tests/test_integration.py +172 -0
  179. package/mcp_servers/openscad-mcp-server/tests/test_transports.py +314 -0
  180. package/mcp_servers/openscad-mcp-server/uv.lock +1123 -0
  181. package/package.json +44 -0
  182. package/scripts/install_mcps.sh +86 -0
  183. package/scripts/openscad_wrapper.sh +62 -0
  184. package/scripts/run_kicad_mcp.sh +25 -0
  185. package/scripts/run_openscad_mcp.sh +41 -0
  186. package/scripts/test_mcp_connection.py +626 -0
  187. package/scripts/test_mcp_connection.sh +168 -0
  188. package/skills/code-first-hardware-design/SKILL.md +260 -0
  189. package/skills/pcb-constraint-definition/SKILL.md +236 -0
  190. package/skills/pcb-layout-routing-automation/SKILL.md +153 -0
  191. package/skills/pcb-validation-dfm-signoff/SKILL.md +194 -0
  192. package/skills/schematic-datasheet-analysis/SKILL.md +202 -0
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env bash
2
+ # ==============================================================================
3
+ # AOS MCP Verification Test Suite Runner
4
+ # ==============================================================================
5
+ # Companion bash script to execute scripts/test_mcp_connection.py against
6
+ # KiCad and OpenSCAD MCP servers, individual configs, and harnesses.
7
+ # ==============================================================================
8
+
9
+ set -euo pipefail
10
+
11
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
12
+ REPO_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
13
+ PYTHON="${PYTHON:-python3}"
14
+ VERIFIER="${SCRIPT_DIR}/test_mcp_connection.py"
15
+
16
+ # Ensure all scripts have executable permissions
17
+ chmod +x "${SCRIPT_DIR}/"*.sh 2>/dev/null || true
18
+
19
+ print_usage() {
20
+ echo "Usage: $0 [OPTIONS]"
21
+ echo ""
22
+ echo "Options:"
23
+ echo " --all Run complete test suite across runners and all config files"
24
+ echo " --kicad Test KiCad MCP server runner only"
25
+ echo " --openscad Test OpenSCAD MCP server runner only"
26
+ echo " --antigravity Test config/mcp/antigravity.json"
27
+ echo " --claude Test config/mcp/claude.json"
28
+ echo " --codex Test config/mcp/codex.toml"
29
+ echo " --configs Test all three multi-harness config files"
30
+ echo " --export-schemas Export Antigravity lazy schemas into ~/.gemini/antigravity-cli/mcp/"
31
+ echo " --report PATH Generate a machine-readable JSON verification report"
32
+ echo " --help Show this help message"
33
+ }
34
+
35
+ REPORT_FILE=""
36
+ MODE="default"
37
+
38
+ while [[ $# -gt 0 ]]; do
39
+ case "$1" in
40
+ --all)
41
+ MODE="all"
42
+ shift
43
+ ;;
44
+ --kicad)
45
+ MODE="kicad"
46
+ shift
47
+ ;;
48
+ --openscad)
49
+ MODE="openscad"
50
+ shift
51
+ ;;
52
+ --antigravity)
53
+ MODE="antigravity"
54
+ shift
55
+ ;;
56
+ --claude)
57
+ MODE="claude"
58
+ shift
59
+ ;;
60
+ --codex)
61
+ MODE="codex"
62
+ shift
63
+ ;;
64
+ --configs)
65
+ MODE="configs"
66
+ shift
67
+ ;;
68
+ --export-schemas)
69
+ MODE="export"
70
+ shift
71
+ ;;
72
+ --report)
73
+ REPORT_FILE="$2"
74
+ shift 2
75
+ ;;
76
+ --help|-h)
77
+ print_usage
78
+ exit 0
79
+ ;;
80
+ *)
81
+ echo "Unknown option: $1" >&2
82
+ print_usage
83
+ exit 1
84
+ ;;
85
+ esac
86
+ done
87
+
88
+ EXTRA_ARGS=()
89
+ if [[ -n "${REPORT_FILE}" ]]; then
90
+ EXTRA_ARGS+=("--json-report" "${REPORT_FILE}")
91
+ fi
92
+
93
+ # config/mcp/*.json|.toml are portable reference templates (placeholder
94
+ # __INSTALL_DIR__, no machine-specific path baked in — see their header
95
+ # comments). installer.js never reads them; it generates real configs at
96
+ # install time. For local verification only, resolve the placeholder to this
97
+ # checkout's actual path in a throwaway temp copy.
98
+ RESOLVED_TMP_FILES=()
99
+ cleanup_resolved_configs() {
100
+ for f in "${RESOLVED_TMP_FILES[@]+"${RESOLVED_TMP_FILES[@]}"}"; do
101
+ rm -f "$f"
102
+ done
103
+ }
104
+ trap cleanup_resolved_configs EXIT
105
+
106
+ resolve_config() {
107
+ local src="$1"
108
+ local ext="${src##*.}"
109
+ local tmp
110
+ tmp="$(mktemp "${TMPDIR:-/tmp}/mcp_config.XXXXXX")"
111
+ mv "${tmp}" "${tmp}.${ext}"
112
+ tmp="${tmp}.${ext}"
113
+ sed "s#__INSTALL_DIR__#${REPO_DIR}#g" "${src}" > "${tmp}"
114
+ RESOLVED_TMP_FILES+=("${tmp}")
115
+ echo "${tmp}"
116
+ }
117
+
118
+ case "${MODE}" in
119
+ default)
120
+ echo "Running default MCP connection verification..."
121
+ "${PYTHON}" "${VERIFIER}" ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}
122
+ ;;
123
+ kicad)
124
+ echo "Testing KiCad MCP Server Runner..."
125
+ "${PYTHON}" "${VERIFIER}" --command "${SCRIPT_DIR}/run_kicad_mcp.sh" ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}
126
+ ;;
127
+ openscad)
128
+ echo "Testing OpenSCAD MCP Server Runner..."
129
+ "${PYTHON}" "${VERIFIER}" --command "${SCRIPT_DIR}/run_openscad_mcp.sh" ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}
130
+ ;;
131
+ antigravity)
132
+ echo "Testing Antigravity MCP Config (config/mcp/antigravity.json)..."
133
+ "${PYTHON}" "${VERIFIER}" --config "$(resolve_config "${REPO_DIR}/config/mcp/antigravity.json")" ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}
134
+ ;;
135
+ claude)
136
+ echo "Testing Claude Code MCP Config (config/mcp/claude.json)..."
137
+ "${PYTHON}" "${VERIFIER}" --config "$(resolve_config "${REPO_DIR}/config/mcp/claude.json")" ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}
138
+ ;;
139
+ codex)
140
+ echo "Testing Codex MCP Config (config/mcp/codex.toml)..."
141
+ "${PYTHON}" "${VERIFIER}" --config "$(resolve_config "${REPO_DIR}/config/mcp/codex.toml")" ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}
142
+ ;;
143
+ configs)
144
+ echo "Testing all multi-harness configuration files..."
145
+ echo "--- 1. Testing Antigravity Configuration ---"
146
+ "${PYTHON}" "${VERIFIER}" --config "$(resolve_config "${REPO_DIR}/config/mcp/antigravity.json")"
147
+ echo "--- 2. Testing Claude Code Configuration ---"
148
+ "${PYTHON}" "${VERIFIER}" --config "$(resolve_config "${REPO_DIR}/config/mcp/claude.json")"
149
+ echo "--- 3. Testing OpenAI Codex Configuration ---"
150
+ "${PYTHON}" "${VERIFIER}" --config "$(resolve_config "${REPO_DIR}/config/mcp/codex.toml")" ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}
151
+ ;;
152
+ export)
153
+ TARGET_DIR="${HOME}/.gemini/antigravity-cli/mcp"
154
+ echo "Exporting lazy tool JSON schemas to ${TARGET_DIR}..."
155
+ "${PYTHON}" "${VERIFIER}" --export-antigravity "${TARGET_DIR}" ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}
156
+ ;;
157
+ all)
158
+ echo "Executing Full MCP Verification Suite..."
159
+ TARGET_DIR="${HOME}/.gemini/antigravity-cli/mcp"
160
+ "${PYTHON}" "${VERIFIER}" --export-antigravity "${TARGET_DIR}"
161
+ echo "--- Testing Antigravity Config ---"
162
+ "${PYTHON}" "${VERIFIER}" --config "$(resolve_config "${REPO_DIR}/config/mcp/antigravity.json")"
163
+ echo "--- Testing Claude Code Config ---"
164
+ "${PYTHON}" "${VERIFIER}" --config "$(resolve_config "${REPO_DIR}/config/mcp/claude.json")"
165
+ echo "--- Testing OpenAI Codex Config ---"
166
+ "${PYTHON}" "${VERIFIER}" --config "$(resolve_config "${REPO_DIR}/config/mcp/codex.toml")" ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}
167
+ ;;
168
+ esac
@@ -0,0 +1,260 @@
1
+ ---
2
+ name: code-first-hardware-design
3
+ description: "Programmatic schematic capture, circuit synthesis (SKiDL, text netlists, S-expressions), and parametric 3D CAD enclosure co-design (OpenSCAD/BOSL2). Use when generating circuits in code, exporting netlists, scripting KiCad schematics, or designing 3D enclosures."
4
+ category: engineering-hardware
5
+ compatibility: "Python 3.10+, SKiDL, OpenSCAD 2024+, BOSL2, mcp:openscad"
6
+ ---
7
+
8
+ # Code-First Hardware & Circuit Design
9
+
10
+ ## 1. Overview and Core Philosophy
11
+
12
+ In the AOS autonomous engineering architecture, hardware design is treated as code. Graphical schematic and mechanical CAD entry are prone to hallucinated coordinates, misaligned pins, and drift between PCB and enclosure models.
13
+
14
+ This skill governs two tightly integrated code-first workflows:
15
+ 1. **Programmatic Circuit Synthesis (SKiDL / S-Expressions)**: Generating electronic schematics, hierarchical sheets, and netlists via type-safe, reviewable Python code with built-in Electrical Rules Checks (ERC).
16
+ 2. **Parametric Mechanical Co-Design (OpenSCAD / BOSL2)**: Generating production-ready 3D enclosures driven directly by exported PCB physical outlines, mounting hole centroids, and connector coordinates.
17
+
18
+ ---
19
+
20
+ ## 2. Programmatic Circuit Synthesis via SKiDL
21
+
22
+ SKiDL allows circuits to be designed as Python programs. Components are instantiated from KiCad symbol libraries, connected via pythonic operator overloading, and compiled to netlists or KiCad schematic files.
23
+
24
+ ### 2.1 The SKiDL Connection Paradigm
25
+ - **Nets**: Created as `Net('NAME')`.
26
+ - **Buses**: Created as `Bus('DATA', 8)`.
27
+ - **Connections**: Handled using the `+=` operator or list indexing:
28
+ ```python
29
+ vcc = Net('VCC')
30
+ gnd = Net('GND')
31
+ r1 = Part('Device', 'R', value='10k', footprint='Resistor_SMD:R_0603_1608Metric')
32
+ c1 = Part('Device', 'C', value='100nF', footprint='Capacitor_SMD:C_0603_1608Metric')
33
+ # Connect in parallel across power rail
34
+ vcc += r1[1], c1[1]
35
+ gnd += r1[2], c1[2]
36
+ ```
37
+
38
+ ### 2.2 Production Reference Circuit: Microcontroller Node with Power & USB
39
+ Below is a complete, executable SKiDL circuit module (`hardware_design.py`) that instantiates power regulation, an RP2040 MCU, crystal oscillator, decoupling, and USB-C protection:
40
+
41
+ ```python
42
+ #!/usr/bin/env python3
43
+ """
44
+ Production-grade Code-First Hardware Circuit Synthesis using SKiDL.
45
+ Generates KiCad netlist with built-in ERC validation.
46
+ """
47
+ from skidl import *
48
+
49
+ # Set target EDA tool to KiCad
50
+ set_default_tool(KICAD)
51
+
52
+ # 1. Global Power & Ground Nets
53
+ vbus = Net('VBUS')
54
+ v3v3 = Net('+3V3')
55
+ gnd = Net('GND')
56
+
57
+ # 2. USB-C Input & ESD Protection
58
+ usbc = Part('Connector', 'USB_C_Receptacle_USB2.0', footprint='Connector_USB:USB_C_Receptacle_GCT_USB4105')
59
+ tvs = Part('Power_Protection', 'USBLC6-2SC6', footprint='Package_TO_SOT_SMD:SOT-23-6')
60
+
61
+ # Ground receptacle shield and GND pins
62
+ gnd += usbc['GND*'], usbc['SHIELD'], tvs['GND']
63
+ vbus += usbc['VBUS*'], tvs['VBUS']
64
+
65
+ # CC Pull-Down Resistors (5.1k for standard 5V/3A UFP mode)
66
+ r_cc1 = Part('Device', 'R', value='5.1k', footprint='Resistor_SMD:R_0402_1005Metric')
67
+ r_cc2 = Part('Device', 'R', value='5.1k', footprint='Resistor_SMD:R_0402_1005Metric')
68
+ usbc['CC1'] += r_cc1[1]
69
+ usbc['CC2'] += r_cc2[1]
70
+ gnd += r_cc1[2], r_cc2[2]
71
+
72
+ # USB Data Lines through TVS
73
+ usb_dp = Net('USB_DP')
74
+ usb_dn = Net('USB_DN')
75
+ usbc['DP*'] += tvs['I/O1']
76
+ tvs['I/O1'] += usb_dp
77
+ usbc['DN*'] += tvs['I/O2']
78
+ tvs['I/O2'] += usb_dn
79
+
80
+ # 3. LDO Voltage Regulator (5V -> 3.3V, AP2112K-3.3)
81
+ ldo = Part('Regulator_Linear', 'AP2112K-3.3', footprint='Package_TO_SOT_SMD:SOT-23-5')
82
+ cin = Part('Device', 'C', value='4.7uF', footprint='Capacitor_SMD:C_0603_1608Metric')
83
+ cout = Part('Device', 'C', value='4.7uF', footprint='Capacitor_SMD:C_0603_1608Metric')
84
+
85
+ vbus += ldo['VIN'], ldo['EN'], cin[1]
86
+ gnd += ldo['GND'], cin[2], cout[2]
87
+ v3v3 += ldo['VOUT'], cout[1]
88
+
89
+ # 4. RP2040 Microcontroller
90
+ mcu = Part('MCU_RaspberryPi_RP2040', 'RP2040', footprint='Package_DFN_QFN:QFN-56-1EP_7x7mm_P0.4mm_EP3.2x3.2mm')
91
+ gnd += mcu['GND*'], mcu['EP']
92
+ v3v3 += mcu['IOVDD*'], mcu['USB_VDD'], mcu['VREG_IN']
93
+
94
+ # Connect USB Data
95
+ mcu['USB_DP'] += usb_dp
96
+ mcu['USB_DM'] += usb_dn
97
+
98
+ # Decoupling Array: 100nF per IOVDD pin
99
+ for pin in mcu.get_pins():
100
+ if 'IOVDD' in pin.name or 'VREG_IN' in pin.name:
101
+ c_dec = Part('Device', 'C', value='100nF', footprint='Capacitor_SMD:C_0402_1005Metric')
102
+ v3v3 += c_dec[1]
103
+ gnd += c_dec[2]
104
+
105
+ # 5. Execute Electrical Rules Check (ERC)
106
+ print("--> Running SKiDL Electrical Rules Check (ERC)...")
107
+ ERC()
108
+
109
+ # 6. Generate Netlist for KiCad
110
+ print("--> Compiling KiCad Netlist: board.net")
111
+ generate_netlist(file_='board.net')
112
+ ```
113
+
114
+ ---
115
+
116
+ ## 3. Parametric Mechanical Enclosure Co-Design (OpenSCAD / BOSL2)
117
+
118
+ Hardware enclosure design must strictly depend on exported PCB physical measurements:
119
+ 1. **Board Outline**: Ingested via `kicad-cli pcb export dxf --layers Edge.Cuts`.
120
+ 2. **Mounting Hole Coordinates**: Ingested from the Centroid placement file (`board_positions.csv`).
121
+ 3. **Connector Boundaries**: Aligned to exact component coordinates with manufacturing tolerances.
122
+
123
+ ### 3.1 Tolerance Standards for Enclosure Fit
124
+ - **FDM 3D Printing (PLA / PETG)**:
125
+ - Internal cavity clearance around PCB perimeter: $+0.4\text{mm}$ per side.
126
+ - Connector cutouts (USB-C, HDMI): $+0.4\text{mm}$ height and width.
127
+ - Screw hole clearance: $+0.3\text{mm}$ (e.g., $3.3\text{mm}$ hole for M3 screw).
128
+ - Minimum wall thickness: $2.0\text{mm}$ for structural rigidity.
129
+ - **Heat-Set Threaded Inserts (Brass)**:
130
+ - M2 Insert: Hole diameter $3.2\text{mm}$, depth $4.0\text{mm}$, boss outer diameter $\ge 6.0\text{mm}$.
131
+ - M3 Insert: Hole diameter $4.0\text{mm}$, depth $5.7\text{mm}$, boss outer diameter $\ge 7.5\text{mm}$.
132
+
133
+ ### 3.2 Production BOSL2 Enclosure Code (`enclosure.scad`)
134
+ The following script utilizes the **BOSL2** library for analytical rounding (avoiding `minkowski()`) and builds a parametric snap-together / screw-down enclosure with standoff bosses and port cutouts:
135
+
136
+ ```openscad
137
+ // Production Parametric PCB Enclosure using BOSL2
138
+ // Run with: openscad -o enclosure.stl --backend=Manifold enclosure.scad
139
+
140
+ include <BOSL2/std.scad>
141
+
142
+ $fn = 64;
143
+
144
+ // --- Parametric Dimensions (Derived from PCB constraints.yaml) ---
145
+ pcb_w = 75.0; // PCB width in X
146
+ pcb_l = 45.0; // PCB length in Y
147
+ pcb_t = 1.6; // PCB thickness
148
+ xy_clearance = 0.4; // Tolerance per side
149
+ wall_t = 2.0; // Outer wall thickness
150
+ standoff_h = 5.0; // Clearance below PCB
151
+ ceiling_h = 12.0; // Component height ceiling above PCB
152
+
153
+ // Computed internal dimensions
154
+ int_w = pcb_w + (2 * xy_clearance);
155
+ int_l = pcb_l + (2 * xy_clearance);
156
+ int_h = standoff_h + pcb_t + ceiling_h;
157
+
158
+ // Outer dimensions
159
+ out_w = int_w + (2 * wall_t);
160
+ out_l = int_l + (2 * wall_t);
161
+ out_h = int_h + (2 * wall_t);
162
+
163
+ // Mounting Hole Locations relative to PCB center [X, Y]
164
+ mounting_holes = [
165
+ [-34.0, -19.0],
166
+ [ 34.0, -19.0],
167
+ [-34.0, 19.0],
168
+ [ 34.0, 19.0]
169
+ ];
170
+
171
+ // --- Subassembly: Lower Enclosure Half ---
172
+ module bottom_case() {
173
+ difference() {
174
+ // Outer rounded shell
175
+ cuboid([out_w, out_l, out_h/2], rounding=3, edges="Z", anchor=BOTTOM) {
176
+ // Internal cavity cutout
177
+ attach(TOP, TOP, inside=true)
178
+ cuboid([int_w, int_l, (out_h/2) - wall_t], anchor=TOP);
179
+ }
180
+
181
+ // USB-C Connector Cutout (centered at X = -out_w/2, Z = standoff_h + pcb_t)
182
+ translate([-out_w/2, 0, standoff_h + pcb_t + 1.6])
183
+ cube([wall_t * 2, 9.6, 3.8], center=true);
184
+ }
185
+
186
+ // Standoff Bosses with M3 Heat-Set Insert Pockets
187
+ for (pos = mounting_holes) {
188
+ translate([pos[0], pos[1], wall_t]) {
189
+ difference() {
190
+ // Cylindrical standoff boss
191
+ cylinder(h=standoff_h, r=3.8, center=false);
192
+ // Heat-set brass insert pocket (M3: dia 4.0mm, depth 5.0mm)
193
+ translate([0, 0, standoff_h - 4.8])
194
+ cylinder(h=5.0, r=2.0, center=false);
195
+ }
196
+ }
197
+ }
198
+ }
199
+
200
+ // --- Subassembly: Top Lid ---
201
+ module top_case() {
202
+ translate([0, out_l + 15, 0]) {
203
+ difference() {
204
+ cuboid([out_w, out_l, out_h/2], rounding=3, edges="Z", anchor=BOTTOM) {
205
+ attach(TOP, TOP, inside=true)
206
+ cuboid([int_w, int_l, (out_h/2) - wall_t], anchor=TOP);
207
+ }
208
+ // Ventilation slots
209
+ for (i = [-3:3]) {
210
+ translate([i * 6, 0, 0])
211
+ cube([2.5, int_l - 10, wall_t * 3], center=true);
212
+ }
213
+ }
214
+ }
215
+ }
216
+
217
+ // Render complete assembly for 3D printing
218
+ bottom_case();
219
+ top_case();
220
+ ```
221
+
222
+ ---
223
+
224
+ ## 4. Automated Execution & Verification CLI Workflow
225
+
226
+ 1. **Synthesize Circuit Netlist via SKiDL**:
227
+ ```bash
228
+ python3 hardware_design.py
229
+ # Confirms ERC passes with 0 errors and writes board.net
230
+ ```
231
+
232
+ 2. **Ingest Physical Features from PCB via `kicad-cli`**:
233
+ ```bash
234
+ # Export board outline DXF
235
+ kicad-cli pcb export dxf -o cad/board_outline.dxf --layers Edge.Cuts board.kicad_pcb
236
+ # Export mounting hole centroids
237
+ kicad-cli pcb export pos --format csv -o cad/board_positions.csv board.kicad_pcb
238
+ ```
239
+
240
+ 3. **Validate and Compile 3D Enclosure via OpenSCAD Manifold**:
241
+ ```bash
242
+ # Fast syntax validation
243
+ openscad -o /dev/null --check-parameters true cad/enclosure.scad
244
+
245
+ # High-speed mesh compilation using the Manifold C++ engine
246
+ openscad -o cad/enclosure.stl --backend=Manifold cad/enclosure.scad
247
+
248
+ # Generate high-resolution perspective preview PNG
249
+ openscad -o cad/enclosure_preview.png --camera=0,0,0,55,0,25,180 --imgsize=1024,768 cad/enclosure.scad
250
+ ```
251
+
252
+ ---
253
+
254
+ ## 5. Negative Constraints (Anti-Slop Directives)
255
+
256
+ - **DO NOT** use OpenSCAD's `minkowski()` function to generate rounded edges on production enclosures. It is computationally intractable and will cause agent timeouts. Always use BOSL2's analytical `cuboid(..., rounding=..., edges=...)`.
257
+ - **DO NOT** guess mounting hole or connector positions. Coordinates must be read directly from `constraints.yaml` or exported from `kicad-cli pcb export pos`.
258
+ - **DO NOT** generate SKiDL circuits without running `ERC()` before netlist export. An unverified netlist is prohibited from passing to layout.
259
+ - **DO NOT** design 3D printable enclosures with wall thickness $<1.6\text{mm}$ or standoff bosses with wall thickness $<1.5\text{mm}$ around heat-set insert pockets (causes layer splitting upon insert press).
260
+ - **DO NOT** omit the $+0.4\text{mm}$ mechanical tolerance margin around PCB board edges when modeling internal enclosure cavities.
@@ -0,0 +1,236 @@
1
+ ---
2
+ name: pcb-constraint-definition
3
+ description: "Translates high-level hardware requirements into formal engineering constraints, layer stackup calculations, netclasses, and custom DRC rules for KiCad. Use when defining board constraints, stackup, impedance matching, power budgeting, or netclasses."
4
+ category: engineering-hardware
5
+ compatibility: "Python 3.10+, kicad-cli 8+, mcp:kicad"
6
+ ---
7
+
8
+ # PCB Constraint & Specification Definition
9
+
10
+ ## 1. Overview and Core Philosophy
11
+
12
+ In the AOS hardware engineering pipeline, constraints are not informal recommendations; they are formal, machine-executable boundary conditions. An AI hardware agent must never begin schematic capture or board layout with unconstrained nets or default 0.25mm trace widths.
13
+
14
+ This skill provides the mathematical models, layer stackup architectures, netclass definitions, and custom Design Rule Check (DRC) constraint files required to translate product specifications into production-ready physical parameters.
15
+
16
+ ---
17
+
18
+ ## 2. Mathematical and Physical Foundations
19
+
20
+ All physical trace geometry and thermal boundaries must be derived from first principles and IPC standards:
21
+
22
+ ### 2.1 Trace Current Capacity (IPC-2152)
23
+ The current carrying capacity $I$ (Amperes) for a given allowable temperature rise $\Delta T$ ($^\circ\text{C}$) and conductor cross-sectional area $A$ ($\text{mils}^2$) is calculated as:
24
+
25
+ $$I = k \cdot \Delta T^{0.44} \cdot A^{0.725}$$
26
+
27
+ Where:
28
+ - $k = 0.048$ for external surface microstrip traces (convective cooling).
29
+ - $k = 0.024$ for internal stripline traces (conductive cooling through dielectric only).
30
+ - $A = w \cdot t$, with trace width $w$ ($\text{mils}$) and copper thickness $t$ ($1\text{ oz} \approx 1.37\text{ mils} = 35\mu\text{m}$, $2\text{ oz} \approx 2.74\text{ mils} = 70\mu\text{m}$).
31
+
32
+ **Minimum Trace Width Calculation for DC Power Rails:**
33
+ To support a continuous current of $2.5\text{A}$ with $\Delta T = 10^\circ\text{C}$ on $1\text{ oz}$ external copper:
34
+ $$A = \left( \frac{I}{0.048 \cdot \Delta T^{0.44}} \right)^{\frac{1}{0.725}} = \left( \frac{2.5}{0.048 \cdot 10^{0.44}} \right)^{1.379} \approx 42.5\text{ mils}^2$$
35
+ $$w = \frac{A}{t} = \frac{42.5}{1.37} \approx 31.0\text{ mils} \approx 0.79\text{ mm}$$
36
+
37
+ ### 2.2 Controlled Impedance Modeling (IPC-2141)
38
+
39
+ #### Single-Ended Microstrip (Surface Layer over Solid GND Plane)
40
+ Characteristic impedance $Z_0$ ($\Omega$):
41
+ $$Z_0 = \frac{87}{\sqrt{\varepsilon_r + 1.41}} \ln\left( \frac{5.98 h}{0.8 w + t} \right)$$
42
+ Valid for $0.1 < \frac{w}{h} < 3.0$ and $1 < \varepsilon_r < 15$.
43
+ - Standard FR-4 dielectric constant: $\varepsilon_r \approx 4.3 - 4.5$.
44
+ - For standard $h = 0.2\text{mm}$ (7.87 mils), $t = 35\mu\text{m}$ (1.37 mils), target $Z_0 = 50\Omega \implies w \approx 0.36\text{mm}$ (14.2 mils).
45
+
46
+ #### Edge-Coupled Differential Microstrip (USB 90Ω, Ethernet/PCIe 100Ω)
47
+ Differential impedance $Z_{diff}$ ($\Omega$):
48
+ $$Z_{diff} \approx 2 Z_0 \left( 1 - 0.48 e^{-0.96 \frac{s}{h}} \right)$$
49
+ Where $s$ is the edge-to-edge separation between the two complementary conductors, and $h$ is the dielectric height to the nearest solid reference plane.
50
+
51
+ ### 2.3 Thermal Budgeting & Junction Temperature
52
+ For any active linear regulator or power switch:
53
+ $$T_J = T_A + P_D \cdot \theta_{JA}$$
54
+ $$P_D = (V_{in} - V_{out}) \cdot I_{load} + V_{in} \cdot I_Q$$
55
+ If $T_J > 105^\circ\text{C}$ at $T_A = 40^\circ\text{C}$ (maximum ambient), the agent must constrain:
56
+ 1. Addition of a dedicated copper thermal pad connected via an array of thermal vias ($0.3\text{mm}$ drill, $0.6\text{mm}$ pitch).
57
+ 2. Minimum copper plane area: $A_{Cu} \ge \frac{P_D \cdot 1000}{35}\text{ mm}^2$.
58
+
59
+ ---
60
+
61
+ ## 3. Standard Layer Stackups
62
+
63
+ The agent must select one of the following industry-standard stackups based on circuit frequency and density:
64
+
65
+ ### 3.1 4-Layer Standard Controlled-Impedance Stackup (JLC04161H-7628)
66
+ Total nominal thickness: $1.6\text{mm}$.
67
+ - **Layer 1 (Top Signal / High-Speed)**: $35\mu\text{m}$ Copper ($1\text{ oz}$)
68
+ - *Prepreg 7628*: $0.2104\text{mm}$, $\varepsilon_r = 4.6$
69
+ - **Layer 2 (Internal GND Plane)**: $17.5\mu\text{m}$ Copper ($0.5\text{ oz}$) - Continuous reference
70
+ - *Core FR-4*: $1.065\text{mm}$, $\varepsilon_r = 4.6$
71
+ - **Layer 3 (Internal Power Plane)**: $17.5\mu\text{m}$ Copper ($0.5\text{ oz}$) - Power split planes
72
+ - *Prepreg 7628*: $0.2104\text{mm}$, $\varepsilon_r = 4.6$
73
+ - **Layer 4 (Bottom Signal / Power Return)**: $35\mu\text{m}$ Copper ($1\text{ oz}$)
74
+
75
+ ### 3.2 6-Layer Advanced High-Density Stackup
76
+ For dense microcontrollers (BGA/QFN) with mixed RF and high-speed memory:
77
+ - **L1 (Top Signal)**: $35\mu\text{m}$ - Microstrip signals & RF
78
+ - **L2 (GND 1)**: $17.5\mu\text{m}$ - Solid ground plane directly below L1
79
+ - **L3 (Inner Signal 1)**: $17.5\mu\text{m}$ - Stripline high-speed routing
80
+ - **L4 (Power / GND 2)**: $17.5\mu\text{m}$ - Power distribution
81
+ - **L5 (GND 3)**: $17.5\mu\text{m}$ - Solid ground plane directly above L6
82
+ - **L6 (Bottom Signal)**: $35\mu\text{m}$ - Low-speed signals, testpoints, connectors
83
+
84
+ ---
85
+
86
+ ## 4. Formal Constraint Manifest Schema (`constraints.yaml`)
87
+
88
+ Every hardware project must emit a validated `constraints.yaml` prior to schematic or PCB routing. The schema is specified below:
89
+
90
+ ```yaml
91
+ schema_version: "1.0.0"
92
+ project_name: "iot-telemetry-node"
93
+ target_fabricator: "JLCPCB"
94
+
95
+ operating_conditions:
96
+ ambient_temp_min_c: -20
97
+ ambient_temp_max_c: 65
98
+ max_allowable_temp_rise_c: 15
99
+ v_in_nominal: 5.0
100
+ v_in_max: 5.5
101
+ peak_current_a: 2.2
102
+
103
+ board_envelope:
104
+ outline_type: "rectangular"
105
+ width_mm: 75.0
106
+ length_mm: 45.0
107
+ corner_radius_mm: 2.5
108
+ pcb_thickness_mm: 1.6
109
+ copper_layers: 4
110
+ mounting_holes:
111
+ diameter_mm: 3.2 # M3 screw clearance
112
+ keepout_diameter_mm: 6.5 # Screw head + washer clearance
113
+ locations_mm:
114
+ - [3.5, 3.5]
115
+ - [71.5, 3.5]
116
+ - [3.5, 41.5]
117
+ - [71.5, 41.5]
118
+
119
+ stackup:
120
+ profile: "JLC04161H-7628"
121
+ dielectric_er: 4.6
122
+ copper_outer_oz: 1.0
123
+ copper_inner_oz: 0.5
124
+ layer_assignments:
125
+ 1: "TOP_SIGNAL"
126
+ 2: "GND_PLANE"
127
+ 3: "PWR_PLANE"
128
+ 4: "BOTTOM_SIGNAL"
129
+
130
+ netclasses:
131
+ Default:
132
+ track_width_mm: 0.20
133
+ clearance_mm: 0.20
134
+ via_drill_mm: 0.30
135
+ via_size_mm: 0.60
136
+ description: "Standard low-speed digital GPIO and logic nets"
137
+
138
+ PWR_HIGH_CURRENT:
139
+ track_width_mm: 0.80 # Sized via IPC-2152 for 2.5A, 10C rise
140
+ clearance_mm: 0.30
141
+ via_drill_mm: 0.40
142
+ via_size_mm: 0.80
143
+ nets: ["+5V", "VBUS", "+3V3_REG"]
144
+
145
+ GND:
146
+ track_width_mm: 0.40
147
+ clearance_mm: 0.25
148
+ via_drill_mm: 0.30
149
+ via_size_mm: 0.60
150
+ nets: ["GND", "GND_PWR"]
151
+
152
+ USB_DIFF_90:
153
+ impedance_target_ohms: 90
154
+ impedance_tolerance_pct: 10
155
+ track_width_mm: 0.38
156
+ diff_pair_gap_mm: 0.18
157
+ clearance_mm: 0.30
158
+ max_unmatched_length_mm: 0.10
159
+ nets: ["USB_DP", "USB_DN"]
160
+
161
+ ANALOG_SENSITIVE:
162
+ track_width_mm: 0.25
163
+ clearance_mm: 0.35
164
+ guard_ring: true
165
+ nets: ["ADC_IN0", "ADC_IN1", "VREF"]
166
+
167
+ manufacturing_limits:
168
+ min_track_width_mm: 0.127 # 5 mil
169
+ min_clearance_mm: 0.127 # 5 mil
170
+ min_drill_diameter_mm: 0.20 # 8 mil
171
+ min_annular_ring_mm: 0.15
172
+ min_solder_mask_bridge_mm: 0.10
173
+ board_edge_clearance_mm: 0.35
174
+ ```
175
+
176
+ ---
177
+
178
+ ## 5. KiCad Custom Design Rules (`.kicad_dru`) Generation
179
+
180
+ The agent must translate the netclasses and clearance constraints into KiCad's native custom rules syntax (`project.kicad_dru`):
181
+
182
+ ```lisp
183
+ (version 1)
184
+
185
+ # Ensure high voltage nets have adequate physical clearance
186
+ (rule "High_Voltage_Clearance"
187
+ (constraint clearance (min 1.2mm))
188
+ (condition "A.NetClass == 'MAINS_AC' && B.NetClass != 'MAINS_AC'"))
189
+
190
+ # Prevent high-speed signals from getting close to board edges
191
+ (rule "Board_Edge_Clearance_HighSpeed"
192
+ (constraint edge_clearance (min 1.0mm))
193
+ (condition "A.NetClass == 'USB_DIFF_90' || A.NetClass == 'RF_50'"))
194
+
195
+ # Enforce minimum drill hole-to-hole clearance to prevent drill wander shorts
196
+ (rule "Hole_To_Hole_Clearance"
197
+ (constraint hole_to_hole (min 0.25mm)))
198
+
199
+ # Guard sensitive analog nets from digital switching noise
200
+ (rule "Analog_Clearance_To_Digital"
201
+ (constraint clearance (min 0.40mm))
202
+ (condition "A.NetClass == 'ANALOG_SENSITIVE' && B.NetClass == 'Default'"))
203
+
204
+ # Require thermal reliefs on ground plane connection
205
+ (rule "Plane_Thermal_Reliefs"
206
+ (constraint thermal_spoke_width (min 0.35mm))
207
+ (condition "A.NetClass == 'GND'"))
208
+ ```
209
+
210
+ ---
211
+
212
+ ## 6. Execution Workflow & Tool Invocations
213
+
214
+ 1. **Parameter Ingestion**:
215
+ - Extract power requirements, communication interfaces, and mechanical form factors from the user brief.
216
+ 2. **IPC-2152 & IPC-2141 Synthesis**:
217
+ - Calculate trace widths for every power net based on peak expected current.
218
+ - Calculate trace width ($W$) and differential gap ($S$) based on stackup dielectric height ($h$).
219
+ 3. **Artifact Generation**:
220
+ - Write `pcb_constraints.yaml` in the project root.
221
+ - Write `board.kicad_dru` in the project root.
222
+ 4. **Validation via `kicad-cli`**:
223
+ - Verify that the generated rule syntax compiles cleanly against `kicad-cli`:
224
+ ```bash
225
+ kicad-cli pcb drc --exit-code-violations --rules board.kicad_dru board.kicad_pcb
226
+ ```
227
+
228
+ ---
229
+
230
+ ## 7. Negative Constraints (Anti-Slop Directives)
231
+
232
+ - **DO NOT** use default KiCad trace widths (0.25mm) for power rails carrying $>0.5\text{A}$. Every power rail must be sized using the IPC-2152 formula.
233
+ - **DO NOT** specify 2-layer stackups for designs containing high-speed USB (480 Mbps+), Ethernet, or microcontrollers running $>100\text{ MHz}$ core clocks without an explicit solid ground flood on Layer 2.
234
+ - **DO NOT** define mounting hole clearances that only cover the drill hole. Mounting keepouts must encompass the bolt head plus standard socket tool clearance ($\ge 6.5\text{mm}$ for M3).
235
+ - **DO NOT** place annular rings below $0.15\text{mm}$ ($6\text{ mils}$) unless the project explicitly targets advanced laser micro-via processes ($>10\times$ fabrication cost).
236
+ - **DO NOT** define differential pairs without an explicit intra-pair skew tolerance (maximum allowable length mismatch $\le 0.1\text{mm}$).