Skip to content

Feat/deterministic vouch sync#91

Merged
plind-junior merged 2 commits into
vouchdev:testfrom
jsdevninja:feat/deterministic-vouch-sync
May 26, 2026
Merged

Feat/deterministic vouch sync#91
plind-junior merged 2 commits into
vouchdev:testfrom
jsdevninja:feat/deterministic-vouch-sync

Conversation

@jsdevninja

@jsdevninja jsdevninja commented May 26, 2026

Copy link
Copy Markdown
Contributor

What changed

Added a CLI-only deterministic sync workflow for reconciling another .vouch directory or exported bundle. vouch sync-check reports new, identical, and conflicting files without writing, while vouch sync-apply imports only non-conflicting files and supports --on-conflict fail|skip|propose. The propose mode writes a local conflict report under proposed/sync-reports/ for human review.

Closes #90

Why

This closes the biggest gap in the distributed multi-agent story: separate agents, teammates, branches, or repos can now converge reviewed knowledge without relying only on git conflicts or manual bundle import interpretation. It keeps the review-gated model intact by refusing to silently overwrite divergent approved artifacts.

What might break

This is additive. Existing .vouch/ files do not move, and no on-disk artifact fields change shape. No kb.* methods are added or changed because the feature is CLI-only. Bundle format is unchanged.

One compatibility fix was included: page frontmatter parsing now tolerates CRLF line endings, and read_under_root no longer assumes os.O_NOFOLLOW exists on Windows.

VEP

This adds CLI surface but does not change object model, kb.* methods, on-disk layout, bundle format, or audit-log event shape beyond adding a new sync.apply event. If CLI surface changes require a VEP for this repo, this should be backed by one before merge.

Tests

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

Summary by CodeRabbit

  • New Features

    • Added CLI: vouch pending --json, vouch diff (read-only, auto-detects artifacts, --json), vouch review (interactive queue with --limit/--type/--dry-run), vouch sync-check and vouch sync-apply (configurable conflict policies and non-destructive sync)
  • Bug Fixes

    • Safer file reads and symlink protections; normalized CRLF handling in pages
  • Documentation

    • Expanded CLI docs, onboarding content, and distributed sync guidance
  • Tests

    • New/expanded tests for diff, sync, pending, and review flows

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown

Caution

Review failed

Failed to post review comments

📝 Walkthrough

Walkthrough

Adds JSON-capable proposal listing and an interactive review CLI; implements read-only artifact diffs; introduces deterministic sync-check/sync-apply for KB directories or bundles with conflict policies; hardens storage reads and normalizes page line endings; updates docs and adds tests covering these flows.

Changes

New CLI commands and core infrastructure

Layer / File(s) Summary
Design specs and docs
CHANGELOG.md, README.md, docs/superpowers/specs/2026-05-25-vouch-diff-design.md, docs/multi-agent.md
Documents CLI surfaces (pending --json, review, diff, sync-check/sync-apply), formalizes vouch diff contract and distributed sync behavior.
Artifact diff logic and tests
src/vouch/diff.py, tests/test_diff.py
Adds DiffError, FieldChange, ArtifactDiff, and diff_artifacts() to compute scalar/list changes and unified line diffs for long text; includes unit and CLI tests for claims/pages and error cases.
Deterministic sync/check and apply
src/vouch/sync.py, tests/test_sync.py
Adds IncomingFile/SyncConflict/SyncCheckResult, loads directory or bundle sources, validates members and computes deterministic source id, classifies new/identical/conflicting files, and applies non-conflicting members per on_conflict policy (`fail
Storage safety improvements
src/vouch/storage.py
Converts CRLF→LF before frontmatter parsing and hardens KBStore.read_under_root (directory rejection, conditional O_NOFOLLOW, error wrapping).
CLI wiring and review flow
src/vouch/cli.py, tests/test_cli.py
Adds pending --json, refactors review (interactive approve/reject/skip/quit, --limit, --type, --dry-run), and registers sync-check, sync-apply, and diff commands producing JSON or formatted output; tests validate pending JSON, review actions, and dry-run safety.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant diff_artifacts
  participant KBStore
  Client->>diff_artifacts: old_id, new_id
  diff_artifacts->>KBStore: resolve old_id (claim or page)
  diff_artifacts->>KBStore: resolve new_id (claim or page)
  diff_artifacts->>diff_artifacts: validate same kind
  diff_artifacts->>diff_artifacts: compute field changes (scalar/list)
  diff_artifacts->>diff_artifacts: compute unified text diff
  diff_artifacts->>Client: ArtifactDiff (changes, text_diff)
Loading
sequenceDiagram
  participant Source as Source KB/Bundle
  participant sync_check
  participant sync_apply
  participant LocalKB
  Source->>sync_check: incoming files
  sync_check->>LocalKB: compare (new/identical/conflict)
  sync_check->>sync_check: classify conflicts (semantic/decided)
  sync_check-->>Source: SyncCheckResult
  Source->>sync_apply: on_conflict policy
  sync_apply->>LocalKB: validate source issues
  alt conflict detected and on_conflict=fail
    sync_apply-->>Source: RuntimeError
  else new or identical file
    sync_apply->>LocalKB: revalidate hash and content
    sync_apply->>LocalKB: write file
  else conflicting and on_conflict=propose
    sync_apply->>LocalKB: write conflict report JSON
  end
  sync_apply->>LocalKB: audit.log_event()
  sync_apply-->>Source: operation summary
Loading
sequenceDiagram
  participant User
  participant pending_cmd
  participant review_cmd
  participant KBStore
  User->>pending_cmd: vouch pending [--json]
  pending_cmd->>KBStore: list proposals by status
  alt --json
    pending_cmd->>User: JSON array of proposals
  else text
    pending_cmd->>User: formatted proposal list
  end
  User->>review_cmd: vouch review [--limit] [--type] [--dry-run]
  review_cmd->>KBStore: fetch proposals
  loop each proposal
    review_cmd->>User: render proposal preview
    User->>review_cmd: approve/reject/skip/quit
    alt --dry-run
      review_cmd->>User: Would approve/reject
    else live
      review_cmd->>KBStore: update proposal status and claim
    end
  end
  review_cmd->>User: completion summary
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • vouchdev/vouch#55: Overlaps with onboarding/seed starter KB changes referenced in this PR.
  • vouchdev/vouch#86: Implements a similar vouch diff feature and tests, closely related to src/vouch/diff.py here.
  • vouchdev/vouch#89: Overlaps on CLI proposal JSON output (pending --json) and related tests/Changelog edits.

Poem

🐰 A rabbit hopped through docs and code,

syncing bundles down the road.
Diffs that whisper line by line,
Reviews that keep the gates in line.
Safe reads, JSON, tests — all fine.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.64% 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/deterministic vouch sync' is concise and clearly identifies the primary change: adding deterministic sync capabilities to vouch.
Linked Issues check ✅ Passed The PR implements all primary coding requirements from issue #90: vouch sync-check and vouch sync-apply commands with configurable --on-conflict handling (fail|skip|propose), deterministic sync logic distinguishing new/identical/conflicting files.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the sync feature and supporting infrastructure (diff utility, CLI enhancements, storage hardening for platform compatibility). No unrelated modifications detected.

✏️ 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 26, 2026 04:45
@jsdevninja

Copy link
Copy Markdown
Contributor Author
image

@plind-junior

Copy link
Copy Markdown
Collaborator

Really nice work — the sync logic is careful in the right ways (reuses the bundle safety checks, re-verifies hashes at write time, never overwrites conflicts), and the tests cover the main paths.

Three things before merge:

  1. This targets the test branch, not main — was that intentional? If not, please retarget to main.
  2. CHANGELOG needs an entry under ## [Unreleased] (your checklist flags this too).
  3. VEP check — it adds CLI + a new sync.apply audit event, so it likely needs a VEP. Worth confirming with a maintainer.

Minor, non-blocking: on Windows the O_NOFOLLOW fallback drops the symlink guard (low risk, just worth a comment), and you might not want config.yaml in sync at all.

Thanks for tackling the multi-agent story! 🙏

@jsdevninja jsdevninja force-pushed the feat/deterministic-vouch-sync branch from 200114d to 53d148a Compare May 26, 2026 05:07
@jsdevninja jsdevninja changed the base branch from test to main May 26, 2026 05:08
@jsdevninja

Copy link
Copy Markdown
Contributor Author

@plind-junior Done.

@plind-junior

Copy link
Copy Markdown
Collaborator

Create the PR against the test branch

@jsdevninja jsdevninja force-pushed the feat/deterministic-vouch-sync branch from 53d148a to a764129 Compare May 26, 2026 05:17
@jsdevninja jsdevninja changed the base branch from main to test May 26, 2026 05:17
@jsdevninja

Copy link
Copy Markdown
Contributor Author

@plind-junior Done

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: Add deterministic sync/merge for diverged .vouch/ directories

2 participants