Skip to content

Latest commit

 

History

History
232 lines (198 loc) · 12.1 KB

headless-cli.md

File metadata and controls

232 lines (198 loc) · 12.1 KB

Headless CLI

PR 6 adds a single-process, single-environment command-line runner around the authoritative JavaScript HeadlessEpisode. It executes immutable portable cev-sim.run-bundle version 1 documents and does not start the web server. --bundle accepts a bundle file or use:<manifestId>. The catalog form reads the last saved run manifest from CEV_SIM_DATA_DIR (the same store the browser writes), validates it, and resolves a bundle in memory. Unsaved Config drafts are not visible. HeadlessRunner and SupervisorRunner still accept only the verified bundle.

Commands

cev-sim validate (--bundle bundle.json | --bundle use:manifestId | --package run.run-package) [--episode episode.json] [--config supervisor.json] [--sensor-transport-config host.json]
cev-sim create-smoke-bundle --output bundle.json
cev-sim create-bundle --output bundle.json [--manifest igvc-default] [--environment ID] [--vehicle ID] [--data-dir DIR] [--road EDGE | --start-node A --finish-node B] [--finish route|none] [--sensors state|all] [--max-steps N]
cev-sim catalog [--data-dir DIR]
cev-sim inspect bundle.json
cev-sim inspect run.run-package
cev-sim inspect output-directory
cev-sim inspect output-directory/run.sflog
cev-sim run (--bundle bundle.json | --bundle use:manifestId | --package run.run-package) --output result-root [--episode episode.json] [--actions actions.jsonl] [--config supervisor.json] [--sensor-transport-config host.json]
cev-sim replay (--bundle bundle.json | --bundle use:manifestId | --package run.run-package) --tape tape.json --output result-dir [--config supervisor.json] [--sensor-transport-config host.json]
cev-sim gpu-preflight --config supervisor.json

create-bundle writes a validated planning run bundle. It copies the selected environment into a temporary workspace, verifies a route, keeps state sensors unless --sensors all is set, and advances the start pose until the vehicle box is clear of obstacles. A source manifest with no IMU, GNSS, or wheel odometry receives those three sensors, so the bundle can still run. --vehicle selects a built-in or stored vehicle and uses that vehicle's box for the clearance check. A stored vehicle that names dynamics.plant must also carry a matching plugin lock. create-bundle copies those locks onto the run and embeds the packages installed in --data-dir. A missing package fails before export. A vehicle with no plugin locks keeps the plugin-free world-bound@2 bundle. --finish route, the default, ends the episode in a zone at the far end of the route. --finish none keeps the verified route and replaces that zone with a trigger on the flag cev-sim.free-drive.stop, which nothing sets, so arriving does not end the episode. --data-dir is read-only. The command deletes its temporary workspace and writes only --output.

catalog prints one JSON object, cev-sim.headless.catalog version 1, with environments and vehicles. Each entry is { id, name, builtIn }. Built-in environments and vehicles are included. --data-dir is read-only. Without it, the command reads the default data directory beside the server package.

validate checks bundle integrity, semantic identity, episode profiles, backend capabilities, world/vehicle/sensor prerequisites, and spaces without stepping or writing artifacts. Without --config, it uses the direct single-process runner and rejects GPU sensors because that runner does not own a renderer. With --config, it creates a temporary process-isolated supervisor, prepares one environment through the configured Chromium renderer pool, and tears the worker, pool, and temporary files down immediately. Configured validation is the supported CLI preflight for camera and GPU-LiDAR bundles. inspect reads a bundle, atomic result directory, or native SFLog. run reads actions from --actions or stdin. Without --config, it uses the direct in-process runner. With --config, it creates one process-isolated supervisor environment and executes camera or GPU-LiDAR captures through that config's Chromium pool. The transient supervisor, worker, and renderer are closed after finalization; a separately started supervisor is not required for this form. Bundle replay without config remains direct; --config selects supervisor-backed replay. Package validate, run, and replay require config and automatically stage, admit, close the batch, and release the admission. Package inspection is strict offline verification and reports runtime support and trusted rights as unevaluated. replay reads the versioned policy tape described below. gpu-preflight launches the configured Chromium stack, validates production WebGL2/ANGLE identity and required formats, performs minimal camera/LiDAR render-readback, and verifies shared-memory round-trip, stale-generation rejection, and cleanup. Its single JSON result includes launch/sandbox and renderer provenance. It requires a supervisor config containing renderer.chromiumExecutable; software renderers cannot satisfy production availability.

create-smoke-bundle builds a portable GPU-enabled IGVC bundle through the normal authoring resolver. It creates an ephemeral scenario, verifies a route from the Ego vehicle's nearest directed road endpoint, selects that scenario in a dedicated manifest, exports the resolved bundle, and removes the temporary authoring data. Use this command for host smoke tests; exporting the built-in igvc-default directly is not sufficient because that browser default intentionally has scenario: null, while every current headless observation/reward profile requires a verified Ego route.

use:<manifestId> is one saved catalog id: no slashes, and not . or ... ./use:<manifestId> is still a file path. Validation issues are a stderr cev-sim.headless.error record with exit code 3 and the issue list in details.issues; the command does not export or run after that failure. A successful catalog load is not written to a temporary file. exportedAt can differ from a previously downloaded bundle, while resolvedHash and episode identity follow the resolved run. --package remains a file.

The local repository executable is ./bin/cev-sim.js. Installed packages expose the cev-sim bin. JSON and JSONL are written to stdout; diagnostics are written to stderr.

PR 12 distributes the CLI as a verified internal npm tarball rather than a registry package. Download the coordinated candidate artifact and install it with npm run artifacts:install; the staged package requires Node >=22.22.2 <23 on Linux/macOS x64 or ARM64 and excludes browser assets and persisted data. See Headless release and CI gates.

Streaming actions and output

Each non-empty JSONL input line contains one normalized policy action:

{"policyStep":1,"action":[0.5,-0.1]}

policyStep is one-based and contiguous. Speed and steering must both be finite and within [-1, 1]. EOF before termination or truncation finalizes an interrupted, non-passing result. An interactive terminal requires --actions; a pipe may supply actions on stdin.

run and replay emit cev-sim.headless.reset, zero or more cev-sim.headless.transition, and one cev-sim.headless.result version 1 record. Packed tensor bytes use { "encoding": "base64", "type": "...", "data": "..." }; uint64 result fields are decimal strings. Configured run records also contain executionMode: "supervisor".

  • Reset records contain environmentIndex, the episode/space descriptor, initial observation, and reset info.
  • Transition records contain policyStep, observation, reward, terminal flags, hashes, reward terms, and diagnostic info.
  • Final records contain the canonical result, content-addressed artifacts, and the atomically published outputDirectory.

Policy action tape

The runner tape is deliberately distinct from the PR 1 topic-characterization tape:

{
  "kind": "cev-sim.headless.policy-action-tape",
  "version": 1,
  "episodeSpec": { "actionRepeat": 5 },
  "actions": [
    { "policyStep": 1, "action": [0.5, -0.1] }
  ],
  "expect": {
    "episodeHash": null,
    "trajectoryHash": null,
    "passed": null
  }
}

Expectation fields are optional. A mismatch is a semantic failure and is recorded in the final result. The canonical PR 1 cev-sim.headless.action-tape remains a topic-level characterization input and is not accepted by this command.

Atomic artifacts

The direct runner stages beside the requested output path and publishes the complete directory with one rename. Existing destinations are refused. Configured runs interpret --output as a supervisor output root and publish beneath <output>/<batch-id>/env-0/episode-1-<episode-hash-prefix>/; use the final record's outputDirectory as the authoritative episode directory. Semantic failures still publish evidence; invalid input, runtime failure, and required artifact failure leave no final episode directory.

Every artifact profile writes:

run-results.json
run-bundle.json
provenance.json

Retained native logs use stable names run.sflog and run.json. SFLog embeds the resolved run, portable bundle, calibration when present, provenance, and final result. Provenance records runtime/package, Node, platform, architecture, git hash when supplied, and backend identities; it omits host, user-path, and credential data.

Profiles:

  • evaluation always retains a full SFLog. Log failure is fatal when the manifest policy is required and degradable otherwise.
  • training keeps core JSON and retains a full SFLog when deterministically sampled or failure-promoted. Defaults are sample rate 0 and promotion on.
  • disabled keeps core JSON and omits SFLog.

Use --artifact-profile, --sflog-sample-rate, --sflog-on-failure, or --no-sflog-on-failure. Required manifest logging cannot be downgraded and always produces a required evaluation log. Otherwise, an explicit caller profile selects evaluation, training, or disabled; without one, optional logging produces a degradable evaluation log and disabled logging omits SFLog. Artifact policy and paths never enter episode or trajectory identity.

Direct runs accept --sensor-transport-config <file>, an operator-owned cev-sim.sensor-transport-host-config@1 document. It is mutually exclusive with --config; supervisors read the same document from packetTransports in the supervisor config. Wrapper MAC/IPv4/UDP addresses, MTU, and PCAP filenames are operational and do not change resolvedHash, simulationHash, episodeHash, or trajectoryHash. Requested pcap bindings require artifact output and fail with UNSUPPORTED_CAPABILITY when the host adapter, endpoint, or capture is unavailable. Live UDP is rejected on this direct path. Supervised run --config reads the same document from packetTransports and executes UDP in a supervisor-owned sidecar. See Sensor packet transports.

Exit codes

Code Meaning
0 Validation/inspection succeeded or the episode passed
1 Semantic failure, interrupted episode, or replay expectation mismatch
2 Command-line usage error
3 Invalid bundle, episode specification, action, or capability
4 Required artifact/output failure
5 Unexpected runtime failure
130 SIGINT after result finalization and teardown

Process isolation, batching, limits, watchdogs, and the configured Chromium pool are used by run --config. Long-lived multi-environment and Python clients use the separate headless batch supervisor over gRPC.

VIS-12a/VIS-13b integrity and compatibility

Bundle inspection reports the exact bundleBytesHash, identity version, and required protocol minor. File ingestion preserves the original bytes and rejects invalid UTF-8, duplicate keys, and malformed exact JSON. v10 bundles remain executable with unchanged hashes; v11 uses world-bound@2 and the local protocol 1.5 runtime. run-bundle.json artifacts preserve received bytes for direct file execution; canonical supervisor wire serialization is a separate representation. Historical unsupported bundle versions require verified authoring import and re-resolution. Package artifacts preserve exact archived bundle bytes even when canonical supervisor wire bytes differ.