Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
eba1075
docs(readme): link example-kb screenshots from the 30-second tour
plind-junior Jun 30, 2026
c27095e
fix(examples): resolve interpreter-local vouch in screenshot render
plind-junior Jun 30, 2026
97ce4c6
Merge pull request #291 from vouchdev/docs/example-screenshots-followups
plind-junior Jun 30, 2026
8ac0775
docs: add tutorials, host-comms walkthrough, one-line mcp install
dripsmvcp Jun 30, 2026
3e8df7e
Merge pull request #295 from dripsmvcp/docs/tutorials-and-host-comms
plind-junior Jun 30, 2026
93f5836
fix(storage): survive unreadable artifact files and pin utf-8 i/o
plind-junior Jun 30, 2026
660bb59
Merge pull request #296 from vouchdev/fix/resilient-listing-and-utf8-io
plind-junior Jun 30, 2026
a501ceb
chore(release): bump version to 1.0.0
plind-junior Jul 1, 2026
ca636f5
Merge pull request #299 from vouchdev/chore/version-1.0.0
plind-junior Jul 1, 2026
81c4da4
docs(capture): spec + plan for claude code session auto-capture
plind-junior Jul 1, 2026
2231e64
feat(capture): add capture config, buffer paths, gitignore
plind-junior Jul 1, 2026
fa9d68b
feat(capture): harvest tool-use observations with dedup
plind-junior Jul 1, 2026
4f67d98
feat(capture): roll a session into one pending summary proposal
plind-junior Jul 1, 2026
51d0604
feat(capture): add vouch capture observe, finalize, banner cli
plind-junior Jul 1, 2026
4e390fd
feat(capture): wire claude code adapter hooks for session capture
plind-junior Jul 1, 2026
44f7e25
test(capture): add end-to-end smoke script and make target
plind-junior Jul 1, 2026
8e99dd8
feat(capture): merge adapter hooks into an existing settings.json
plind-junior Jul 1, 2026
0a66807
fix(storage): read and write kb files as utf-8
plind-junior Jul 1, 2026
4cf2f2b
feat(recall): inject approved knowledge digest at session start
plind-junior Jul 1, 2026
1a040d0
test(recall): add end-to-end smoke script and make target
plind-junior Jul 1, 2026
8b8e16b
test: cover capture, recall, and settings-merge edge branches
plind-junior Jul 1, 2026
adc0b28
docs: changelog entries + readme how-to-run-tests section
plind-junior Jul 1, 2026
230a2c7
chore: merge origin/test into feat/session-autocapture
plind-junior Jul 1, 2026
d6b5393
Merge pull request #303 from vouchdev/feat/session-autocapture
plind-junior Jul 1, 2026
432d17f
docs(superpowers): add design and plan for vscode session auto-proposal
plind-junior Jul 1, 2026
5933700
feat(capture): add finalize_all_except() for old buffer cleanup
plind-junior Jul 1, 2026
f6cb506
feat(capture): add 'vouch capture finalize-all' CLI command
plind-junior Jul 1, 2026
6ec0fe7
feat(adapter): wire capture finalize-all into sessionstart hook
plind-junior Jul 1, 2026
d68a376
docs(adapter): document windowclose fallback behavior
plind-junior Jul 1, 2026
2d76811
docs(adapter): explain session capture auto-proposal behavior
plind-junior Jul 1, 2026
b2955f0
test(capture): add e2e test for sessionstart cleanup + finalize flow
plind-junior Jul 1, 2026
2a5d2d2
fix(capture): skip git context when finalizing buffers with unknown o…
plind-junior Jul 1, 2026
63a1ee6
Merge pull request #304 from vouchdev/feat/session-autocapture
plind-junior Jul 1, 2026
4c4b66a
feat(themes): cross-session pattern detection via entity co-occurrence
dripsmvcp Jul 1, 2026
7e495fc
fix(themes): address review on config defensiveness, dedup, and cli o…
dripsmvcp Jul 1, 2026
c6e69eb
Merge pull request #332 from dripsmvcp/feat/cross-session-themes
plind-junior Jul 1, 2026
95b886c
chore(bench): wire make bench, add pytest-benchmark, record baseline
plind-junior Jul 1, 2026
dd6529b
Merge remote-tracking branch 'origin/test' into chore/benchmarks
Copilot Jul 1, 2026
35eac96
Merge pull request #334 from vouchdev/chore/benchmarks
plind-junior Jul 2, 2026
d2fdb12
docs: redraw hero banner + reframe gittensor around the miner workflow
plind-junior Jul 2, 2026
0278fc6
Merge pull request #335 from vouchdev/docs/readme-hero-and-gittensor-…
plind-junior Jul 2, 2026
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
25 changes: 25 additions & 0 deletions .claude/commands/vouch-propose-from-pr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
description: Distill a merged PR into vouch claim proposals
---

# /vouch-propose-from-pr

A PR is a decision: someone proposed a change, the team accepted it. The
"why" gets compressed into the merge message and forgotten. This command
preserves the why as cited claims in the KB.

Steps:

1. Parse `$ARGUMENTS` as a PR URL or `<owner>/<repo>#<num>`; default to the
most-recently-merged PR you authored.
2. Fetch the PR title, body, and the merged-commit SHA via `gh`.
3. Register the merge commit as a `kb_register_source` so subsequent claims
can cite it.
4. Read the diff. For each *behavioural* change (not formatting / renaming),
draft one `kb_propose_claim` whose text summarises the new invariant the
code now upholds, citing the source from step 3.
5. Propose at most five claims per PR. If a PR is that big, suggest the
contributor split it next time.

Do not auto-approve. The KB's review gate is intentional; this command
only fills the queue.
20 changes: 20 additions & 0 deletions .claude/commands/vouch-recall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
description: Recall what the project's vouch KB knows about a topic
---

# /vouch-recall

Use vouch's `kb_context` MCP tool to assemble a working set of claims, sources,
and entities the KB already has on the current topic. Print them with their
ids and citations; do not write anything.

Steps:

1. Call `kb_context` with `query: "$ARGUMENTS"`.
2. List every returned claim by id + one-line text; for each, show the
source ids it cites.
3. End with a one-sentence summary of what's *missing* from the KB on this
topic — the gap the user can fill with `/vouch-propose-from-pr` or
`kb_propose_claim`.

Be terse. The KB is meant to remove ambiguity, not pad it.
27 changes: 27 additions & 0 deletions .claude/commands/vouch-resolve-issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
description: Use vouch's KB to ground a fix for a GitHub issue
---

# /vouch-resolve-issue

Wire vouch's `kb_context` into an issue-resolution flow: the KB should
inform the fix, and the act of solving should propose new claims that
make the next contributor faster.

Steps:

1. Parse `$ARGUMENTS` as a GitHub issue URL or `<owner>/<repo>#<num>` shorthand.
If neither, ask for clarification.
2. `kb_context` with the issue title + body — what does the KB already know
about this area? Show the top 5 claims.
3. Read the relevant code paths.
4. Propose the smallest fix (run the project's tests first to confirm the
bug reproduces).
5. After the fix is committed, propose **at most three** new claims via
`kb_propose_claim` that capture:
* the root cause in one sentence (cited by the offending file:line),
* the chosen fix pattern (cited by the patch commit), and
* any policy/precedent established (only if novel).

Do not auto-approve. Leave the proposals in `.vouch/proposed/` for the
maintainer to review with `vouch approve` after the PR merges.
23 changes: 23 additions & 0 deletions .claude/commands/vouch-status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
description: Show the project's vouch KB at a glance
---

# /vouch-status

Run vouch's `kb_status` MCP tool and surface the result. Use this when the
user asks "what's in our KB?" or before/after a long claim-proposal flow so
they can see the proposal count tick up.

Format:

```
KB at <root>
claims: <n>
sources: <n>
entities: <n>
pending: <n> ← review queue depth
last audit: <iso8601 timestamp>
```

If `pending > 0`, suggest the user run `vouch approve <id>` (or `vouch lint`
if they want to inspect anything first). Do not propose anything yourself.
60 changes: 60 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"permissions": {
"allow": [
"mcp__vouch__kb_status",
"mcp__vouch__kb_capabilities",
"mcp__vouch__kb_search",
"mcp__vouch__kb_context",
"mcp__vouch__kb_read_claim",
"mcp__vouch__kb_read_source",
"mcp__vouch__kb_read_page",
"mcp__vouch__kb_read_entity",
"mcp__vouch__kb_read_relation",
"mcp__vouch__kb_list_claims",
"mcp__vouch__kb_list_sources",
"mcp__vouch__kb_list_pages",
"mcp__vouch__kb_list_entities",
"mcp__vouch__kb_list_relations",
"mcp__vouch__kb_list_pending"
]
},
"hooks": {
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "vouch status --json || true"
},
{
"type": "command",
"command": "vouch capture banner || true"
}
]
}
],
"PostToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "vouch capture observe || true"
}
]
}
],
"SessionEnd": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "vouch capture finalize || true"
}
]
}
]
}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ __pycache__/
.ruff_cache/
.coverage
htmlcov/
bench.json
.benchmarks/
dist/
build/
*.swp
Expand Down
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,38 @@ All notable changes to vouch are documented here. Format follows
committed SVGs stay reproducible (#286).

### Added
- auto-capture: claude code sessions are harvested via hooks and filed as a
single pending session-summary proposal for human approval. a `PostToolUse`
hook (`vouch capture observe`) appends compact tool-use observations to an
ephemeral, gitignored `.vouch/captures/<session>.jsonl` buffer; a
`SessionEnd` hook (`vouch capture finalize`) rolls the buffer plus a git-diff
backstop into one `session` page proposal — mechanical, no llm, and never
auto-approved. a `SessionStart` banner (`vouch capture banner`) nudges the
next session when captured summaries await review. opt out with
`capture.enabled: false` in `.vouch/config.yaml`.
- session-start recall: a `SessionStart` hook (`vouch recall`) injects a digest
of every live approved claim (`[id] text`) plus approved page titles into a
new claude session's context, so it starts aware of the reviewed KB. only
approved knowledge is emitted; archived / superseded / redacted claims are
excluded; size-guarded by `recall.max_chars` with an explicit truncation
notice. opt out with `recall.enabled: false`.
- `vouch install-mcp claude-code` now merges its hooks and read-only permission
allowlist into an existing `.claude/settings.json` (a `json_merge` install
strategy) instead of skipping it, so the capture / recall hooks land on
projects that already have a settings file. idempotent; user entries are
preserved.
- GitHub PR auto-labeling: a pull-request metadata-only labeler workflow now
applies vouch surface labels from `.github/labeler.yml`, keeps those labels
in sync as files change, and adds OpenClaw-style `size: XS` through
`size: XL` labels based on non-doc changed lines. Maintainers can also run
it manually to backfill labels on already-open PRs.
- `vouch detect-themes` — cross-session pattern detection via deterministic
entity co-occurrence scoring. `kb.detect_themes` is read-only (returns
ranked clusters); `kb.propose_theme` routes synthesis pages through the
review gate so they appear in `kb.list_pending`. Supports `--propose` for
one-shot propose-all and `--json` for machine-readable output. Configurable
via `themes.min_sessions`, `themes.min_claims`, `themes.top_k`, and
`themes.enabled` in `config.yaml` (#311).
- `vouch dual-solve <issue-url>` — run claude + codex on one github issue in
isolated git worktrees, compare the two diffs, keep the branch you pick, and
propose the chosen solution's rationale into the KB. A sibling tool to
Expand Down Expand Up @@ -96,6 +123,12 @@ All notable changes to vouch are documented here. Format follows
KB under `eval/fixture-kb/`, and an `eval` workflow gating retrieval changes
(#226).
### Fixed
- `vouch pending` (and every bulk `list_*` path) no longer crashes when a
single artifact file is unreadable — a corrupt or mojibake yaml is skipped
with a warning instead of aborting the whole listing.
- all text-mode file i/o under `src/vouch/` now pins `encoding="utf-8"`, so a
non-utf-8 locale (e.g. latin-1) can no longer mangle non-ascii claim text
into raw control bytes that the yaml loader rejects, nor crash on write.
- `parse_since` (the `--since` parser behind `vouch metrics`/`vouch audit`) now raises a clean `MetricsError` for a duration too large to represent (e.g. `--since 1000000000000d`), instead of letting an uncaught `OverflowError` traceback escape — restoring the documented "clean error, not a traceback" contract.
- `sync_apply` now loads the sync source exactly once and passes the same `_SyncSource` instance into `sync_check`, closing a TOCTOU window where a bundle replaced on disk between the two `_load_source` calls could cause the validation and write phases to operate on different snapshots. Also eliminates redundant directory walks (KB sources) and triple tarball opens (bundle sources). Fixes #217.
- `vault_to_kb` now passes `slug_hint=page_id` to `propose_page` so vault edit proposals target the existing page id from frontmatter instead of a slugified copy of the title (fixes #219).
Expand Down
11 changes: 9 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,15 @@ Four registration sites — `test_capabilities` will fail if you miss one:
Plus a test under `tests/test_<feature>.py`.

If the method *reads* the KB, consider whether it should attach the
`_meta.vouch_hot_memory` sidebar from `src/vouch/hot_memory.py`. The
sidebar is added per-tool — there's no global decorator.
`_meta.vouch_salience` sidebar (built in `src/vouch/salience.py`,
attached inline by `kb_context` — see `kb_context` in
`src/vouch/server.py`). It's added per-tool — there's no global
decorator. Don't confuse it with `_meta.vouch_hot_memory`, which is
written only by the OpenClaw context engine's `assemble()`
(`src/vouch/openclaw/context_engine.py`); `src/vouch/hot_memory.py` is
the in-process session registry that *feeds* salience, not a response
field. (`_meta.vouch_trust` is separate again — stamped on every
dict-shaped result by a global wrapper, not per-tool.)

## Release flow

Expand Down
22 changes: 19 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: help install dev test test-cov lint format type check build clean examples-screenshots
.PHONY: help install dev test test-cov bench lint format type check build clean examples-screenshots smoke-capture smoke-recall

PY ?= python
PIP ?= $(PY) -m pip
Expand All @@ -9,13 +9,16 @@ help:
@echo " make install editable install with dev extras"
@echo " make test run pytest"
@echo " make test-cov run pytest with coverage"
@echo " make bench run the performance benchmark suite (needs pytest-benchmark)"
@echo " make lint ruff check"
@echo " make format ruff format (writes)"
@echo " make type mypy"
@echo " make check lint + type + test"
@echo " make build build sdist + wheel"
@echo " make clean remove caches, build artifacts, *.egg-info"
@echo " make examples-screenshots re-render docs/img/examples/*.svg"
@echo " make smoke-capture end-to-end check of session auto-capture"
@echo " make smoke-recall end-to-end check of session-start recall"

install:
$(PIP) install -e '.[dev]'
Expand All @@ -39,15 +42,28 @@ type:

check: lint type test

# the bench_*.py filenames don't match pytest's default python_files glob,
# so the override is required or zero benchmarks are collected.
bench:
$(PY) -m pytest benchmarks/ --benchmark-only \
-o python_files='bench_*.py test_*.py' \
--benchmark-json=bench.json

examples-screenshots:
$(PY) docs/img/examples/render.py

smoke-capture:
VOUCH="$(PY) -m vouch" bash scripts/smoke-capture.sh

smoke-recall:
VOUCH="$(PY) -m vouch" bash scripts/smoke-recall.sh

build:
$(PY) -m pip install --upgrade build
$(PY) -m build

clean:
rm -rf build dist *.egg-info src/*.egg-info \
.pytest_cache .ruff_cache .mypy_cache \
coverage.xml .coverage htmlcov
.pytest_cache .ruff_cache .mypy_cache .benchmarks \
coverage.xml .coverage htmlcov bench.json
find . -type d -name __pycache__ -prune -exec rm -rf {} +
Loading
Loading