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.
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.jsoncreate-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.
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/spacedescriptor, initialobservation, and resetinfo. - Transition records contain
policyStep,observation,reward, terminal flags, hashes, reward terms, and diagnosticinfo. - Final records contain the canonical
result, content-addressedartifacts, and the atomically publishedoutputDirectory.
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.
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:
evaluationalways retains a full SFLog. Log failure is fatal when the manifest policy isrequiredand degradable otherwise.trainingkeeps core JSON and retains a full SFLog when deterministically sampled or failure-promoted. Defaults are sample rate0and promotion on.disabledkeeps 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.
| 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.
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.