Documentation menu

Tasks & method transfer

A claim becomes testable as a Task Spec — instrument-bound predicates, a piloted method, and a frozen, mutually signed revision.

"Our robot makes espresso" is not testable as stated. It becomes testable as a Task Spec: a declarative, versioned protocol whose success predicates are measurable by the cell's instrumentation. Onboarding a claim is a first-class API flow, not a sales process — and the spec, not a conversation, is what every verification report cites.

Anatomy of a Task Spec

roborama.tasks.create() + lifecycle
import roborama  # reads ROBORAMA_API_KEY from the environment

# A claim becomes testable as a Task Spec: declarative, versioned, with
# success predicates measurable by the cell's instrumentation.
task = roborama.tasks.create(
    name="espresso",
    visibility="private",  # "private" | "published" (comparable, citable)
    initial_conditions={
        "machine": {"object": "kit/acme-breville",
                    "pose": "P1", "tol_mm": 20},
        "cup": {"object": "catalogue/cup-std-08", "randomize": "zone-A"},
    },
    success_predicates=[               # each must bind to an instrument
        {"cup_on_tray": "gt.pose(cup) within tray_zone"},     # mocap
        {"liquid_mass": "scale.delta between 25 and 40 g"},   # load cell
        {"no_spill": "vision.spill_area < 2 cm2"},            # scene cams
        {"t_complete": "episode.duration < 180 s"},
    ],
    instructions={  # language-conditioned policies are tested
        "sampled_per_episode": [  # against a distribution, not one phrasing
            "make an espresso", "brew me a coffee", "fais un espresso",
        ],
        "held_out": ["prepare a single shot"],  # reported separately
    },
    stages=[                           # long-horizon tasks score progress
        {"grasp_cup": "gt.pose(cup) in gripper"},
        {"cup_placed": "gt.pose(cup) within drip_zone"},
        {"extraction": "scale.delta > 0 within 60s"},
        {"served": "all success_predicates"},
    ],
    envelope={                         # the claim's declared boundaries
        "lighting": ["3000K", "5600K"], "distractors": "set-B",
        "out_of_scope": ["oat_milk"],
    },
    baseline={"internal_trials": 30, "internal_rate": 0.87},  # private
)
print(task.status)  # "draft"

# Lifecycle — the protocol agreement, encoded:
pilot = task.pilot(robot="g1-edu-pro@fw2.3", episodes=25)  # calibration
print(pilot.stream_url)  # customer watches live

task.amend(  # iterate on the method while piloting
    success_predicates=[
        {"cup_on_tray": "gt.pose(cup) within tray_zone"},
        # widened after the pilot:
        {"liquid_mass": "scale.delta between 22 and 42 g"},
        {"no_spill": "vision.spill_area < 2 cm2"},
        {"t_complete": "episode.duration < 180 s"},
    ],
)

task.freeze()   # -> "espresso@v1": immutable, mutually signed;
                #    every verification report cites the frozen rev
print(task.status)  # "frozen", rev "espresso@v1"
FieldNotes
visibilityprivate tasks stay the customer's method; published tasks join the public catalogue, become cross-customer comparable, and amortize onboarding
initial_conditionsnamed objects with poses, tolerances, and randomization zones; kit hardware is referenced as kit/<name>
success_predicatesvalidated at creation: every predicate must bind to an available instrument in the target environment class
instructionsthe phrasing distribution for language-conditioned policies; held_out paraphrases are never sampled during iteration and are reported separately
stagesordered progress predicates; per-stage rates ship in results, so long-horizon tasks score progress, not just end-state
envelopethe claim's declared boundaries; out-of-scope declarations appear verbatim on reports
baselinecustomer's internal trials, used to sanity-check the pilot and set expectations, never published

Predicates bind to instruments, not to intentions: cup_on_tray reads mocap, liquid_mass reads the load cell, no_spill reads the scene cameras. A predicate that binds to no instrument in the target environment class fails at creation with contract_validation_failed — the same before-any-motor-moves discipline as policy contracts.

Lifecycle: draft → piloting → frozen

The lifecycle is a protocol agreement, encoded. task.pilot() runs a small calibration session the customer watches live; task.amend() iterates on the method while piloting — the worked example widens the liquid_mass band after watching real pulls; task.freeze() produces espresso@v1: immutable and mutually signed.

Frozen means frozen. Changes create espresso@v2, and results across revisions are not silently comparable. A report against a frozen spec is reproducible by construction and contestable only by contesting a protocol the customer approved — the ISO 17025 method-transfer mechanism, as an API.

Staged and language-conditioned results

A spec with stages gets run.stage_rates in results: per-stage rates, each with its n and Wilson interval, so you see where a long-horizon task degrades. A spec with instructions gets run.instruction_breakdown, with held-out paraphrases reported separately. The canonical espresso run in /fixtures/runs.json shows both — held-out phrasing 0.795 (n=83, ci95 0.696–0.868) against the sampled set's best of 0.873 (n=118, ci95 0.801–0.921). The shapes are in the data contract.

Object kits

When the claim involves the customer's own hardware, the hardware ships in as a kit.

roborama.kits.register()
import roborama  # reads ROBORAMA_API_KEY from the environment

# When the claim involves the customer's own hardware, ship it as a kit.
kit = roborama.kits.register(
    name="acme-breville",
    items=[{"desc": "Breville BES870", "qty": 1}],
)

print(kit.shipping_label())  # inbound label to the facility
print(kit.status)
# "received"  -> "tracked" (mocap markers, mass, mesh scan)
#             -> "available" as kit/acme-breville in environments

# Once available, reference it from a Task Spec's initial conditions:
#   {"machine": {"object": "kit/acme-breville", "pose": "P1", "tol_mm": 20}}

Status progresses received → tracked → available: on arrival the machine gets mocap markers, a mass measurement, and a mesh scan, then becomes referenceable from Task Specs as kit/acme-breville. Kits integrate into the standard fixture/tracking/reset system — the system is never customized around a kit.

Where next