# Evidence

How a Numinance change becomes a signed, hash-linked record chain that an independent party can verify offline, and what that verification does and does not prove.

<FeatureStatus kind="public-spec">The evidence format (`evidence/v1`), its schemas, the conformance vectors and the offline verifier are public and runnable today. Exports are produced by the proprietary Numinance runtime, which is not generally available.</FeatureStatus>

<SourceReference paths={["docs/evidence/README.md", "docs/evidence/verification.md", "schemas/evidence/v1", "conformance/evidence/v1", "sdk/go/evidenceverify"]} />

<ShortProductTruth>
Don't trust the agent. Check the evidence.
</ShortProductTruth>

## Evidence is engineering accounting [#evidence-is-engineering-accounting]

An autonomous engineer is only as credible as the account it leaves behind. Numinance treats that account as a first-class artifact: every change produces an append-only chain of records written by the runner identity, not by the agent. Each record names the action, the actor, the policy decision that allowed it, the risk class, the inputs and outputs by digest, and the outcome, including `denied`. The chain is exported as a plain directory of files that someone who does not run Numinance can check.

That someone needs three things and nothing else: the export directory, the public key of the runner, and the public key and origin of the transparency log. They do not need the engine, a network connection or an account. The checker is `numi evidence verify` in the open build, a thin wrapper over the Go package `sdk/go/evidenceverify`, which is written from the public specification only and uses the standard library only.

The design consequence is the one that matters: the party that ran the agent is not the party whose word you take. You decide which keys to trust before you look at the export, and the verifier tells you how much of the account those keys can vouch for.

## What you can do with it today [#what-you-can-do-with-it-today]

| Task | Where |
| --- | --- |
| Read the shape of a record and the rules of the chain | [Record chain](/docs/evidence/record-chain) |
| Know which files an export directory holds and why | [Export format](/docs/evidence/export-format) |
| Verify an export with the CLI or from Go, read the exit codes | [Offline verification](/docs/evidence/offline-verification) |
| Interpret `verified`, `self-consistent`, `unauthenticated` and the rest | [Trust levels](/docs/evidence/trust-levels) |
| Understand checkpoints, inclusion proofs and component receipts | [Anchoring and receipts](/docs/evidence/anchoring-and-receipts) |
| Run the 302 conformance vectors against a verifier | [Conformance vectors](/docs/evidence/conformance-vectors) |
| Know what a pass cannot tell you | [Threat model and limits](/docs/evidence/threat-model-and-limits) |

## How the parts fit [#how-the-parts-fit]

<EvidenceChainInspector />

The pipeline has five stages, and each is verifiable on its own terms.

1. **Actions become records.** Every privileged action, lifecycle transition and policy denial becomes one canonical JSON record. Records are hash-linked: record `n` carries the hash of record `n-1`.
2. **Records are signed.** The runner signs each record with an Ed25519 key. The signature covers the chain fields, so reordering or editing a record is visible.
3. **Components add receipts.** The credential broker and the egress proxy state what they did as records in the same chain, so an auditor reads component behavior from the chain and not from a side log.
4. **The log anchors the head.** A transparency log commits the chain head, and the attestation, in a Merkle tree. An inclusion proof in the export lets a verifier confirm the head against a log key it pinned.
5. **The export is a directory.** Records, a summary, an index, derived views, a signed attestation and a signed manifest of every file. The verifier reads it as untrusted input.

Verification then runs the other way. It decodes strictly, re-derives everything the chain can state (summary, diff digest, views, attestation fields), checks signatures against your pinned keys, and reports one level and a set of findings.

## What one real run looks like [#what-one-real-run-looks-like]

This is the open verifier against a conformance fixture, a golden export generated by the Numinance evidence code over in-memory adapters with fixed test keys. It is not an export of a real engineering run. The test public keys are stored in the spec repository.

<VerifiedSnippet what="numi evidence verify against conformance/evidence/v1/exports/closed-author" exit="0">
```text
$ numi evidence verify --runner-key keys/runner.pub --log-key keys/log.pub --log-origin numinance.test/log --complete exports/closed-author
change: chg_01010101010101010101010101010101
records: 12, head sha256:8dec4e3d5cf4bd7650ef6010671298793c05493cb20c3dd946bc3ef805689e48
state: ended Closed
level: verified
chain: records link, hash and end as stated
signatures: verified under the pinned runner keys
anchor: head proved under the pinned log
attestation: signed, re-derived from the chain
credential_scopes: unsourced: no credential broker statement is in the attestation
network_policy: unsourced: no egress proxy statement is in the attestation
not applicable: deployment.json (not applicable at PR level: the change closed from Merging (design section 6) and was never released, deployed or observed)
not applicable: observation.json (not applicable at PR level: the change closed from Merging (design section 6) and was never released, deployed or observed)
result: verified
```
</VerifiedSnippet>

Read the last two notes before the verdict. The attestation states no credential-broker or egress-proxy source, and the verifier says so as a note instead of hiding it. A `verified` result is exact about what it verified; it does not round up.

## The boundary, stated once [#the-boundary-stated-once]

<Callout type="warn" title="Verified is provenance, not correctness">
`verified` means the records link and hash as stated, the signatures hold under keys you pinned, and the head is proved under a log you pinned. It does not mean the code is correct, the tests were thorough, the model reasoned well, or that a compromised host logged every event. Numinance's own verifier stages and your own review decide quality. Evidence decides who did what, in what order, under which decision. See [Threat model and limits](/docs/evidence/threat-model-and-limits).
</Callout>

Two more boundaries keep the claim honest:

- There is no built-in trust root. A key stated by the export never reaches `verified`, whatever it says about itself.
- Passing the conformance vectors shows that a verifier agrees with the specification at a version. It is not an audit or a certification of any deployment.

## Where it fits in the rest of the platform [#where-it-fits-in-the-rest-of-the-platform]

Evidence is the last link of the loop that [governed execution](/docs/concepts/governed-execution) opens: policy decides before the action, the runner writes the record at the action, and a third party checks the record afterwards. The concept-level view is in [Evidence and trust](/docs/concepts/evidence-and-trust). To run the verifier on your own machine in a few minutes, use the [evidence quickstart](/docs/get-started/evidence-quickstart).

<Cards>
  <Card title="Verify an export" href="/docs/evidence/offline-verification" description="Flags, JSON fields, exit codes and a compile-checked Go call." />
  <Card title="Trust levels" href="/docs/evidence/trust-levels" description="What each level proves and the rule automation must follow." />
  <Card title="Conformance vectors" href="/docs/evidence/conformance-vectors" description="Run vectors yourself and compare with the expected outcome." />
</Cards>

