Provenance
Every step attempt stores what it ran on: the provider, CLI version, model, step and protocol versions, and hashes of the prompt, request, instructions, skills, MCP servers, config, and env names. Only hashes and names are stored. Env values, secret values, prompt text, and file contents are not.
Every step attempt stores what it ran on: the provider, CLI version, model, step and protocol versions, and hashes of the prompt, request, instructions, skills, MCP servers, config, and env names. Only hashes and names are stored. Env values, secret values, prompt text, and file contents are not.
The record is written when the attempt starts and completed when it ends. Custom command steps may add what only they know through an optional protocol v2 result field.
There is no Dashboard provenance block in this version. The data is on the run detail API and in the CLI.
Record
| Field | Meaning |
|---|---|
factory_version | Factory binary version |
protocol_version | Negotiated handshake version (2) |
step | {id, kind, name, version} and command_sha256 for command steps |
provider | claude-code or cursor for agent built-ins; custom steps may report one |
cli_version | Runner Probe at attempt start, or custom provenance.tools |
model | {requested, reported} |
preset, sandbox | Runner preset; seatbelt or bwrap when the attempt ran inside the OS sandbox, else empty |
prompt_sha256 | Hash of the prompt bytes the step got |
request_sha256 | Hash of the step request with run-specific ids, paths, and times removed |
instructions | [{repo, path, sha256}] from step.access |
skills, mcp_servers | [{repo, name, sha256}] from step.access (names and hashes only) |
config_sha256 | Hash of the resolved step config, provider, and limits |
env_names_sha256 | Hash of the sorted env names the step received, never values |
provenance_id is SHA-256 of the canonical JSON of every field except model.reported, and except cli_version when it is null. setup_id is the same hash without prompt_sha256 and request_sha256, so two different tasks can share a setup.
Rows live in attempt_provenance (attempt_id, provenance_id, setup_id, record JSON). CLI Probe results are cached until the CLI file's size or mtime changes.
Where it shows
GET /api/f/{factory}/runs/{id}: each attempt includesprovenance,provenance_id, andsetup_id.kusaw runs show <run> --provenanceprints one block per attempt.kusaw provenance diff <attempt-a> <attempt-b>lists changed fields with both values (short hashes). Exit 1 when any field differs.- Benchmarks store each replay's
setup_ids.kusaw bench showandkusaw bench reportprint the setups per variant. A variant that used more than one setup in the batch gets W1. - Improvement proposals list the setups of the runs they learned from. When those runs span more than one
setup_idfor the targeted step, the proposal carries W2.
Custom steps
A protocol v2 result may include:
"provenance": {
"provider": "claude-code",
"model": "opus",
"prompt_sha256": "…",
"tools": { "claude-code": "1.2.3" }
}The factory type-checks strings and at most 32 tools, then merges the fields. A wrong type is ignored and reported as a step.progress message (E1). The attempt is not failed. Missing fields stay as the factory filled them.
Warnings
- W1 (bench):
<variant> ran on <n> setups in this batch (<fields> changed). Compare its replays with care. - W2 (proposals):
This proposal learned from runs on <n> different setups for step "<id>". - E1 (custom result):
Step "<id>" returned provenance with <field> of the wrong type; it was ignored.