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

## [Unreleased]

### Added
- 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
page. operator-declared kinds always win; the merge is additive and
idempotent. see `docs/company-brain.md`.
- `vouch init --template <name>` dispatches the onboarding template registry
(starter stays the default; templates layer on top of it).
- frontmatter filters on `kb.list_pages` across mcp/jsonl/cli: kind equality,
field equality, and inclusive ordered bounds (numbers, iso dates), plus the
`vouch pages` human mirror. a viewport over `store.list_pages()`, not a
query language.
- `kb.digest` / `vouch digest`: read-only reviewer briefing — pending
proposals oldest-first, recent decisions, stale claims, followups due, and
citation coverage. `--format text|json|markdown`; writes nothing, so it is
safe to run from cron.
- five company-brain slash commands in the claude-code adapter (mirrored to
the plugin skills list): `/vouch-ask`, `/vouch-remember`, `/vouch-record`,
`/vouch-followup`, `/vouch-standup`. every flow terminates at
`kb_propose_*` — none may call `kb_approve`.
- `vouch source fetch <url>`: snapshot a url's exact bytes as a
content-addressed source so claims cite immutable evidence. conservative
intake: http/https only, redirects re-validated, private-network hosts
refused, 2 mib cap, `fetched_at` recorded in source metadata.
- `vouch inbox --dir <path> [--watch]`: dropped `.md`/`.txt` files become a
registered source plus one pending page proposal each — mechanical, no
model in the loop, never approves. content-hash seen-state makes re-runs
idempotent; bounded stdlib poll, no daemon.
- `vouch notify sweep|test`: config-declared reviewer webhooks
(`proposal.created`, `queue.backlogged`, `proposal.aged`) with optional
hmac-signed envelopes and `env:` secret refs. read-and-notify only;
best-effort delivery; idempotent per (event, proposal).
- protected page kinds: `page_kinds.<kind>.protected: true` exempts a kind
from the `trusted-agent` self-approval opt-out — its pages always need a
reviewer other than the proposer. the template marks `voice` and
`decision-record` protected.
- string-typed frontmatter schema fields now accept yaml's native
date/datetime scalars, fixing approve-time re-validation of pages whose
frontmatter round-tripped through disk (e.g. `due_at: 2026-07-01`).

## [1.1.0] — 2026-07-03

### Added
Expand Down
24 changes: 24 additions & 0 deletions adapters/claude-code/.claude/commands/vouch-ask.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
description: Answer a question from the vouch KB with citations, or say what's missing
---

# /vouch-ask

Answer "$ARGUMENTS" using only reviewed knowledge from the vouch KB. Every
statement in the answer must carry a `[claim-id]` or `[source-id]` citation.

Steps:

1. Call `kb_search` with `query: "$ARGUMENTS"`, then `kb_context` on the same
query to assemble the working set.
2. If the results answer the question, write the answer citing every claim id
you relied on. Use `kb_read_page` for typed record detail (contacts,
project records, followups).
3. If the KB cannot support an answer, say so plainly and list the closest
claims found. Do not fill gaps from your own knowledge — an uncited answer
is worse than no answer.
4. Only when the user explicitly asks about in-flight knowledge, list
`kb_list_pending` items — each labeled `UNREVIEWED` — after the cited
answer, never mixed into it.

Never call `kb_approve`. Never restate pending proposals as facts.
24 changes: 24 additions & 0 deletions adapters/claude-code/.claude/commands/vouch-followup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
description: Propose a dated followup the vouch digest will surface until closed
---

# /vouch-followup

File "$ARGUMENTS" as a `followup` page proposal — a commitment with a due
date that `vouch digest` lists until it's closed. Requires the company-brain
page kinds (`vouch init --template company-brain`).

Steps:

1. Extract what's owed, by whom, and when. If no due date is stated, ask —
an undated followup never surfaces.
2. Call `kb_propose_page` with `page_type: "followup"`, a short imperative
title, and `metadata`: `due_at` (ISO date), `followup_status: "open"`,
`owner` when known. Put context in the body; cite a source id if the
commitment came from a registered conversation or document.
3. To close or move one later: re-propose the same page (`slug_hint: <page
id>`) with `followup_status: "done"` (or a new `due_at`) — status changes
go through the gate like any other edit.
4. Report the proposal id and the due date filed.

Never call `kb_approve`.
27 changes: 27 additions & 0 deletions adapters/claude-code/.claude/commands/vouch-record.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
description: Propose a typed record (contact, org, project) into the vouch KB
---

# /vouch-record

File "$ARGUMENTS" as a typed record: an entity plus a kind-validated page,
both as pending proposals. Requires the company-brain page kinds
(`vouch init --template company-brain`; check with `vouch schema list`).

Steps:

1. Decide the record shape: person -> entity type `person` + `contact` page
(frontmatter: `role`, optional `org`, `email`); organisation -> `company`
entity + `org` page; project -> `project` entity + `project-record` page
(frontmatter: `record_status`, optional `owner`).
2. Call `kb_search` first — if the entity already exists, propose only the
page update (pass the existing page id as `slug_hint`) instead of a
duplicate.
3. Call `kb_propose_entity`, then `kb_propose_page` with `page_type` set to
the record kind and the frontmatter in `metadata`. Cite a registered
source when the record distills one (register the conversation via
`kb_register_source` if the user is dictating facts).
4. Link ownership or membership with `kb_propose_relation` where it's clear.
5. Report every proposal id filed.

Never call `kb_approve`. One record per invocation; ask before batching.
22 changes: 22 additions & 0 deletions adapters/claude-code/.claude/commands/vouch-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
description: File something the user wants remembered as a cited, review-gated proposal
---

# /vouch-remember

Turn "$ARGUMENTS" into durable KB knowledge — proposed, never self-approved.

Steps:

1. Call `kb_register_source` with the user's exact wording as `content`
(`source_type: "message"`, a short descriptive `title`). Sources are
evidence intake; registering one writes no knowledge.
2. Distill the durable fact(s) into one `kb_propose_claim` each, citing the
registered source id in `evidence`. Keep each claim one sentence,
present tense, self-contained.
3. If the fact is about a person, org, or project the KB doesn't know yet,
also file `kb_propose_entity` (and `kb_propose_relation` to link it).
4. Report the proposal id(s) and remind the user: pending items are invisible
to retrieval until a human runs `vouch approve <id>` or `vouch review`.

Never call `kb_approve` — the human at the gate decides what the KB believes.
22 changes: 22 additions & 0 deletions adapters/claude-code/.claude/commands/vouch-standup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
description: Narrate the vouch digest — pending reviews, decisions, stale claims, due followups
---

# /vouch-standup

Give the user a morning briefing from the KB, then get out of the way.

Steps:

1. Call the `kb_digest` MCP tool (or run `vouch digest --format markdown`
via Bash if MCP is unavailable). Default window is fine unless the user
names one.
2. Narrate it in four short lines, leading with counts: pending proposals
(oldest first — nudge `vouch review` if any), decisions since the window
start, stale claims worth a `kb_confirm` or supersede, and followups due
(with owners).
3. If a followup in the list is done, offer to file the close — a
`kb_propose_page` with the page's id as `slug_hint` and
`followup_status: "done"` — but only on explicit confirmation.

Read-only otherwise. Never call `kb_approve`; reviewing is the human's job.
11 changes: 9 additions & 2 deletions adapters/claude-code/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
#
# T1 = MCP wire (project-local `.mcp.json` picked up by `claude` on launch).
# T2 = CLAUDE.md fenced snippet (idempotent append, see install_adapter._install_fenced).
# T3 = four custom slash commands (`/vouch-recall`, `/vouch-status`,
# `/vouch-resolve-issue`, `/vouch-propose-from-pr`).
# T3 = custom slash commands (`/vouch-recall`, `/vouch-status`,
# `/vouch-resolve-issue`, `/vouch-propose-from-pr`, plus the
# company-brain set: `/vouch-ask`, `/vouch-remember`, `/vouch-record`,
# `/vouch-followup`, `/vouch-standup`).
# T4 = `.claude/settings.json`: SessionStart (kb status + capture review banner +
# recall digest of approved knowledge), PostToolUse (capture observe),
# SessionEnd (capture finalize), plus read-only kb_* auto-allow.
Expand All @@ -22,5 +24,10 @@ tiers:
- { src: .claude/commands/vouch-status.md, dst: .claude/commands/vouch-status.md }
- { src: .claude/commands/vouch-resolve-issue.md, dst: .claude/commands/vouch-resolve-issue.md }
- { src: .claude/commands/vouch-propose-from-pr.md, dst: .claude/commands/vouch-propose-from-pr.md }
- { src: .claude/commands/vouch-ask.md, dst: .claude/commands/vouch-ask.md }
- { src: .claude/commands/vouch-remember.md, dst: .claude/commands/vouch-remember.md }
- { src: .claude/commands/vouch-record.md, dst: .claude/commands/vouch-record.md }
- { src: .claude/commands/vouch-followup.md, dst: .claude/commands/vouch-followup.md }
- { src: .claude/commands/vouch-standup.md, dst: .claude/commands/vouch-standup.md }
T4:
- { src: .claude/settings.json, dst: .claude/settings.json, json_merge: true }
25 changes: 25 additions & 0 deletions adapters/openclaw/skills/vouch-ask/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: vouch-ask
description: Answer a question from the vouch KB with citations, or say what's missing
---

# /vouch-ask

Answer "$ARGUMENTS" using only reviewed knowledge from the vouch KB. Every
statement in the answer must carry a `[claim-id]` or `[source-id]` citation.

Steps:

1. Call `kb_search` with `query: "$ARGUMENTS"`, then `kb_context` on the same
query to assemble the working set.
2. If the results answer the question, write the answer citing every claim id
you relied on. Use `kb_read_page` for typed record detail (contacts,
project records, followups).
3. If the KB cannot support an answer, say so plainly and list the closest
claims found. Do not fill gaps from your own knowledge — an uncited answer
is worse than no answer.
4. Only when the user explicitly asks about in-flight knowledge, list
`kb_list_pending` items — each labeled `UNREVIEWED` — after the cited
answer, never mixed into it.

Never call `kb_approve`. Never restate pending proposals as facts.
25 changes: 25 additions & 0 deletions adapters/openclaw/skills/vouch-followup/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: vouch-followup
description: Propose a dated followup the vouch digest will surface until closed
---

# /vouch-followup

File "$ARGUMENTS" as a `followup` page proposal — a commitment with a due
date that `vouch digest` lists until it's closed. Requires the company-brain
page kinds (`vouch init --template company-brain`).

Steps:

1. Extract what's owed, by whom, and when. If no due date is stated, ask —
an undated followup never surfaces.
2. Call `kb_propose_page` with `page_type: "followup"`, a short imperative
title, and `metadata`: `due_at` (ISO date), `followup_status: "open"`,
`owner` when known. Put context in the body; cite a source id if the
commitment came from a registered conversation or document.
3. To close or move one later: re-propose the same page (`slug_hint: <page
id>`) with `followup_status: "done"` (or a new `due_at`) — status changes
go through the gate like any other edit.
4. Report the proposal id and the due date filed.

Never call `kb_approve`.
28 changes: 28 additions & 0 deletions adapters/openclaw/skills/vouch-record/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: vouch-record
description: Propose a typed record (contact, org, project) into the vouch KB
---

# /vouch-record

File "$ARGUMENTS" as a typed record: an entity plus a kind-validated page,
both as pending proposals. Requires the company-brain page kinds
(`vouch init --template company-brain`; check with `vouch schema list`).

Steps:

1. Decide the record shape: person -> entity type `person` + `contact` page
(frontmatter: `role`, optional `org`, `email`); organisation -> `company`
entity + `org` page; project -> `project` entity + `project-record` page
(frontmatter: `record_status`, optional `owner`).
2. Call `kb_search` first — if the entity already exists, propose only the
page update (pass the existing page id as `slug_hint`) instead of a
duplicate.
3. Call `kb_propose_entity`, then `kb_propose_page` with `page_type` set to
the record kind and the frontmatter in `metadata`. Cite a registered
source when the record distills one (register the conversation via
`kb_register_source` if the user is dictating facts).
4. Link ownership or membership with `kb_propose_relation` where it's clear.
5. Report every proposal id filed.

Never call `kb_approve`. One record per invocation; ask before batching.
23 changes: 23 additions & 0 deletions adapters/openclaw/skills/vouch-remember/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: vouch-remember
description: File something the user wants remembered as a cited, review-gated proposal
---

# /vouch-remember

Turn "$ARGUMENTS" into durable KB knowledge — proposed, never self-approved.

Steps:

1. Call `kb_register_source` with the user's exact wording as `content`
(`source_type: "message"`, a short descriptive `title`). Sources are
evidence intake; registering one writes no knowledge.
2. Distill the durable fact(s) into one `kb_propose_claim` each, citing the
registered source id in `evidence`. Keep each claim one sentence,
present tense, self-contained.
3. If the fact is about a person, org, or project the KB doesn't know yet,
also file `kb_propose_entity` (and `kb_propose_relation` to link it).
4. Report the proposal id(s) and remind the user: pending items are invisible
to retrieval until a human runs `vouch approve <id>` or `vouch review`.

Never call `kb_approve` — the human at the gate decides what the KB believes.
23 changes: 23 additions & 0 deletions adapters/openclaw/skills/vouch-standup/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: vouch-standup
description: Narrate the vouch digest — pending reviews, decisions, stale claims, due followups
---

# /vouch-standup

Give the user a morning briefing from the KB, then get out of the way.

Steps:

1. Call the `kb_digest` MCP tool (or run `vouch digest --format markdown`
via Bash if MCP is unavailable). Default window is fine unless the user
names one.
2. Narrate it in four short lines, leading with counts: pending proposals
(oldest first — nudge `vouch review` if any), decisions since the window
start, stale claims worth a `kb_confirm` or supersede, and followups due
(with owners).
3. If a followup in the list is done, offer to file the close — a
`kb_propose_page` with the page's id as `slug_hint` and
`followup_status: "done"` — but only on explicit confirmation.

Read-only otherwise. Never call `kb_approve`; reviewing is the human's job.
Loading
Loading