The CLI binary is ultrafuzz.
Every command accepts --project <path>. Commands that support automation
accept --json and emit the ultrafuzz.cli.result.v2 envelope.
| Command | Purpose |
|---|---|
ultrafuzz init |
Create root config plus .ultrafuzz/** product surfaces and workflow plumbing. |
ultrafuzz validate |
Validate config, topology, prompts, path guards, agent references, and trust posture without launching agents. |
ultrafuzz json validate |
Validate one JSON document against a strict local Draft 2020-12 schema without mutation. |
ultrafuzz artifact validate |
Validate a declared artifact's registered schema and document-local semantic gates. |
ultrafuzz run |
Validate, render prompts, build run evidence, compile a workflow, and launch a linked workflow run. |
ultrafuzz config audit-profiles |
List shipped audit profiles, intended uses, and selected topologies. |
ultrafuzz config audit-profile <name> |
Show one profile's effective project topology and settings. |
ultrafuzz topology list |
List packaged topology assets, logical node counts, and digests. |
ultrafuzz topology show <name> |
Show metadata and YAML for one packaged topology. |
ultrafuzz topology copy <name> <path> |
Safely copy a packaged topology into the project. |
ultrafuzz references status |
Report whether pinned references are present in the local digest-checked cache. |
ultrafuzz references sync |
Explicitly fetch pinned references into the local cache. |
ultrafuzz references update |
Rewrite the project reference catalog to newer pinned commits when requested. |
ultrafuzz ps |
List Ultrafuzz runs and linked workflow status. |
ultrafuzz inspect <run-id> |
Show product evidence and linked workflow details for a run. |
ultrafuzz status <run-id> |
Show run health, progress, whether execution ended, and final report availability. |
ultrafuzz stats <run-id> |
Derive per-node timing, token usage, cost, retry, outcome, and completeness statistics. |
ultrafuzz pause <run-id> |
Gracefully pause an active run after its in-flight tasks finish. |
ultrafuzz why <run-id> |
Diagnose why a run is blocked, paused, quota-parked, waiting, or unable to progress. |
ultrafuzz timeline <run-id> |
Show checkpoint frames and fork lineage, including the frame numbers fork --frame accepts. |
ultrafuzz events <run-id> |
Show linked workflow lifecycle events, with optional streaming. |
ultrafuzz node <run-id> <node-id> |
Show one workflow node's status, attempts, retries, timing, and output metadata. |
ultrafuzz snapshots <run-id> |
List durability and workspace checkpoints for recovery and time-travel diagnosis. |
ultrafuzz cancel <run-id> |
Cancel an active run; cancellation is terminal, unlike pause. |
ultrafuzz doctor |
Report validation, toolchain, and engine posture without changing project or run state. |
ultrafuzz resume <run-id> |
Delegate resume for the linked workflow run after product checks. |
ultrafuzz replay <run-id> |
Delegate replay for the linked workflow run after product checks. |
ultrafuzz fork <run-id> |
Delegate fork for the linked workflow run after product checks. |
ultrafuzz report <run-id> |
Locate the agent-written final report artifacts. |
ultrafuzz materialize <run-id> |
Copy selected reviewed outputs into the target project after confirmation and path checks. |
ultrafuzz clean <run-id> |
Remove selected generated .ultrafuzz/** paths after confirmation and path checks. |
ultrafuzz dashboard |
Serve the local loopback dashboard and API for product state inspection and editing. |
ultrafuzz eval plan |
Dry-run an eval suite matrix without launching workflows. |
ultrafuzz eval run |
Launch Ultrafuzz runs for an eval suite matrix and watch local progress. |
ultrafuzz eval status <id> |
Show disclosure-safe node progress and ETA for every row in an eval matrix. |
ultrafuzz eval score <id> |
Score finished eval run reports against external ground truth. |
ultrafuzz eval report <id> |
Show the scored eval run variant ranking. |
ultrafuzz eval compare <id> |
Compare scored eval variants against a baseline variant. |
ultrafuzz eval analyze <type> |
Generate private offline tables, provenance, score, intersection, and cost reports from a finalized handoff. |
ultrafuzz eval history [id] |
Validate/render public eval history, or append one complete scored run. |
Generated workflow-engine files are implementation plumbing. The stable product
surfaces are root ultrafuzz.toml, .ultrafuzz/**, reviewed project files,
and the CLI commands above.
| Flag | Meaning |
|---|---|
--project <path> |
Project root. Defaults to the current working directory. |
--json |
Emit a schema-versioned JSON envelope instead of human text. |
JSON output has this shape:
{
"schema_version": "ultrafuzz.cli.result.v2",
"command": "init",
"ok": true,
"diagnostics": [],
"data": {
"project_root": "/project",
"created": [],
"preserved": [],
"overwritten": []
}
}Machine consumers should read ok, diagnostics, and data. The v2 envelope
is intentionally breaking and command-discriminated: every known command has a
closed data shape, public diagnostics omit private implementation details,
and unknown invocation failures can emit only ok: false with data: null.
Only explicit operator workflow input and redacted third-party tool
input/output retain deliberately open nested JSON. Version 1 is not accepted
or converted.
ultrafuzz init [--project <path>] [--force] [--json]init creates or preserves:
ultrafuzz.toml
.ultrafuzz/topology.yml
.ultrafuzz/prompts/**
.ultrafuzz/references.yml
.ultrafuzz/runs/
.ultrafuzz/workspaces/
.ultrafuzz/cache/
Without --force, existing config, topology, prompts, and reference catalogs
are preserved. The .smithers/agents adapter closure is not project-owned:
planning accepts only the byte-exact packaged copy, so every init rewrites
each adapter that differs from the current templates and leaves matching ones
untouched. Refreshing the adapters after an upgrade therefore needs no
--force. A symbolic link, hard link, or special file at an adapter path makes
init fail with INIT_PATH_UNSAFE instead of being followed or written
through. init also
migrates a recognized generated smithers-orchestrator@0.32.0 manifest or a
smthrs@0.34.0 manifest to the current smthrs@0.35.0 pin. The 0.34.0 migration
requires the rest of the manifest to match the current generated document. Use
--force to replace the other existing generated files with the current
templates.
ultrafuzz validate [--project <path>] [--audit-profile <name>] \
[--topology-path <path>] [--json]Validation covers typed TOML config, .ultrafuzz/topology.yml, project prompt
copies, safe paths, reference nodes, agent references, and trusted local
execution posture. It does not launch agents. A project prompt that differs
from the built-in prompt at the same path sets the prompts posture to warn
with one PROMPT_DIFFERS_FROM_BUILT_IN warning per file; warnings do not fail
validation.
ultrafuzz json validate \
--schema <schema.json> \
--file <artifact.json> \
[--ref <local-schema.json>] \
[--max-errors <1-1000>] \
[--json]This is a single-document validator, separate from project-wide ultrafuzz validate. It uses strict Draft 2020-12 Ajv validation, standard formats, strict
UTF-8 and JSON parsing, duplicate-key rejection, offline local references, and
bounded worker execution. --ref may be repeated. No stdin, YAML, JSON5,
remote schema fetching, coercion, defaults, property removal, or repair is
supported.
The exit contract is:
| Exit | Meaning |
|---|---|
| 0 | The artifact conforms to the schema. |
| 1 | The artifact is unreadable, malformed, has duplicate keys, or violates the schema. |
| 2 | Invocation, schema/reference loading, schema compilation, resource limits, or validator setup failed. |
Human-readable failures go to stderr. --json emits the standard
ultrafuzz.cli.result.v2 envelope. Neither success nor failure changes the
schema or artifact bytes.
Checked-in artifact, eval, Modal, and topology schemas are loaded from composed package-local registries. A registered schema whose filename or bytes differ from its pinned entry is a setup failure. Successful JSON output reports whether the schema was registered plus its fragment-free ID, schema SHA-256, owning package's bundle SHA-256, validator build identity, and the artifact SHA-256. The schema identities bind the producer command to the later host check, and the validator build is reported as provenance only; none of them is a mutable validation receipt.
For schema-backed producer tasks, Ultrafuzz places a run-owned trusted launcher
before target-controlled PATH entries and validates a real known-valid fixture
before model work. Modal uses a root-owned, read-only
/usr/local/bin/ultrafuzz. Missing, stale, shadowed, or tampered validator
identity is an exit-2 setup failure, not a reason to use another binary or
edit the supplied schema.
Producer prompts display exact schema and contract validation commands for each
JSON output. The producer must run every command after its final write and
before returning; an exit 1 draft is corrected and rerun in the same session.
Once the session returns, the host checks the same bytes and then applies named
semantic/context gates. It never repairs, converts, normalizes, synthesizes, or
falls back to another artifact, and post-session shape failure is terminal
rather than a model retry.
ultrafuzz artifact validate <contract-id> <artifact-path> [--json]Use the contract ID and path declared in the rendered Ultrafuzz Output Contract.
The command applies the contract's registered JSON Schema and every
document-local semantic gate, reporting failures without modifying the file.
It does not authenticate workspace inputs or evaluate cross-artifact or run
context. The runtime performs those publication checks after the producer
finishes. Run ultrafuzz artifact validate --help for the current positional
arguments.
ultrafuzz run \
[--project <path>] \
[--run-id <id>] \
[--input-json <strict-json> | --input-file <json-path>] \
[--prompt <text>] \
[--agent <agent-ref>] \
[--model <model>] \
[--audit-profile <name>] \
[--topology-path <path>] \
[--max-concurrency <n>] \
[--json]--input-json and --input-file are mutually exclusive. Inline input is
always strict RFC 8259 JSON and is never retried as a path after a parse error.
Relative file paths resolve from the project root. File input is read from one
bounded, non-symlink regular-file snapshot and is rejected if it changes
during the read. Both forms reject invalid UTF-8,
duplicate keys, malformed JSON, and non-finite numbers. Their application data
is explicitly operator-defined; Ultrafuzz validates that it is JSON but does
not infer, repair, normalize, or convert its domain shape. Model-only overrides
keep the configured agent and reasoning. When --agent selects another agent,
backend-specific reasoning is cleared, including when --model also pins a
replacement model.
--max-concurrency caps workflow task submission concurrency.
--audit-profile selects a profile for one command, while --topology-path
atomically replaces the project or profile topology for that command.
A run ID must be new to the project. run fails with RUN_ALREADY_EXISTS
before it plans anything when the run directory exists, or when the workflow
engine already records a run with that ID. The second case happens after
ultrafuzz clean <run>, which removes the run directory but not the engine's
record. Choose another --run-id, or continue a run whose directory still
exists with ultrafuzz resume <run-id>. run asks the engine only once the
project has engine records, so a project's first launch skips the query.
ultrafuzz config audit-profiles [--json]
ultrafuzz config audit-profile <name> [--project <path>] [--json]
ultrafuzz topology list [--json]
ultrafuzz topology show <name> [--json]
ultrafuzz topology copy <name> <project-relative-path> [--force] [--json]Profile detail resolves against the selected project so explicit project
settings and topology overrides are visible. topology copy stays inside the
project, rejects symlink paths, and does not replace an existing file unless
--force is present.
Runs require pinned reference material to already be present in the local cache
when the topology uses reference nodes. Use ultrafuzz references sync as the
explicit network step before run.
ultrafuzz references status [--project <path>] [--json]
ultrafuzz references sync [--project <path>] [--json]
ultrafuzz references update --latest [--project <path>] [--json]status validates the reference catalog and digest-checked cache presence.
sync fetches pinned catalog entries into the local cache. update requires
--latest and rewrites .ultrafuzz/references.yml to current default-branch
SHAs.
ultrafuzz ps [--project <path>] [--json]
ultrafuzz inspect <run-id> [--project <path>] [--json]
ultrafuzz status <run-id> \
[--project <path>] \
[--window <minutes>] \
[--watch] \
[--interval <seconds>] \
[--json]
ultrafuzz stats <run-id> [--project <path>] [--json]
ultrafuzz stats --bundle <report-bundle.zip> [--json]
ultrafuzz pause <run-id> [--project <path>] [--json]
ultrafuzz cancel <run-id> [--project <path>] [--json]
ultrafuzz why <run-id> [--project <path>] [--json]
ultrafuzz timeline <run-id> [--tree] [--project <path>] [--json]
ultrafuzz snapshots <run-id> [--project <path>] [--json]
ultrafuzz events <run-id> \
[--node <node-id>] \
[--type <category>] \
[--since <duration>] \
[--limit <n>] \
[--watch] \
[--interval <seconds>] \
[--history] \
[--project <path>] \
[--json]
ultrafuzz node <run-id> <node-id> \
[--iteration <n>] \
[--attempts] \
[--tools] \
[--watch] \
[--interval <seconds>] \
[--project <path>] \
[--json]
ultrafuzz resume <run-id> [--project <path>] [--max-concurrency <n>] \
[--reset-node <workflow-node-id>] [--retry-failed] [--refresh-controller] [--json]
ultrafuzz replay <run-id> [--project <path>] [--json]
ultrafuzz fork <run-id> \
[--project <path>] \
[--frame <n>] \
[--reset-node <workflow-node-id>] \
[--label <label>] \
[--max-concurrency <n>] \
[--json]status, pause, resume, replay, and fork operate on the workflow run
linked from Ultrafuzz run metadata. status reports a concise health verdict
and maps workflow details into the stable Ultrafuzz JSON envelope.
Detached run and resume record local running state when Smithers admits
the workflow. If that workflow later terminates without another successful
Ultrafuzz synchronization, raw state.json can retain that admission-time
state: there is not yet a detached completion reconciler. ps therefore shows
the linked workflow status when it is available; its JSON output retains both
workflow_status and ultrafuzz_status so lifecycle divergence remains
explicit.
A launch that fails after planning has created its run directory, but before
its workflow controls are sealed (while planning, compiling the workflow, or
checking its task manifest), records the run as failed with its original
error. status, resume, and the other commands that read the linked
workflow then report that error as RUN_LAUNCH_FAILED. Such a run never
reached Smithers and cannot be resumed; fix the cause and start a new run. A
launch that fails after sealing is also recorded as failed, with its error in
events.jsonl, but those commands do not report it as RUN_LAUNCH_FAILED. A
goal-planning topology without its vulnerability-database reference, and a
missing or invalid reference cache (run ultrafuzz references sync), are
rejected before the run directory is created.
resume delegates continuation to Smithers with the same Ultrafuzz and
Smithers run IDs and automatically accepts changed workflow source. Control
seals, link journals, controller generations, graph fingerprints, current
schema bindings, and metadata projections remain provenance for inspection;
they are not resume authorization. The resumed tasks keep the schemas the run
was planned with: after an upgrade that changed a schema, task preparation
copies, and the verifier and dependency admission validate against, the bundle
sealed in the run's execution snapshot. Smithers decides which finished rows can be
reused and which newly rendered or unfinished tasks run. Ultrafuzz does not
rewrite historical artifacts or automatically reset, replay, timetravel, or
fork completed work. The run's smithers/resolved-config.json records the
execution mode its tasks were planned with, so before starting Smithers
resume fails with WORKFLOW_LIFECYCLE_FAILED when that file is missing or
does not parse as the current resolved-config schema, and with
WORKFLOW_CLOUD_EXECUTION_REMOVED when it records mode = "cloud". A plain
resume of a run whose launch workflow predates planned schema bundles fails
with WORKFLOW_CONTROLLER_REFRESH_REQUIRED, also before starting Smithers,
because that workflow cannot prepare a task with this release; continue such a
run with resume --refresh-controller, every time. Agent
adapters in the continued workflow read the run's
smithers/execution-config.toml (launch gave them a copy of the same file). If
resume cannot prune stale task-worktree registrations, it reports a
WORKFLOW_WORKTREE_REPAIR_FAILED warning and continues.
resume --retry-failed reruns every failed task except a failed task in a
failure_policy: continue group that a started task already ran without. That
task was admitted while the failed one had no output, and a rerun cannot reach
the outputs it already produced, so the run would read as complete over work
that never used the rerun's output. resume leaves such a task failed, reports
a WORKFLOW_RETRY_SKIPPED warning that names it and the tasks that ran without
it, and the final report stays partial. A task whose preparation failed has not
started: its preparation, which admits its inputs, reruns after the failed task,
so both are retried. A task whose agent or verifier failed reruns at once,
without waiting for the failed task, so it counts as started. The Modal
benchmark worker does not resume a finished run whose only failures are such
tasks and the tasks skipped because one of them failed.
resume runs the workflow engine from Ultrafuzz's own install: pnpm applies
the committed compatibility patches (patches/) to it at install time, so
resume makes no package-registry request and leaves nothing in the OS
temporary directory. Resume refuses an install that lacks any of those
patches, such as a plain npm install of the packed packages, and an engine
inside the target project. Launch refuses the same install before it creates
the run directory, because the run could not be resumed; replay and fork
run the run's sealed engine instead. To fix the install, run
pnpm install --frozen-lockfile && pnpm -w build in the Ultrafuzz repository
checkout. The build matters because the patch registry that checks the
installed files is compiled into Ultrafuzz.
Run long campaigns from a dedicated checkout or worktree, and leave its install
and build alone while they run. The resumed engine and its supervisor run from
that install, and the resumed workflow imports that checkout's built
@ultrafuzz/runtime.
A pnpm install there that changes the engine's resolved dependency tree
moves the engine to a new package directory. A Smithers patch changes that
tree, and so does a version change anywhere in the engine's dependency graph,
such as TypeScript or React; a pull or a branch switch often brings both.
pnpm then deletes the old directory, in that install or a later one: by
default it clears orphaned package directories during an install once seven
days have passed since it last did. From then on the running engine can fail
on its next lazy import, and the supervisor's next relaunch of it fails. Run
ultrafuzz resume again to continue the run from the new install.
Restart long-lived Ultrafuzz processes, such as the dashboard or
ultrafuzz eval run, after such an install: each resolves the engine once, so
once that directory is gone their engine commands fail with
restart this Ultrafuzz process.
Every task of a resumed run, with or without --refresh-controller,
--retry-failed or --reset-node, and of a replay or fork, receives the
run's own artifacts/<attempt-id>/prompt.rendered.md. Unless
run.refresh_prompts_on_resume = false, resume first renders that file again
from the project's current prompts for every task that has not finished;
replay and fork never do. Before any of these commands starts an engine, it
restores a missing static prompt from its launch copy in prompt-snapshots/,
never over an existing file. A prompt that is still missing or cannot be read,
or a runtime prompt that no longer renders, fails only its task. See
Change a prompt of a running campaign.
A run that ends failed with no failed durable node was stopped by something
no durable node owns: a run-level workflow runner error, such as an exception
thrown while rendering the workflow, or a failed workflow task outside the
durable graph. status reports it as WORKFLOW_TERMINAL_WITHOUT_FAILED_NODE,
names any failed workflow tasks, and appends the runner's run-level error to
the message. For a run-level error, fix that cause, then resume the same run;
it continues from the tasks that already finished. While the cause persists,
the resume either fails with WORKFLOW_LIFECYCLE_FAILED or the run fails
again.
resume --refresh-controller first renders the currently installed Ultrafuzz
controller and stock adapters beside the historical source, then delegates to
that same Smithers run. It does not publish or authenticate a historical
controller generation. The refreshed workflow keeps each declared output's
recorded schema binding, contract digest, and validator build, so its
verification markers still match the run's sealed plan after a rebuild or an
upgrade that changed a schema. After such an upgrade the refresh also keeps the
run's own validator launcher, which validates with the run's planned schemas,
instead of switching to the installed CLI, which validates with other ones. It
reports WORKFLOW_TRUSTED_CLI_UNVERIFIED when it cannot verify the launcher it
keeps or the installed CLI it switches to. Refresh rejects an actively owned
workflow. Because Smithers admits changed workflow source, replay determinism is
the operator's responsibility; inspect the retained source and Smithers workflow
hash when auditing a continuation.
status human output is watch-friendly:
Run: <run-id>
Status: running-healthy (running)
Run ended: no
Report: pending
Report reason: The run has not ended.
Report completion: UNKNOWN
Report verification: unknown
Reason: 1 running, 2 finished in last 10m
Progress: 99% (262 finished / 1 running / 1 pending / 0 failed / 264 total)
ETA: 20 minutes
Time on current step: 10 minutes on stateful-invariant-campaign
Pace: 4 finished in the last 10m
A poll that succeeds with diagnostics, such as a WORKFLOW_DEADLINE_CANCEL_FAILED
or WORKFLOW_STATE_SYNC_SKIPPED warning, prints each one on stdout after these
lines as <severity>: <code>: <message>, where a message can span several
lines. The warnings do not change the exit status, so scripts should read them
from the diagnostics array of --json output.
--watch re-polls every --interval seconds (default 30) until the run
reaches a terminal state (succeeded, failed, timed-out, or canceled),
needs attention, is paused, or the poll fails. With --json --watch, every poll writes one
newline-delimited ultrafuzz.cli.result.v2 envelope so the stream pipes into
jq and other line-oriented tools; without --watch, --json keeps the
existing pretty-printed single envelope.
stats derives its snapshot on demand; it does not read or write a precomputed
statistics artifact. Local-run mode synchronizes linked workflow evidence when
available, then reads attempts.jsonl, usage.jsonl, state.json,
graph.json, graph.fingerprint, and run.json twice as one evidence set.
The command accepts the bytes only when both complete reads match, retries a
recognized mutation race at most three times, and timestamps the snapshot
immediately after the accepted second read. The table shows each node's status,
completed and currently elapsed execution time, token components, estimated
spend, model, and attempt count. JSON output uses ultrafuzz.stats.v1 inside
the normal CLI envelope and additionally exposes retries, executed/reused
counts, outcomes, failure categories, completeness, unattributed usage, and
cumulative run accounting. Run state records a task that Smithers cancelled,
for example by ultrafuzz cancel, as failed. When Smithers cancelled every
failed task of a node, stats reports the node with status canceled and
counts it under canceled rather than failed; status likewise counts
cancelled tasks apart from failures.
The closed stats v1 field pricing_complete continues to mean complete cost
coverage: it is the inverse of run accounting partial_pricing. Accounting v4's
own pricing_complete field independently reports whether each event had
sufficient pricing evidence; an adapter-recorded cost satisfies that evidence
without requiring catalog component rates.
stats --bundle reads an ultrafuzz report bundle ZIP directly without
extracting it and without the original checkout, workflow backend, provider,
or network. It accepts only the registered
ultrafuzz.report-bundle-manifest.v3 contract and validates the current run,
state, graph, graph-fingerprint, and ledger contracts against the manifest run
ID. The manifest creation time anchors live elapsed calculations and must not
precede any historical timestamp in the included state, attempts, usage, or
accounting evidence, or be later than the host statistics clock.
A genuinely absent attempt ledger produces a warning and unavailable attempt
counts and durations. A genuinely absent usage ledger produces warnings and
null usage; metadata cumulative accounting is also hidden because the
missing ledger cannot authenticate it. A local run that still claims
accounting after losing usage.jsonl, a present-but-empty usage ledger paired
with accounting, invalid UTF-8, duplicate JSON keys, malformed rows, duplicate
or conflicting ledger identities, cross-run rows, and aliased or duplicate ZIP
members fail the command. An artifacts/ subtree by itself is not sufficient.
Bundle creation requires current sealed workflow authority, but manifest v3
does not archive workflow-run-link-journal.json or the sealed workflow
control files. Offline statistics therefore prove agreement among the bundled
workflow IDs, control generation, state provenance, graph tasks, and ledgers;
they cannot independently prove the historical backend link that originally
authorized those IDs. The v3 manifest is a snapshot contract, not a standalone
attestation of workflow-link history.
The JSON envelope carries stable machine-readable fields alongside the existing counts:
ended:truewhen local and workflow records agree that execution ended,falsewhile the run is active, pending, or paused, andnullwhen the records do not establish a consistent outcome. A cancellation request is not completion.report:status(available,unavailable,pending, orunknown),reason,completion(complete,partial, orunknown),verification(verified,not-checked, orunknown),json_path, andmarkdown_path. A failed run may have an available PARTIAL report. If the report agent did not produce usable output, the report is unavailable; status does not create a replacement. Missing or unreadable publication records leave availability unknown. Unavailable and unknown reports expose no stale report paths. Verification records the check made when that report was published. Usereport --require-verifiedwhen current verification is required.progress:percent,finished,in_progress,pending,failed,skipped,remaining, andtotal.remainingis every node that is not finished, failed, or skipped, andpercentis the share of nodes that are settled, so it agrees withremainingreaching zero even when nodes failed or were skipped.eta:available,seconds,basis, andunavailable_reason.basisisrecent-throughputwhen the recent activity window observed completions,run-throughputwhen only whole-run throughput is available, andno-remaining-nodeswhen nothing is left to run.unavailable_reasonisno-node-counts(a live run whose snapshot reports no nodes),no-finished-nodes,no-observed-elapsed-time,run-paused(a paused run is deliberately not progressing), orrun-terminal.current_step:node_id,iteration,started_at,elapsed_seconds, andrunning_count. Elapsed time comes from Ultrafuzz's synchronized durablestate.jsonnode timestamps, and the reported step is the longest-running one.elapsed_secondsisnullwhen no running node has a recorded start. Nodes parked on an approval, event, timer, or controller handover are excluded — they are not executing, andultrafuzz whyexplains those waits.
progress and current_step are denominated differently and can legitimately
disagree. progress counts the linked workflow's own tasks, which include
preparation and verification work that has no durable node, while
current_step counts durable Ultrafuzz nodes. Treat progress as campaign-wide
completion and current_step as what is executing right now.
--watch re-synchronizes linked workflow evidence on every poll, exactly as a
single status call does. Final report publication is recorded once for the
current stopped run. Later polls read a small saved summary and inspect its
report file identities; they do not rebuild reports, run agents, or retry tasks.
Resuming work invalidates the prior final summary. If a published report file
changes or disappears, status shows unknown availability.
The watch prints the final publication result, including unavailable, and stops.
It may also stop for attention or a pause, so scripts must read ended rather
than treating watch exit as proof of completion. A successful status query exits
with code 0 even when the observed run failed or its report is unavailable;
query errors remain nonzero. Use the execution status and report fields to decide
whether your job meets its requirements. Use ultrafuzz report <run-id> to read
an available agent-written report.
pause requests a graceful stop: no new tasks are scheduled, in-flight tasks
finish, and the run settles in the resumable paused state. resume reports
submitted: false (text output Run already active) instead of launching a
duplicate continuation when the linked workflow is still active (its Smithers
run state is running, recovering, or one of the waiting-* states), and
leaves the run's recorded state and workflow deadline unchanged. A run still
finishing its in-flight tasks after pause is still active; resume it again
once status reports paused. Smithers also reports a run as running for up
to 30 seconds after its controller process exits (its heartbeat window), so
resume such a run again after that. resume --reset-node retries one failed
workflow node and its dependents in the same linked run; the applied reset is
recorded so retrying the command after a failed continuation resumes the
already-reset run instead of repeating the reset. fork may start from a
checkpoint frame and may reset one workflow node before starting the fork.
Every command in this section takes an Ultrafuzz run ID and resolves the linked workflow run from existing product evidence; none of them require the workflow-engine run ID.
cancel is terminal, unlike pause. The engine accepts a durable cancellation
request before the run actually stops, so cancel distinguishes the two: a
submitted request reports cancel-requested and leaves the product run
nonterminal, and a confirmed cancellation reports Ultrafuzz's canonical
terminal spelling canceled with its terminal timestamp. Rerunning cancel
after the run has already stopped converges on the confirmed result instead of
failing. Both outcomes append
distinct product events. Failures use the stable WORKFLOW_CANCEL_FAILED
diagnostic.
pause and cancel read run evidence the way status does, without the
workflow control lock. A run whose sealed control documents diverged, for
example a hand-patched published workflow or a planned graph that no longer
matches the current build's artifact contracts after a rebuild, can therefore
still be paused or cancelled; status reports the divergence. They start the
workflow runner from the run's published execution snapshot, so, like
status, they still refuse a run whose sealed execution files changed: the
files the control seal lists in that snapshot, such as the run plan, agent
adapters, and the runtime packages and their dependencies. A run's prompt files
are not among them.
Because they take no lock, pause and cancel issued while a launch is still
preparing fail without changing the run; retry once ultrafuzz run has
returned. They also do not reconcile a replay or fork that was interrupted
while linking its new workflow run, so they act on the workflow run it
replaced, or refuse. Run ultrafuzz why <run-id> before pausing or cancelling
such a run: it reconciles that link, even when it then reports a diverged
control document.
why returns a deterministic diagnosis: a summary, the current node, and typed
blockers with kind, node_id, iteration, reason, unblocker,
waiting_since, attempt, and max_attempts. Blocker kinds are
waiting-approval, waiting-event, waiting-timer, retry-backoff,
retries-exhausted, dependency-failed, stale-heartbeat, engine-busy,
binding, side-effect-boundary, and other. It synchronizes linked workflow
evidence first, matching single-run status, and status recommends it as the
next step.
The workflow runner's resume, task-retry, checkpoint-replay, log, and inspect
suggestions in unblocker, the notes, and the summary are rebuilt as
ultrafuzz commands for the run, without the runner's workflow path or run ID.
Replaying from a checkpoint becomes ultrafuzz fork <run-id> --frame <n>. On a
failed run, resuming or retrying a task becomes
ultrafuzz resume <run-id> --retry-failed, because a plain resume leaves a
failed node failed; on a live run, retrying one task becomes
ultrafuzz resume <run-id> --reset-node <node-id>. A suggestion with no
ultrafuzz equivalent, such as approving or signalling a task, stays in the
runner's words with the runner called workflow runner; generated workflows
never wait on either.
timeline is read-only and returns frames with frame, created_at,
content_hash, and fork points. Pass a listed frame number to
ultrafuzz fork <run-id> --frame <n>. --tree adds forked runs recursively
under lineage, each with its own depth and frames.
snapshots is read-only and lists durability and workspace checkpoints with
sequence, node_id, iteration, attempt, tier (an integer durability
tier), source, label, and created_at. There is no restore or rewind command: those need separate
product-state and side-effect-boundary design.
events shows the linked workflow lifecycle log, which is distinct from
Ultrafuzz's own product evidence in .ultrafuzz/runs/<run-id>/events.jsonl. It
defaults to lifecycle events and never requests raw agent chunks. --type is
restricted to lifecycle categories (approval, frame, memory, node,
revert, run, sandbox, scorer, snapshot, supervisor, timer,
workflow); a raw agent or tool category is rejected with
WORKFLOW_EVENTS_TYPE_UNSUPPORTED rather than silently widening the view.
Without --watch it returns a bounded typed array with limit and
truncated;
--limit defaults to 200 and is capped at 2000. --watch streams new events
incrementally rather than buffering the run, printing one redacted event per
line in human mode and one newline-delimited ultrafuzz.cli.result.v2 envelope
per event with --json. --history replays existing history before streaming.
node takes a workflow node ID as already reported by ultrafuzz inspect. It
returns node state, status, duration, attempt counts, agent/model identity, and
output metadata. Attempt and retry history requires --attempts. Tool
input/output payloads appear only with explicit --tools and pass through the
shared secret redaction helpers; node output itself is reported as metadata
only, never inlined. --watch follows the same bounded streaming and cleanup
contract as events --watch.
ultrafuzz doctor [--project <path>] [--json]doctor is the operational superset of validate; validate keeps its
non-launching configuration contract unchanged. Doctor reports:
-
config, topology, prompt, and reference validation posture;
-
required topology backends, toolchain, and configured agent executable availability on the local
PATH. Only the executables of agents the selected topology can dispatch to, including its[retry] agentsfallbacks, are required; other configured profiles' executables are listed as not required; -
the bundled workflow engine version, the version the generated project requires, and the version and bin target of the engine Ultrafuzz's own install provides;
-
npm's latest published stable engine version when the registry check is available;
-
whether that installed engine passes Ultrafuzz's version and path checks, and the posture of each compatibility patch in it. Launch and
resumerefuse an engine that fails either check, so each failure is reported as an error. Doctor then binds an engine that passes both for the project the way those commands do, and reports it as refused when it lies inside the project (for example, when the Ultrafuzz checkout is under--project) or whenbunis not onPATH; -
the OS temporary directory, where launch installs the controller it seals into the run: its free space and how many
ultrafuzz-controller-*directories it holds, with their total size. Sizing them stops after about one second, and the size is then reported asat leastthe bytes counted so far. Doctor warns when the directory is a RAM-backed tmpfs or has less than 2 GiB free, and never removes those directories, because a native resume from an earlier release kept its controller there for the detached engine. -
the provider home of each agent the selected topology can dispatch to. Agents refuse a provider home that is not a private directory the operator owns (mode
0700) below directories only the operator can write, and so does the Ultrafuzz provider-home root above one. Claude Code and Codex create~/.claudeand~/.codexfrom the umask, usually0755or0775, so a home either CLI created is refused.validate, and sorun, report such a home asPROVIDER_HOME_UNSAFEbefore planning, with the directory and the command that fixes it, such aschmod 700 ~/.codex.
Doctor does not create project run state or install, upgrade, or repair local dependencies.
Diagnostics are stable: DOCTOR_AGENT_CREDENTIAL_MISSING,
DOCTOR_TOOLCHAIN_MISSING, DOCTOR_TOOLCHAIN_PROBE_FAILED,
DOCTOR_WORKFLOW_ENGINE_OUTDATED, DOCTOR_REGISTRY_UNAVAILABLE, and
DOCTOR_TEMPORARY_DIRECTORY_CONSTRAINED. A registry or network failure produces a
warning and an unknown latest version instead of failing an otherwise valid
offline project. Doctor never installs, mutates, or upgrades dependencies.
ultrafuzz report <run-id> [--project <path>] [--json]report reads agent-written final report artifacts from:
.ultrafuzz/runs/<run-id>/artifacts/final-report/report.md
.ultrafuzz/runs/<run-id>/artifacts/final-report/report.json
If run metadata contains populated cumulative accounting, report --json
emits REPORT_ACCOUNTING_MISMATCH diagnostics when report.md or
report.json.run_metadata leaves Tokens used unavailable, non-positive, or
greater than accounting.cumulative.tokens_used, or leaves Estimated spend
unavailable, non-numeric, or greater than accounting.cumulative.estimated_spend_usd
in the report's format. A $0.00 spend is valid. The spend must also end in
+ when run.json says the amount is probably low: accounting.cumulative
has partial_pricing or a positive unpriced_event_count, or
attempts_without_usage is present. Without accounting, no expectation
applies.
ultrafuzz materialize <run-id> \
--copy <run-relative-source:project-relative-destination> \
[--project <path>] \
[--yes | --confirm] \
[--dry-run] \
[--force] \
[--json]Materialization is copy-only. Each --copy source is relative to the run root,
and each destination is relative to the project root. Non-dry-run
materialization requires --yes or --confirm. --force allows overwriting an
existing file destination after path checks.
Patch artifacts may exist as evidence, but patch application is rejected until a safe patch applier exists.
ultrafuzz clean <run-id> \
[--project <path>] \
[--select <path-under-.ultrafuzz>] \
[--yes | --confirm] \
[--dry-run] \
[--json]Without --select, clean selects runs/<run-id>. Selections are relative to
.ultrafuzz/ and must name generated run, artifact, or workspace directories.
For a selected run that an earlier release planned for per-node Modal
execution, clean, including --dry-run, reports a
CLEAN_CLOUD_STORAGE_RETAINED warning, which text output prints before
anything is removed. The warning names the run's Modal app, the volume and
sandbox run tag the removed provider derived from its run ID, and the
modal volume delete command. clean no longer removes that storage, and
still deletes the run.
ultrafuzz dashboard \
[--project <path>] \
[--host 127.0.0.1] \
[--port 3875] \
[--run-id <run-id>] \
[--no-live]dashboard starts a local loopback server and prints the /dashboard URL. The
API reads and edits only beta product surfaces, validates mutating saves before
writing, and guards mutating requests with a per-session token.
ultrafuzz eval plan \
[--project <path>] \
[--suite <suite-yaml-path>] \
[--provider none] \
[--target-root <path>] \
[--ground-truth-root <external-path>] \
[--skip-target-validation] \
[--json]
ultrafuzz eval run \
[--project <path>] \
[--suite <suite-yaml-path>] \
[--provider none] \
[--eval-run-id <id>] \
[--row <row-id>]... \
[--target-root <path>] \
[--ground-truth-root <external-path>] \
[--watch-timeout-seconds <seconds>] \
[--no-watch] \
[--json]
ultrafuzz eval status <eval-run-id> \
[--project <path>] \
[--watch] \
[--interval <seconds>] \
[--json]
ultrafuzz eval score <eval-run-id> [--project <path>] [--llm-judge] [--json]
ultrafuzz eval report <eval-run-id> [--project <path>] [--json]
ultrafuzz eval compare <eval-run-id> --baseline <variant-id> [--project <path>] [--json]
ultrafuzz eval bundle <eval-run-id> --output <directory> [--project <path>] [--json]
ultrafuzz eval compare <candidate-eval-run-id> \
--against <baseline-eval-run-id> \
[--allow-incompatible] \
[--project <path>] \
[--json]
ultrafuzz eval analyze all \
--input </external/private-handoff.zip> \
--output </external/private-analysis-directory> \
[--project <path>] \
[--json]
ultrafuzz eval history [eval-run-id] \
[--project <path>] \
[--history <history-json-path>] \
[--charts <svg-directory>] \
[--benchmark evmbench|ultrafuzz-bench] \
[--lane smoke|full] \
[--repository <public-repository-url>] \
[--artifact <immutable-artifact-reference>] \
[--publication-url <validated-result-url>] \
[--check] \
[--json]eval analyze reads a finalized handoff ZIP directly. It accepts only the
current, closed benchmark-analysis contracts. The archive contains an exact
handoff/current-state.json member, optionally below one canonical top-level
directory. That document uses
ultrafuzz.eval.adjudication-handoff.v1 and declares the exact adjudication
output path. The declared directory must contain these versioned documents:
finding-manifest.json—ultrafuzz.eval.finding-manifest.v1, with typed row descriptors, explicit candidate labels/titles, explicit finding IDs and severities, and declared row archive/run metadata paths;instance-to-cluster.json—ultrafuzz.eval.instance-clusters.v1, with aninstancesarray and explicit nullable match/duplicate fields; andground-truth-tp-credits.json—ultrafuzz.eval.ground-truth-credits.v1, with a typedclustersarray.
Each declared row archive and nested run metadata member is read by exact path.
Nested run.json must be ultrafuzz.run-metadata.v2, must identify the row's
declared runId, and must contain validated accounting.cumulative evidence.
The CLI rejects unmatched findings, rows, candidates, clusters or credits;
count drift; duplicate projected identities; inconsistent duplicate targets;
and duplicate-reference cycles before analysis.
Historical field names and shapes are not compatibility inputs. In particular,
schemaVersion, unversioned array/map payloads, candidate heading, lowercase
severity aliases, titles containing an inferred finding label, current-only
accounting, and malformed source references are rejected. The CLI does not
rewrite slashes, search ZIP/tar suffixes, supply metadata defaults, parse IDs
from titles, normalize severity, filter invalid rows/references, or repair a
document. A prior handoff must be regenerated against the current schemas.
Available report types are all, upset (upsert alias), scores
(precision-recall-f1 alias), provenance, table, cost, and pairwise.
The pairwise chart connects matched Ultrafuzz/no-fuzz rows across ground-truth
TP credits, F1, and total tokens. Charts are written as PNG and editable SVG
alongside CSV, JSON, and Markdown reports. provenance.json,
source_manifest.json, and analysis_manifest.json are validated against
their current JSON Schemas and semantic joins before they are written.
Condition score summaries report the mean, median, and sample standard
deviation across the declared rows.
The input and output paths are required to be outside --project. Handoff
archives and generated reports may contain private target details,
ground-truth findings, and adjudication evidence; the CLI refuses to place
either inside the repository tree. Generated reports are private local
artifacts and must not be committed or published without a separate redaction
and disclosure review.
Eval suites benchmark the fuzzing pipeline against targets with known
ground-truth bugs. The experiment definition lives in a committable eval YAML
(default suite path from [eval].eval_config, overridable per command with
--suite). Reporting accepts only none; historical provider profiles are
inert and do not load credentials or enable uploads. An explicit
--provider none can override a retired provider selection. Precedence for
suite and reporting selection is CLI flag > env
(ULTRAFUZZ_EVAL_PROVIDER, ULTRAFUZZ_EVAL_CONFIG) > ultrafuzz.toml.
plan validates config plus suite and prints the trial matrix without
launching workflows. By default it also validates local target checkouts (one
directory per target id under --target-root) against the pinned git refs;
--skip-target-validation skips that check.
run launches Ultrafuzz runs for matrix rows (all rows, or a --row
selection) and polls them to a terminal state. Reports remain in local run
artifacts. --no-watch launches detached without polling.
status reads the eval matrix, its latest runs.jsonl records, and each
linked durable state.json without synchronizing or changing workflow state.
Every matrix row remains present in matrix order. Labels are deterministic
opaque ordinals (row-01, row-02, …), including for private targets; neither
table nor JSON output represents target identities, repositories, paths, refs,
ground truth, findings, diagnostics, raw node output, provenance, or
configuration.
Progress is the count of durable nodes in succeeded, failed, skipped,
timed-out, reused-from-prior-run, or invalidated divided by all planned
nodes in durable state. The output always pairs available percentages with
their completed/total counts. ETA uses observed terminal-node throughput from
the durable workflow start through its latest checkpoint and is explicitly an
estimate because node runtimes differ. ETA is typed as unavailable when no
node has completed, timestamps are missing or invalid, or an incomplete row's
checkpoint is more than five minutes old. --watch refreshes the whole matrix
at the requested interval while at least one row is still pending, running,
paused, or not yet launched; typed invalid or inaccessible rows remain visible
without making the command poll forever. Combined with --json, watch mode
emits one schema-versioned JSON object per line.
score grades finished run reports against external ground truth resolved
under [eval].ground_truth_root, deterministically by default and with the
suite's judge model profile when --llm-judge is passed. The optional LLM judge
requires an explicit ULTRAFUZZ_EVAL_JUDGE_URL and a dedicated
ULTRAFUZZ_EVAL_JUDGE_API_KEY; there is no default endpoint or fallback to
reporting or model-provider credentials. The URL must be HTTPS without embedded
credentials, and redirects are rejected. Private targets additionally require
ULTRAFUZZ_EVAL_JUDGE_ALLOW_PRIVATE_DATA=true.
report shows the scored variant ranking. compare either
diffs variants against a --baseline variant or compares a candidate run to
an --against baseline run after verifying cohort identity, scoring identity,
and variant scope; --allow-incompatible is an explicit, reported waiver.
bundle derives a versioned, self-contained analysis directory from local
eval evidence. Its fixed allowlist contains aggregate terminal status,
evaluation metrics, accounting, and sanitized attempt history. Raw reports,
findings, diagnostics, configuration, and execution-local identifiers are not
representable in the bundle. Missing optional evidence is recorded in a typed
omission manifest.
history validates and regenerates deterministic public SVGs when no run ID is
given. With a run ID, it accepts only a complete, successfully scored generation
with immutable lineage, appends observations idempotently, and replaces history
and charts together. Append mode also requires the benchmark, lane, public
candidate repository, immutable source artifact, and publication URL flags.
--check compares the checked-in SVGs with a fresh in-memory render and
performs no writes.
Eval artifacts are written under .ultrafuzz/evals/runs/<eval-run-id>/. See
Eval Suites for configuration and architecture details.