Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 59 additions & 4 deletions agent_context/topics/atomic-actions/atomic-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -442,15 +442,27 @@ asynchronous integrations instead pass `effect_result` explicitly on a due
`step()` call.

```python
import torch

request = tick.pending_effect
effect_result = EffectVerificationResult(
verification_id=request.verification_id,
success_mask=observed_success,
failure_mask=observed_failure,
invalidation_mask=observed_failure,
retry_mask=torch.zeros_like(observed_failure),
)
result = runner.step(effect_result=effect_result)
```

Both failure-policy masks must be subsets of `failure_mask`.
`invalidation_mask` selects rows on which the core applies the request-owned,
removal-only `failure_invalidation` delta; it does not let the verifier inject
state. `retry_mask` is reserved for rows whose physical preconditions still
make replay of the same invocation valid. Other failed rows require external
recovery. Unresolved evidence at the action deadline is reconciled fail-closed
when the pending effect covers active verified state.

The semantic layer keeps physical observation separate from symbolic effect
commit. `SkillPolicyPreset.effect_monitors` maps exact semantic call IDs to
versioned, bounded-declarative `EffectMonitorRef` values. Omitting the mapping
Expand All @@ -472,6 +484,13 @@ command-only `RuntimeEndpointTarget`. This keeps motion, mobile, whole-body,
articulation, and custom controller transports extensible without treating a
control part as symbolic state identity.

`HeldObjectState` is verified symbolic knowledge only. Neither it nor the
standard effect runtime creates simulator joints, managed attachments,
kinematic parents, frozen bodies, or pose overrides. Physical grasp retention
therefore depends on the configured controller, collision geometry, materials,
contact solver, and rigid-body parameters. A command-state evidence value is
only accepted controller intent and never physical contact proof by itself.

Providers emit raw `PoseRelationEvidenceBatch`, `BinaryEffectEvidenceBatch`,
`ScalarEffectEvidenceBatch`, or `JointStateEvidenceBatch` values with stable
environment IDs, per-row validity/acquisition diagnostics, timestamps, and
Expand All @@ -491,6 +510,17 @@ Cause events (`ACTION_PLANNING_FAILED`, `EFFECT_VERIFICATION_FAILED`, and
`EFFECT_VERIFICATION_TIMEOUT`) are distinct from the `ACTION_RETRY` recovery
event. `SESSION_COMPLETED` and `SESSION_FAILED` are distinct terminal events.

Effect verification is currently a terminal action boundary. There is no
in-flight physical-invariant monitor for the held-object relation during Pick
lift or HandOver transfer/release/delivery. A slip can therefore be detected at
the terminal monitor but cannot interrupt the trajectory at the frame where it
occurs. On a failed HandOver, the success-only `StateDelta` is not committed,
but an already verified source-held relation also is not reconciled from
failure evidence; blindly retrying after both grippers lost the object can use
stale symbolic state. Pure-dynamics recovery needs a typed, phase-aware
in-flight guard plus failure-outcome reconciliation rather than a simulator-side
attachment.

Recovery replans reuse the current immutable `ResolvedActionRequest`, including
its owned goal snapshot. Mutable goal values are copied, while simulator-backed
`BatchEntity` handles retain their runtime identity. To change a goal, option,
Expand Down Expand Up @@ -693,7 +723,13 @@ profile catalog rather than duplicate robot data across tasks.
The Open Drawer vertical slice has completed its supported-simulation physical
run and reached the configured drawer joint target. Repeated cube pick/place has
completed one physical Pick/Place/settle/validator cycle; the full three-cycle
run remains in threshold calibration.
run remains in threshold calibration. The dual-UR5/PGI HandOver slice has
completed three consecutive supported-simulation Pick/transfer/settle/validator
runs using contact dynamics only. Its calibrated profile drives only the PGI
master joints, keeps mimic-child drives disabled, uses a 0.011 close target with
stiffness 2000, damping 50, and maximum effort 140, models the can at 0.33 kg,
and uses 200 motion samples. The default 0.05-rad tracking gate and bounded
replanning remain active.

When no explicit contact or constraint callback is installed, simulation grasp
and release evidence combines the live object-to-endpoint pose relation with
Expand All @@ -707,9 +743,28 @@ contact by itself.

`DynamicSettleMonitor` is shared by reset events and the Expert Program
`wait_stable` post-policy. It owns threshold, cadence, consecutive-check,
settled, and timeout state but never steps simulation. The demo policy yields
full-qpos holds through the normal environment step path. Segment validators
remain a separate dataset/task boundary.
settled, and timeout state but never steps simulation. Eligible rows reuse live
target qpos so a contact-blocked position gripper retains closure preload;
initially inactive rows use fresh measured-qpos holds. Early-settled eligible
rows keep their targets until the active cohort terminates. Every action still
passes through the normal environment-step path, and segment validators remain
a separate dataset/task boundary.

The standard simulation factory lowers both `MotionPolicy.control_dt` and
`ExecutionRunnerCfg.minimum_cycle_time` to the authoritative Gym `step_dt`.
When `hold_during_effect_verification=False`, runner polling emits no
observed-position HOLD; the bridge advances physics by replaying the last
accepted environment action. HandOver also sets `hold_on_completion=False`, so
its subsequent `wait_stable` policy continues the existing targets rather than
neutralizing the gripper at its contact-displaced qpos. Cancellation and
failure still perform cancel followed by an observed-position safe hold.

This staged B behavior solves the validated joint-position HandOver path but is
not a generic continuation contract for mobile-base or whole-body transports.
Those endpoints need a typed transport-owned continuation command rather than a
joint-qpos latch. `wait_stable` also runs only after terminal effect verification
and symbolic-state commit, so its timeout is a post-policy failure and does not
trigger atomic-action recovery.

Runtime and demo results expose deterministic JSON-safe metadata. Call traces
include invocation identity, masks, command counts, execution/recovery events,
Expand Down
133 changes: 124 additions & 9 deletions docs/design/declarative_expert_program_plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@
tests are explicitly enabled. Open Drawer has completed its
supported-simulation physical run; repeated cube pick/place has completed one
Pick/Place/settle/validator cycle, while the full three-cycle run remains in
threshold calibration.
- Baseline: `main@bcccb787e8f9165e9c8acf6f39f165ba6ac752a4`
threshold calibration. Dual-UR5/PGI HandOver has completed three consecutive
supported-simulation Pick/transfer/settle/validator runs using contact
dynamics only. Named trajectory-segment effect gates now block Pick lift,
Place retract, and HandOver source release until fresh physical evidence
confirms the required acquisition or release. Preset-owned, row-local
workflow recovery now executes a real re-acquisition `Pick` when the source
relation is lost, or directly retries the failed semantic call when verified
state proves the source relation remains.
- Baseline: `main@bcccb787dcafdafd7b944ba210e5e85f9cd1d0cb`
- Last updated: 2026-08-11
- Related issues: [#471](https://github.com/DexForce/EmbodiChain/issues/471),
[#474](https://github.com/DexForce/EmbodiChain/issues/474)
Expand Down Expand Up @@ -423,7 +430,8 @@ an `arm + tool` schema. It contains a generic resource DAG:
embodiment data owned by generic profile IDs selected by each endpoint
adapter; only the current core bridge lowers applicable profiles to robot
control-part keys;
- versioned `SkillPolicyPreset` values own motion, recovery, and runner policy;
- versioned `SkillPolicyPreset` values own motion, atomic recovery, bounded
workflow recovery, and runner policy;
- per-skill defaults map every skill-local slot to one resource ID.

Resource and endpoint declarations are owned snapshots. A custom endpoint with
Expand Down Expand Up @@ -586,6 +594,90 @@ handover, and articulation-joint progress. Hardware can implement the same
contract with perception, force, or controller feedback. Custom monitors stay
an advanced extension point.

Grasp and handover must remain real dynamics outcomes. A simulation effect
monitor is observational: it must not create a fixed joint, managed attachment,
kinematic parent, frozen body, or pose override to make a held-object relation
persist. Grasp retention comes from embodiment-owned drive settings, collision
geometry, material/contact parameters, solver settings, and the commands sent
through the normal controller path. An accepted semantic ``grasp`` command is
controller intent, not physical proof.

``HeldObjectState`` records a relation only after live physical evidence has
passed the selected monitor. The target contract must treat contradictory
evidence, including object-to-endpoint slip, as a real effect failure, invalidate
the affected row's assumed relation, and enter bounded recovery instead of
repairing the scene. The runtime now exposes the active named trajectory
segment, observes segment-scoped held-object invariants from fresh physical
evidence, and
applies removal-only ``StateDelta`` reconciliation to failed rows before any
retry or recovery hand-off. The monitor publishes one current-observation
outcome per physical expectation, including the stronger proof that every
clause reached its inverse band. ``Pick`` can use the existing bounded action
retry. ``Place`` retries only when that complete inverse proof shows the source
is still attached; otherwise it invalidates the relation and emits a typed
``RECOVERY_REQUIRED`` boundary. ``HandOver`` always hands terminal failure to
workflow recovery, retaining the source relation only when complete inverse
evidence proves it is still attached. A verifier selects row-local retry versus
external recovery, but the core owns the removal-only invalidation delta and
applies it before either path. Evidence that remains unresolved at the action
deadline is reconciled fail-closed: any active verified state covered by the
pending effect is removed before external recovery. Workflow-level
re-acquisition is owned by the same ``SkillRuntime`` and may not repair the
scene implicitly. ``SkillPolicyPreset`` schema version 3 adds a
``WorkflowRecoveryPolicy`` whose per-row attempt budget defaults to zero. The
runtime consults it only after the atomic core emits ``RECOVERY_REQUIRED``. A
row whose reconciled ``TaskState`` still proves the source held-object relation
retries the failed semantic call from a fresh observation. A row whose source
relation was invalidated executes a real semantic ``Pick`` using the failed
call's resolved source resource, then retries the original call. Each recovery
call receives normal analysis, grounding, planning, command dispatch, physical
effect verification, and trace metadata; it is not a state edit or simulator
repair. Attempts are bounded independently per row, while already successful
rows wait at the existing shared call barrier. This is runtime policy, not an
Expert Program ``Retry`` node or a second workflow executor.

Blocking physical-effect gates are enforced at named trajectory-segment
entries. ``Pick`` requires destination attachment before ``lift``; ``Place``
requires source detachment before ``retract``; and ``HandOver`` requires
destination attachment before the source ``release`` segment. While a gate is
unresolved, the session does not advance its waypoint cursor and replays the
preceding command for the complete synchronized active cohort, so gripper
preload or open intent remains active under real dynamics. Gate success only
unlocks motion and never commits ``TaskState``; terminal effect verification
remains authoritative. Contradiction uses the enclosing action's bounded retry
policy, stale request IDs are rejected, and the action deadline covers gate
polling. Every gate owns a fresh monitor instance independent from the terminal
monitor and in-flight loss guard. For handover, terminal success transfers the
verified relation from source to destination while the destination remains
physically closed. Releasing the destination is a separate ``Place`` or
``Release`` semantic call.

The first pure-dynamics rollout uses the staged **B** continuation policy. The
standard simulation factory lowers both trajectory ``control_dt`` and runner
``minimum_cycle_time`` to the authoritative Gym step. A persistent
joint-position task may disable observed-position holds during terminal effect
verification and on successful completion; bridge wait steps then replay the
last accepted environment action, and a following ``wait_stable`` policy keeps
eligible rows on their live drive targets. Cancellation and failure retain the
normal cancel-then-observed-position safe stop. This split preserves physical
gripper preload without converting a success continuation into a universal
safe-state policy.

The validated dual-UR5/PGI slice drives only each PGI master joint (the mimic
child drive is disabled), uses a ``0.011`` close target with
``stiffness=2000``, ``damping=50``, and ``max_effort=140``, models the can at
``0.33 kg``, and executes a 200-sample motion policy. These values are task and
embodiment calibration, not effect-monitor success shortcuts: the normal
``0.05 rad`` tracking gate, bounded replanning, physical effect evidence, and
settling thresholds remain enabled.

The B policy is the complete continuation scope of this refactor. A generic
mobile-base or whole-body continuation abstraction is deliberately excluded
from the implementation plan and acceptance checklist. If a later transport
requires persistence beyond its normal command contract, it should be proposed
and validated independently instead of becoming a blocker for the declarative
expert-program rollout.

## 8. Expert Program configuration

### 8.1 Version 1 schema
Expand Down Expand Up @@ -1165,10 +1257,19 @@ The backend-neutral typed state expectations, evidence addresses and sources,
pose/binary/scalar/joint evidence clauses, versioned monitor registry,
profile-owned monitor selection, grounded Pick/Place/HandOver/articulation
effects, row-local composite hysteresis kernel, canonical `SkillRuntime`, and
production simulation evidence ports are wired end to end. Physical simulation
acceptance is partial: Open Drawer and one cube Pick/Place/settle/validator
cycle have completed, while the full repeated-cube run and embodiment-owned
HandOver pose integration remain validation work.
production simulation evidence ports are wired end to end. Segment-scoped
held-object guard requests, live evidence collection, row-local symbolic
invalidation, bounded Pick retry, and typed external-recovery hand-off are also
implemented. Physical simulation acceptance is partial: Open Drawer and one
cube Pick/Place/settle/validator cycle have completed. The embodiment-owned
dual-UR5/PGI HandOver slice now completes Pick, transfer, terminal
physical-effect verification, settling, and target validation through real
contact dynamics. Per-expectation terminal outcomes, core-owned failure
invalidation, row-local retry/recovery decisions, fail-closed deadline
reconciliation, and blocking named-segment effect gates are implemented.
Workflow-level re-acquisition is implemented through the preset-owned bounded
policy and canonical runtime. Real-simulation fault-injection coverage and the
full repeated-cube run remain validation work.

Deliverables:

Expand Down Expand Up @@ -1271,7 +1372,7 @@ migration is outside the current scope because it would require modifying
Action Bank code.

The current follow-up also makes task registration the sole standard-runtime
extension owner. `SkillPolicyPreset` schema version 2 requires exact typed
extension owner. `SkillPolicyPreset` schema version 3 requires exact typed
action-option templates for every reachable semantic call; lowering may fill
only explicitly compiler-owned dynamic target fields. Endpoint adapters,
ordered Gym transports, and a parallel-safety factory are declared on
Expand Down Expand Up @@ -1416,7 +1517,21 @@ The design is complete when all of the following hold:
goals without caller duplication.
- [x] `Place` is object-centric and consumes verified held-object state.
- [ ] Built-in grasp, release, handover, and supported articulation effect
monitors work in simulation.
monitors work in simulation. The dual-UR5/PGI HandOver vertical slice is
physically validated; remaining skill/embodiment coverage keeps this
aggregate item open.
- [ ] Grasp and handover simulation gates retain objects through configured
drive/contact dynamics only; no monitor or runtime path creates a
synthetic attachment, freezes the object, or overrides its pose.
- [ ] Physical held-object loss is observed as effect failure, invalidates the
affected symbolic relation, and exercises bounded recovery rather than
being hidden by a simulator-side attachment. The segment-aware observation,
row-local core-owned invalidation, per-expectation terminal
reconciliation, fail-closed deadline handling, bounded Pick/retained-Place
retry, typed recovery boundary, and blocking acquisition/release gates are
implemented. Preset-owned per-row workflow re-acquisition now performs
real `Pick` and semantic-call retries; real-simulation fault injection
remains open.
- [x] Repeated sub-threshold motion eventually publishes the correct scene
revision.
- [x] Custom actions have a documented and tested intentional hard-break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ embodichain.lab.sim.atomic_actions
ControlPartCommandProfile
ActionControlOverrides
ActionInvocation
PhaseEffectGateRequirement
ResolvedActionRequest
ActionOptions
MotionPolicy
Expand Down Expand Up @@ -73,6 +74,11 @@ embodichain.lab.sim.atomic_actions
SimulationExecutionAdapter
ExecutionTick
EffectVerificationRequest
EffectVerificationResult
PhaseEffectGateRequest
PhaseEffectGateResult
HeldObjectGuardRequest
HeldObjectGuardResult
ExecutionEvent
ExecutionEventKind
ExecutionStatus
Expand Down
Loading