Skip to content

Feat/vouch expire stale proposals#136

Merged
plind-junior merged 1 commit into
vouchdev:testfrom
jsdevninja:feat/vouch-expire-stale-proposals
Jun 1, 2026
Merged

Feat/vouch expire stale proposals#136
plind-junior merged 1 commit into
vouchdev:testfrom
jsdevninja:feat/vouch-expire-stale-proposals

Conversation

@jsdevninja

@jsdevninja jsdevninja commented May 29, 2026

Copy link
Copy Markdown
Contributor

What changed

Adds vouch expire (dry-run by default, --apply to run GC) plus kb.expire on MCP and JSONL. Stale pending proposals (older than review.expire_pending_after_days, default 90) are moved from proposed/ to decided/ as rejected with decision_reason: expired, decided_by: vouch-expire, and a proposal.expire audit event. No durable artifacts are written. Starter config.yaml from vouch init now includes expire_pending_after_days: 90.

Why

The review-gate spec already describes STALE proposal GC and the init template documents expire_pending_after_days, but nothing enforced it — pending proposals could sit in gitignored proposed/ indefinitely. This closes that gap for multi-agent setups and periodic CI cleanup without bypassing the review gate.

Closes #135

What might break

No breaking changes for existing .vouch/ directories:

  • No file moves or schema changes to durable artifacts (claims, pages, etc.).
  • No change to kb.approve / kb.reject behavior.
  • Additive surface: new CLI command vouch expire, new kb.expire method (capabilities + JSONL handler list updated).
  • Only mutates proposed/decided/ when the operator explicitly runs vouch expire --apply (or kb.expire with apply: true).
  • KBs without expire_pending_after_days in config use the default threshold of 90 days.

VEP

Not required — additive CLI/MCP/JSONL surface; on-disk proposal/decided layout and audit event vocabulary already specified in spec/review-gate.md and spec/audit-vocabulary.md.

Tests

  • make check passes locally (lint + mypy + pytest)
  • New / changed behaviour has a test (tests/test_expire.py)
  • CHANGELOG.md updated under ## [Unreleased]

Summary by CodeRabbit

Release Notes

  • New Features

    • Batch approval via vouch approve <id> <id>... with --keep-going flag
    • Added vouch review, vouch expire, and vouch diff commands
    • Added vouch init --template for template seeding
    • Added vouch sync-check/sync-apply for KB directory synchronization
    • JSON output for lint, search, pending, expire, and diff commands
    • Configurable retrieval backend selection (auto/embedding/fts5/substring)
    • Progress reporting during long operations
  • Bug Fixes

    • Claims now require at least one citation
    • Improved error output formatting

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 29, 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: 381c8ff9-2a09-4859-ac9b-adf559e3b13b

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
📝 Walkthrough

Walkthrough

This PR implements the 0.1 surface stabilization with proposal expiration, batch approval, retrieval backend selection, KB synchronization, template-based seeding, and artifact diffing, alongside CLI improvements for output formatting and progress reporting, plus foundational claim validation enforcement and session security hardening.

Changes

Vouch 0.1 surface stabilization

Layer / File(s) Summary
Claim validation and storage hardening
src/vouch/models.py, src/vouch/storage.py, src/vouch/health.py, tests/test_storage.py, tests/test_health.py, tests/test_bundle.py
Claim.evidence enforces non-empty validation at the model level; KBStore.update_claim() re-validates before writes; health.lint() safely skips invalid YAMLs with error findings instead of crashing; file reading hardened with directory rejection and symlink protection.
Proposal expiration and lifecycle management
src/vouch/proposals.py, src/vouch/server.py, src/vouch/jsonl_server.py, src/vouch/cli.py (expire), tests/test_expire.py
New expire_pending() and expire_one() functions move stale pending proposals to decided state with audit events; respects config-driven review.expire_pending_after_days with override; vouch expire CLI supports dry-run (default), --apply, --days, and --json; MCP tool kb_expire added.
Batch approval and guided review queue
src/vouch/cli.py (approve, review), tests/test_cli.py
vouch approve accepts multiple proposal IDs with all-or-nothing or --keep-going best-effort modes; new vouch review guided queue supports approve/reject/skip/quit with --limit, --type, and --dry-run.
Retrieval backend configuration and dispatch
src/vouch/context.py, src/vouch/storage.py, tests/test_retrieval_backend.py
New retrieval.backend config option supports auto (embedding → FTS5 → substring fallback), embedding, fts5, and substring; starter config defaults to auto; legacy retrieval.backends list supported.
Artifact diffing with semantic field comparison
src/vouch/diff.py, src/vouch/cli.py (diff), tests/test_diff.py
Read-only diff_artifacts() computes field changes and line-based text diffs for claims/pages; vouch diff CLI with --json support emits field changes and unified diffs; clean error handling for unknown/mismatched IDs.
Template registry and gittensor seeding
src/vouch/onboarding.py, src/vouch/cli.py (init), tests/test_templates.py
Template registry via TEMPLATES with SeedResult dataclass; seed_gittensor_kb() idempotently seeds gittensor-sn74 project with source and seven claims; vouch init --template validates and seeds selected or default starter template.
Deterministic KB synchronization and conflict handling
src/vouch/sync.py, src/vouch/bundle.py (progress callbacks), src/vouch/cli.py (sync commands), tests/test_sync.py
sync_check() and sync_apply() enable conservative KB reconciliation with conflict detection/classification and fail/skip/propose modes; bundle and directory sources supported; excludes config.yaml from sync; index rebuilt after apply.
CLI formatting, progress reporting, and JSON output
src/vouch/cli.py (helpers, output commands), tests/test_cli_output.py
Terminal-aware colored output with NO_COLOR/FORCE_COLOR control; progress callbacks on TTY for long operations (index rebuild, export, import); JSON modes for lint/doctor/pending/search/diff/expire; clean styled error rendering.
Session crystallization security and audit improvements
src/vouch/sessions.py, tests/test_sessions.py
Summary page body restricted to server-controlled fields (excludes agent task/note/identifier); session.crystallize audit event includes summary_page_id in object_ids.
Documentation, defaults, and capabilities registration
CHANGELOG.md, README.md, ROADMAP.md, docs/PROJECT-INDEX.md, docs/multi-agent.md, docs/review-gate.md, docs/superpowers/specs/*.md, src/vouch/storage.py, src/vouch/capabilities.py
Updated CHANGELOG with feature/fix notes; README CLI examples reflect batch approval and new commands; ROADMAP documents retrieval backend shipping alongside FTS5; design specs for diff and templates; distributed sync documented; PROJECT-INDEX.md generated; kb.expire capability registered.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

  • vouchdev/vouch#82: Both PRs enforce the same Claim.evidence non-empty invariant and re-validate during updates; overlapping bundle/health/lint error handling for uncited claims.
  • vouchdev/vouch#91: Both implement deterministic sync workflow with sync_check/sync_apply CLI commands and conflict handling logic.
  • vouchdev/vouch#133: Both implement vouch init --template with template registry and gittensor seed pack.

Suggested reviewers

  • plind-junior

Poem

🐰 Whiskers twitch with feature glee,
Expire, sync, and templates three!
Batch approvals, diffs so clean,
Finest surface ever seen! 🌱✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Changes are well-scoped to proposal expiration. However, the PR includes significant enhancements beyond #135 objectives: new vouch init templates, retrieval backend selection, batch approve, sync commands, diff, review queue, and session security fixes that are not mentioned in the linked issue. Review scope creep: clarify whether all enhancements were intentional or if some should be split into separate PRs. Confirm with issue author that multi-feature consolidation aligns with project goals.
Docstring Coverage ⚠️ Warning Docstring coverage is 24.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Feat/vouch expire stale proposals' is concise and directly related to the main objective of the changeset: implementing proposal expiration functionality.
Linked Issues check ✅ Passed All coding requirements from issue #135 are met: vouch expire command with dry-run default, --apply support, --json output, config.yaml integration honoring review.expire_pending_after_days, proper audit events, and decided/ placement.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

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

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

@jsdevninja jsdevninja changed the base branch from main to test May 29, 2026 11:43
@jsdevninja

Copy link
Copy Markdown
Contributor Author
image

@plind-junior

Copy link
Copy Markdown
Collaborator

Check the comments, other than that LGTM!
Thanks for contributing core feature

@jsdevninja

Copy link
Copy Markdown
Contributor Author

Thanks — addressed.

This PR is intentionally scoped to #135 only (vouch expire / kb.expire, config threshold, audit event, and tests). The CodeRabbit “out-of-scope” summary appears to include unrelated prior work; current diff is expiration-focused. Docstring warning is noted as repo-wide and can be handled in a separate follow-up PR.

@jsdevninja

Copy link
Copy Markdown
Contributor Author

@plind-junior

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: vouch expire — garbage-collect stale pending proposals

2 participants