The canonical CLI entrypoint is src/cli/doppler-cli.js.
For the npm-facing quickstart path, use npx doppler-gpu. That bin is a thin
first-run surface for local generation. The doppler CLI below is the
contract-driven tooling surface for verify, debug, bench, convert, and
operator workflows. It also exposes the Node-only release command for signed,
non-promoting Electron release eligibility. Other Node-only maintenance and
investigation paths include program-bundle and diagnose.
It also exposes profiles, a read-only discovery command for checked-in
runtime profile IDs.
node src/cli/doppler-cli.js <command> --config <request> [flags]--configis required for workload commands.profilesdoes not take a config.--helpprints CLI usage.--prettyprints human-readable output.- JSON output is default;
--jsonis accepted for explicit automation.
| Command | Workload intent | Notes |
|---|---|---|
bench |
calibrate |
Requires request.workload. |
debug |
investigate |
Requires request.workload. |
verify |
verify |
Requires request.workload (except legacy kernels shape). |
diagnose |
investigate |
Node-only operator-diff investigation command. |
convert |
convert |
Node-only command. |
release |
production eligibility | Node-only; emits signed eligible or blocked evidence and never activates. |
profiles |
discovery | Lists checked-in runtime profile IDs; no workload is executed. |
lora |
operator lifecycle | Node-only command. |
distill |
operator lifecycle | Node-only command. |
program-bundle |
maintenance/export | Node-only artifact exporter; outside the browser/Node command-runner contract. |
--config is polymorphic and can be provided as one of:
- Inline JSON object
--config '{"request":{"workload":"inference","modelId":"gemma-3-270m-it-q4k-ehf16-af32"}}'
- File path
--config ./configs/cli-request.json
- URL
--config https://example.org/configs/cli-request.json
The parsed object is contract-validated by resolveConfigEnvelope():
- Either top-level object has
request+ optionalrun, or an old-style object where all fields belong torequest. - Runtime override fields can be set in either:
- top-level
runtimeProfile,runtimeConfigUrl, andruntimeConfig, or - inside
request.
- top-level
runtimeProfile/runtimeConfig/runtimeConfigUrlshould be defined in exactly one location.
This flag is a compatibility alias for setting runtime overrides.
For harnessed commands, it accepts the same input shapes as --config.
If you use --runtime-config, do not put runtime override fields inside --config at the same time.
For harnessed commands (bench, debug, diagnose, verify) the same polymorphic formats are accepted:
- inline JSON object
- file path
- URL
Example:
node src/cli/doppler-cli.js bench \
--config '{"request":{"workload":"inference","modelId":"gemma-3-270m-it-q4k-ehf16-af32"}}' \
--runtime-config '{"inference":{"sampling":{"temperature":0,"topK":1}}}' \
--jsonUse profiles to discover checked-in runtime profile IDs before selecting a
verify, debug, diagnose, or bench runtime:
node src/cli/doppler-cli.js profiles --json
node src/cli/doppler-cli.js profiles --pretty--runtime-profile <id> is a convenience alias for setting
request.runtimeProfile before command normalization:
node src/cli/doppler-cli.js debug \
--config '{"request":{"workload":"inference","modelId":"gemma-3-270m-it-q4k-ehf16-af32"},"run":{"surface":"auto"}}' \
--runtime-profile profiles/verbose-trace \
--jsonFor profile IDs under src/config/runtime/profiles/, the profiles/ prefix may
be omitted:
node src/cli/doppler-cli.js verify \
--config '{"request":{"workload":"inference","modelId":"gemma-3-270m-it-q4k-ehf16-af32"}}' \
--runtime-profile production \
--json--runtime-profile is intentionally narrow. It cannot be combined with
--runtime-config, runtimeProfile, runtimeConfigUrl, or runtimeConfig
inside --config; use one runtime input path per command.
--surface auto(default) tries Node first; falls back to browser relay for supported harnessed commands.--surface nodeforces Node execution.--surface browserforces headless Chromium relay.
convert, release, diagnose, lora, and distill reject --surface browser.
convert, lora, and distill reject runtime-input fields in the Node operator surface.
Command-level surface support:
bench,debug,verify:auto|node|browserconvert:auto|node(browseris rejected)release:auto|node(browseris rejected)lora,distill:auto|node(browseris rejected)diagnose:auto|node(browseris rejected)program-bundle: no--surface; reads declared files and writes a JSON artifactprofiles: no--surface; reads checked-in runtime config metadata only
The installable public binary is doppler from the doppler-gpu package. Use
either an installed binary or the explicit npm package form:
doppler release --manifest doppler-release.json \
--out .doppler-release/evidence \
--pack-trusted-signers trust/pack-signers.json \
--fleet-trusted-signers trust/fleet-signers.json \
--fleet-receipts evidence/windows.json,evidence/macos.json \
--signing-private-key "$RELEASE_PRIVATE_JWK_PATH" \
--signing-public-key "$RELEASE_PUBLIC_JWK_PATH" \
--signing-authority doppler-release-authority
npx --package doppler-gpu doppler release --config release-command.jsonThe default CLI phase is decide. Customer-operated Windows and macOS agents
run the explicit qualification phase:
doppler release --action qualify \
--manifest doppler-release.json \
--target windows-x64-nvidia-webgpu \
--device-identity evidence/windows-device.json \
--out .doppler-release/windows \
--pack-trusted-signers trust/pack-signers.json \
--signing-private-key "$FLEET_PRIVATE_JWK_PATH" \
--signing-public-key "$FLEET_PUBLIC_JWK_PATH" \
--signing-authority customer-windows-agentdecide verifies the Pack and every exact-device fleet receipt, then writes a
retained candidate.pack.json, release-decision.json,
known-exclusions.json, rollback-target.json, and
revocation-configuration.json. A blocked decision also writes and retains
failure-bundle.json. A failed qualification or blocked decision still prints
its JSON result and exits nonzero. Neither phase deploys, activates, rolls back,
mutates the customer repository, or invents a fleet receipt. The customer
activation system must separately verify and act on an eligible decision.
program-bundle exports doppler.program-bundle/v1 from a manifest plus a
browser/WebGPU reference report. It is intentionally a maintenance/export path,
not a shared browser command.
node src/cli/doppler-cli.js program-bundle --config '{
"manifestPath": "models/local/gemma-3-270m-it-q4k-ehf16-af32/manifest.json",
"referenceReportPath": "tests/fixtures/reports/gemma-3-270m-it-q4k-ehf16-af32/2026-03-18T13-33-38.973Z.json",
"conversionConfigPath": "src/config/conversion/gemma3/gemma-3-270m-it-q4k-ehf16-af32.json",
"outputPath": "examples/program-bundles/gemma-3-270m-it-q4k-ehf16-af32.program-bundle.json"
}'The exporter fails if the reference report lacks prompt/output/token identity, if a reachable WGSL kernel is undeclared, or if a kernel digest drifts from the checked-in digest registry.
For a fresh proof run plus export, use the bounded reference lane:
npm run program-bundle:reference -- --manifest models/local/gemma-4-e2b-it-q4k-ehf16-af32-int4ple/manifest.json \
--conversion-config src/config/conversion/gemma4/gemma-4-e2b-it-q4k-ehf16-af32-int4ple.json \
--out examples/program-bundles/gemma-4-e2b-it-q4k-ehf16-af32-int4ple.program-bundle.json \
--surface browser --prompt "The color of the sky is" --max-tokens 8That command runs a bounded verify, writes the actual returned report under
reports/program-bundles/, and exports the bundle from that report. A manual
receipt without transcript metrics is not accepted as a Program Bundle source.
Program Bundle parity uses the normal verify command so browser and Node
surfaces share the same request contract. The export/check maintenance command
above still only writes or validates bundle files.
node src/cli/doppler-cli.js verify --config '{
"request": {
"workload": "inference",
"workloadType": "program-bundle",
"programBundlePath": "examples/program-bundles/gemma-3-270m-it-q4k-ehf16-af32.program-bundle.json",
"parityProviders": ["browser-webgpu", "node:webgpu", "node:doe-gpu"],
"programBundleParityMode": "contract"
}
}' --jsonThere is no default parity mode or provider list. contract validates the
closed bundle and probes selected providers without claiming execution. Use
"programBundleParityMode":"execute" for replay. Provider results separate
schema validity, provider availability, execution, and transcript matching.
JSON output is the default. --json is accepted as an explicit no-op for scripts.
Use --pretty for human-readable summaries.
JSON success and failure return envelopes:
- Success:
{ ok: true, schemaVersion: 1, surface, request, result } - Error:
{ ok: false, schemaVersion: 1, surface, request, error }
For automation, use the default JSON output or pass --json explicitly.
doppler-serve accepts include_receipt: true on non-streaming
POST /v1/chat/completions requests. A successful local runtime receipt sets
resolutionStatus to resolved and carries logicalModelId,
resolvedArtifactVariantId, and resolvedExecutionId in resolution.
The logical ID preserves the model string requested by the client even when it
resolves through a canonical registry ID or explicit artifact URL.
If execution fails before those identities exist, the diagnostic receipt sets
resolutionStatus to unavailable and records
resolutionUnavailableReason: execution-failed-before-resolution. The server
does not synthesize artifact or execution identity from catalog labels.
node src/cli/doppler-cli.js verify --config '{"request":{"workload":"inference","modelId":"qwen3-0.8b"}}' --jsonnode src/cli/doppler-cli.js verify --config '{
"request": {
"workload": "inference",
"modelId": "gemma-3-270m-it-q4k-ehf16-af32",
"modelUrl": "file:///tmp/gemma-3-270m-it-q4k-ehf16-af32"
},
"run": {
"surface": "node"
}
}' --jsonnode src/cli/doppler-cli.js debug \
--config '{"request":{"modelId":"qwen3-0.8b","workload":"inference"},"run":{"surface":"node"}}' \
--runtime-config '{"inference":{"generation":{"maxTokens":8}}}' \
--json- If
--configis omitted:command requires --config <path|url|json>. - For bad URLs in
--configor--runtime-config, errors include HTTP or fetch diagnostics. - For malformed JSON: error reports
Invalid --config/Invalid --runtime-config.