Task configuration

September 20, 2026 ยท View on GitHub

A task is a JSON document loaded by name or path:

jev-libero tasks
jev-libero validate-task microwave
jev-libero run --task ./my-task.json --out runs/my-task

Start with the complete microwave or top_drawer configuration. The CLI saves the resolved configuration in every run.

Sections

SectionResponsibility
bindingSuite, exact task name, target object, optional joint suffix; original LIBERO success predicate
measurementsNamed, read-only measurements to compute, with explicit entities and dependencies
record_featuresOptional list of feature names to record at every executed control step
contactForce threshold, permitted other geometry contacts, contact-part labels, obstacle rejection and release-pair priority
featuresTask-facing measurements derived from common sensors
predictionsEffect formulas evaluated from branch start/end observations
thresholdsProgress and approach deadbands; the public runner uses the collision-aware profile
contractsBoolean eligibility condition for each local intent
policyIntent descriptions; per-layer prompts, projections, summaries, review conditions and feedback
searchLexicographic ranking of a second-step witness for each first input
displayTask value, label, units and progress field for logs/media

The drawer configuration changes object/joint bindings, task wording, and progress units from degrees to millimeters, including a 0.01mm progress deadband. It does not introduce a new executor or action sequence.

Expressions, not embedded code

An expression is a scalar/list literal or an object with exactly one operator. Example: meters of joint motion converted to millimeters.

{
  "closing_mm": {
    "mul": [
      {"sub": [{"ref": "after.qpos_m"}, {"ref": "before.qpos_m"}]},
      1000.0
    ]
  }
}

Operators:

  • ref: a dotted field reference.
  • add, sub, mul, div: scalar or vector arithmetic.
  • ge, gt, le, lt, eq: comparisons.
  • all, any, not: Boolean conditions.
  • norm: Euclidean norm; index: select a vector element; round: numeric presentation; count: list length.

There is no eval, dynamic Python import, or executable task script. Unknown operators raise errors.

Available contexts:

Expression locationContext
Measurement expressionsraw.NAME referring to another declared measurement
Task featuresraw.NAME from the task's declared measurements
Prediction metricsbefore, after
Goal contractsbefore, after, p (prediction), thresholds, released_required_contacts, has_reposition_witness
Witness rankingbefore, after, p, effects.GOAL_NAME
Model projections/feedbackThe corresponding before, after, and/or p fields shown in the examples

The executor retains its mandatory end-effector pose, jaw gap, target/obstacle contacts, force sums, approach gap, and native success check. These support control and feasibility checking independently of task-selected measurements. Summary reducers support any or a rounded [min,max] range over candidate fields.

Select measurements, then select outputs

All tasks use the same measurements interface. For example, a drawer only needs:

{
  "measurements": {
    "joint_position": {"kind": "joint_position"}
  },
  "features": {
    "remaining_open_mm": {"mul": [{"ref": "raw.joint_position"}, -1000]}
  }
}

This does not compute object bounds, external target contacts, or initial-height references. An explicit empty measurements object requests no additional measurements. For compatibility, archived schema-1 configurations without this section retain their former joint/body/site sensors.

KindArguments and result
joint_positionActive bound joint value, or null for a free object
positionsentity: body or site; names: alias-to-simulator-name map; positions in meters
bounds_mm, center_mmentity: collision-geometry selector; world AABB bounds or its center
pair_center_mm, axis, gap_mmleft, right: geometry selectors; midpoint of point-cloud means, normalized left-to-right axis, or signed surface gap along that axis
span_mmentity: selector; axis: name of an axis measurement; projected collision-shape width
contact_groupsentity: selector; groups: label-to-selector map; labels touching the entity
external_contacts, external_contact_countentity: selector; exclude: selector list; contact records or count, excluding self-contact and excluded geometry
expressionvalue: expression combining declared measurements
initialsource: measurement name; value captured at world initialization, unchanged by previews/restores

Geometry selectors are {"object": "LIBERO_OBJECT_NAME"} or {"group": "target"}. Built-in groups also include gripper, left_fingerpad, and right_fingerpad. Contact measurements accept min_normal_force_N; otherwise they use the task's contact threshold. Counts count contact records, not unique objects. Contact details include geometry name and normal force; the count-only kind does not construct those details.

Dependencies are validated for unknown references and cycles. Measurements and shared point clouds are cached within a read, and only declared operations are evaluated. Intermediate measurements remain in raw; only features projections are exported. The existing policy.intent_state, strategy_state, and motor_options independently select what each Jev layer receives. record_features separately controls per-step local logging to measurements.jsonl.

The alphabet_soup configuration composes geometry, contact groups, initial values, and expressions through this same interface. It introduces no task-specific measurement class or executor branch. Bilateral contact and lift remain separate observations, not a universal stable-grasp classifier. LIBERO can declare containment while the gripper still holds the object; this configuration does not add a release-and-settle success requirement.

What a contract means

The current configurations offer approach, establish contact, advance, release contact, and reposition. These are effect conditions, not a fixed sequence. An already-established contact does not remain an unachieved "establish contact" goal.

When all one-step pools are empty, a two-step witness may admit a repositioning input. The terminal effect is evaluated relative to the original state, avoiding a spurious "move away then return" improvement. The solver chooses a witness to describe each candidate; Jev still chooses the actual first input. The second input is never executed automatically.

Contact rules currently observe gripper contacts at control-step boundaries. allowed_other_geoms contains exact MuJoCo geometry names whose contacts should not count as obstacles. Such permission is task semantics, not a claim of physical safety.

Boundaries

Configuration externalizes the existing task-dependent logic; it is not a universal task compiler. The engine has one active target, a Panda/OSC interface, and the listed measurements/operators. Stable grasp estimation, multi-target selection, and more elaborate temporal goals need reusable engine capabilities before a JSON file can express them. Model-mutating switch/light tasks are explicitly rejected by the snapshot contract.

Keep LIBERO's success predicate authoritative. A convenient progress score is not a substitute for task completion, and a passive joint drift is not necessarily an action's causal contribution.