Symptom
node dist/cli/index.js validate --include-interference examples/assemblies/two-link-connector-arm.kcad.ts reports mechanism: broken. 4 failures:
mechanism.orphan-part ×2: parts 'link' and 'tool' are not reachable from the mate graph.
mechanism.interpenetration ×2: 'base'↔'link' overlap 450 mm³, 'link'↔'tool' overlap 117 mm³.
Root cause
The example uses the v0.6 connect: shorthand ({ connector, to, name }) on arm.part(...) rather than the proper arm.mate(...) API. The new physics loop iterates arm.__mates(); the shorthand records connection metadata but does not emit mate edges, so every part except the first is flagged as orphan. The 'interpenetration' failures are a downstream consequence: with no mate edges, the loop treats the inter-part contacts as unexplained overlap.
Fix scope
Migrate the example to the proper arm.mate(name, aRef, bRef, kind, ...) API. Three mates required:
shoulder-fixed: base.shoulder to link.root (fastened).
wrist-fixed: link.wrist to tool.mount (fastened).
- (Drop the duplicate
arm.connect('tool-inspection', ...) call — the mate covers it.)
After migration the orphan-part failures clear. The geometry-interpenetration failures may persist if the rest-pose geometries actually overlap (likely they do, since the original connect-shorthand pinned them by edge-touching frames); if so a small clearance translate on the link or tool resolves it. <1 hour of work.
Spec
- docs/specs/2026-06-01-physics-grounded-loop-design.md §criterion 4 / §criterion 2
- docs/plans/2026-06-01-physics-loop-P3-sweep-and-demote.md
Symptom
node dist/cli/index.js validate --include-interference examples/assemblies/two-link-connector-arm.kcad.tsreportsmechanism: broken. 4 failures:mechanism.orphan-part×2: parts 'link' and 'tool' are not reachable from the mate graph.mechanism.interpenetration×2: 'base'↔'link' overlap 450 mm³, 'link'↔'tool' overlap 117 mm³.Root cause
The example uses the v0.6
connect:shorthand ({ connector, to, name }) onarm.part(...)rather than the properarm.mate(...)API. The new physics loop iteratesarm.__mates(); the shorthand records connection metadata but does not emit mate edges, so every part except the first is flagged as orphan. The 'interpenetration' failures are a downstream consequence: with no mate edges, the loop treats the inter-part contacts as unexplained overlap.Fix scope
Migrate the example to the proper
arm.mate(name, aRef, bRef, kind, ...)API. Three mates required:shoulder-fixed:base.shouldertolink.root(fastened).wrist-fixed:link.wristtotool.mount(fastened).arm.connect('tool-inspection', ...)call — the mate covers it.)After migration the orphan-part failures clear. The geometry-interpenetration failures may persist if the rest-pose geometries actually overlap (likely they do, since the original connect-shorthand pinned them by edge-touching frames); if so a small clearance translate on the link or tool resolves it. <1 hour of work.
Spec