Keeps assembled beings assembled. A part's feetPosition is LOCAL to its parent; a body's is WORLD. Snaps drifted limbs back to their bind, re-adopts parts that came unparented, reports parts that were destroyed, and proves a child is a live entity before writing to it — because a child LISTED by getObjectChildren(host) is not necessarily alive.
PROOF BEATS MEMBERSHIP — the second clause of the child-handle law.
Measured in a live world at spec v7363–v7392: a child LISTED by getObjectChildren(host) is not necessarily a live, writable entity. getObject answers falsy for it, every setObjectProperty to it is silently ignored, and ten of those earn "<host> is looping bad entity references". 68 of that world's 326 rig parents carried at least one such ghost — bees, trees, bushes, medusas — each animating a limb that was not there.
- lib/bind.js gains liveChild(api, id), proveChildren(api, ids) and provenRing(api, host) — membership then proof in one call, returning { known, listed, live, views, ghosts }, with the proven views riding along so a caller never pays a second getObject.
- adopt() and snapChild() prove before they write and return false for a ghost, so a caller counts a part lost instead of counting a repair that never happened. snapChild takes an optional already-proven view.
- intact.js walks the PROVEN ring; ghosts are skipped silently in the hot path and surface only on the 30-tick roster audit as state.intactGhosts / intactGhostIds, and are no longer counted as present, so a ghost key now reports through intactLostKeys.
- watch.js proves every part before its re-seat writes and counts the ones it skipped.
- README documents both clauses, the witness experiment (getObject vs a 3058-id query census: zero disagreements), the observed ghost genesis (a <host>/__god_mode_visual helper reaped without its ring row being pruned), and the warning that api.getObject(host).children is never a list.
Also in this version: parts that came unparented are re-adopted rather than snapped in a world frame, and destroyed parts are reported via state.intactLost / intactLostKeys.
1.1.0
Fixes from a night of real crabs: localOf() now reads properties.feetPosition (LOCAL) first — a parented view's top-level feetPosition is WORLD, and treating it as local re-seated every limb every other tick (200k+ snaps on one crab) and stomped pose animation. Drift slack tightened 2.5 → 0.4: poses rotate limbs, they never move a limb's local anchor, and 2.5 let genuinely-detached parts (a crab's eyes 2.4m off) read as attached. Hosts that position-animate parts can widen it per-body via state.intactSlack.
First release. Enforces the one law: a part's feetPosition is local, a body's is world. intact.js pins the pieces on a multi-part being; watch.js re-seats orphans place-wide (and destroys parts whose host is gone instead of piling them at world origin); lib/bind.js is the spawn path, minting host-scoped part ids so two creatures never share a limb. Both behaviors report through entity state and log their first API failure once, so a mod that isn't working says so.