Skip to content

feat(digest): vouch digest — read-only operator briefing (#324)#351

Open
dhgoal wants to merge 1 commit into
vouchdev:testfrom
dhgoal:feat/digest
Open

feat(digest): vouch digest — read-only operator briefing (#324)#351
dhgoal wants to merge 1 commit into
vouchdev:testfrom
dhgoal:feat/digest

Conversation

@dhgoal

@dhgoal dhgoal commented Jul 3, 2026

Copy link
Copy Markdown

closes #324.

vouch metrics answers "is the review gate healthy?" with aggregate gauges. vouch digest is its human-facing counterpart: named, oldest-first lists of what to act on now, folded into one glance for an operator returning to a kb after a day or a week.

it composes four viewports over an existing .vouch/, all derived from files that already exist on disk:

  • pending reviewstore.list_proposals(PENDING), oldest proposed_at first (the same set behind kb.list_pending), shown as an actionable list rather than the count metrics.pending_now gives.
  • decided in window — approvals/rejections read from the authoritative append-only audit.log.jsonl via audit.read_events, reusing the _APPROVE_RE / _REJECT_RE matching in metrics.py and titled best-effort from the decided/ record.
  • stale claims — active claims whose freshness anchor (last_confirmed_at or updated_at or created_at) is older than --stale-days, the exact predicate in metrics._fill_corpus_metrics / vouch lint, listed oldest first.
  • citation-coverage movementnow is reused verbatim from metrics.compute so the digest never disagrees with vouch metrics; at window start is that same coverage restricted to the cohort of claims that already existed at the --since cutoff (evaluated against the current source/evidence set — it shows how coverage moved as newer claims landed, not a historical snapshot, since vouch retains no past citation state). unbounded window → no baseline → delta is null.

review gate & scope

read-only by construction. it calls list_* / read_events and formats; it never routes through propose_* / approve / reject, so the review gate is untouched and there is nothing to approve. no new on-disk state, no schema migration — storage.py stays pure i/o and the compose logic lives in a new src/vouch/digest.py. tests/test_digest.py::test_digest_writes_nothing snapshots every file's mtime+size and asserts a digest run creates/modifies nothing.

surface

vouch digest [--since <spec>] [--stale-days N] [--limit N] [--format text|json|markdown]

--since reuses metrics.parse_since verbatim (duration / iso date / all) but defaults to 7d since a digest is inherently "since last look". --stale-days mirrors metrics.DEFAULT_STALE_DAYS. --limit caps each list (default 10) so the briefing stays a briefing. --format json is a documented, stable to_dict() schema; markdown is pasteable into a standup note.

shipped cli-only on purpose — the issue makes kb.digest conditional ("if exposed over mcp…"), and the four-site registration is a separate concern; keeping this pr to one concern per CONTRIBUTING. compute_digest() + Digest.to_dict() are already factored so a follow-up can wire the mcp method with no rework.

what breaks for an existing .vouch/

nothing. purely additive; a new read-only command over files that are already committed.

tests

tests/test_digest.py (15 tests): oldest-first pending ordering, --limit capping while total stays full, decision window-filtering (a 100d-old approval excluded from a 7d window) and all-history, the stale predicate (retired claims exempt), the coverage delta (null when unbounded; movement when a new uncited claim lands after the cutoff), empty-kb rendering, the stable to_dict() schema, bad-input errors, and the cli text/json/markdown paths. make check green (pytest, mypy, ruff).

fold four viewports over an existing .vouch/ into one glance so an
operator returning after a day or a week sees where to spend attention
before opening the review queue:

- pending proposals awaiting review, oldest proposed_at first (the same
  set as kb.list_pending, rendered as an actionable list)
- approvals/rejections in a --since window, read from the authoritative
  audit.log.jsonl and titled from the decided/ record
- active claims aged past --stale-days (the exact metrics/lint predicate)
- citation-coverage movement over the window

read-only by construction: it composes metrics.compute and store reads
and never routes through propose_*/approve/reject, so the review gate is
untouched and there is nothing to approve. no new on-disk state, no
schema migration.

--format text|json|markdown; the json shape is a documented, stable
to_dict() schema. defaults to a 7d window since a digest is inherently
"since last look". ships cli-only; a kb.digest mcp method is deferred to
keep this one concern per pr.
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e200702-cef6-435a-8220-088ee5e9494c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added docs documentation, specs, examples, and repo guidance cli command line interface tests tests and fixtures size: L 500-999 changed non-doc lines labels Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli command line interface docs documentation, specs, examples, and repo guidance size: L 500-999 changed non-doc lines tests tests and fixtures

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant