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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ All notable changes to vouch are documented here. Format follows
## [Unreleased]

### Added
- `vouch compile` — the llm-wiki ingest pass: a deployment-configured LLM
(`compile.llm_cmd` in `.vouch/config.yaml`) drafts topic pages from live
approved claims; every inline `[claim: …]` marker and `[[wikilink]]` is
verified mechanically against the store, and surviving drafts are filed as
PENDING page proposals by the `wiki-compiler` actor. never approves — the
review gate is the ingest review. `--dry-run`, `--max-pages`, `--llm-cmd`,
`--json`. see `docs/compile.md`.
- review-ui: a **compile wiki** button on the queue (shown once
`compile.llm_cmd` is configured) runs the same ingest pass and lands the
drafts in the queue; success and per-draft drop counts surface as a notice.
- company-brain template: `vouch init --template company-brain` declares
typed record kinds (contact, org, project-record, meeting-notes, followup,
decision-record, voice) as `page_kinds` config and seeds a cited guide
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ 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)

**[▶ 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.

## Why this exists

Four opinionated choices distinguish vouch from the neighbours:
Expand Down
77 changes: 77 additions & 0 deletions docs/compile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# vouch compile — the llm-wiki ingest pass

`vouch compile` turns approved, cited claims into drafted **topic pages** and
files them as pending proposals. It is the "compile" in *stop re-deriving,
start compiling*: sessions and sources feed claims through the review gate;
compile distills those claims into the small, durable wiki a future agent (or
human) reads first.

```
sessions / sources claims topic pages
───────────────────▶ gate ───────────▶ compile ───────────▶ gate ──▶ wiki
(capture) (approve) (LLM drafts) (approve)
```
Comment on lines +9 to +13

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Label the ASCII diagram fence as text.

The unlabeled fence triggers markdownlint MD040. Mark it as text so the diagram stays valid markdown without lint noise.

💡 Proposed fix
-```
+```text
 sessions / sources          claims               topic pages
    ───────────────────▶ gate ───────────▶ compile ───────────▶ gate ──▶ wiki
         (capture)             (approve)      (LLM drafts)       (approve)
-```
+```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
sessions / sources claims topic pages
───────────────────▶ gate ───────────▶ compile ───────────▶ gate ──▶ wiki
(capture) (approve) (LLM drafts) (approve)
```
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 9-9: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/compile.md` around lines 9 - 13, The ASCII diagram fence in the compile
documentation is unlabeled and triggers markdownlint MD040; update the fenced
block in the diagram section to use a text language label so the diagram remains
valid markdown without lint warnings. Locate the fenced diagram near the compile
flow illustration and change the opening fence to a text-labeled fence while
keeping the diagram content unchanged.

Source: Linters/SAST tools


## Setup

Compile needs a deployment-configured LLM command in `.vouch/config.yaml`:

```yaml
compile:
llm_cmd: "claude -p --model sonnet" # reads prompt on stdin, prints JSON
max_pages: 5 # optional, default 5
timeout_seconds: 180 # optional, default 180
```

vouch ships no model dependency; any command that reads a prompt on stdin and
prints JSON on stdout works.

## Run it

```bash
vouch compile # draft pages, file as pending proposals
vouch compile --dry-run # show what would be drafted, file nothing
vouch compile --json # machine-readable report
vouch review # the human half: approve / reject each draft
```

Or click **compile wiki** in the review UI (`vouch review-ui`) — the button
appears once `compile.llm_cmd` is configured, and the drafts land in the same
queue, marked `by wiki-compiler`.

## What the validator enforces

Drafts are LLM prose, so every citation is verified mechanically before a
proposal is filed. A draft is dropped (and reported) when:

- it lists a claim id that doesn't exist or is retracted,
- its body cites `[claim: x]` for a claim it doesn't list,
- it cites no claims at all,
- a `[[wikilink]]` doesn't resolve to an existing page or a *surviving* page
in the same batch (drops cascade: if a linked sibling is dropped, the
linking draft drops too rather than shipping a dangling link),
- its title collides with an existing page or a page draft already pending
review (`approve()` would route a colliding id through `update_page` and
silently overwrite — so collisions never reach the queue; this also makes
re-running compile idempotent instead of queueing duplicates),
- its type is `session` or `log` (raw material, not topics),
- it exceeds `max_pages`.

The compiler proposes; it never approves. Proposals are filed by the
`wiki-compiler` actor (or `VOUCH_AGENT` when set), so under the default gate
the reviewing human is always a different actor and self-approval stays
impossible. Each non-dry run appends a `compile.run` audit event attributed
to whoever triggered it (CLI user, or the review-ui token label), with the
filed proposal ids.

The review UI runs one compile at a time per KB; a second click while one is
running comes back with a "already running" notice instead of stacking LLM
runs.

## Current limits

- **Creates only.** Compiled *updates* to existing pages are a future
feature; today a colliding draft is dropped at validation (see above) and
the prompt tells the compiler to skip taken topics.
- One pass over the whole KB. Compile inlines all live claims into the
prompt; very large KBs will want an incremental "since last compile" mode.
Binary file added docs/img/how-it-works-poster.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/vouch-how-it-works.mp4
Binary file not shown.
1 change: 1 addition & 0 deletions src/vouch/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"kb.provenance_rebuild",
"kb.detect_themes",
"kb.propose_theme",
"kb.compile",
]


Expand Down
41 changes: 41 additions & 0 deletions src/vouch/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from . import __version__, bundle, health, volunteer_context
from . import audit as audit_mod
from . import capture as capture_mod
from . import compile as compile_mod
from . import digest as digest_mod
from . import fetch as fetch_mod
from . import inbox as inbox_mod
Expand Down Expand Up @@ -2026,6 +2027,46 @@ def recall_cmd() -> None:
click.echo(digest)


@cli.command(name="compile")
@click.option("--dry-run", is_flag=True, help="Draft and validate; file nothing.")
@click.option("--max-pages", type=int, default=None,
help="Cap drafted pages (default: compile.max_pages, 5).")
@click.option("--llm-cmd", default=None,
help="Override compile.llm_cmd from config.yaml for this run.")
@click.option("--json", "as_json", is_flag=True, help="Machine-readable report.")
def compile_cmd(dry_run: bool, max_pages: int | None,
llm_cmd: str | None, as_json: bool) -> None:
"""Compile approved claims into topic-page proposals (llm-wiki ingest).

Runs the deployment-configured LLM (compile.llm_cmd) over the live
approved claims, validates every citation in the drafts, and files the
survivors as pending page proposals. Approval stays a separate human
step (`vouch review`).
"""
store = _load_store()
actor = os.environ.get("VOUCH_AGENT") or compile_mod.COMPILE_ACTOR
try:
report = compile_mod.compile_kb(
store, actor=actor, triggered_by=_whoami(), llm_cmd=llm_cmd,
max_pages=max_pages, dry_run=dry_run,
)
except compile_mod.CompileError as e:
raise click.ClickException(str(e)) from e
if as_json:
_emit_json(report.to_dict())
return
verb = "would propose" if dry_run else "proposed"
_echo(f"{verb} {len(report.proposed)} page draft(s):")
for row in report.proposed:
_echo(f" • {row['proposal_id']} {row['title']}")
if report.dropped:
_echo(f"dropped {len(report.dropped)}:")
for row in report.dropped:
_echo(f" • {row['title']} — {row['reason']}")
if report.proposed and not dry_run:
_echo("run `vouch review` to decide.")


@cli.command()
@click.argument("session_id")
@click.option("--no-page", is_flag=True, help="Skip the session-summary page.")
Expand Down
Loading
Loading