provrun.evidence
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 closesEach 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
Evidence could not be written or does not verify.
It is also a provevi EvidenceError, which is what provevi’s checks raise.
read_events
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 |
| returns | list[EvidenceEvent] | Its events, in order |
class Step
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
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
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 | NoneWrite 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
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
EvidenceRecorder.close() -> dictWrite 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 |