# $defs.Id.description
Stable identifier for this component or feature. A coder agent implementing this part is likely to use this id as a source-code variable or object name, so it must start with a letter or underscore and contain only letters, digits, and underscores.

# $defs.Relation.properties.type.description
How this component or feature is anchored relative to the target, before `position` is added as a further offset. Anchor points are defined against the target's axis-aligned bounding box (its footprint and height/thickness), not its visual surface, so the same rule applies uniformly across component kinds. See docs/composable-parts.md for the exact anchor point per type; `rib` and `wedge` targets don't have a well-defined bounding-box footprint, so `on_top_of`/`attached_to_face`/`centered_on`/`aligned_with` against them fall back to the target's own origin and `position` must express the full offset manually.

# $defs.Relation.properties.target.description
Id of the component, feature, or group this relation is relative to; required for every relation type except "absolute".

# $defs.Relation.properties.face.description
Face of the target's bounding box this relation attaches to; required when type is "attached_to_face". "side" is only meaningful for cylindrical kinds (cylinder, boss, tube) and anchors at the +X point on the target's circumference at mid-height.

# $defs.Relation.properties.mirrorAxis.description
Only used when type is "mirrored_from": the axis to mirror the target's resolved position across ("x" negates X, mirroring across the YZ plane, and so on). Defaults to "x", the common left/right mirrored-pair case. Rotation is not mirrored; see inheritRotation to copy the target's rotation verbatim instead, or set rotation explicitly.

# $defs.Relation.properties.inheritRotation.description
If true, this component's or feature's own rotation starts from the target's fully-resolved rotation (its own `rotation`, further composed with its transforming group's `rotation`, if grouped) instead of starting from zero -- so it naturally stays flush with a rotated target without hand-copying and re-deriving the same rotation value onto every dependent down a chain. A component's own `rotation` field, if also set, is applied on top of (not instead of) the inherited rotation. Only valid on a component or feature relation, not a group relation. Not automatically applied for "mirrored_from" (the target's rotation is copied verbatim, not mirrored, matching how mirrorAxis only mirrors position); combine with an explicit `rotation` if the mirrored orientation also needs adjusting.

# $defs.Relation.properties.targetInstance.description
Zero-based index into target's own pattern instances (see docs/composable-parts.md, "Patterns"), anchoring to that specific instance's resolved position instead of the pattern's center -- for example a counterbore that should stack on only one corner of a 4-hole bolt pattern. Only valid when target is a patterned component or feature (not a group, and not an unpatterned target) and less than the pattern's total instance count; semantic validation checks both. Addresses only target's own pattern, not a transforming group's pattern it may also belong to.

# $defs.Relation.description
Describes how a component, feature, or group is positioned relative to another component, feature, or group. `position` (on the component/feature/group itself) is the single offset mechanism, applied on top of the relation's resolved anchor; there is no separate offset field on the relation.

# $defs.Group.properties.description.description
Optional human-readable notes explaining what this group represents, for example "lid latch sub-assembly".

# $defs.Group.properties.memberIds.description
Ids of the components in this group. Every id must be a component id (not a feature or group id); groups are not nestable, and a component may belong to more than one group. Features stay associated with their target component and move with it implicitly; they are not listed here.

# $defs.Group.properties.position.description
Position in millimeters, relative to the part's local origin or, when relation is set, relative to the related component/feature/group. Applied as an additional transform on top of each member's own position/rotation: a group transform composes with, rather than replaces, each member's individually-authored placement.

# $defs.Group.properties.rotation.description
Optional rotation in degrees applied to the whole group as a rigid body, before translation by position. Rotations are extrinsic (fixed-axis) and applied in X, then Y, then Z order. Composes with each member's own rotation the same way position does.

# $defs.Group.properties.pattern.description
Optional repetition of the whole group (every member, as one rigid unit) instead of a single component or feature. All instances share this group's single `id` and are not individually addressable. The resolved position (from `position`/`relation`) is the center of the pattern, not its first instance; per-instance offsets are computed in the group's own (pre-rotation) local frame, so they rotate together with the group's own `rotation`. See docs/composable-parts.md for the exact per-instance offset rule.

# $defs.Group.description
A named collection of components that can be positioned, rotated, patterned, or targeted by a relation as a single unit, without changing any member's own position/rotation relative to the group. Useful once a part has enough components that a flat list becomes hard to reason about, or when a recognizable sub-assembly (for example a latch or a standoff pair) needs to move, mirror, or repeat together.

# $defs.BoxDimensions.properties.length.description
Length along the X axis, in millimeters.

# $defs.BoxDimensions.properties.height.description
Height along the Z axis, in millimeters.

# $defs.BoxDimensions.description
Dimensions for a rectangular box component.

# $defs.RoundedBoxDimensions.properties.length.description
Length along the X axis, in millimeters.

# $defs.RoundedBoxDimensions.properties.height.description
Height along the Z axis, in millimeters.

# $defs.RoundedBoxDimensions.properties.radius.description
Corner radius in millimeters; should be no more than half of the smaller of length and width.

# $defs.RoundedBoxDimensions.description
Dimensions for a box component with rounded vertical edges.

# $defs.CylinderDimensions.properties.height.description
Height along the cylinder axis, in millimeters.

# $defs.CylinderDimensions.description
Dimensions for a solid cylinder component.

# $defs.TubeDimensions.properties.innerDiameter.description
Inner bore diameter in millimeters; must be less than outerDiameter.

# $defs.TubeDimensions.properties.height.description
Height along the tube axis, in millimeters.

# $defs.PlateDimensions.properties.length.description
Length along the X axis, in millimeters.

# $defs.PlateDimensions.properties.thickness.description
Plate thickness along the Z axis, in millimeters.

# $defs.TabDimensions.properties.length.description
Length along the X axis, in millimeters.

# $defs.TabDimensions.properties.thickness.description
Tab thickness along the Z axis, in millimeters.

# $defs.TabDimensions.description
Dimensions for a small flat tab or ear component.

# $defs.BossDimensions.properties.height.description
Height along the boss axis, in millimeters.

# $defs.BossDimensions.description
Dimensions for a cylindrical mounting boss component.

# $defs.RibDimensions.properties.height.description
Rib height in millimeters, measured from its base.

# $defs.RibDimensions.description
Dimensions for a thin structural reinforcing rib component.

# $defs.WedgeDimensions.properties.length.description
Length along the sloped (X) axis, in millimeters.

# $defs.WedgeDimensions.properties.height.description
Height of the tall edge in millimeters; the wedge tapers to zero height along length.

# $defs.WedgeDimensions.description
Dimensions for a wedge (sloped right-triangular prism) component.

# $defs.ExtrudedProfileCurve.oneOf[].description
The edge from this point to the next is a circular arc through this point, the given through point, and the next point (in that order) -- not a straight line.

# $defs.ExtrudedProfileCurve.oneOf[].properties.controlPoints.description
One or more control points between this point and the next (one gives a quadratic Bezier curve; two gives cubic; and so on).

# $defs.ExtrudedProfileCurve.oneOf[].description
The edge from this point to the next is a Bezier curve through this point, the given control point(s) in order, and the next point -- not a straight line.

# $defs.ExtrudedProfileCurve.oneOf[].properties.through.description
One or more points the edge passes through (approximately -- brepjs's underlying B-spline approximation, not an exact interpolation), between this point and the next, in order.

# $defs.ExtrudedProfileCurve.oneOf[].description
The edge from this point to the next is a smooth B-spline curve through this point, the given through point(s) in order, and the next point -- not a straight line. Use this instead of `arc` for a smooth curve through more than one intermediate point, or instead of `bezier` when a smooth, organic curve is wanted rather than one shaped by a pulling control point.

# $defs.ExtrudedProfileCurve.description
Describes the edge from a profile point to the next one (in points' authored order) as a curve instead of the default straight line.

# $defs.ExtrudedProfilePoint.properties.x.description
X coordinate in millimeters, relative to the part's local origin.

# $defs.ExtrudedProfilePoint.properties.y.description
Y coordinate in millimeters, relative to the part's local origin.

# $defs.ExtrudedProfilePoint.properties.curve.description
Optional: makes the edge from this point to the next one a curve (arc or Bezier) instead of a straight line. Has no effect on the last point's own coordinates -- it only describes the closing edge back to the first point.

# $defs.ExtrudedProfilePoint.description
One vertex of an extruded_profile's footprint, with an optional curve describing the edge to the next vertex.

# $defs.ExtrudedProfileDimensions.properties.points.description
Vertices of the footprint's polygon in the XY plane, in order around its perimeter (either winding direction; the shape comes out the same either way). The polygon is implicitly closed -- the last point connects back to the first, so don't repeat it. Points may be given in any convenient coordinate space; the generator centers the polygon's bounding box (including any curve's through/control points, not just the vertices themselves) at the component's own local origin, the same convention used for every other component kind, so the same list of points always produces the same shape regardless of where it happens to sit numerically. Each point may set an optional `curve` to make the edge to the *next* point (in this array's order) an arc or a Bezier curve instead of a straight line.

# $defs.ExtrudedProfileDimensions.properties.height.description
Extrusion height along the Z axis, in millimeters, from the footprint (at the component's base) upward.

# $defs.ExtrudedProfileDimensions.description
Dimensions for a component whose footprint is an arbitrary polygon -- not just a box or a circle -- extruded to a given height. Use this for a custom cross-section none of the other component kinds can approximate (an L-shaped bracket profile, a custom brace, a rounded/filleted custom footprint via curved points, and so on).

# $defs.SphereDimensions.description
Dimensions for a solid sphere component. Like every other kind, a sphere sits with its base (its lowest point) at Z=0 on its own local origin, not centered on Z -- rest a sphere on top of another component with an ordinary on_top_of relation, the same as any other kind, rather than needing to manually offset it upward by its own radius.

# $defs.TorusDimensions.properties.outerDiameter.description
Overall outer diameter of the whole ring in millimeters, measured across the outside of the tube.

# $defs.TorusDimensions.properties.tubeDiameter.description
Diameter of the tube's own circular cross-section in millimeters; must be less than outerDiameter (the ring's major radius, which the tube sweeps around, is (outerDiameter - tubeDiameter) / 2, and must be positive).

# $defs.TorusDimensions.description
Dimensions for a solid torus (ring/donut) component, lying flat with its axis along Z by default -- rotate it (for example 90 degrees about X) to stand it up as a loop. Like every other kind, a torus sits with its base at Z=0 on its own local origin, not centered on Z.

# $defs.EllipsoidDimensions.properties.lengthX.description
Full length along the X axis, in millimeters.

# $defs.EllipsoidDimensions.properties.lengthY.description
Full length along the Y axis, in millimeters.

# $defs.EllipsoidDimensions.properties.lengthZ.description
Full length along the Z axis, in millimeters.

# $defs.EllipsoidDimensions.description
Dimensions for a solid ellipsoid component -- a sphere stretched independently along each axis. Like every other kind, an ellipsoid sits with its base (its lowest point) at Z=0 on its own local origin, not centered on Z.

# $defs.RevolveProfileCurve.oneOf[].description
The edge from this point to the next is a circular arc through this point, the given through point, and the next point (in that order) -- not a straight line.

# $defs.RevolveProfileCurve.oneOf[].properties.controlPoints.description
One or more control points between this point and the next (one gives a quadratic Bezier curve; two gives cubic; and so on).

# $defs.RevolveProfileCurve.oneOf[].description
The edge from this point to the next is a Bezier curve through this point, the given control point(s) in order, and the next point -- not a straight line.

# $defs.RevolveProfileCurve.oneOf[].properties.through.description
One or more points the edge passes through (approximately -- brepjs's underlying B-spline approximation, not an exact interpolation), between this point and the next, in order.

# $defs.RevolveProfileCurve.oneOf[].description
The edge from this point to the next is a smooth B-spline curve through this point, the given through point(s) in order, and the next point -- not a straight line. Use this instead of `arc` for a smooth curve through more than one intermediate point, or instead of `bezier` when a smooth, organic curve is wanted rather than one shaped by a pulling control point.

# $defs.RevolveProfileCurve.description
Describes the edge from a revolve profile point to the next one (in points' authored order) as a curve instead of the default straight line.

# $defs.RevolveProfilePoint.properties.radius.description
Distance from the revolve axis (Z) in millimeters; must be non-negative -- 0 sits exactly on the axis.

# $defs.RevolveProfilePoint.properties.z.description
Position along the revolve axis in millimeters, in whatever coordinate space is convenient -- the generator shifts the whole profile's Z range so its minimum lands at the component's own Z=0, the same "Z=0 at base" convention as every other kind.

# $defs.RevolveProfilePoint.properties.curve.description
Optional: makes the edge from this point to the next one a curve (arc or Bezier) instead of a straight line. Has no effect on the last point's own coordinates -- it only describes the closing edge back to the first point.

# $defs.RevolveProfilePoint.description
One vertex of a revolve profile's cross-section, in the (radius, z) half-plane the profile is revolved around Z from.

# $defs.RevolvedProfileDimensions.properties.points.description
Vertices of the profile's cross-section in the (radius, z) half-plane, in order around its perimeter (either winding direction), implicitly closed back to the first point -- the same convention as extruded_profile's footprint, just in the revolve axis's half-plane instead of the XY plane. Revolved around the Z axis (by sweepAngle, or a full 360 degrees if omitted) to produce a solid of revolution. A profile that includes radius: 0 at some point produces a solid revolve with no center hole (a knob, a dome); a profile entirely at radius > 0 produces a hollow ring (a torus-like shape) instead. All radius values must be >= 0; the generator shifts the whole profile's Z range so its minimum lands at the component's own Z=0, the same "Z=0 at base" convention as every other kind, but does not shift or center radius, since the revolve axis (radius=0) is a fixed reference, not an arbitrary footprint to center.

# $defs.RevolvedProfileDimensions.properties.sweepAngle.description
Angle in degrees to revolve the profile through, measured counterclockwise around the Z axis starting from the +X direction; defaults to a full 360-degree revolution. A value less than 360 produces an open, partial solid of revolution (for example a quarter-round channel), correctly capped with flat faces at each end -- real-kernel-verified.

# $defs.RevolvedProfileDimensions.description
Dimensions for a component whose cross-section (an arbitrary polygon in the (radius, z) half-plane) is revolved around the Z axis to form a solid of revolution -- pulleys, custom shafts, flanges, bushings, knobs, and similar rotationally-symmetric shapes none of the other component kinds can approximate directly.

# $defs.LoftProfileSection.properties.points.description
Vertices of this cross-section's footprint in the XY plane, in order around its perimeter (either winding direction), implicitly closed back to the first point -- the same convention (including optional per-point `curve`) as extruded_profile's own `points`. Centered at this section's own local origin independently of every other section's points, so cross-sections stack concentrically by default.

# $defs.LoftProfileSection.properties.z.description
Height along Z, in millimeters, at which this cross-section sits, in whatever coordinate space is convenient -- the generator shifts every section's Z uniformly so the lowest section's z lands at the component's own Z=0, the same "Z=0 at base" convention as every other kind.

# $defs.LoftProfileSection.description
One cross-sectional profile of a loft_profile component, at a given height along Z.

# $defs.LoftProfileDimensions.properties.profiles.description
Cross-sectional profiles to blend between, in order of increasing or decreasing z (order in this array does not need to match z order, but the shape will be more predictable if it does). Profiles may have different numbers of points; brepjs's underlying loft algorithm corresponds vertices automatically. At least 2 profiles are required -- a single profile has nothing to loft to.

# $defs.LoftProfileDimensions.description
Dimensions for a component that blends between 2 or more cross-sectional profiles at different heights -- a square-to-round adapter, a tapered housing, or any other transitional shape none of the other component kinds can approximate directly.

# $defs.SweptProfileDimensions.properties.profile.description
Closed cross-section swept along `path`, in the same {x, y} convention (including optional per-point `curve`) as extruded_profile's own `points`. Unlike extruded_profile, this is NOT centered on its own bounding box -- it's authored directly in the path's own local coordinate frame, so a profile point at {x: 0, y: 0} sits exactly on the path's own centerline. Offset the profile deliberately (for example to sweep an off-center channel) by using non-zero coordinates.

# $defs.SweptProfileDimensions.properties.path.description
The spine to sweep `profile` along: a sequence of 3D points connected by straight lines (curved path segments are not yet supported). path[0] is the component's own local origin (Z=0), the same base convention as every other kind. The first two points must differ only in z -- the path's first segment must run parallel to the Z axis, matching the profile's fixed orientation in the XY plane -- see docs/composable-parts.md for why. No two consecutive points may be identical.

# $defs.SweptProfileDimensions.description
Dimensions for a component built by sweeping an arbitrary closed cross-section along a 3D path -- a cable channel, a handle, a bent standoff, or any other shape that follows a path none of the other component kinds can approximate directly.

# $defs.HoleFeatureParameters.properties.depth.description
Hole depth in millimeters, or "through" to cut completely through the target; defaults to a through hole when omitted.

# $defs.HoleFeatureParameters.properties.countersink.description
Optional countersink for a flat-head fastener.

# $defs.HoleFeatureParameters.properties.counterbore.description
Optional counterbore for a fastener head.

# $defs.HoleFeatureParameters.description
Parameters for a hole feature cut into the target component.

# $defs.SlotFeatureParameters.properties.length.description
Slot length in millimeters, measured along its long axis.

# $defs.SlotFeatureParameters.properties.depth.description
Slot depth in millimeters, or "through" to cut completely through the target; defaults to a through slot when omitted.

# $defs.SlotFeatureParameters.description
Parameters for a slot feature cut into the target component.

# $defs.FilletFeatureParameters.properties.radius.description
Fillet radius in millimeters; must be less than half of the target's smallest relevant dimension.

# $defs.FilletFeatureParameters.properties.edges.description
Which subset of the target's edges to fillet: "vertical" selects the target's edges parallel to its own local Z axis (its vertical corners); "top"/"bottom" select the perimeter edges of the target's top/bottom face; "all" selects every edge on the target (a full 3D round-over, like a soap bar), only supported for kinds with no curved surfaces and no fillets already baked into their own construction ("box"/"plate"/"tab" -- not "rounded_box", "cylinder"/"boss"/"tube", or any curved/profile-based kind). Whether a given kind supports a given value depends on its geometry; an unsupported combination is dropped with a warning rather than guessed at. See docs/composable-parts.md.

# $defs.FilletFeatureParameters.description
Parameters for a fillet (rounded edge) feature applied to a bounded subset of the target component's edges.

# $defs.ChamferFeatureParameters.properties.distance.description
Chamfer distance in millimeters, measured along each adjoining face; must be less than half of the target's smallest relevant dimension.

# $defs.ChamferFeatureParameters.properties.edges.description
Which subset of the target's edges to chamfer: "vertical" selects the target's edges parallel to its own local Z axis (its vertical corners); "top"/"bottom" select the perimeter edges of the target's top/bottom face; "all" selects every edge on the target, only supported for kinds with no curved surfaces and no fillets already baked into their own construction ("box"/"plate"/"tab" -- not "rounded_box", "cylinder"/"boss"/"tube", or any curved/profile-based kind). Whether a given kind supports a given value depends on its geometry; an unsupported combination is dropped with a warning rather than guessed at. See docs/composable-parts.md.

# $defs.ChamferFeatureParameters.description
Parameters for a chamfer (beveled edge) feature applied to a bounded subset of the target component's edges.

# $defs.TextFeatureParameters.properties.depth.description
Emboss/engrave depth in millimeters. For "engrave", must be less than the target's own depth dimension.

# $defs.TextFeatureParameters.properties.size.description
Font size in millimeters (roughly the cap height); defaults to 10 if omitted.

# $defs.TextFeatureParameters.properties.fontUrl.description
URL to a TrueType/OpenType font file, fetched at runtime when the generated brepjs module is loaded (brepjs has no bundled default font). Must be a scheme `fetch()` can actually retrieve -- an `http(s)://` URL, or a `data:` URI with the font bytes inlined; a local filesystem path or `file://` URL will not work under Node's built-in `fetch`. Required because there is no safe default to fall back to.

# $defs.TextFeatureParameters.properties.fontUrl.x-printspec-hint
Point this at a font file your printed part's target environment can actually fetch at generation-verification/build time -- for example a direct link to a Google Fonts TTF file, or a data: URI with a small font embedded.

# $defs.TextFeatureParameters.properties.mode.description
Whether the text is raised (emboss) or recessed (engrave).

# $defs.TextFeatureParameters.description
Parameters for a text feature applied to the target component.

# $defs.ShellFeatureParameters.properties.thickness.description
Wall thickness in millimeters, measured inward from the target's outer surface; must be less than half of the target's smallest relevant dimension.

# $defs.ShellFeatureParameters.properties.openFaces.description
Faces of the target's bounding box to remove (open up), using the same face convention as Relation.face. At least one is required -- the underlying brepjs shell operation has no "fully sealed" mode. Which faces are actually supported depends on the target component's kind; an unsupported face is dropped with a warning rather than guessed at. See docs/composable-parts.md.

# $defs.ShellFeatureParameters.description
Parameters for a shell (hollow-out) feature applied to the target component.

# $defs.ThreadFeatureParameters.properties.pitch.description
Axial distance per full turn, in millimeters.

# $defs.ThreadFeatureParameters.properties.height.description
Total thread length along the target's axis, in millimeters, starting at the feature's own resolved position (Z=0 relative to the target, like every other feature).

# $defs.ThreadFeatureParameters.properties.depth.description
Radial thread height (crest minus root) in millimeters; defaults to 0.6 x pitch (an approximately ISO 60-degree V profile) when omitted.

# $defs.ThreadFeatureParameters.properties.toothHalfWidth.description
Axial half-width of the tooth at the root, in millimeters; defaults to 0.42 x pitch when omitted.

# $defs.ThreadFeatureParameters.properties.crest.description
Axial half-width of a flat crest, in millimeters, giving a trapezoidal tooth instead of a pointed V; 0 (default) is a sharp V (ISO/UN). Use a positive value for a power-screw profile (roughly 0.18 x pitch for Acme/trapezoidal, near toothHalfWidth for a square thread). Must be less than toothHalfWidth.

# $defs.ThreadFeatureParameters.properties.sectionsPerTurn.description
Loft sections per turn; higher is smoother but slower to generate.

# $defs.ThreadFeatureParameters.properties.mode.description
"external" fuses the thread ridge onto the target's outer surface (a printed screw/bolt/threaded post) -- valid targets are a "cylinder", "boss", or "tube" component. "internal" cuts the thread ridge from the target's inner bore (a printed nut/threaded insert) -- valid targets are a "tube" component (its own inner bore) or a "hole" feature (its own bore).

# $defs.ThreadFeatureParameters.description
Parameters for a thread feature applied to the target component -- a real helical screw-thread ridge built via brepjs's thread() operation. The thread's own radius is not author-specified; it is derived directly from the target's own diameter/outerDiameter/innerDiameter (whichever applies), so the thread always sits exactly flush with the surface it belongs to.

# $defs.DimensionRef.properties.ref.description
Id of the component or feature whose dimensions/parameters this references.

# $defs.DimensionRef.properties.key.description
Key within the referenced component's `dimensions` object or feature's `parameters` object, for example "diameter" or "radius".

# $defs.DimensionRef.description
References a single already-authored numeric value from a component's `dimensions` or a feature's `parameters`, for use in a `dimension` constraint.

# $defs.DimensionConstraint.properties.id.description
Optional identifier used in validation error messages; if omitted, the constraint's position in the array is used instead.

# $defs.DimensionConstraint.properties.description.description
Optional human-readable explanation of intent, for example "boss must clear the mounting hole with at least 0.2mm radial play".

# $defs.DimensionConstraint.properties.left.description
Left-hand value: a literal number, or a reference to a component's dimension or feature's parameter.

# $defs.DimensionConstraint.properties.right.description
Right-hand value: a literal number, or a reference to a component's dimension or feature's parameter.

# $defs.DimensionConstraint.properties.margin.description
Added to the right-hand value before comparing, for example to require a minimum clearance: `left >= right + margin` with `margin: 0.2` requires left to exceed right by at least 0.2mm, not just be greater.

# $defs.DimensionConstraint.description
Asserts a numeric relationship between two dimension/parameter values (or literals), checked at validation time against the part's already-authored numbers -- not solved for. Every value referenced must already be concretely specified elsewhere in the spec (a component's `dimensions`, a feature's `parameters`); this only validates the numbers that are already there, the same way the schema's built-in checks do (for example a hole's diameter against its target's width), just author-expressible for relationships the schema doesn't hardcode.

# $defs.ClearanceConstraint.properties.id.description
Optional identifier used in validation error messages; if omitted, the constraint's position in the array is used instead.

# $defs.ClearanceConstraint.properties.description.description
Optional human-readable explanation of intent, for example "latch arm must clear the housing wall by 0.3mm to move freely".

# $defs.ClearanceConstraint.properties.a.description
Id of the first component this clearance constraint checks. Must be a component id (not a feature or group id) with well-defined geometry (not `rib`/`wedge`, which have no bounding box to measure a gap against).

# $defs.ClearanceConstraint.properties.b.description
Id of the second component this clearance constraint checks; same restrictions as `a`, and must be a different component.

# $defs.ClearanceConstraint.properties.minDistance.description
Minimum required gap in millimeters between a's and b's fully resolved geometry (every pattern instance of each, if patterned). 0 means they must not overlap but may touch.

# $defs.ClearanceConstraint.description
Asserts a minimum spatial gap between two components -- unlike `dimension` constraints (checked by semantic validation, shared by both languages, against already-authored numbers), this needs each component's fully resolved world position (including relations, rotation, and group/pattern composition), which only the TypeScript brepjs generator can compute; semantic validation only checks that `a`/`b` reference real, geometrically well-defined components, not whether the constraint actually holds. A violated `clearance` constraint is reported as a `generateBrepJs` warning, not a semantic validation error, and only when generating with brepjs -- there is no Python-side equivalent, since the Python package has no composable_part generator at all. Approximated the same way the generator's connectivity check already is: via each component's axis-aligned bounding box (every pattern instance of it), not real boolean geometry, so it can miss a real gap between two components whose *boxes* still overlap. See `examples/composable/clearance-fit-boss-and-cap.json`, which predates this constraint type and expresses the same clearance relationship as a `dimension` constraint on diameters instead (still the better choice whenever the clearance is really just a dimension comparison, as it is there); use `clearance` when the two components' relative position, not just their sizes, is what actually needs checking.

# properties.type.description
Stable printspec part family identifier.

# properties.description.description
Optional human-readable notes for this part.

# properties.components.items.properties.appliesTo.description
Optional list of component ids this operation applies to. For a "subtract" or "intersect" component, this scopes the operation to specific components instead of everything added so far (the default when omitted); has no effect on "add" components.

# properties.components.items.properties.dimensions.description
Kind-specific dimensions; the required and allowed keys depend on this component's kind.

# properties.components.items.properties.position.description
Position in millimeters of this component's local origin, relative to the part's local origin (or, when relation is set, relative to the related component). Every component kind is modeled centered on its own local origin along X and Y, with Z=0 at its base and its height/thickness extending in +Z; rotation, if set, is applied before this translation.

# properties.components.items.properties.rotation.description
Optional rotation in degrees around this component's local origin, applied before translation by position. Rotations are extrinsic (fixed-axis) and applied in X, then Y, then Z order.

# properties.components.items.properties.pattern.description
Optional repetition of this component. All instances share this component's single `id` and are not individually addressable by other features/relations/groups; author separate components instead if instances need individual treatment. The resolved position (from `position`/`relation`) is the center of the pattern, not its first instance. See docs/composable-parts.md for the exact per-instance offset rule.

# properties.features.items.properties.description.description
Optional human-readable notes explaining why this feature exists or how it should be implemented, for example "M3 clearance hole for the standoff screw".

# properties.features.items.properties.target.description
Id of the component (or feature, for stacked features such as a counterbore on top of a hole) this feature applies to.

# properties.features.items.properties.position.description
Position in millimeters, relative to the target's local origin (or, when relation is set, relative to the related component), using the same origin convention as component position: centered along X and Y, with Z=0 at the target's base.

# properties.features.items.properties.pattern.description
Optional repetition of this feature (for example a bolt circle of holes). All instances share this feature's single `id` and are not individually addressable; author separate features instead if instances need individual treatment. The resolved position (from `position`/`relation`) is the center of the pattern, not its first instance. See docs/composable-parts.md for the exact per-instance offset rule.

# properties.features.items.properties.parameters.description
Kind-specific parameters; the required and allowed keys depend on this feature's kind.

# properties.groups.description
Optional named collections of components that can be positioned, rotated, or targeted by a relation as a single unit. See docs/composable-parts.md for how group transforms compose with each member's own position/rotation.

# properties.constraints.description
Optional declarative assertions, for example "boss diameter must be less than hole diameter minus 0.2mm clearance" (a `dimension` constraint) or "the latch arm must clear the housing wall by 0.3mm" (a `clearance` constraint). `dimension` constraints are checked at validation time (both languages) against the part's already-authored dimension/parameter values, not solved for. `clearance` constraints need each component's fully resolved world position, so they can only be evaluated by the TypeScript brepjs generator (reported as a warning if violated), not by semantic validation in either language -- see ClearanceConstraint's own description.

# description
Composable Part schema for printspec documents.