Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
225 changes: 40 additions & 185 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@

It also captures your Claude Code sessions automatically — each session's work is harvested and rolled up into a summary. But where the persistent-memory tools compress with an LLM and inject straight back, vouch's rollup is **mechanical (no LLM)** and the summary lands in the **same review gate**: nothing becomes durable memory until you approve it.

Still alpha — surface is small on purpose; expect breaking changes pre-1.0.

> **Built for Gittensor (SN74) miners.** Mining subnet 74 means landing merged PRs across a whitelist of repos that keeps shuffling — which means re-investigating each repo's codebase and merge bar every session your agent opens. vouch auto-captures what a session works out, you approve what's worth keeping, and the next session recalls it: less re-discovery, more merged PRs. → **[docs/gittensor.md](docs/gittensor.md)**

## Watch it work (110 seconds)

[![vouch demo — capture, summarize, approve, compile, recall](docs/img/how-it-works-poster.jpg)](docs/vouch-how-it-works.mp4)
[![vouch demo — capture, summarize, approve, compile, recall](docs/img/how-it-works-preview.gif)](docs/vouch-how-it-works.mp4)

**[▶ docs/vouch-how-it-works.mp4](docs/vouch-how-it-works.mp4)** — captured live from the review console, no mockups: a Claude Code session auto-captures itself, one click has an LLM summarize what it meant, a human approves it at the gate, **`vouch compile`** distills the approved claims into cited topic pages (drafted by a real LLM, every `[claim: …]` citation machine-verified, still gated), and the film ends on the actual `vouch recall` digest — the knowledge the video just built, injected into the next session's first turn.
Captured live from the review console, no mockups — the preview above is muted and 3× speed; the real thing is **[▶ docs/vouch-how-it-works.mp4](docs/vouch-how-it-works.mp4)**. A Claude Code session auto-captures itself, an LLM summarizes what it meant, a human approves it at the gate, **`vouch compile`** distills the approved claims into cited topic pages (every `[claim: …]` citation machine-verified, still gated), and `vouch recall` injects the result into the next session's first turn.

## Why this exists

Expand All @@ -43,9 +41,8 @@ Four opinionated choices distinguish vouch from the neighbours:

Worth it when:

- **You mine Gittensor (SN74).** Emissions come from merged PRs across a whitelist that keeps shuffling, so your agent burns each session re-learning the same codebases and merge bars. vouch captures each session's findings for approval and recalls them next time — it stops re-deriving what it already knew and keeps targeting the repos that pay. See [docs/gittensor.md](docs/gittensor.md).
- **Multiple agents share a repo** (Claude Code + Cursor + a CI bot). Per-agent attribution in the audit log makes "which agent claimed what" answerable.
- **Sessions keep re-explaining the same context.** Curated, cited claims let new sessions start from your team's agreed answer instead of re-grepping — and vouch auto-captures each Claude Code session into a summary you can approve, so memory accrues without letting the agent write its own history.
- **Sessions keep re-explaining the same context.** Curated, cited claims let new sessions start from your team's agreed answer instead of re-grepping.
- **You want decision records without the ADR ceremony.** `vouch crystallize` promotes a session's durable parts into proposals; one approve and they're permanent.
- **You'd review agent-stated facts the way you review agent-written code.** Vouch is a PR queue for claimed knowledge.
- **Compliance / audit trails matter.** Required citations + append-only audit log give you "who decided X, citing what, when" for free.
Expand All @@ -64,15 +61,10 @@ curl -fsSL https://raw.githubusercontent.com/vouchdev/vouch/main/install.sh | sh

# …or directly via pipx (vouch-kb on PyPI; the command stays `vouch`)
pipx install vouch-kb

# …or from the cloned repo, in a venv
pip install -e '.[dev]'
```

The one-liner is POSIX `sh`, never needs `sudo`, and detects an existing
Claude Code install to point you at the next step (`vouch install-mcp
claude-code`). Inspect it first if you'd like — it's [`install.sh`](install.sh)
at the repo root.
The one-liner is POSIX `sh` and never needs `sudo` — inspect
[`install.sh`](install.sh) first if you'd like.

Or skip the install entirely and run the released container image
([`ghcr.io/vouchdev/vouch`](https://github.com/vouchdev/vouch/pkgs/container/vouch)),
Expand All @@ -87,33 +79,6 @@ docker run -i --rm -v "$PWD:/data" ghcr.io/vouchdev/vouch:latest
docker run --rm -v "$PWD:/data" ghcr.io/vouchdev/vouch:latest status
```

## Running the tests

From a clone with the dev extras installed (`pip install -e '.[dev]'`):

```bash
# the full CI gate — lint + types + unit tests (exactly what CI runs)
make check # == ruff check + mypy src + pytest

# just the unit tests
python -m pytest tests/ -q --ignore=tests/embeddings

# a single module or test
python -m pytest tests/test_capture.py -q
python -m pytest tests/test_recall.py::test_digest_includes_approved_claim_and_page -q

# with coverage
make test-cov # term-missing + coverage.xml

# end-to-end smoke checks for the claude-code session hooks
make smoke-capture # capture: observe → finalize → pending summary
make smoke-recall # recall: approved knowledge injected at session start
```

The embedding-heavy tests live under `tests/embeddings/` and need the extra
`pip install -e '.[embeddings]'` (they run as a separate CI job); drop the
`--ignore` flag once installed.

## Quick start

```bash
Expand Down Expand Up @@ -154,46 +119,18 @@ with your project's first real source and claim when you are ready.

### Automatic session capture

Once vouch's Claude Code hooks are installed, sessions capture *themselves* —
this is the loop the demo shows. A `PostToolUse` hook harvests each tool call
into a gitignored scratch buffer; at session end a `SessionEnd` hook rolls the
buffer plus a `git diff` backstop into **one pending "session summary" page** —
mechanically, no LLM, never auto-approved. You review and `vouch approve` it
like any other write, and the next session starts with it injected via `vouch
recall`. Passive harvest, human-gated commit, no re-explaining:
Once vouch's Claude Code hooks are installed, sessions capture *themselves*:
each tool call is harvested into a gitignored scratch buffer and rolled up at
session end into **one pending "session summary" page** — mechanically, no
LLM, never auto-approved. You review and `vouch approve` it like any other
write, and the next session starts with it injected via `vouch recall`:

![vouch auto-capture demo](docs/demo.gif)

The full walkthrough with real output lives at [docs/example-session.md](docs/example-session.md); re-render the GIF from [docs/demo.tape](docs/demo.tape) with `vhs docs/demo.tape`.

Prefer reading to running? The [examples/](examples/) directory ships sample KBs as committed files, each with rendered screenshots of `vouch status`, `search`, `show`, `audit`, and `diff` against the fixture — see what the CLI returns before installing anything.

## Gittensor (SN74)

**Gittensor** — Bittensor subnet 74 — pays miners in TAO for landing *merged* pull requests into whitelisted open-source repos. Contributions are scored by code quality, each repo's allocation, and programming-language factors, and the whitelist itself shuffles as the subnet matures. So mining well means pointing a coding agent at a rotating set of target repos and landing mergeable PRs in the ones that pay.

The tax on that is re-investigation. Every target repo means (re)learning its architecture, its CI, its `CONTRIBUTING.md`, the maintainer's merge bar, and which past attempts got rejected and why. Across a dozen repos and a dozen sessions, your agent re-derives all of it from cold each time — time not spent landing PRs. vouch turns each session's findings into reviewed memory the next session recalls, so the investigation happens once:

```bash
cd acme-httpkit # a whitelisted target repo — Go, healthy allocation
vouch init # review-gated KB at .vouch/
vouch install-mcp claude-code # wires the capture + recall hooks

# session 1: the agent maps the repo and works issue #212 (a pool leak).
# the claude-code hooks auto-capture the work. you approve the durable
# summary and file one cited claim: httpkit's merge bar.
vouch pending
vouch approve <id> --reason "accurate session summary"

# session 2: opens with `vouch recall`. the agent already knows the layout,
# that merges need `make test` green + a changelog entry, and where #212's
# fix and regression test landed. it skips re-discovery and takes the PR
# to merge.
```

The KB compounds session over session: merge bars, rejected approaches, targeting notes. When the whitelist shuffles and httpkit's allocation drops, `vouch supersede` the claim that said it was worth targeting — your agent re-prioritizes toward a higher-allocation repo, and the decision stays cited and reviewed instead of lost in a Discord thread. Each session you approve makes the next one start further ahead; the walkthrough in [docs/gittensor.md](docs/gittensor.md) runs the loop with real output.

vouch reads **no** live signals — it never checks on-chain scores, verifies PATs, or submits weights (that's the `gitt` miner client). It's the reviewed record of what your agent already worked out, so it never works it out twice. Full miner walkthrough: **[docs/gittensor.md](docs/gittensor.md)**.
The full walkthrough with real output lives at
[docs/example-session.md](docs/example-session.md); the [examples/](examples/)
directory ships sample KBs with rendered CLI output so you can see what vouch
returns before installing anything.

## Object model

Expand Down Expand Up @@ -243,69 +180,27 @@ The files are the source of truth; `state.db` is a derivable cache (`vouch index

## CLI surface

```
vouch init # set up .vouch/ at PATH
The daily loop:

```text
vouch init # set up .vouch/ at the project root
vouch install-mcp HOST [--tier T1-T4] # wire MCP + capture/recall hooks into a host
vouch discover [--path P] # find the nearest .vouch/ root
vouch capabilities # emit the JSON capabilities descriptor
vouch status [--json] # KB counts + pending proposals
vouch stats [--days N] [--json] # observability: queue, review rates, citations
vouch lint [--stale-days N] # user-actionable problems
vouch doctor # full sweep incl. source verification
vouch fsck # deep consistency: indexes, lifecycle, decided
vouch migrate [--check] [--dry-run] # upgrade .vouch/ format safely

vouch pending # list pending proposals
vouch review [--limit N] [--type KIND] # guided proposal review queue
vouch show <proposal-id> # show pending proposal details
vouch read-claim <claim-id> # read an approved claim
vouch read-page <page-id> # read an approved page
vouch read-entity <entity-id> # read an approved entity
vouch read-relation <relation-id> # read an approved relation
vouch list-claims # list all approved claims
vouch list-pages # list all approved pages
vouch list-entities # list all approved entities
vouch list-relations # list all approved relations
vouch approve <proposal-id> [--reason ...]
vouch reject <proposal-id> --reason "..."
vouch expire [--apply] [--days N] [--json] # GC stale pending proposals

vouch propose-claim --text ... --source ... [--type ...] [--confidence X]
vouch propose-page --title ... [--body -] [--claim ID ...]
vouch propose-entity --name ... --type ...
vouch propose-relation --from ID --rel uses --to ID

vouch source add PATH [--title ...] [--url ...]
vouch source verify [--fail-on-issue]

vouch supersede OLD_ID NEW_ID
vouch contradict CLAIM_A CLAIM_B
vouch archive CLAIM_ID
vouch confirm CLAIM_ID
vouch cite CLAIM_ID

vouch session start [--task ...] [--note ...]
vouch session end SESSION_ID
vouch crystallize SESSION_ID [--no-page]

vouch recall # digest of approved knowledge for session-start injection
vouch capture observe|finalize|finalize-all|banner # hook-driven session capture (claude code)

vouch search QUERY [--limit N]
vouch context TASK [--max-chars N] [--min-items N] [--require-citations]
vouch index
vouch audit [--tail N] [--json]

vouch export --out path.tar.gz
vouch export-check path.tar.gz
vouch import-check path.tar.gz
vouch import-apply path.tar.gz [--on-conflict skip|overwrite|fail]
vouch sync-check PATH_OR_BUNDLE
vouch sync-apply PATH_OR_BUNDLE [--on-conflict fail|skip|propose]

vouch serve [--transport stdio|jsonl]
vouch serve [--transport stdio|jsonl] # the agent-facing tool server

vouch status | pending | review | show <id> # inspect the queue
vouch approve <id> [--reason ...] # the gate
vouch reject <id> --reason "..."

vouch propose-claim|propose-page|... # human mirror of the kb.propose_* tools
vouch search QUERY | context TASK | recall # retrieval
vouch compile [--dry-run] # llm-wiki ingest: draft topic pages from claims
vouch export | import-check | import-apply # portable bundles
Comment on lines +190 to +197
```

The full surface — lifecycle ops, sessions, sources, maintenance,
migration — is listed by `vouch --help` and machine-readably by
`vouch capabilities`.

## MCP tools / JSONL methods (same surface, two transports)

Read (unrestricted): `kb.capabilities`, `kb.status`, `kb.search`, `kb.context`, `kb.read_{page,claim,entity,relation}`, `kb.list_{pages,claims,entities,relations,sources,pending}`
Expand Down Expand Up @@ -385,35 +280,9 @@ The JSONL transport reads one envelope per line on stdin, writes one per line on

Errors come back with `ok:false` and a structured `error.code` (`method_not_found`, `missing_param`, `invalid_request`, `internal_error`).

Every successful `kb.*` result that is object-shaped carries read-only trust metadata so clients can detect remote confinement:

```json
{
"id": "r1",
"ok": true,
"result": {
"backend": "fts5",
"hits": [],
"_meta": {
"vouch_trust": {
"remote": false,
"caller_kind": "jsonl",
"auth_subject": null
}
}
}
}
```

| Transport | `remote` | `caller_kind` | `auth_subject` |
|-----------|----------|---------------|----------------|
| JSONL stdio | `false` | `jsonl` | `null` |
| HTTP `/rpc` | `true` | `jsonl_http` | bearer fingerprint when authenticated |
| MCP stdio | `false` | `mcp_stdio` | `null` |
| HTTP `/mcp` | `true` | `mcp_http` | bearer fingerprint when authenticated |
| CLI `--json` | `false` | `cli` | `null` |

The block is server-attached metadata — client mutations are ignored. Array-shaped read results (e.g. `kb.list_claims`) pass through unchanged; trust rides on dict-shaped responses only (#233).
Every dict-shaped `kb.*` result also carries a server-attached
`_meta.vouch_trust` block (`remote`, `caller_kind`, `auth_subject`) so clients
can detect remote confinement — see [SPEC.md](SPEC.md) for the full contract.

## Portable bundles

Expand Down Expand Up @@ -441,27 +310,13 @@ vouch import-apply kb.tar.gz --on-conflict skip # apply (default skip; never de
| Portable bundle | no | no | **yes** |
| Transports | SDK / HTTP | none | **MCP + JSONL** |

## What ships today

| Area | Current support |
|------|-----------------|
| Knowledge base | `.vouch/` folder, YAML claims/entities/relations/evidence/sessions, markdown pages with frontmatter, JSONL audit log, content-addressed sources |
| CLI | `init`, `install-mcp`, `discover`, `capabilities`, `status`, `lint`, `doctor`, `fsck`, `pending`, `show`, `approve`, `reject`, `propose-{claim,page,entity,relation}`, `source add`, `source verify`, `supersede`, `contradict`, `archive`, `confirm`, `cite`, `session {start,end}`, `crystallize`, `capture {observe,finalize,finalize-all,banner}`, `recall`, `search`, `context`, `index`, `audit`, `export`, `export-check`, `import-check`, `import-apply`, `serve` |
| Tool servers | MCP over stdio + JSONL over stdin/stdout, same `kb.*` surface across both transports, capabilities + knowledge-capability descriptor |
| Schemas | 13 JSON Schemas (Draft 2020-12) generated from pydantic in [schemas/](schemas/), plus hand-maintained `bundle.manifest` and `jsonl-envelope` schemas |
| Write safety | review-gated writes via [proposed/](spec/review-gate.md), `dry_run:true` previews, host trust required for `approve`/`reject`, atomic exclusive-create storage, path-traversal blocked on source intake and bundle import |
| Session capture | Claude Code hooks harvest each session (`PostToolUse` → `vouch capture observe`) into a gitignored scratch buffer; `SessionEnd` rolls it up mechanically (no LLM) into one review-gated session-summary page; `SessionStart` injects approved knowledge via `vouch recall` and nudges pending summaries. Never auto-approves |
| Retrieval | `retrieval.backend` in `config.yaml` selects the path: `auto` (default — embedding → FTS5 → substring), `embedding`, `fts5`, or `substring`. Semantic backends (`all-mpnet-base-v2`, `MiniLM-L6`, fastembed-BGE) ship behind install extras; `auto` degrades to FTS5 when they aren't installed. Context packs with citations + quality gate |
| Lifecycle | `supersede`, `contradict`, `archive`, `confirm`, `cite` — direct mutations, all audited |
| Portability | tar.gz bundles with per-file sha256 `manifest.json`, `export-check`, `import-check`, `import-apply` with skip/overwrite/fail conflict modes |
| Audit | append-only `audit.log.jsonl`, per-event actor (`VOUCH_AGENT`), object ids, dry-run flag, reversible flag |
| Adapters | Claude Code wiring documented via `.mcp.json` + `VOUCH_AGENT` env; per-runtime adapter templates not yet shipped |
| Validation | pytest suite (storage, FTS5, audit, source-verify, review-gate, bundle, JSONL), ruff + mypy gates, GitHub CI |
| Specification | dated snapshots under [spec/](spec/), JSON Schemas in [schemas/](schemas/), generator script at [scripts/gen_schemas.py](scripts/gen_schemas.py) |

## Status

Pre-1.0. What's *not* in this implementation: per-runtime adapter templates, benchmark fixtures, multi-agent sync, scopes beyond a single field on Claim/Source. If a hole matters to you, file an issue.
Pre-1.0 — the surface is small on purpose; expect breaking changes. What's
*not* in this implementation: benchmark fixtures, multi-agent sync, scopes
beyond a single field on Claim/Source. If a hole matters to you, file an
issue. Development setup and the test gate live in
[CONTRIBUTING.md](CONTRIBUTING.md).

## License

Expand Down
Binary file removed docs/img/how-it-works-poster.jpg
Binary file not shown.
Binary file added docs/img/how-it-works-preview.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading