Trace a change back to the human who authorized it

tovio audit graph — the lineage projection across humans, tokens, agents, and artifacts.

Written By Dustin

Last updated About 3 hours ago

tovio audit graph <target>
tovio audit graph chg:<id> --depth 3
tovio audit graph <target> --format mermaid

audit graph assembles a change's lineage graph: the derivation chain running from the human who issued a capability token, through that token and any delegations of it, to the agent, the model and tool manifest the agent ran, the change it produced, the rationale and session record behind it, the signed audit entry that attests it, the parent changes it derives from, and any check verdicts.

It is the answer to "who authorised this, under what, and what did they run" — assembled from objects that were already signed, rather than reconstructed from a narrative afterwards.

What you can point it at

  • A change id — chg:<id>.
  • A commit address, with or without the blake3: prefix.
  • task:<id> — an agent task.
  • session:<id> — a run record's correlation id.

One positional argument, four target classes. The task and session forms are prefixes on that one argument, not separate flags.

Depth

The walk from a change to its parent changes is bounded, and the default is 1 — the target and its immediate derivation. --depth widens it. The bound is deliberate: an unbounded provenance walk on a long history turns a read command into a hang.

Rendering

FormatUse it for
json (default)Piping into a compliance tool, or diffing two runs.
dotGraphviz — a picture for an incident write-up.
mermaidPasting into a document or ticket that renders Mermaid.

Any other value is rejected as a usage error, but the format is checked after the target is resolved and the graph is assembled — so a typo costs you the walk, and an unresolvable target reports the target problem rather than the format one.

It reads; it never writes

The graph is a projection computed at read time over existing signed objects. It creates no stored object, no index, and nothing that syncs — running it changes the repository not at all. For a fixed store and a fixed reader it is deterministic: nodes and edges come out in a canonical order, so two runs produce identical JSON and a diff between them means something actually changed.

What you cannot read shows up locked, not missing

A sealed session or rationale you hold no key for renders as a typed locked node — its kind and address, no content. It is never silently dropped.

That is the whole design. A graph that quietly omitted what you cannot see would let anyone map the shape of a repository's protected material simply by watching which nodes disappear. Present-but-opaque tells you a thing exists and that you are not cleared for it, which is exactly as much as you are entitled to know.

It is diagnostic, not a verifier

The graph renders what is there. A session whose prompt does not match what the commit attested still renders, so you can look at the mismatch instead of being handed an error you cannot inspect. The provenance export refuses in that situation; the graph deliberately does not.

If what you want is the audit chain checked, that is tovio audit verify. If what you want is object integrity, that is tovio fsck.

What a signature does and does not prove

The graph shows attested lineage: a named party signed these claims and has not altered them since. It does not certify that the claims are complete or true. An agent that reports a partial session signs a partial session; the signature makes that non-repudiable, not accurate. Read it as evidence of who said what, under whose authority — which is the useful thing, and is not the same as proof of what happened.

Before sharing the output

Clear node labels can include change ids, model names, task ids, and DIDs. None of it is protected file content, but it does describe your repository's structure and who works in it. Trim it to the nodes the conversation needs before pasting a graph into a ticket or a vendor's support form.