Skip to content

feat: vouch trace — provenance graph + impact analysis for the review gate #197

Description

@plind-junior

Labels: enhancement

What you're trying to do

vouch already records everything needed to explain a claim's existence — the session that proposed it, the source it cites, the supersedes chain it sits on, the contradiction that demoted it to contested, the page that embeds it as evidence. The trouble is that all of it is scattered across audit.log.jsonl, relations/, evidence/, sessions/, and the claim file itself, and there is no way to ask the obvious operational question: "why is this claim here, and what depends on it?". A reviewer in front of a 500-item queue ends up guessing.

The other half of the same gap is forward-looking. Before archiving or contradicting a durable claim, a reviewer has no way to see the blast radius. Today archiving a claim that ten approved pages cite is just as cheap as archiving an orphan, and the reviewer only finds out something broke when an agent retrieves stale context an hour later. A persistent provenance DAG built from artifacts vouch already records — plus a small CLI surface (vouch why, vouch trace, vouch impact) and matching kb.* methods — closes the loop without inventing any new on-disk schema, and gives the review gate the explainability it needs to scale past one human reviewer.

Suggested shape

vouch why <claim_id>                    # backward: cites, session, supersedes chain, contradictions
vouch why <claim_id> --depth 3 --json   # machine-readable provenance tree
vouch trace <claim_id> --to <other_id>  # shortest path between two artifacts
vouch impact <claim_id>                 # forward: who cites this, what pages embed it, downstream claims
vouch impact <claim_id> --if archive    # dry-run a lifecycle op and report breakage
vouch graph --session <session_id>      # render the DAG for one agent run as dot/mermaid
  • New src/vouch/provenance/ module builds an in-memory typed DAG on top of audit.log.jsonl + relations/ + evidence/ + sessions/; the graph is maintained incrementally on every mutation and cached in a state.db table prov_edges(src_id, dst_id, kind, event_ts, session_id) so cold queries on a 100k-claim KB still return in under a second.
  • Edge kinds are typed and load-bearing: cites, supersedes, supersededBy, contradicts, contradictedBy, embeds (page → claim), proposedIn (claim → session), approvedBy (claim → audit event), derivedFrom (claim → source span).
  • vouch why walks edges backward from a target and prints a tree grouped by edge kind, each leaf carrying its citation span or audit timestamp; --json emits a stable shape suitable for downstream tooling.
  • vouch impact walks forward and surfaces every artifact that would change state if the target were archived, contradicted, or superseded; --if <op> dry-runs the lifecycle op against the in-memory graph and reports the breakage list without writing.
  • Reviewer output is bare prose + indentation — no curses, no colors by default — so it diffs cleanly into a gh pr comment or a session log.
  • New kb.* methods: kb.why, kb.trace, kb.impact, kb.graph_export — registered in capabilities.METHODS, MCP server, JSONL server, CLI. No schema migration; the provenance table is derived state.
  • vouch provenance rebuild reconstructs prov_edges from scratch in a single pass over the audit log, so the DAG is treated as a cache, not a source of truth — matches the ethos that text files diff cleanly and indexes are disposable.

Acceptance

  • vouch why <claim_id> on a claim proposed in session A, citing source S, superseding claim X prints a tree with all three branches and the originating audit timestamps.
  • vouch impact <claim_id> --if archive against a claim cited by two approved pages prints those two pages by id and exits non-zero; without --if, it exits zero and just lists.
  • vouch trace <a> --to <b> finds the shortest typed-edge path between two artifacts and prints it, or exits non-zero with no path if disconnected.
  • vouch provenance rebuild reconstructs prov_edges byte-equivalent to the live-maintained one on a 10k-claim fixture KB; CI asserts equivalence.
  • kb.why / kb.impact / kb.trace are reachable over MCP stdio, JSONL, and HTTP (chore(deps): bump actions/setup-python from 5 to 6 #1), return stable JSON, and appear in kb.capabilities.
  • On a 100k-claim KB, vouch why and vouch impact both return in under 1s p95 with a warm state.db, and under 5s on a cold rebuild.

Out of scope

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions