forgecad 0.9.16 → 0.10.1

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 (162) hide show
  1. package/dist/assets/{AdminPage-CXvls4-J.js → AdminPage-DcCnj0qo.js} +1 -1
  2. package/dist/assets/{BenchmarkPage-B27zk8xL.js → BenchmarkPage-BVEpJSVk.js} +1 -1
  3. package/dist/assets/{BlogPage-CMAVvgQL.js → BlogPage-DHaGP50_.js} +1 -1
  4. package/dist/assets/{DocsPage-knf4I4h7.js → DocsPage-CDoxHkz8.js} +40 -859
  5. package/dist/assets/EditorApp-BJ0Dloyh.js +16446 -0
  6. package/dist/assets/{EmbedViewer-D7ZGlFjx.js → EmbedViewer-CRKZbY0y.js} +2 -2
  7. package/dist/assets/{LandingPageProofDriven-CnevhTE8.js → LandingPageProofDriven-BxHkYRE7.js} +1 -1
  8. package/dist/assets/{LegalPage-BPTUmqeg.js → LegalPage-B-u6FrVv.js} +1 -1
  9. package/dist/assets/{PricingPage-B0D4goG_.js → PricingPage-CzpZ6-Ce.js} +1 -1
  10. package/dist/assets/{SettingsPage-CFF-UgjI.js → SettingsPage-CIZSSAd0.js} +1 -1
  11. package/dist/assets/{app-CE3sYcV7.css → app-CjsbDlb7.css} +143 -0
  12. package/dist/assets/{app-T0pDcSX4.js → app-DaTMg3nH.js} +1310 -290
  13. package/dist/assets/cli/{render-C5pcIISc.js → render-DPf4AYJK.js} +55 -60
  14. package/dist/assets/{constructionHistoryWorker-Ba2Hm58b.js → constructionHistoryWorker-AwMMWSxg.js} +1103 -349
  15. package/dist/assets/{evalWorker-vkx310U2.js → evalWorker-CjZZWRWW.js} +5209 -2643
  16. package/dist/assets/{inspectWorker-BuTJDVX6.js → inspectWorker-CZsCFtQT.js} +1163 -409
  17. package/dist/assets/{jointPose-B_Cgedn9.js → jointPose-DzQOViQH.js} +1 -1
  18. package/dist/assets/{manifold-BWgsjmAM.js → manifold-BYlzU521.js} +1 -1
  19. package/dist/assets/{manifold-D6IFSkhH.js → manifold-DgXo0T5P.js} +2 -2
  20. package/dist/assets/{manifold-rZexZI0G.js → manifold-K1SkarlQ.js} +1 -1
  21. package/dist/assets/{reportWorker-0AGij1Ru.js → reportWorker-B9nWwSrB.js} +8501 -3393
  22. package/dist/assets/{scalar-sampling-budget-J5cuzxT1.js → scalar-sampling-budget-prBw_s8t.js} +6067 -3479
  23. package/dist/assets/{scanProxyWorker-Vl4Wxa1y.js → scanProxyWorker-2GtDLk-R.js} +1 -1
  24. package/dist/assets/{javascript-1kQXfVaz.js → typescript-DBQ6RN5l.js} +874 -22
  25. package/dist/cli/render.html +1 -1
  26. package/dist/docs/index.html +3 -3
  27. package/dist/docs-raw/AI/usage.md +1 -1
  28. package/dist/docs-raw/CLI.md +77 -240
  29. package/dist/docs-raw/README.md +6 -0
  30. package/dist/docs-raw/component-model.md +17 -150
  31. package/dist/docs-raw/generated/assembly.md +188 -582
  32. package/dist/docs-raw/generated/concepts.md +259 -3501
  33. package/dist/docs-raw/generated/core.md +283 -1250
  34. package/dist/docs-raw/generated/curves.md +387 -1608
  35. package/dist/docs-raw/generated/legacy.md +162 -0
  36. package/dist/docs-raw/generated/lib.md +227 -85
  37. package/dist/docs-raw/generated/output.md +35 -99
  38. package/dist/docs-raw/generated/runtime-names.md +23 -23
  39. package/dist/docs-raw/generated/sdf.md +68 -284
  40. package/dist/docs-raw/generated/sheet-metal.md +68 -335
  41. package/dist/docs-raw/generated/sketch.md +240 -1161
  42. package/dist/docs-raw/generated/viewport.md +75 -316
  43. package/dist/docs-raw/generated/wood.md +21 -49
  44. package/dist/docs-raw/guides/coordinate-system.md +4 -42
  45. package/dist/docs-raw/guides/inspection-bundles.md +44 -442
  46. package/dist/docs-raw/guides/joint-design.md +18 -79
  47. package/dist/docs-raw/guides/positioning.md +21 -143
  48. package/dist/docs-raw/guides/scene-presentation.md +89 -0
  49. package/dist/docs-raw/guides/simready-quickstart.md +171 -0
  50. package/dist/docs-raw/simulation-workflow.md +273 -0
  51. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +25 -111
  52. package/dist/docs-raw/skills/forgecad-blockout-model.md +20 -117
  53. package/dist/docs-raw/skills/forgecad-component-model.md +23 -107
  54. package/dist/docs-raw/skills/forgecad-high-level-spec.md +47 -155
  55. package/dist/docs-raw/skills/forgecad-image-replicator.md +26 -143
  56. package/dist/docs-raw/skills/forgecad-lld.md +19 -113
  57. package/dist/docs-raw/skills/forgecad-make-a-model.md +112 -532
  58. package/dist/docs-raw/skills/forgecad-model-grader.md +38 -108
  59. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +24 -211
  60. package/dist/docs-raw/skills/forgecad-project.md +13 -131
  61. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +42 -134
  62. package/dist/docs-raw/skills/forgecad-render-inspect.md +27 -174
  63. package/dist/docs-raw/skills/forgecad-visual-spec.md +32 -112
  64. package/dist/docs-raw/skills/forgecad.md +19 -18
  65. package/dist/docs-raw/skills/index.md +2 -0
  66. package/dist/docs-raw/welcome.md +2 -2
  67. package/dist/index.html +2 -2
  68. package/dist/llms.txt +1 -2
  69. package/dist/sitemap.xml +25 -13
  70. package/dist-cli/{check-compiler-SYQ2PWOB.js → check-compiler-II7NLPAB.js} +1 -1
  71. package/dist-cli/{check-query-propagation-HIAGV62W.js → check-query-propagation-7462TR3R.js} +1 -1
  72. package/dist-cli/{chunk-SPZE3DUY.js → chunk-UWTJCGXF.js} +5848 -2915
  73. package/dist-cli/forgecad.js +3496 -703
  74. package/dist-skill/CONTEXT.md +1797 -7963
  75. package/dist-skill/SKILL.md +15 -15
  76. package/dist-skill/docs/API/core/concepts.md +27 -157
  77. package/dist-skill/docs/CLI.md +77 -240
  78. package/dist-skill/docs/generated/assembly.md +182 -532
  79. package/dist-skill/docs/generated/core.md +283 -1250
  80. package/dist-skill/docs/generated/curves.md +387 -1609
  81. package/dist-skill/docs/generated/lib.md +227 -85
  82. package/dist-skill/docs/generated/output.md +35 -99
  83. package/dist-skill/docs/generated/runtime-names.md +16 -21
  84. package/dist-skill/docs/generated/sdf.md +68 -284
  85. package/dist-skill/docs/generated/sheet-metal.md +68 -335
  86. package/dist-skill/docs/generated/sketch.md +240 -1160
  87. package/dist-skill/docs/generated/viewport.md +75 -223
  88. package/dist-skill/docs/generated/wood.md +21 -49
  89. package/dist-skill/docs/guides/coordinate-system.md +4 -42
  90. package/dist-skill/docs/guides/inspection-bundles.md +44 -442
  91. package/dist-skill/docs/guides/joint-design.md +18 -79
  92. package/dist-skill/docs/guides/positioning.md +21 -143
  93. package/dist-skill/docs/guides/scene-presentation.md +89 -0
  94. package/dist-skill/docs/guides/surface-members.md +26 -0
  95. package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +23 -111
  96. package/dist-skill/library/forgecad-blockout-model/SKILL.md +18 -117
  97. package/dist-skill/library/forgecad-component-model/SKILL.md +21 -107
  98. package/dist-skill/library/forgecad-high-level-spec/SKILL.md +45 -155
  99. package/dist-skill/library/forgecad-image-replicator/SKILL.md +24 -143
  100. package/dist-skill/library/forgecad-lld/SKILL.md +17 -113
  101. package/dist-skill/library/forgecad-make-a-model/SKILL.md +110 -532
  102. package/dist-skill/library/forgecad-model-grader/SKILL.md +36 -108
  103. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +35 -224
  104. package/dist-skill/library/forgecad-prepare-prompt/references/default-profiles.md +43 -271
  105. package/dist-skill/library/forgecad-prepare-prompt/references/master-prompt.md +30 -99
  106. package/dist-skill/library/forgecad-project/SKILL.md +13 -133
  107. package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +29 -123
  108. package/dist-skill/library/forgecad-render-inspect/SKILL.md +25 -174
  109. package/dist-skill/library/forgecad-visual-spec/SKILL.md +30 -111
  110. package/dist-skill/website/skills/forgecad-3d-reconstruction.md +58 -0
  111. package/dist-skill/website/skills/forgecad-blockout-model.md +49 -0
  112. package/dist-skill/website/skills/forgecad-component-model.md +53 -0
  113. package/dist-skill/website/skills/forgecad-high-level-spec.md +101 -0
  114. package/dist-skill/website/skills/forgecad-image-replicator.md +63 -0
  115. package/dist-skill/website/skills/forgecad-lld.md +41 -0
  116. package/dist-skill/website/skills/forgecad-make-a-model.md +186 -0
  117. package/dist-skill/website/skills/forgecad-model-grader.md +82 -0
  118. package/dist-skill/website/skills/forgecad-prepare-prompt.md +63 -0
  119. package/dist-skill/website/skills/forgecad-project.md +26 -0
  120. package/dist-skill/website/skills/forgecad-reconstruction-benchmark.md +60 -0
  121. package/dist-skill/website/skills/forgecad-render-inspect.md +80 -0
  122. package/dist-skill/website/skills/forgecad-visual-spec.md +71 -0
  123. package/dist-skill/website/skills/forgecad.md +122 -0
  124. package/dist-skill/website/skills/index.md +26 -0
  125. package/examples/api/comparison-imported-sphere-candidate.forge.js +1 -1
  126. package/examples/api/conformal-product-ribbon.forge.js +1 -1
  127. package/examples/api/exact-sheet-shell-assembly.forge.js +1 -1
  128. package/examples/api/extrude-options.forge.js +4 -2
  129. package/examples/api/field-loft-drive-tip.forge.js +40 -0
  130. package/examples/api/guided-loft-olive-oil-bottle.forge.js +1 -1
  131. package/examples/api/highlight-debug.forge.js +10 -10
  132. package/examples/api/mesh-import-slats.forge.js +1 -1
  133. package/examples/api/real-product-curves.forge.js +1 -1
  134. package/examples/api/sculpt-box-circle-booleans.forge.js +1 -1
  135. package/examples/api/sdf-shapes.forge.js +2 -5
  136. package/examples/api/sketch-rounding-strategies.forge.js +6 -6
  137. package/examples/api/surface-member-bottle-cage.forge.js +3 -3
  138. package/examples/api/surface-member-conformal-product-ribbon.forge.js +3 -3
  139. package/examples/api/surface-member-razor-inlay.forge.js +1 -1
  140. package/examples/api/variable-sweep-test.forge.js +3 -3
  141. package/examples/mechanical/airplane-propeller.forge.js +74 -39
  142. package/examples/nurbs-surface.forge.js +1 -1
  143. package/examples/products/iphone.forge.js +1 -1
  144. package/examples/robotics/README.md +46 -0
  145. package/examples/robotics/scout-cam-rover-simready/README.md +119 -0
  146. package/examples/robotics/scout-cam-rover-simready/lib/dims.js +140 -0
  147. package/examples/robotics/scout-cam-rover-simready/main.forge.js +343 -0
  148. package/examples/robotics/scout-cam-rover-simready/parts/body.forge.js +304 -0
  149. package/examples/robotics/scout-cam-rover-simready/parts/chassis.forge.js +320 -0
  150. package/examples/robotics/scout-cam-rover-simready/parts/hardware.forge.js +21 -0
  151. package/examples/robotics/scout-cam-rover-simready/parts/turret.forge.js +70 -0
  152. package/examples/robotics/scout-cam-rover-simready/parts/wheel.forge.js +116 -0
  153. package/examples/robotics/simready-asset-crate.forge.js +79 -0
  154. package/examples/robotics/simready-diff-drive-rover.forge.js +141 -0
  155. package/examples/robotics/simready-parallel-gripper.forge.js +102 -0
  156. package/package.json +1 -1
  157. package/dist/assets/EditorApp-BHMQlJ-D.js +0 -14686
  158. package/dist/docs-raw/guides/geometry-conventions.md +0 -52
  159. package/dist/docs-raw/guides/modeling-recipes.md +0 -78
  160. package/dist-skill/docs/guides/geometry-conventions.md +0 -52
  161. package/dist-skill/docs/guides/modeling-recipes.md +0 -78
  162. package/dist-skill/library/forgecad-visual-spec/references/prompt-template.md +0 -79
@@ -5,176 +5,43 @@ skill-order: 4
5
5
 
6
6
  # The Component Model
7
7
 
8
- ## Parts Are Components. Assemblies Are Composition.
8
+ Long-form rationale for ForgeCAD's multi-part architecture. The enforceable rule sheet — anti-patterns, design gate, file-structure rules — lives in the `forgecad-component-model` skill (`agent-skill-library/forgecad-component-model/SKILL.md`). Connector and joint mechanics (frame semantics, mating, mirrored-revolute handedness) live in the assembly JSDoc, surfaced in `docs/permanent/generated/assembly.md`.
9
9
 
10
- ForgeCAD's multi-part design model follows one principle:
10
+ ## The Principle
11
11
 
12
- > **A part is a function from props to shape + connectors. It knows nothing about where it sits in the world. The assembly decides.**
12
+ > **A part is a function from props to shape + connectors + metadata. It knows nothing about where it sits in the world. The assembly decides.**
13
13
 
14
- This is how React changed UI: components render content, the layout system positions them. Components don't know their screen coordinates. Before React, jQuery code positioned elements in page-space. After React, components are local and composable.
14
+ This is how React changed UI: components render content, the layout system positions them. Components don't know their screen coordinates. Before React, jQuery code positioned elements in page-space; after React, components are local and composable.
15
15
 
16
- ForgeCAD applies the same principle to mechanical design. Before: parts compute their assembly-space coordinates (translate to the right X, Y, Z, using a shared-dims file). After: parts build at origin in local space, declare connectors, and the assembly uses `connect()` to position everything.
17
-
18
- ## The Three Rules
19
-
20
- ### Rule 1: Parts Build at Origin
21
-
22
- A part is built in its own local coordinate system. Origin at `[0, 0, 0]`. No knowledge of the assembly. No imports of sibling part files. No global coordinate offsets.
23
-
24
- ```js
25
- // WRONG — part positions itself in assembly space
26
- const rackPlaced = rack.translate(pinionPitchR, 0, layout.pinionZ);
27
-
28
- // RIGHT — part builds at origin, connector declares the interface
29
- const rack = lib.rackGear({ ... }).rotateZ(90);
30
- // pitch line at X=0, teeth face -X, local coordinates only
31
- return rack.withConnectors({
32
- teeth: connector("rack-slide", { origin: [0, 0, faceWidth/2], axis: [0, 1, 0] }),
33
- });
34
- ```
35
-
36
- ### Rule 2: Connectors Are the Interface
37
-
38
- Every part that participates in an assembly declares connectors. A connector says: "here's where I connect, what direction I face, and what roll I consider upright." It's the part's public interface — the only thing the assembly needs to know.
39
-
40
- ```js
41
- return mount.withConnectors({
42
- flange: connector("bolt-face", {
43
- origin: [0, 0, 0], // where the mating surface is
44
- axis: [0, 0, 1], // direction it faces (outward from part)
45
- up: [1, 0, 0], // roll reference when orientation matters
46
- }),
47
- });
48
- ```
49
-
50
- A connector is a small local frame:
51
-
52
- - `origin` is the pivot, contact point, socket center, or mating-face point.
53
- - `axis` is the primary direction: face normal, hinge line, or slide direction.
54
- - `up` is the secondary direction that fixes roll around `axis`.
55
-
56
- `up` is not world up. It is the connector's local roll reference and must not be parallel to `axis`. If `up` is omitted, ForgeCAD picks a deterministic perpendicular vector. That is fine when roll does not matter, but hinges, wheels, levers, and keyed parts should author `up` explicitly.
57
-
58
- Connectors meet **face-to-face**. Both axes point outward from their respective parts. The system brings them together from opposite sides, then uses `up` to pin the rest orientation — like plugging in a keyed connector instead of a round peg.
59
-
60
- ### Rule 3: The Assembly Is Pure Composition
61
-
62
- The assembly file does three things: instantiate parts with props, connect them, and define motion. Zero coordinate math. Zero translate calls. Zero shared-dims imports.
63
-
64
- ```js
65
- assembly("Gripper")
66
- .addPart("Base", base)
67
- .addPart("Mount", mount)
68
- .connect("Base.mount_face", "Mount.flange", { as: "mount-fix" })
69
- .addPart("Pinion", pinion)
70
- .connect("Base.pinion_seat", "Pinion.bore", { as: "spin" })
71
- // ...
72
- ```
73
-
74
- If you're writing `translate()` in an assembly file, something is wrong. Either the part should have a connector, or the prop should carry the dimension.
16
+ ForgeCAD applies the same principle to mechanical design. Before: parts compute their assembly-space coordinates (translate to the right X, Y, Z, fed by a shared-dims file). After: parts build at origin in local space, declare connectors as their public interface, and the assembly uses `connect()` to position everything. The assembly file becomes pure composition — instantiate parts with props, connect them, define motion — with zero coordinate math.
75
17
 
76
18
  ## Data Flow: Props Down, Metadata Up
77
19
 
78
- Data flows in one direction: from parent (assembly) to children (parts).
79
-
80
- ```
81
- Assembly (root)
82
- ├── passes { servo, wall, clearance } → Motor Mount
83
- │ └── returns { shape, boltPattern, flange connector }
84
- ├── passes { gears, boltPattern } → Base Body
85
- │ └── returns { shape, pinionZ, rack connectors }
86
- ├── passes { gears, rackZ, armSpan } → Jaw Unit
87
- │ └── returns { shape, armWidth, rack connector }
88
- └── passes { boltPattern, armSlot } → Cover Plate
89
- └── returns { shape, seat connector }
90
- ```
91
-
92
- **Props flow down:** The assembly knows the cross-cutting decisions (base height, wall thickness, servo model) and passes them to parts as `require()` param overrides.
93
-
94
- **Metadata flows up:** Parts return their shape + connectors + any computed data that siblings need. The assembly reads this metadata and passes relevant pieces to other parts.
20
+ Data flows in one direction, from parent (assembly) to children (parts):
95
21
 
96
- **Siblings never import each other.** The cover plate doesn't import the motor mount to read bolt positions. The assembly reads the mount's bolt pattern and passes it to the cover plate. The parent mediates all sibling communication.
22
+ - **Props flow down.** The assembly owns the cross-cutting decisions (base height, wall thickness, servo model) and passes them to parts as `require()` param overrides.
23
+ - **Metadata flows up.** Parts return shape + connectors + any computed data siblings need (`return { shape, boltPattern, pinionZ }`).
24
+ - **Siblings never import each other.** The cover plate doesn't import the motor mount to read bolt positions; the assembly reads the mount's bolt pattern and passes it to the cover plate. The parent mediates all sibling communication.
97
25
 
98
26
  ```js
99
- // Assembly mediates sibling data flow
100
27
  const mount = require('./motor-mount.forge.js', { Wall: wall });
101
- const base = require('./base-body.forge.js', {
102
- Height: baseH,
103
- BoltPattern: mount.boltPattern, // parent passes mount's data to base
104
- });
105
28
  const cover = require('./cover-plate.forge.js', {
106
- BoltPattern: mount.boltPattern, // same data to cover
107
- ArmSlot: jaw.armProfile, // jaw's data to cover
29
+ BoltPattern: mount.boltPattern, // parent routes mount's data to a sibling
108
30
  });
109
31
  ```
110
32
 
111
33
  ## Why This Matters
112
34
 
113
- ### For Humans
114
-
115
- Each part file tells a complete story. You open `motor-mount.forge.js` and see everything: its geometry, its connectors, its parameters, its verifications. No chasing imports across 8 files. No 266-line shared-dims.js to understand.
116
-
117
- Modifying one part doesn't break siblings — connectors are the contract. Change the mount's internal cavity dimensions and nothing else changes, as long as the flange connector stays at the same position.
118
-
119
- ### For AIs
120
-
121
- Each part file is self-contained context. An AI generates `base-body.forge.js` without reading `jaw-unit.forge.js`. The assembly file is a high-level plan — generate it from a natural language description. Props are the interface contract — the AI knows exactly what each part needs and provides.
122
-
123
- ### For Swap-ability
124
-
125
- Change the servo model → the mount rebuilds with new cavity dimensions → its bolt pattern updates → the assembly passes the new pattern to base and cover → everything adapts. One change, cascading update, zero manual re-derivation.
126
-
127
- ## The Connector Convention
128
-
129
- Connectors follow one convention: **face-to-face connector frames**.
130
-
131
- Each connector's axis points **outward** from its part — the direction the connection faces. When two connectors mate, the system makes their origins coincide and, for fixed/revolute joints, negates one axis so they approach from opposite sides. The `up` vectors define the roll reference that makes the rest pose deterministic.
132
-
133
- - **Fixed joints** (bolt flange): both faces point outward, system brings them together
134
- - **Revolute joints** (hinge): both parts point outward along the hinge line, system opposes them, and `up` pins zero angle
135
- - **Prismatic joints** (slider): both connectors point along the slide direction (co-directional exception — the slide axis IS the shared direction), while `up` still pins roll around the rail
136
-
137
- Revolute joint values are still signed by the physical hinge axis. If a bilateral
138
- mechanism mirrors a hinge axis, the mirrored pose uses the negated physical value
139
- (`Right: +theta`, `Left: -theta`), and physical limits mirror as
140
- `[min, max] -> [-max, -min]`. Prismatic joints do not have this angle-handedness
141
- flip. Use a side-neutral link graph or explicit state mapping when equal semantic
142
- pose values should drive both sides.
143
-
144
- ```js
145
- // Base bottom face points down, mount flange points up → meet in the middle
146
- base.withConnectors({ mount_face: connector("bolt-face", { origin: [0,0,0], axis: [0,0,-1], up: [1,0,0] }) });
147
- mount.withConnectors({ flange: connector("bolt-face", { origin: [0,0,0], axis: [0,0,1], up: [1,0,0] }) });
148
-
149
- // Hinge: axes oppose along the pin, up pins the closed/rest roll
150
- frame.withConnectors({ hinge: connector("hinge", { origin: [0,0,40], axis: [0,0,1], up: [1,0,0] }) });
151
- door.withConnectors({ hinge: connector("hinge", { origin: [0,0,40], axis: [0,0,-1], up: [1,0,0] }) });
152
- ```
153
-
154
- ## One File vs. Many Files
155
-
156
- **Default: one file per assembly.** For a project-specific assembly (robot gripper, drone frame), put everything in one file. Parts are sections separated by comments. Shared data is just variables. This maximizes locality — you see the whole design by scrolling.
157
-
158
- **Split when:** A part is reusable across projects (standard servo cradle, parametric gear pair), or the file exceeds ~300 lines. Split parts into separate `.forge.js` files that export component functions.
159
-
160
- **Never split for "organization."** Eight files with 40 lines each is worse than one file with 300 lines. The context-switching cost of 8 files destroys locality.
161
-
162
- ## What This Forbids
163
-
164
- 1. **No shared-dims files.** If you're writing a file whose only job is to compute derived dimensions from component specs, the assembly should be doing that work (or the parts should derive their own internal dimensions from props).
165
-
166
- 2. **No sibling imports.** A part file never `require()`s another part file. Data flows through the parent.
167
-
168
- 3. **No assembly-space coordinates in parts.** A part doesn't know `pinionZ = 14`. It receives `rackZ: 14` as a prop, or it computes its own internal Z from its own props.
35
+ **For humans.** Each part file tells a complete story: geometry, connectors, parameters, verifications — no chasing imports across eight files, no 266-line shared-dims.js to internalize. Modifying one part doesn't break siblings, because connectors are the contract: change the mount's internal cavity and nothing else moves, as long as the flange connector stays put.
169
36
 
170
- 4. **No `translate()` in assembly files.** If you're translating a part to position it, use a connector instead. The exception: ghost/reference geometry that isn't structural.
37
+ **For AIs.** Each part file is self-contained context. An agent generates `base-body.forge.js` without reading `jaw-unit.forge.js`. The assembly file is a high-level plan generatable from a natural-language description, and props are an explicit interface contract the agent knows exactly what each part needs and provides.
171
38
 
172
- 5. **No console.log validation.** Use `verify.*` for spatial checks. It's structured, clickable, and fails visibly.
39
+ **For swap-ability.** Change the servo model → the mount rebuilds with new cavity dimensions → its bolt pattern updates → the assembly passes the new pattern to base and cover → everything adapts. One change, cascading update, zero manual re-derivation.
173
40
 
174
- ## Design Gate
41
+ ## File Granularity
175
42
 
176
- **Every new multi-part example and every agent-built assembly must follow this model:**
43
+ One file per project-specific assembly is the default because it maximizes locality: parts as comment-separated sections, shared data as plain variables, the whole design visible by scrolling. Eight 40-line files are worse than one 300-line file — the context-switching cost destroys exactly the locality this model exists to create. Split only for genuine cross-project reuse or when a file outgrows ~300 lines (the binding rule is in the skill).
177
44
 
178
- > Can you understand each part file without reading any other file? Does the assembly file contain zero coordinate math? Do all inter-part relationships flow through connectors and props?
45
+ ## Enforcement
179
46
 
180
- If the answer to any is no, refactor until it's yes.
47
+ The anti-pattern list and the three-question design gate live in the `forgecad-component-model` skill; every multi-part example and agent-built assembly must pass that gate.