Object instances before contact — grasp regions without a hovering policy
Status: design + prototype (default off), pending Safety-WG review, 2026-10-05. Issue #349.
Developed on feat/object-primitives-349; landed on master with #289. The prototype is §4:
openral_hal._object_primitives + GraspTargetLeg(premeasure=True), behind
vision_attachment.grasp_target_premeasure. Everything in §3 that is not in §4 is design.
Revision 2 (2026-10-05): camera first, map confirms. Revision 1 of this note made the voxel map's connected components the primitives and the camera an optional refinement. The map cannot give identity and cannot separate objects packed together (cartons in a bin are one 26-connected blob, HZ-0115-30), and it integrates slowly; segmentation is per frame and names one object per mask. So the order is reversed: every box is originated by a head-camera mask and confirmed by the map; the map's one remaining job is to hold the confirmed box while the hand occludes the camera in the final approach. The map never originates a box.
Revision 3 (2026-10-11): the map adjudicates an occluded re-fit while the hand approaches.
Isaac s_mix07 (one of 46 deploy trials on the Spark host; the only target_moved retraction in
them): the carton's instance was held 7 s, then, as the right hand descended onto it, a
pre-measurement re-fit came back shifted and shrunk on the hand's side — held centre (0.150,
−0.091, −0.508) half (0.059, 0.044, 0.028) → re-fit (0.168, −0.088, −0.517) half (0.047, 0.041,
0.038). It was retracted as target_moved; 0.9 s later the finger reached the carton with no
exemption live and the kernel stopped (PhysX ground truth: the finger touched nothing, the
carton had not moved). Two gaps: the re-fit's only excursion past the held box grown by one
voxel was its bottom, 19 mm lower, standing on the measured board where the held fit (support
unseen) stood on its own lowest point; and the hand was approaching, not yet over the held
footprint, so the own-hand occlusion test could not apply. (Superseded by Revision 4: the
move test's downward growth and the approaching-hand map overrule are removed.)
Revision 4 (2026-10-11): frozen after map confirmation. Revision 3 patched one gate; the next Isaac deploy trials showed the camera re-fit loop redefining or retracting the held region exactly while the approaching hand occludes the target, each time through a different gate, after which the kernel stopped the finger at the target with no exemption live (PhysX: no real contact):
- s_mix07 — the occluded re-fit 19 mm lower at the bottom and shifted 18 mm on the hand's
side →
target_moved(the case Revision 3 patched); - t_mix04 (after Revision 3) — the hand above the carton, the re-fit saw only a thin top
layer: re-fit centre (0.156, −0.081, −0.495) half_z 0.015, yawed 14° off the held centre
(0.157, −0.081, −0.511) half_z 0.032 →
target_movedupward → retracted → the finger stopped at the target's edge 0.8 s later, exemption not live; - t_mix02 — a re-fit near the tote wall, centre (0.283, 0.106, −0.492) half (0.091, 0.055,
0.063) against the held (0.262, 0.078, −0.517) half (0.063, 0.042, 0.038), reached outside
the named search box →
outside_named_search_box→ retracted (re-accepted 2 s later).
Decision (maintainer-approved; the per-gate patching is replaced by one posture): once a region is
accepted and map-confirmed while a declaration is live, it is frozen for the life of that
declaration. Camera re-fits never shrink, move, grow or retract it. Only the voxel map retracts
it — on every tick with a fresh grid, map_confirms of the held box on its measured support:
map_disagrees (the grid no longer holds it: the object removed or moved off it) or map_split (a
second body inside it, unless that body lies wholly in a declared hand's own space, whose own points
can leak into the map: then a lost view and the freeze TTL runs; a foreign body such as a person's
hand retracts even with the robot's hand over the box) — or the declaration ends, is retracted or
expires, or the grid goes stale beyond freeze_s (a confirming grid re-stamps the box with its
source_stamp; with no confirming grid it ages out freeze_s after the last one). Before the first
acceptance nothing changes: every gate decides what is accepted. After it, re-fits keep running
(diagnostics, the instance tracker) and their verdict is logged once per change of outcome, grasp
target re-fit ignored, region frozen (map-confirmed) — <the gate's reason>. The camera path (no
pre-measurement) is frozen the same way (§3.2). The attach, handover, payload and release paths are
unchanged. Safety argument and what is given up: §3.7.
1. Problem
The grasp-target exemption (ADR-0115, real pick-and-place design §2.1)
exempts the declared finger links inside a producer-measured region. Without pre-measurement
the region is measured by openral_hal._grasp_target_leg only once a hand is within
grasp_target_approach_m (0.20 m) of occupied cells (arming), and only from one clean
head-camera SegmentInView fit of the target gated against the voxel map (measuring). A
scripted driver can hover 5 cm over the target until a region arrives; a VLA moves continuously,
so the leg has at most the time the hand takes to cross the approach band to get one unoccluded
fit — and the hand is what occludes the target. No region when the fingers arrive is a kernel
stop: safe, and the end of the run.
Goal: the target's region exists when the hand arms, for any object, scene and robot, with no
pause — and the kernel's contract unchanged (no region, no exemption; the region age bound,
freeze_s and the caps stay where they are).
2. Who knows what
| source | gives | cannot give |
|---|---|---|
head-camera mask (SegmentInView) |
identity (one mask, one object); the boundary between touching objects; sub-voxel extents; not_on_support (a mask of the target alone that does not reach the support is a stacked body) |
a view while the hand occludes; a prompt-free mode (one positive 3-D point per request) |
voxel map (/openral/world_voxels) |
a measured support; whether something is there (cover); whether a box holds one body or two; memory of views from before the hand arrived | identity; a split between bodies within one voxel of each other (HZ-0115-30); a split between a target and the same-footprint body it stands on |
Every gate the camera path already applies is one of these: the fit (target_region_from_masks:
support, caps, nested-mask rules) is the camera's; region_covers_occupied and the whole-body
checks are the map's. The design keeps every one of them and changes only when the camera
fit is made — before the approach, not during it — and who holds the box while the camera
cannot see.
3. Design
3.1 Pre-measurement: every instance near a hand, before any hand arms
GraspTargetLeg._premeasure runs on every leg tick when premeasure is on:
- Drop what is stale. An instance last fitted more than
freeze_sago (it could not stand a live region:acceptwould expire it) or whose box the map no longer covers (region_covers_occupiedbelowgrasp_target_min_cover— its cells cleared, the object taken away) is dropped. - Pick one prompt (at most
_PREMEASURE_MAX_HZ= 2 Hz, one request in flight; the segmenter shares the GPU with the policy). Columns, first first: the named search box or the armed hand's box; then, for each located hand holding nothing, its TCP box grown by_PREMEASURE_REACH_APPROACHES= 2 approach distances (the band the hand crosses before it arms). In each: a refresh — the centre of a tracked instance last fitted more than half a freeze ago (inside a convex body, so it projects inside its silhouette; in the armed box every instance is due at every prompt, as the camera path re-fits every tick) — or a discovery (instance_prompt: the raised top-surface cell no instance covers, nearest the hand, preferring interior cells); whichever is nearer the hand. A cell prompted within half a freeze is skipped.SegmentInViewhas no prompt-free mode and the continuous detector is evicted before every VLA dispatch (vram_lifecycle_peers) and lives in layer 2, so the map says where to look and the camera says what is there. - Fit and confirm the reply (
_on_instance_reply): the camera path's own fit (_fit: self-filtered masks, nested-mask rules, support, caps), thenmap_confirms: the map holds the box (map_disagreesotherwise) and the occupied above-support cells in its cell closure are one 26-connected body (map_splitotherwise). The box is never completed or grown from the map (map_completed_regionis not used here): that would merge exactly what the mask separated. - Track it (
PrimitiveTracker.update, label-free): a fit within one voxel refreshes its instance; one whose centre lies in an instance's box (or holds its centre) is that instance nudged; anything else is new. Bounded atmax_tracks= 16 (the one seen longest ago goes).
Packed objects. Two cartons face to face are one body in the map. The first discovery prompt
lands one cell inside the near carton's top (interior preference; the merged top's centroid
would be the seam), its mask names that carton, map_confirms passes (its padded box holds that
carton and a sliver of the touching one — one body), and once its instance covers that top the
next prompt lands on the other carton. Two masks, two instances; the map alone would have
offered the blob or nothing.
3.2 Arming: the region on the arming tick, no segmenter call
GraspTargetLeg._tick_instances, on every tick a target is armed (unchanged arming: the approach
box holds min_cells occupied cells above its lowest layer, or a named search box):
- Nothing held — acceptance. The candidate is the tracked instance nearest the armed hand's
TCP points inside the search column, refused on a tie within one voxel (
nearest_primitive, HZ-0115-2); for a named search box, the lone instance inside it (two:ambiguous; none: the lost viewno_instance). A named target also requires the whole measured instance to fit within its search box plus one voxel (outside_named_search_box). The candidate must be confirmed on the current grid (map_confirms: covered, one body) and pass_gate_refit(complete=False); then it is accepted. On the arming tick the pre-measured instance is the region before the next chunk. - Held — frozen (Revision 4). Every tick,
_map_holdrunsmap_confirmson the held box and its measured support:map_disagreesretracts;map_splitretracts unless every second body lies in a declared contact link's own space (_hand_boxes: its TCP grown by voxel + occluder margin, reaching the approach distance below;map_confirms(own=…)), where it is a lost view (the freeze TTL runs from the box's stamp, nothing re-stamps it); confirmed, the same box is re-accepted stamped with the grid'ssource_stamp— never moved, never grown. A newer re-fit of the instance still runs every gate of step 1 against the held box (_gate_instance, tracking,occluded_refit,target_moved,unoccluded_refit), but only its outcome is logged (_refit_ignored, once per change).
The camera path (premeasure off, _tick / _on_reply) is frozen the same way: _hold_frozen
runs _map_hold on each tick's grid, and once a region is held every re-fit refusal
(_refuse_refit: seed, request, deadline, reply gates) and every re-fit that would have replaced
it is logged as ignored instead of applied. Its first acceptance is unchanged (including the
completion from the map); the held region then meets the same per-tick map rule — a completed
box holds one body by construction (completion is refused when its closure holds another body's
cell). A tick that finds a request in flight takes no grid (as before), so on that path the map
check runs on every tick with no request in flight: the gap is at most deadline_s (0.25 s).
3.3 Staleness — a region never outlives its evidence
| evidence | lifetime |
|---|---|
| instance (camera fit) | dropped freeze_s after its fit, or when the map stops covering it |
| region from an instance | its stamp is min(depth frame, grid source_stamp) of the fit; the freeze TTL and the kernel's grasp_region_max_age_s run from it, as for any camera fit |
| held (frozen) region (Revision 4) | re-stamped to each confirming grid's source_stamp, hand or no hand; dies freeze_s after the last one; at once when a grid no longer covers it (map_disagrees) or holds a second body in it with outside every declared hand's own space (map_split); a stalled octomap ages it out (grid_source_stale, the kernel's bound) |
| any region | retracted with the declaration (end, retraction, expiry), at approach_ended, as today; camera re-fits never retract it once held |
The frozen region is the one place a region lives longer than its last camera fit: on map
evidence the kernel already bounds by source_stamp, for the life of the declaration. That is
the posture change §6 asks the Safety-WG to accept.
3.4 A reasoner-declared target
ExecuteRskillTool.grasp_target → ground_grasp_target → GraspDeclaration.search_box is
unchanged. The named box is the first pre-measurement column, so its instance is fitted within a
prompt or two of dispatch, and the region is the lone instance in it on the next tick — before
the goal's first chunk reaches the object, hands wherever they are. Later (§3.7): the store
published from world state, the detector label grounded to an instance id, target_id =
prim:<id>.
3.5 A VLA that picks its own target
The approach-armed path is unchanged up to the search box. Instances near each free hand are
measured while it is still two approach distances away; the candidate on the arming tick is the
nearest one. At 0.20 m approach and a 3 Hz tick the kernel has the region with 7–20 cm left,
against 0 cm when no clean fit arrives in the band. Chunk-lookahead arming (option 3 of the issue)
plugs in at one point — the TCP points handed to approach_box, the pre-measurement box and
nearest_primitive become the predicted ones — and is out of scope.
3.6 Robot and scene agnosticism
Nothing names a robot or a scene: hands from openral_core.gripper_hands, TCPs from tf2 through
the bridge (jaw_point), the camera and its depth from the vision leg's config, the support
measured under each prompt, the lattice's resolution/frame/orientation from OccupancyVoxels, the
caps the declaration's; every threshold a calibration point with a stated default.
3.7 Failure modes
| failure | outcome | why it fails safe |
|---|---|---|
| no segmenter / no depth / deadline | no instance; prompt noted once per change | nothing tracked, no region, kernel stops at the target |
| mask spans two separated bodies | map_split, not tracked |
a box over two bodies is never an instance |
| mask on something the map does not hold | map_disagrees, not tracked |
the map must confirm every box |
| packed pair (touching) | one instance per mask; each box holds a sliver of its neighbour | residual (HZ-0115-30, now a sliver within the camera padding, not the whole neighbour) |
| target on a same-footprint body | the whole-stack mask is refused STACKED; the target's own mask, refused not_on_support, is re-fitted on its own lowest point |
the body it stands on never enters the region (HZ-0115-37 closed, HZ-0115-42) |
| support unseen (a bin floor out of the camera's view; a neighbour's top or a bin rim above the target's bottom) | the region stands on the target's own lowest kept point, logged support unseen |
the box never reaches into space nothing measured; a finger below it meets the kernel's voxels |
| two instances tie for the hand / two in a named box | ambiguous, retracted |
neither exempt until the hand commits |
| hand points leak into the map | a map_split whose second body lies in a declared hand's own space is a lost view; the box is never replaced |
freeze TTL bounds it |
| second body slides into the frozen box | map_split, retracted at once (the body is outside every hand's own space, even with a hand over the box) |
only the target is ever exempt; the map shows the second body within its freshness deadline |
| object removed | held region retracted (map_disagrees), instance dropped |
the region dies with the map evidence |
| object moved off the frozen box | map_disagrees once the box no longer holds min_cover of its footprint's cells |
the region dies with the map evidence |
| object nudged within the frozen box (e.g. two voxels inside its padding) | kept: the box still holds one body, the target | the exemption still covers only the target's cells; a part pushed out of the box is not exempt, so the kernel stops the finger there (stricter, never looser) |
| camera re-fit disagrees while the hand occludes (Revision 4, Isaac s_mix07, t_mix04, t_mix02) | ignored, logged once per outcome (re-fit ignored, region frozen (map-confirmed) — target_moved / outside_named_search_box / …) |
posture change, see the safety argument below |
| re-fit with no hand near (a person's hand, the target tipped) | ignored, logged (unoccluded_refit / target_moved) |
given up (below); the map catches the outcomes that change what the box holds |
| instance not re-seen | dropped after freeze_s |
an instance that could not stand a live region is not kept |
| stalled octomap | grid_source_stale; nothing pre-measured; every region ages out |
unchanged kernel bound |
Safety argument (Revision 4). The exemption box is a measured, map-confirmed box: a camera
mask originated it, every acceptance gate passed it, and the map confirmed it held one body. While
frozen, the map re-checks exactly that on every fresh grid: a removed or moved-away object is
caught within the map's freshness deadline (≤ grid_max_age_s + one octomap integration), the
same bound as before Revision 4; a second body inside the box retracts it (map_split) unless it
lies in a declared hand's own space; source_stamp + freeze_s bound a stalled map; the kernel
contract (no region, no exemption; grasp_region_max_age_s; the caps) is unchanged and the box
never grows, so nothing outside the confirmed box is ever exempt.
What is given up is camera evidence after arming. A re-fit that contradicts the frozen box no longer retracts it: a person's hand at the target, the target tipped or nudged inside its box, or a second object slid into the box while the declared hand is over it (where leaked hand points and a real second body look the same) stay exempt until the map shows the change — a second body with the hand away, or the box no longer covered. A second object entering the box during the same octomap interval in which the target leaves it would be a one-body box again; this needs two world changes inside one map update and was equally open under the Revision 2/3 hold. Safety-WG review and a hazard-log row in the management repo are owed for this posture (not yet assigned an id); until then it inherits the parameter's default-off posture.
3.8 Layers
| piece | layer | status |
|---|---|---|
_object_primitives (prompt, confirmation, tracker), leg wiring |
0 HAL (openral_hal, beside _grasp_target; the bridge owns the segmenter client) |
prototype |
vision_attachment.grasp_target_premeasure |
core schema + HAL param + deploy-sim mapping | prototype |
publishing the store (/openral/object_primitives, an ObjectPrimitiveSet IDL) |
2 World State | design |
label → instance id grounding, GraspTargetRef.object_id = prim:<id> |
4 Reasoner (openral_reasoner.grounding) |
design |
| hull on the grasp region | 5 Safety (kernel; PlaceRegion.geometry on a grasp region) |
design, separate ADR |
The prototype crosses no layer boundary (the HAL already consumes /openral/world_voxels and owns
the SegmentInView client). It changes two recorded safety judgements, both in the producer, not
the kernel: the region may be accepted from a camera fit made before the arming (bounded by the
freeze TTL from that fit), and once accepted the map alone holds it for the declaration's life
(Revision 4: camera re-fits are logged, never applied). An ADR amendment and hazard-log rows are
required before the parameter is turned on in any committed scene, Safety-WG reviewed; the kernel
is untouched. Draft text for the private management log (OpenRAL/management, adr/):
ADR-0116 — Pre-measured camera instances as the grasp-target region source (amends ADR-0115). Context. ADR-0115 measures the grasp region from one unoccluded
SegmentInViewfit gated against the voxel map, made after a hand arms. A continuously moving policy gives the producer no unoccluded fit while armed (Isaac trials i25–i76 required a hover); without a region the kernel stops the fingers at the target. The voxel map alone cannot separate objects packed together, and cannot name one. Decision. (1) The producer may measure object instances before any hand arms: oneSegmentInViewmask per instance, prompted on a raised top surface of the map near a free hand or in a named search box (≤ 2 Hz, one in flight), fitted by the existing fit (self-filtered masks, nested-mask rules, support, caps) and confirmed by the map — it covers the box and the box's cell closure holds one 26-connected body above the support. The map never originates, completes or grows an instance. (2) On arming, the region is the tracked instance nearest the armed hand's TCP points (refused on a tie within one voxel), or the lone instance in a named search box, gated as any re-fit (tracking, own-hand occlusion); its stamp is the fit's (min(depth, grid source_stamp)) and the freeze TTL runs from it. (3) Once accepted, the region is frozen for the declaration's life (Revision 4): camera re-fits are logged, never applied; a newer grid that confirms it re-stamps the same box (source_stamp); a grid that no longer covers it, or holds a second body in it with no declared hand over it, retracts it. (4) An instance is droppedfreeze_safter its last fit or when the map stops covering it. (5) The kernel contract is unchanged: no region, no exemption; the region age bound andfreeze_sare unchanged;PlaceRegion.geometrystays empty on grasp regions. (6) Production posture: off by default; on in a committed scene only with this ADR accepted. Consequences. The region exists on the arming tick (named targets: within a prompt or two of dispatch). Packed objects are separated by their masks. The camera'snot_on_supportgate is kept. Hazard rows: HZ-0115-35 (a pre-measured instance on the wrong object — tie rule, one hand, map confirmation, freeze TTL from the fit), HZ-0115-36 (a packed neighbour's sliver inside an instance's padded box — residual, bounded by the camera padding and the cell closure), HZ-0115-38 (the map hold keeps a region alive past its last camera fit — same box only, retracted when the map stops covering it or splits it, bounded bysource_stampandfreeze_s; leaked hand points never replace it; Revision 4 extends it to the declaration's life against disagreeing camera re-fits — its own row owed).
4. Prototype (this branch)
python/hal/src/openral_hal/_object_primitives.py:instance_prompt,map_confirms,nearest_primitive,point_box_gap_m,PrimitiveTracker(update,prune),PrimitiveFit,ObjectPrimitive. Pure numpy; reuses_grasp_target's lattice, components, cover and tracking.GraspTargetLeg(premeasure=True):_premeasure(prune, one prompt,_requestwith no declaration),_on_instance_reply(_fit→map_confirms→ tracker),_tick_instances(the armed region from the instances,_gate_instance→_gate_refit(complete=False); once held,_map_holdand_refit_ignored). The camera path's freeze:_hold_frozen,_refuse_refit. Every request is a pre-measurement in this mode;kernel_region,fill, the handover, the payload and the support witness are untouched.- Parameter chain:
VisionAttachmentRuntime.grasp_target_premeasure(scene) →vision_attachment_grasp_target_premeasure(HAL param,deploy_sim._vision_attachment_hal_params) →VisionAttachmentConfig.grasp_target_premeasure→ the leg. Default off everywhere; needsgrasp_target_enabled; the approach-armed path also needsgrasp_target_approach_m. - Tests:
tests/unit/test_object_primitives.py(the committed Isaac warehouse scene's three props on the pallet deck at 15 mm cells, ray-cast into the manifest'shead_zed—tests/unit/_head_camera_render.py: each prop one confirmed instance in the kernel's contract, nearest/tie, the packed pair the map merges separated by two masks with the prompts landing one per carton, map refusal of a box it does not hold or that holds two bodies, tracker identities, staleness and map-contradiction drops);tests/unit/test_grasp_target_leg.py:: test_premeasured_instances_arm_the_region_with_no_segmenter_call(real bridge, tf2, lattice andSegmentInView.Responsereplies through_on_instance_reply; no segmenter in the graph: the arming tick holds the instance's box, the map hold re-stamps it, removal retracts it, staleness drops the rest),::test_a_named_search_box_grounds_to_the_lone_instance_in_it,::test_a_map_confirmed_grasp_target_is_frozen_and_only_the_map_retracts_it(Revision 4: the s_mix07, t_mix04 and t_mix02 re-fits on the s_mix07 cell kept and logged as ignored; map cleared, carton moved off the box, second body with the hand away → retracted; nudged inside the box, second body with the hand over it → kept; stale grids →freeze_ttl; declaration retracted → cleared) and::test_the_camera_path_freezes_its_held_region_the_same_way.
Enable in a deploy scene (with the vision leg already enabled):
runtime:
vision_attachment:
enabled: true # camera + driver topics as the scene already sets them
grasp_target_enabled: true
grasp_target_approach_m: 0.20 # the approach-armed path (a VLA picking its own target)
grasp_target_premeasure: true
5. Evaluation plan — shelf placement in Isaac Sim
Environment. A private shelf USD stage (four cartons on a shelf board in front of the
bimanual OpenArm, deploy sim with the Isaac backend, octomap at 15 mm, the kernel's world-voxel
check and grasp allowance on, the vision bridge with the head camera and the segmenter). The stage
and its scene YAML live outside this repository and are referenced only as such.
Driver. The same perception-driven scripted driver the i25–i76 trials used, with its hover wait
set to zero so it descends continuously from the pre-grasp pose (descend_without_region when no
region is held at the start of the descent) — the VLA's behaviour, with a known-good grasp pose.
Two arms: A (grasp_target_premeasure: false, the per-arming camera path) and B (true). Same
stage, same target, same driver settings. A third arm with cartons packed face to face exercises
the split.
Metrics (all from the run's logs: the driver's driver.jsonl, the HAL's grasp target region
accepted and instance pre-measurement lines, the kernel's safety.collision /
grasp_region_latched lines, the runner result):
| metric | definition |
|---|---|
| region before contact | the kernel held a region for the armed hand before the first safety.collision involving a finger link or the ATTACH, whichever first |
| region on the arming tick | first accepted − first approach arming line ≤ one tick |
| instances before arming | instances tracked around the hand at its arming line |
| split | packed arm: distinct instances on the packed cartons / cartons |
| false region rate | accepted regions whose box does not overlap the driver's chosen cluster / accepted regions |
| map-hold span | longest run of re-stamped (source_stamp) acceptances of one box |
| stop rate | runs ending in a kernel stop on the target's cells / runs |
| outcome | ATTACH reached; handover with a region; lift without a stop |
Procedure. run_trial.sh-style: boot the graph, wait for the segmenter and voxels, send the
goal, record; one trial per arm, then repeat if the host allows. Scratch scene YAML and driver copy
stay under the host's scratch directory; nothing is committed.
Result. See the PR report for the run or what blocked it; this section is updated when a run completes.
6. Decisions needed
- Safety-WG: accept the pre-measured instance source and the map hold (ADR-0116 draft, HZ-0115-35/36/38) for sim evaluation, and the production posture. Revision 4 freezes a map-confirmed region for its declaration's life and lets only the map retract it (§3.7): it gives up camera evidence after arming, so it needs its own Safety-WG review and a hazard-log row in the management repo (not yet assigned; it supersedes Revision 3's, which was owed for the narrower approaching-hand overrule).
- Where the store lives long-term: in the HAL leg (one consumer, no new topic) or published from
world state for the reasoner (grounding by instance id) — the latter needs the ADR's
layer-crossing clause and an
ObjectPrimitiveSetIDL. - The pre-measurement budget on the shared GPU (
_PREMEASURE_MAX_HZ, the reach): measured in the Isaac evaluation against the policy's chunk latency. - Whether a prompt-free instance mode (SAM automatic masks on the head frame) should replace the map-seeded prompts once the segmenter node offers one.