Skip to content

feat: add vouch migrate for safe on-disk KB upgrades#108

Merged
plind-junior merged 1 commit into
vouchdev:testfrom
jsdevninja:feat/vouch-migrate
Jun 3, 2026
Merged

feat: add vouch migrate for safe on-disk KB upgrades#108
plind-junior merged 1 commit into
vouchdev:testfrom
jsdevninja:feat/vouch-migrate

Conversation

@jsdevninja

@jsdevninja jsdevninja commented May 26, 2026

Copy link
Copy Markdown
Contributor

What changed

Adds vouch migrate and a small on-disk migration framework: version detection in config.yaml, --check / --dry-run / apply flows, a legacy 0 → 1 step, audit logging on successful apply, and index rebuild after migration. Rebased onto latest test so the change is a single commit on current test (no duplicate batch-approve / expire / template work).

Why

As .vouch/ evolves pre-1.0, users need a supported way to upgrade existing KBs without hand-editing files or losing audit history. This lays the groundwork for future format changes (roadmap: vouch migrate before 1.0). The only step today is 0 → 1 (unversioned / legacy KBs → stamped format version 1); a real 1 → 2 migration can land in a follow-up when there is an actual breaking layout change.

Closes #107

What might break

Additive for users who do nothing: existing version-1 KBs are unchanged.

If someone runs vouch migrate on a legacy/unversioned KB, it may:

  • set config.yaml version: 1
  • create missing expected subdirectories
  • extend .gitignore with proposed/, state.db, state.db-*
  • rebuild state.db
  • append a kb.migrate audit event

No durable artifact schema changes, no file moves, and no kb.* method behavior changes.

VEP

Touches on-disk layout compatibility (KB_FORMAT_VERSION, migration story). Likely needs maintainer sign-off or a VEP before merge; happy to pair with the first real 1 → 2 format change if preferred.

Tests

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

Note for reviewers

Rebased onto test after overlapping PRs landed. This PR is intentionally scoped to the migrate framework + 0 → 1 stamping; feedback welcome on keeping it open until a concrete 1 → 2 migration exists.

@jsdevninja jsdevninja changed the base branch from main to test May 26, 2026 12:58
@coderabbitai

coderabbitai Bot commented May 26, 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: 7419e6d2-1e62-44b4-80b1-7e1e52962a5f

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 introduces six new CLI commands and supporting infrastructure to enhance KB lifecycle management: vouch migrate for on-disk format versioning, vouch sync-check and vouch sync-apply for deterministic team KB reconciliation, vouch diff for artifact comparison, vouch review for interactive proposal approval, and vouch pending --json for structured output. New modules handle migrations, sync, and diffing; comprehensive tests validate all workflows.

Changes

KB Lifecycle, Transport, and Inspection

Layer / File(s) Summary
KB version constant and storage improvements
src/vouch/storage.py
Adds KB_FORMAT_VERSION constant, normalizes CRLF to LF in page deserialization, and strengthens read_under_root() file-open path safety with conditional O_NOFOLLOW flags and explicit directory rejection.
Migration system structures and planning
src/vouch/migrations.py
Defines MigrationError, MigrationStep, MigrationPlan, and MigrationResult dataclasses; implements config read/write and version detection; and adds build_plan() logic to construct forward-only migration paths with validation.
Migration execution and v0→v1 step with tests
src/vouch/migrations.py, tests/test_migrations.py
Implements the concrete 0→v1 migration step (KB subdirectory creation, config initialization, .gitignore management), registers it, and validates behavior via tests covering current KBs, version detection, dry-run, legacy upgrades, and rejection of newer-than-supported versions.
Artifact diff computation and testing
src/vouch/diff.py, tests/test_diff.py
Implements read-only field-level and line-diff comparison between claim/page revisions: defines DiffError, FieldChange, and ArtifactDiff structures; auto-detects artifact kind; normalizes Enum values; generates unified line diffs; and validates all code paths and CLI output modes (text and JSON).
Deterministic sync system with testing
src/vouch/sync.py, tests/test_sync.py
Implements conservative bidirectional sync using IncomingFile, SyncConflict, and SyncCheckResult models; loads sources from directory-backed KBs or .tar.gz bundles; detects and classifies conflicts; executes sync_check for comparison and sync_apply with fail/skip/propose policies; writes JSON conflict reports; and validates artifact propagation, config exclusion, and all conflict modes.
CLI command wiring: migrate, pending --json, review, sync, and diff
src/vouch/cli.py, tests/test_cli.py
Adds six new/updated CLI commands with comprehensive option handling: migrate (--check/--dry-run/--to-version/--json) that rebuilds index and logs audit events; pending --json for structured queue output; review (--limit/--type/--dry-run) with interactive approve/reject/skip/quit flow; sync-check and sync-apply for KB reconciliation; and diff for revision comparison. Includes migration exception translation and comprehensive test coverage for all workflows.
Documentation: CHANGELOG, README, design specs, and guides
CHANGELOG.md, README.md, docs/multi-agent.md, docs/superpowers/specs/2026-05-25-vouch-diff-design.md
Updates release notes and CLI documentation to advertise new commands with their flags; documents deterministic distributed-sync workflow; removes prior claim that distributed sync is unsupported; and includes formal design specification for vouch diff detailing kind resolution, field selection, error handling, and expected JSON output.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI
  participant MigrationMod as migrations
  participant Store as KBStore
  User->>CLI: vouch migrate --check
  CLI->>MigrationMod: detect_version, build_plan
  MigrationMod->>Store: read config.yaml
  MigrationMod->>MigrationMod: determine version 0→1
  MigrationMod->>CLI: return MigrationPlan with steps needed
  alt steps_needed and --check
    CLI->>User: exit 1, print "needs migration"
  else no steps needed
    CLI->>User: exit 0, print "up to date"
  end
Loading
sequenceDiagram
  participant User
  participant CLI
  participant ProposalStore as proposals
  participant Output
  User->>CLI: vouch review --limit 5
  CLI->>ProposalStore: list pending proposals
  loop for each proposal
    CLI->>Output: show preview + full YAML
    User->>CLI: approve / reject / skip / quit
    alt approve
      CLI->>ProposalStore: set status=approved
    else reject
      CLI->>ProposalStore: set status=rejected, decision_reason
    else skip
      CLI->>Output: skip to next proposal
    else quit
      CLI->>Output: stop, remaining stay pending
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

  • vouchdev/vouch#89: Overlaps with updates to vouch pending --json and new vouch diff/vouch review command behavior in the same CLI entry points and code paths.
  • vouchdev/vouch#91: Overlaps with the deterministic sync feature set—vouch sync-check/vouch sync-apply and their underlying src/vouch/sync.py implementation (conflict handling, bundle/directory source support, JSON conflict reports).
  • vouchdev/vouch#86: Overlaps with the vouch diff feature end-to-end (new src/vouch/diff.py, CLI command wiring with --json, and test coverage in tests/test_diff.py).

Poem

A rabbit hops through versioned woods,
Migrations smooth and clearly good,
Syncing claims where teams align,
Diffs reveal each change's design,
Review and approve with quiet grace—
The KB finds its resting place. 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat/vouch migrate' refers to the primary feature added in the PR (the vouch migrate command), but uses a generic format-style prefix and is somewhat vague about what 'migrate' entails.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

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

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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 and usage tips.

@jsdevninja

Copy link
Copy Markdown
Contributor Author
image

@plind-junior

Copy link
Copy Markdown
Collaborator

Thanks for putting this together — the framework itself is genuinely clean. But I think we should hold off, because right now it's a migration engine with nothing to migrate.

The only step is 0 → 1, and all it really does is create missing folders, add gitignore lines, stamp version: 1, and rebuild state.db — stuff vouch init/doctor/index already handle. There aren't two real on-disk formats yet: "1" is the only one, and "0" just means "made before this PR." So the engine doesn't have a real job to do today.

The bigger thing: adding KB_FORMAT_VERSION quietly commits us to keeping the on-disk layout stable, which we've specifically said we're not promising before 1.0. I'd love to land exactly this — but bundled with the first actual breaking layout change, so there's a real 1 → 2 migration that earns the framework.

Really nice work regardless — I just think it's a bit early and I will keep this open. 🙏

@jsdevninja jsdevninja force-pushed the feat/vouch-migrate branch from d320db5 to 5022e5e Compare May 28, 2026 05:11
@jsdevninja jsdevninja force-pushed the feat/vouch-migrate branch from 5022e5e to f3ec53f Compare June 1, 2026 14:10
@jsdevninja jsdevninja changed the title Feat/vouch migrate feat: add vouch migrate for safe on-disk KB upgrades Jun 1, 2026
@jsdevninja

jsdevninja commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author
image

Co-authored-by: Cursor <cursoragent@cursor.com>
@jsdevninja jsdevninja force-pushed the feat/vouch-migrate branch from f3ec53f to c90312c Compare June 2, 2026 16:00
@plind-junior

Copy link
Copy Markdown
Collaborator

LGTM!

@plind-junior plind-junior merged commit 6de2ac5 into vouchdev:test Jun 3, 2026
5 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jun 3, 2026
3 tasks
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.

Add vouch migrate for safe on-disk KB upgrades

2 participants