07The demo

One command. Every artefact's shape.

make demo records a synthetic session on the simulator, prints the measured sync error, writes the MCAP source of record, exports a LeRobot v2.1 dataset through the consent gate, validates the card and appends the quality catalog. It shows the shape of every artefact; it is not a collection.
Synthetic · one run · 2026-10-18 · tree 052c6fe0
01Step by step

Six steps.
The lines they printed.

Every line below is the standard output of one make demo run on 2026-10-18 (exit code 0), copied unchanged. The recording is simulated and the consent record synthetic; the sync error is the simulator's detector floor, not a measurement of a device. The card this run wrote is the one rendered on the datasets page.

  1. Record a kit session on the simulator

    cr4dle-capture record-kit puts a simulated Lens on a synthetic consent record for two epochs of two seconds: the episode directory, a raw area that never leaves the device, the MCAP source of record and a recording_ref identity for each. It prints the measured sync error, the discard counts and the regime, gaze and bystander facts of the recording.

    stdoutSynthetic · one run · 2026-10-18 · tree 052c6fe0record-kit (simulated Lens, synthetic consent) -> /tmp/cr4dle-demo/ (+ raw area /tmp/cr4dle-demo-raw/, + /tmp/cr4dle-demo.mcap)
      consent: SYNTHETIC record consent-synthetic-45486bbf-25b1-5b04-8589-b7ae5b898127 (jurisdiction ZZ; sim backend only; granted at the sim clock origin)
      regime=by-hand (default on --backend sim; --regime is required for hardware and replay); gaze role natural by default for regime by-hand: by-hand demonstrators look at the task; --gaze-role overrides
      kit=kit-sim-0001 units=dev-sim-glasses-0001:pupil-labs-neon,dev-sim-headcam-0001:uvc-head-camera,dev-sim-band-0001:mindrove-armband-2,dev-sim-exo-0001:exo-rgbd-camera,dev-sim-force-0001:fingertip-force,dev-sim-flash-0001:led-flash-sync
    recorded episode ep-lens-sim-0 of lens (sim) -> /tmp/cr4dle-demo/
      kit kit-sim-0001: primary=dev-sim-glasses-0001 (pupil-labs-neon; hw_rev=simulated fw_ver=simulated)
      frames=240 streamKinds=hand_pose,head_pose,gaze_target,demonstrator_state videos=0 cameras=- redaction=drop-all-frames-v1
      sync_error_us p50=5000 p95=5000 max=5000  [led_flash+imu_tap; 3 events; measured]
      clock_model sync_error_us p50=53 p95=133  [fit residual without the detection floor of 5000 us; 2 of 2 stream fit(s) have 2 or more events]
      discardCounts={'sync_skew': 0, 'missing_consent': 0, 'redaction_failed': 0, 'low_quality': 0, 'calibration_invalid': 0}
      demonstrationRegime=DEMONSTRATION_REGIME_BY_HAND gazeRole=GAZE_ROLE_NATURAL gazePresent=True bystanderCount=0
      raw (on-device only; never exported): /tmp/cr4dle-demo-raw/  -- replay with `cr4dle replay --device lens --session /tmp/cr4dle-demo`
      mcap (on-device only; never exported): /tmp/cr4dle-demo.mcap  -- chunk groups cameras,state,biosignal, gop_preset=vla; inspect with `cr4dle-capture mcap-info /tmp/cr4dle-demo.mcap`
      recording_ref (T4-R identity; ADR-0107): /tmp/cr4dle-demo.recording_ref.json  -- rec-a740349ccfcd6b43 kind=episode_mcap bytes=151846 hub_id=hub-simulated; purge with `cr4dle-capture purge --sha256 a740349ccfcd6b43e90126b51e23848152c946595bccc942df0157d0d5382107`
      recording_ref (T4-R identity; ADR-0107): /tmp/cr4dle-demo-raw.recording_ref.json  -- rec-313e607d1087113a kind=raw_area bytes=300013 hub_id=hub-simulated; purge with `cr4dle-capture purge --sha256 313e607d1087113a8d5a551aad5ebb381eee05b70247d98333aa81bc1495b652`
    
  2. Measure the clocks again from the raw area

    cr4dle-capture sync-report --recompute re-runs the LED-flash and tap detectors on the raw area and compares the offsets with the ones recorded at capture. The residual per stream is the sync error; a stream with a single event is marked unverified (an offset with no residual), and an episode with fewer than three events on a contributing stream is reported as not measured and discarded under sync skew.

    stdoutSynthetic · one run · 2026-10-18 · tree 052c6fe0sync-report --recompute (the detectors re-run on the raw area)
    sync report of /tmp/cr4dle-demo
      sync_error_us p50=5000 p95=5000 max=5000  [led_flash+imu_tap; 3 events; measured]
      clock_model sync_error_us p50=53 p95=133  [fit residual without the detection floor of 5000 us; 2 of 2 stream fit(s) have 2 or more events]
      enough_events=True (min 3) floor_us=5000 reference=hub
      imu          imu_tap       offset_us=-102 drift_ppm=+27.857 resolution_us=5000 events=3 residual_us=[-15, 30, -15] [measured]
      video        led_flash     offset_us=+0 drift_ppm=-0.000 resolution_us=4167 events=3 residual_us=[0, 0, 0] [measured]
      note: imu_tap is the trigger surrogate for a band without a trigger input; its residual spread includes the operator's tap-to-flash error
      note: drop-frames fallback: RedactorUnavailable: FaceBlurRedactor needs opencv (uv sync --extra vision)
    recomputed from the raw area /tmp/cr4dle-demo-raw/
      sync_error_us p50=5000 p95=5000 max=5000  [led_flash+imu_tap; 3 events; measured]
      clock_model sync_error_us p50=53 p95=133  [fit residual without the detection floor of 5000 us; 2 of 2 stream fit(s) have 2 or more events]
      imu          offset_us=-102  vs recorded -102 (delta +0 us)
      video        offset_us=+0  vs recorded +0 (delta +0 us)
      largest offset delta: 0 us
    
  3. Inspect the MCAP source of record

    cr4dle-capture mcap-info lists the chunk groups, message counts and the three metadata records (consent, episode, provenance), checks that messages of different groups never share a chunk, and prints the recording_ref identity the file's bytes hash to.

    stdoutSynthetic · one run · 2026-10-18 · tree 052c6fe0mcap-info (chunk groups, counts, metadata; the never-share-a-chunk invariant; the recording_ref identity, ADR-0107)
    /tmp/cr4dle-demo.mcap  (151846 B; library 'cr4dle-capture 0.0.1'; compression {'zstd': 8})
      chunk groups: cameras, state, biosignal  chunks=8  log time 0..7966667 us (hub clock)
      cameras    channels=0 messages=0 chunks=0  topics=[]
      state      channels=1 messages=240 chunks=4  topics=['/state/demonstration_frame']
      biosignal  channels=2 messages=8 chunks=4  topics=['/biosignal/gaze', '/biosignal/imu']
      invariant (messages of different groups never share a chunk): holds
      metadata cr4dle.consent/v1: 9 field(s)
        consent_id = consent-synthetic-45486bbf-25b1-5b04-8589-b7ae5b898127
        consent_ver = synthetic-1
        granted_at = 2026-09-13T00:00:00.000000Z
        jurisdiction = ZZ
        purposes = ["PURPOSE_ROBOT_TRAINING_DATA"]
        revocation_checked_at = 2026-09-13T00:00:00.000000Z
        revocation_note = re-checked at export against the consent record (ADR-0049); this file records the status at the i...
        revocation_status = not_revoked_at_capture
        synthetic = true
      metadata cr4dle.episode/v1: 33 field(s)
        bystander_count = 0
        chunk_groups = ["cameras","state","biosignal"]
        clock_model = {"floor_us":5000,"log_time":"hub receive clock of the window (ns); state messages log at the hub-...
        demonstration_regime = DEMONSTRATION_REGIME_BY_HAND
        discard_counts = {"calibration_invalid":0,"low_quality":0,"missing_consent":0,"redaction_failed":0,"sync_skew":0}
        egress = on-device / private store only; the exporter reads the episode directory, never this file
        ended_at = 2026-09-13T00:00:08.000000Z
        episode_dir = cr4dle-demo
        episode_id = ep-lens-sim-0
        flush_interval_s = 2.0
        gaze_present = true
        gaze_role = GAZE_ROLE_NATURAL
        gop = {"b_frames":0,"buyer":"policy (VLA) training: single-frame random access, a keyframe every second...
        gop_preset = vla
        manifest_sha256 = e5850bdaab31cb74584a1f5f50cc356f495e9bcf51c9ea40566e8d1257345164
        n_frames = 240
        participant_pseudonym = psn_synthetic_0000
        persons_seen_max = {}
        session_id = ep-lens-sim-0
        started_at = 2026-09-13T00:00:00.000000Z
        status = complete
        stream_kinds = ["hand_pose","head_pose","gaze_target","demonstrator_state"]
        sync_enough_events = true
        sync_error_us = {"max":5000,"p50":5000,"p95":5000}
        sync_error_us_frames = {"max":5000,"p50":5000,"p95":5000}
        sync_measured = true
        sync_n_events = 3
        sync_notes = ["imu_tap is the trigger surrogate for a band without a trigger input; its residual spread includ...
        sync_report_sha256 = f1ed6e185a26d24b981cfa9c6fd503bc52ab9a720382a3270038bf8657418dd6
        t_end_us = 8000000
        t_start_us = 0
        task_id = 
        videos = []
      metadata cr4dle.provenance/v1: 21 field(s)
        adapters = ["SimulatedSignalSource"]
        backend = simulated
        cal_id = 
        camera_message_format = ref
        device_family = lens
        device_id = dev-sim-glasses-0001
        devices = [{"device_id":"dev-sim-glasses-0001","equipment_id":"pupil-labs-neon","fw_ver":"simulated","hw_re...
        dsp_code_hash = sha256:036329d68dfd9314
        feat_schema_ver = 1
        force_model_id = 
        form = eye-tracking-glasses
        fw_ver = simulated
        hw_rev = simulated
        kit_id = kit-sim-0001
        redaction_policy_ver = drop-all-frames-v1
        redactor_code_hash = sha256:84ba19e6abb7b4a65a8861e63415c114
        sdk_versions = {"cr4dle-capture":"0.0.1","cr4dle-common":"30.0.0","cr4dle-runtime":"0.0.1","mcap":"1.4.0","numpy...
        state_model_id = demonstrator-state-stub-0
        tier = TIER_L0_GLASSES
        vendor = pupil-labs-neon
        video_codec = 
      recording_ref (cr4dle-demo.recording_ref.json; T4-R identity, never a location): recording_id=rec-a740349ccfcd6b43 kind=episode_mcap bytes=151846 hub_id=hub-simulated consent_id=consent-synthetic-45486bbf-25b1-5b04-8589-b7ae5b898127
        sha256 a740349ccfcd6b43e90126b51e23848152c946595bccc942df0157d0d5382107  -- the file's bytes hash to this identity
    
  4. Export through the consent gate

    cr4dle-dataset-export reads the episode directory and first prints which record decides consent. The demo names --consent manifest: the manifest's own consent record, the simulation-only mode, so a withdrawal recorded elsewhere is invisible to this run. A person's data is exported against a consent store instead (--consent <directory of consent records>), where the gate re-checks consent at the instant of export and a withdrawal recorded after capture refuses the episode. The exporter then lays the LeRobot v2.1 files down with the finger_keypoints_v1 action space, writes the card with every unmeasured block as not run, and prints the identity posture from a synthetic re-identification report.

    stdoutSynthetic · one run · 2026-10-18 · tree 052c6fe0cr4dle-dataset-export --consent manifest --format lerobot_v21 --action-space finger_keypoints_v1 --reid-report benchmarks/fixtures/loso-report.reid.json -> /tmp/cr4dle-demo-lerobot/ (cr4dle-quality signal-qc first writes the signal QC verdict that the export admits)
    cr4dle-quality: signal QC ep-lens-sim-0: pass (no failed check; required streams imu, video) -> /tmp/cr4dle-demo/signal_qc.json
    cr4dle-dataset-export: consent lookup: manifest record (consent at capture; a withdrawal recorded elsewhere is invisible -- synthetic sessions only)
    cr4dle-dataset-export: wrote 1 episode(s), 240 frame(s), 0 video(s) to /tmp/cr4dle-demo-lerobot (lerobot v2.1 via --format lerobot_v21, video codec none, action space finger_keypoints_v1 v1, card schema_version 4, source simulation); sync error us p50/p95/max 5000/5000/5000; discards {'sync_skew': 0, 'missing_consent': 0, 'redaction_failed': 0, 'low_quality': 0, 'calibration_invalid': 0}; card meta/dataset_card.json; gate cr4dle-export 0.0.1 (consent: manifest); study CR4-DEMO-2026-10 (resolved)
    cr4dle-dataset-export: identity posture: rank-1 62.0% (chance 20.0%), EER 18.0%, n=5 x 2 sessions on observation.hand_pose, observation.head_pose; no eye image egress is a redaction fact, not an anonymity claim; literature [REPORTED]: pose rank-1 94.0% among 55,541 · gaze EER 6.2%-8.8% at 125-250 Hz · sEMG rank-1 98.5% cross-day; benchmarks/fixtures/loso-report.reid.json; reid_audit@2; synthetic evidence; representation no_video (not_applicable); linkability not applicable
    cr4dle-dataset-export: episode audit: regimes {'by_hand': 1, 'leader_follower': 0, 'vr_teleop': 0, 'exoskeleton': 0, 'walking': 0}; gaze present/labelled 1/1 (control-monitoring gaze excluded 0, scripted gaze excluded 0); hand lost % mean/p95/max 0.0/0.0/0.0 over 1 episode(s) with hand pose; bystanders max 0; rows meta/episodes_audit.jsonl
    
  5. Validate the card

    The stdlib validator of the data platform checks meta/dataset_card.json against the card schema and prints the one line that the counsel of a dataset user can look for.

    stdoutSynthetic · one run · 2026-10-18 · tree 052c6fe0the card validates against the schema
    card validates: /tmp/cr4dle-demo-lerobot/meta/dataset_card.json
    
  6. Measure quality beside the export

    cr4dle-quality detects contact events on the force trace (none here: the simulated Lens recording carries no force stream) and appends its rows to the append-only quality catalog. Its labels are measurements, never a verdict about the episode or the person.

    stdoutSynthetic · one run · 2026-10-18 · tree 052c6fe0cr4dle-quality contact-events + catalog-append (measurements beside the export, ADR-0056)
    cr4dle-quality: contact events on 1 episode(s): contacts 0, slips 0, drops 0 (0 event rows) -> meta/contact_events.parquet + meta/contact_events_summary.json; no contact_force stream in this export, so every count is 0
    cr4dle-quality: thresholds: CONTACT_ON_N=0.5 N, CONTACT_OFF_N=0.3 N, POOLED_ON_N=1.0 N, POOLED_OFF_N=0.6 N, DEBOUNCE_S=0.05 s, SLIP_DROP_N=1.0 N, SLIP_WINDOW_S=0.1 s, RELEASE_WINDOW_S=0.1 s, ABRUPT_RELEASE_N=1.0 N, PLACE_MAX_WRIST_SPEED_MPS=0.15 m/s
    cr4dle-quality: advantage_proxy: 1 / (1 + max(0, incidents - median_incidents)) with incidents = n_slips + n_drops and the median over the collection's episodes with a force stream; bounded (0, 1]; a relative ranking measurement for curation, never a task-completion label and never a verdict (median incidents None)
    cr4dle-quality: labels are measurements of the force trace; never a verdict about the episode or the person
    cr4dle-quality: appended 47 row(s) for 1 episode(s) to /tmp/cr4dle-demo-lerobot/meta/quality_catalog/20261018T064238Z-5bbb45.parquet (run 20261018T064238Z-5bbb45; 1 file(s) in the catalog now; nothing rewritten)
    cr4dle-quality: participant key: consent_id
    

What the run warned

The face-blur redactor needs the optional vision extra; without it the redaction stage drops every frame rather than export one it could not blur. The card records the fallback as its redaction policy.

stderrSynthetic · one run · 2026-10-18 · tree 052c6fe0
face-blur redactor unavailable, falling back to drop-frames: RedactorUnavailable: FaceBlurRedactor needs opencv (uv sync --extra vision)
02Ninety seconds

Recorded when the kit
is on a person.

This slot holds a ninety-second recording of the kit on a person demonstrating a task: the band, the head camera, the flash, the sync report and the card. No such recording exists yet; it is made at the gate that puts the kit on a person, dated . Until then the slot stays empty rather than hold a staged frame.

Video · 90 sNot recorded yetGate 2026-10-05: kit on a person, sync error printed
03Run it

From the repository root.

make bootstrap
make demo

The chain needs no hardware, no account and no data: the capture root, the data platform and the export gate run on synthetic input. The card it writes is cr4dle-demo-b030d2ed16f8 with source: simulation; a card from a person carries the same fields with its numbers measured.

The card, rendered as written