Skip to content

Latest commit

 

History

History
307 lines (244 loc) · 11.9 KB

File metadata and controls

307 lines (244 loc) · 11.9 KB

rfl CLI reference

The rfl command-line interface drives the reference implementation: it validates and retargets Skill ISA compositions, and certifies / verifies / signs driver conformance certificates. Build it from the workspace root:

cargo build -p rfl-cli      # binary at target/debug/rfl

Every subcommand exits non-zero on failure, with a distinct code per failure class (tabulated below) so the tool composes in scripts and CI.

Synopsis

rfl validate <skill.yaml>
rfl retarget <skill.yaml> --embodiment <descriptor.yaml>
rfl certify  --skill <skill.yaml> --embodiment <descriptor.yaml>
             (--report <report.jsonl> | --driver <bin> [--timeout <secs>])
             [--out <certificate.json>]
rfl verify   <certificate.json>
rfl keygen   <secret-key-out>
rfl sign     --key <secret-key> <certificate.json>
rfl badge    <certificate.json>
rfl sim      --skill <skill.yaml> --embodiment <descriptor.yaml>
rfl measure  --skill <skill.yaml> --embodiment <descriptor.yaml> --run <trace.jsonl> --run <trace.jsonl> …
rfl spec-version

rfl validate

Parse a Skill ISA composition and run the Class-1 composition-validity checks (DOF-admissibility, the no_active_grasp lifecycle guard, the STB3 stability-class successor algebra, and GraspRef-supersession).

rfl validate examples/01-cable-insertion/skill.yaml
# VALID: skill 'cable-insertion' — 8 statement(s) (6 primitive call(s), 2 let-bind(s))
Exit Meaning
0 Valid composition.
2 Unreadable file, YAML/ISA parse error, or composition-validity violation.

rfl retarget

Lower a skill onto a specific embodiment and print the resolved canonical actions as JSONL (one execute goal per line) on stdout. This is the exact stream a driver consumes (and the same bytes rfl certify --driver writes to a live driver's stdin).

rfl retarget examples/01-cable-insertion/skill.yaml \
  --embodiment examples/01-cable-insertion/embodiments/allegro.yaml
# {"message":"execute","action_id":"cable-insertion/wonik-allegro-v4/0001-locate", ...}
# {"message":"execute","action_id":"cable-insertion/wonik-allegro-v4/0002-pinch", ...}
# ...
Exit Meaning
0 Retarget succeeded; JSONL written to stdout.
1 Any error: unreadable file, parse error, a capability_absent rejection, or a retarget failure (printed as Error: … on stderr).

Retargeting is byte-deterministic: the same skill + descriptor always produce the same JSONL (invariant I1).

rfl certify

Certify a vendor driver against the Class-3 driver-protocol obligations and emit a deterministic, content-hashed certificate. The driver report can be replayed from a captured JSONL stream (--report) or produced live by spawning the driver over stdio (--driver); the two paths run the identical pipeline and produce byte-identical certificates for identical telemetry.

rfl certify \
  --skill examples/01-cable-insertion/skill.yaml \
  --embodiment examples/01-cable-insertion/embodiments/allegro.yaml \
  --report examples/01-cable-insertion/driver-report.jsonl \
  --out certificate.json
# RFL conformance certificate — cable-insertion on wonik-allegro-v4 (spec v0.1-draft)
#   [PASS] cable-insertion/wonik-allegro-v4/0001-locate (perception)
#   ...
#   [PASS] sequence:momentary_release
# RESULT: PASS (class3_driver_protocol covered, env3/class4 excluded) — sha256:4767…4531
# certificate -> certificate.json

Live mode is a drop-in substitution of the report source:

rfl certify --skill <s> --embodiment <e> --driver ./my-driver --timeout 30 --out certificate.json
Flag Default Meaning
--skill (required) Skill ISA YAML.
--embodiment (required) Embodiment descriptor YAML.
--report Captured driver-report JSONL (replay mode). Mutually exclusive with --driver.
--driver Driver binary to spawn (live mode). Mutually exclusive with --report.
--timeout 30 Per-run timeout in seconds (live mode).
--out Write the canonical certificate JSON to this path.
Exit Meaning
0 Conformance pass; certificate emitted.
1 Conformance fail; the certificate is still emitted (a failing certificate is a valid artifact).
2 Invalid run: neither or both of --report/--driver, a spawn / timeout / malformed-telemetry error, or a --out write failure.

rfl verify

Schema-validate a certificate and re-verify its content hash (tamper detection); when the certificate carries an ed25519 signature, also check the signature and report the signer.

rfl verify certificate.json
# VERIFIED: content_hash sha256:4767…4531 matches (unsigned)
Exit Meaning
0 VERIFIED — content hash matches (and, if signed, the signature is valid).
1 TAMPERED (declared hash ≠ recomputed) or SIGNATURE INVALID.
2 Unreadable or malformed certificate.

verify proves a certificate's shape and integrity, and which key signed it — not whether that key is trusted. Trust (key governance) is out of scope. The hash is reproducible in any language; see Certifying a driver for the canonicalization recipe.

rfl keygen

Generate an ed25519 keypair: write the secret key (hex) to <out> (mode 0600 on Unix) and print the public key to stdout.

rfl keygen signer.key
# public_key 3b1e…              (stdout)
# secret key written to signer.key   (stderr)
Exit Meaning
0 Keypair generated.
2 Failed to write the secret-key file.

rfl sign

Attach an ed25519 signature (over the certificate's content_hash) and print the signed certificate JSON to stdout. The typed certificate is unchanged; the signature is a Value-level block, so a signed certificate still verifies its content hash.

rfl sign --key signer.key certificate.json > certificate.signed.json
rfl verify certificate.signed.json
# VERIFIED: content_hash sha256:… matches; signed by 3b1e… (ed25519)
Exit Meaning
0 Signed certificate written to stdout.
2 Unreadable certificate / key, or a signing error.

rfl badge

Derive a conformance badge from a certificate (spec/05 § Fidelity tier and the badge): the regime tier (who verified), the achieved fidelity tier (the weakest confirmed action's tier, so the badge never over-claims), and the RFL™ trademark gate. A read-only derivation — it changes nothing the content_hash covers.

rfl badge certificate.json
# RFL conformance badge — cable-insertion on wonik-allegro-v4
#   result: PASS
#   regime tier: Tier 1 (self-certification)
#   achieved fidelity: manifold
#   RFL(TM) trademark: not permitted (Tier 1 self-certification)
#   [PASS] …/0002-pinch (grasp_continuity) — fidelity manifold
#

A certificate from rfl certify is Tier 1 (self-certification), so its badge never permits the trademark (Tier 2 / Tier 3 are steward / independent verification). The achieved fidelity rolls up to the weakest tier: a no-tactile hand that degrades to the force/position proxy badges proxy, never manifold.

Exit Meaning
0 Badge derived and printed.
2 Unreadable or malformed certificate.

rfl sim

The reference simulator driver (the supply-side reference), in two modes:

Regenerate mode (--skill + --embodiment) — retarget the skill, execute it with the nominal reference driver, and emit a conformant driver-report JSONL. It generates the report, so it works for any skill, not only ones with a committed recording:

rfl sim --skill examples/01-cable-insertion/skill.yaml \
  --embodiment examples/01-cable-insertion/embodiments/allegro.yaml > report.jsonl
rfl certify --skill … --embodiment … --report report.jsonl   # RESULT: PASS …

Stdin mode (no arguments) — read canonical execute goals from stdin (parsed via rfl-core::canonical::from_jsonl, the driver-input side of the wire), execute them, and emit the report. This is the live --driver protocol, so rfl sim is usable directly as the driver:

rfl certify --skill … --embodiment … --driver "$(command -v rfl) sim"

Stochastic mode (--skill + --embodiment + --seed N + --variation) — perturb each realized value by the declared variation_model noise in the given simulator declaration (seeded by N, so a seed is reproducible). A sweep of seeds gives the run-to-run variation rfl measure needs. The output is a provisional, sim-derived source — the σ are declared, never physically measured (the deterministic regenerate mode yields ε = 0):

for s in 0 1 2 3 4; do
  rfl sim --skill S.yaml --embodiment E.yaml \
    --variation schemas/simulator-declaration.yaml --seed "$s" > "run$s.jsonl"
done
rfl measure --skill S.yaml --embodiment E.yaml --run run0.jsonl … --run run4.jsonl
Exit Meaning
0 Report emitted to stdout.
1 Unreadable file, a parse error (bad skill / goal), or a capability_absent retarget rejection.
2 Exactly one of --skill/--embodiment given, or --seed without --variation.

Both modes produce a byte-identical certificate for the same skill+embodiment — the parsed-goal path and the typed-action path agree. (For real third-party certification, point --driver at a vendor's driver binary instead.)

rfl measure

Measure a provisional ε-tolerance table from N captured driver-report traces of one skill+embodiment. The tool retargets the skill to recover the action_id -> primitive map, then — keyed by the committed epsilon-tolerances.yaml so the result aligns key-for-key with the normative table — fills each contact-dynamics primitive's quantities from the run-to-run deviation versus the first (reference) run (candidate ε = percentile × safety factor; samples pool across actions sharing a primitive). The kinematic / wrench quantities (realized_position / realized_orientation / realized_wrench / final_orientation / securing_force) read their dedicated wire channels; the primitive-specific domain scalars (seating_depth, completion_torque, turns, …) read the driver's opt-in measured_quantities telemetry map, reported in the committed unit. Any quantity no run reports comes back tolerance: null with reason: not_reported.

rfl measure --skill examples/01-cable-insertion/skill.yaml \
  --embodiment examples/01-cable-insertion/embodiments/allegro.yaml \
  --run run1.jsonl --run run2.jsonl --run run3.jsonl \
  --percentile 0.95 --safety 1.2 --out provisional.yaml

The output is never the committed normative schemas/epsilon-tolerances.yaml (all null = "not yet measured"). It is a distinct provisional document: a # PROVISIONAL banner, provisional: true, and per-entry source: measured plus n_runs / n_samples. A quantity observed in the reference but in no later run stays tolerance: null (not yet gradeable) rather than a fabricated zero. Promoting a provisional value into the normative table is a deliberate, out-of-band step.

Deterministic simulators (rfl sim) exhibit zero run-to-run variation, so they yield ε = 0 — a true value, but not a meaningful tolerance. A meaningful table needs real hardware traces or a declared-conformant stochastic simulator.

Exit Meaning
0 Provisional table written (to --out or stdout).
2 Fewer than two --run traces, an unreadable file, a parse error, or a capability_absent retarget rejection.

rfl spec-version

Print the specification version this build implements.

rfl spec-version
# v0.1-draft

Always exits 0.


End-to-end

A complete hardware-free loop (retarget → replay-certify → verify) is in getting-started.md; the third-party driver on-ramp (capture → certify → read → verify → boundary) is in certifying-a-driver.md.