provrun.evidence

Evidence: typed, append-only events for one run, chained by hash.

provrun decides what each event means and builds the chain; provevi stores the events and checks them. A run writes its evidence through a provevi store, by default the file store, into one folder::

<run>/evidence/events.jsonl            one event on each line, in order
<run>/evidence/payloads/<sha256>       large payloads, named by their SHA-256
<run>/evidence/manifest.json           written when the run closes

Each event holds the SHA-256 of the line before it, so a changed, removed or reordered line breaks the chain, and verify finds it. The manifest holds the hash of the last line, so a removed tail is found too.

The platform writes evidence, not the agent. Each component calls emit or step itself. step also opens an OpenTelemetry span, so the live telemetry and the canonical events come from one call.

In the strict mode a failed write raises EvidenceError and stops the run. In the lenient mode it warns, and the manifest records that the evidence is incomplete.

class EvidenceError

source

Evidence could not be written or does not verify.

It is also a provevi EvidenceError, which is what provevi’s checks raise.

read_events

source

read_events(folder: Path) -> list[EvidenceEvent]

Read the events of an evidence folder, as provevi.read_events does.

Raises provrun’s EvidenceError at a line that is not an event.

Parameter Type Default Description
folder Path required An evidence folder, such as /evidence
returns list[EvidenceEvent] Its events, in order

class Step

source

Step(refs: tuple[str, ...], data: dict, payload: Any)

What a component fills in while a step runs, to be written as one event.

EvidenceRecorder.step yields it, and writes it when the step ends.

Parameter Type Default Description
refs tuple[str, …] required The URIs and paths the event is about; kept as a list a step can add to
data dict required The event’s data, copied; a step can add to it
payload Any required The event’s payload, stored apart; a step can set it

class EvidenceRecorder

source

EvidenceRecorder(run_id: str, actor: str, folder: Path, *, mode: str = 'strict', sinks: list[Sink] | None = None, redact: Callable[[dict], dict] | None = None, store: EvidenceStore | None = None)

Writes the evidence of one run. Thread-safe; one recorder per run.

Parameter Type Default Description
run_id str required The run’s ID, which each event records
actor str required Who runs it, which each event records
folder Path required The run’s evidence folder
mode str 'strict' “strict”, where a failed write raises EvidenceError, or “lenient”, where it warns
sinks list[Sink] | None None More sinks that get each line after the store, such as a live feed
redact Callable[[dict], dict] | None None Changes each event’s data before it is written; None keeps it
store EvidenceStore | None None The provevi store that holds the evidence; None is the file store

EvidenceRecorder.emit

source

EvidenceRecorder.emit(type: str, component: str, *, refs: tuple[str, ...] | list[str] = (), data: dict | None = None, payload: bytes | str | dict | list | None = None, confidence: str = 'observed') -> EvidenceEvent | None

Write one event. A payload is stored apart and the event keeps its hash.

A write that fails raises EvidenceError in strict mode and warns in lenient mode; an event after close raises EvidenceError.

Parameter Type Default Description
type str required The event type, one of EVENT_TYPES; another raises ValueError
component str required The part that writes it, such as the class’s name
refs tuple[str, …] | list[str] () The URIs and paths the event is about
data dict | None None The event’s data
payload bytes | str | dict | list | None None A large body, stored apart; a dict or list is stored as canonical JSON
confidence str 'observed' How provrun knows it, one of CONFIDENCE, such as “parsed” for a provider’s account
returns EvidenceEvent | None The event written; None when a lenient write failed

EvidenceRecorder.step

source

EvidenceRecorder.step(type: str, component: str, *, refs: tuple[str, ...] | list[str] = (), data: dict | None = None, payload: Any = None) -> Iterator[Step]

Run a step in an OpenTelemetry span, and write its event when it ends.

If the step raises, the event is step_failed with the error. The event’s data holds started_at, the time the step began, in the format of the event’s time, and the span’s IDs when a span records. The recorder sets those keys; a value the step gives for them is dropped.

Parameter Type Default Description
type str required The event type to write when the step ends, one of EVENT_TYPES
component str required The part that runs the step
refs tuple[str, …] | list[str] () The URIs and paths the event is about
data dict | None None The event’s first data; the step can add to it
payload Any None The event’s first payload; the step can set it
returns Iterator[Step] The step to fill in, inside a with block

EvidenceRecorder.close

source

EvidenceRecorder.close() -> dict

Write the manifest and close the sinks; a second close gives the manifest again.

Raises EvidenceError when the evidence cannot be sealed, and in strict mode when a problem was found.

Parameter Type Default Description
returns dict The manifest: run ID, event count, last hash, payloads, and whether the evidence is complete