Skip to content

feat(diff): add vouch diff for claim/page revisions#86

Merged
plind-junior merged 3 commits into
testfrom
feat/diff-command
May 25, 2026
Merged

feat(diff): add vouch diff for claim/page revisions#86
plind-junior merged 3 commits into
testfrom
feat/diff-command

Conversation

@plind-junior

@plind-junior plind-junior commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Problem

When a claim is superseded or a page is revised, there's no way to see what
changed between the old and new artifact — you have to show both and compare
by eye. ROADMAP 0.1 lists vouch diff <id-old> <id-new> for exactly this.

What this adds

A read-only vouch diff <id-old> <id-new> that compares two claim revisions or
two page revisions:

  • Auto-detects the kind — resolves both ids as claims, else as pages;
    mismatched kinds or unknown ids raise a clean error (no --kind flag).
  • Semantic fields only — shows changed fields as field: old → new and
    hides always-churning metadata (created_at, updated_at, approved_by).
  • Line-diffs the long textclaim.text / page.body render as a
    difflib unified diff.
  • --json for machine output; no differences when nothing changed.

Example:

diff claim c1 → c2
  status: working → stable
  confidence: 0.7 → 0.9
  evidence: ['s1'] → ['s1', 's2']
  text:
    -old wording
    +new wording

New module src/vouch/diff.py (diff_artifacts, DiffError, FieldChange,
ArtifactDiff); CLI command in src/vouch/cli.py. DiffError subclasses
ValueError so the existing _cli_errors() renders it as a clean Error: line.
CLI-only — the kb.* capability surface is unchanged.

Tests

10 new tests (tests/test_diff.py), written test-first:

  • diff_artifacts: scalar field changes; text line-diff; identical → empty;
    page title/body; unknown id → DiffError; claim-vs-page → DiffError.
  • CLI: prints changed fields + text diff; --json emits a dict; identical →
    no differences; unknown id → clean Error: (no traceback).

ruff clean. Full suite green except one pre-existing, unrelated failure on
main (test_crystallize_cli_partial_failures_shows_warning).

Design spec: docs/superpowers/specs/2026-05-25-vouch-diff-design.md.

Summary by CodeRabbit

  • New Features

    • Added vouch diff <id-old> <id-new> CLI command to compare two artifact revisions side-by-side, displaying field-level changes and unified text diffs with automatic artifact-kind detection; includes --json output for programmatic access.
  • Documentation

    • Added design specification for the diff feature.
  • Tests

    • Added comprehensive test coverage for the diff functionality and CLI behavior.

Review Change Stack

read-only `vouch diff <old> <new>` that shows what changed between two
claim or two page revisions: field-level changes plus a line-diff of the
long text/body. auto-detects kind, hides churning metadata.
new read-only `vouch diff <old> <new>` compares two claims or two pages by
id and shows what changed: scalar/list fields as old → new, plus a line-diff
of the long text/body. auto-detects kind, hides churning metadata
(timestamps, approved_by), supports --json. closes a roadmap 0.1 item.
@coderabbitai

coderabbitai Bot commented May 25, 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: 0e6f7ae9-8a11-461c-98f7-812fc36a049c

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 a read-only vouch diff CLI command that compares two artifact revisions (claims or pages), detects field-level changes, generates unified line diffs for text content, supports JSON serialization, and handles errors cleanly.

Changes

vouch diff feature

Layer / File(s) Summary
Design & specification
docs/superpowers/specs/2026-05-25-vouch-diff-design.md
Feature specification defining artifact diffing behavior, implementation model, CLI output contracts, error handling, and TDD test expectations.
Core diff implementation
src/vouch/diff.py
Implements diff_artifacts function that loads artifacts by id, validates matching kind, computes field-level changes via FieldChange, generates unified line diffs for text/body content, and returns ArtifactDiff result with DiffError for error cases.
CLI command wiring
src/vouch/cli.py
New vouch diff subcommand that invokes diff_artifacts, formats results as human-readable output (changed fields, text diff lines, "no differences" message) or JSON via dataclasses.asdict.
Test coverage
tests/test_diff.py
Pytest suite validating claim/page diff field detection, text change line-diff rendering, identical artifact handling, error cases (unknown id, mismatched kind), and CLI output in human and JSON modes.
Release notes
CHANGELOG.md
Changelog entry documenting the new vouch diff <id-old> <id-new> command, field-level diffing, text diffing, auto-detection, metadata hiding, and --json support.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Two revisions compared with care,
Field changes laid bare, text diffs are fair,
A vouch diff command, so clean and precise,
JSON or human—reviewer's choice, twice as nice!
Metadata hidden, no noise in sight,
Read-only diffing done right. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% 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 pull request title clearly and concisely summarizes the main change: adding a new vouch diff CLI command for comparing claim and page revisions.
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
  • Commit unit tests in branch feat/diff-command

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

@plind-junior plind-junior changed the base branch from main to test May 25, 2026 21:27
mypy inferred old/new as Claim from the first branch, so the page branch's
reassignment tripped an incompatible-assignment error in CI. annotate the
union up front.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/superpowers/specs/2026-05-25-vouch-diff-design.md`:
- Around line 63-73: The fenced code block showing the diff (the triple-backtick
block containing "diff claim <old> → <new>" and the lines starting with status:,
confidence:, evidence:, text:, --- a, +++ b, etc.) is missing a language tag and
triggers markdownlint MD040; update the opening fence from ``` to ```text (or
another appropriate language like diff) so the block becomes ```text diff claim
<old> → <new> ... to satisfy MD040 and preserve the displayed content.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ce03b50c-fa94-403c-8915-d15bd467d0e6

📥 Commits

Reviewing files that changed from the base of the PR and between 8d70ffa and 8c45a91.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • docs/superpowers/specs/2026-05-25-vouch-diff-design.md
  • src/vouch/cli.py
  • src/vouch/diff.py
  • tests/test_diff.py

Comment on lines +63 to +73
```
diff claim <old> → <new>
status: working → stable
confidence: 0.7 → 0.9
evidence: ['s1'] → ['s1', 's2']
text:
--- a
+++ b
-old wording
+new wording
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language tag to the fenced code block.

Line 63 starts a fenced block without a language, which triggers markdownlint MD040.

🧩 Suggested fix
-```
+```text
 diff claim <old> → <new>
   status: working → stable
   confidence: 0.7 → 0.9
   evidence: ['s1'] → ['s1', 's2']
   text:
     --- a
     +++ b
     -old wording
     +new wording
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>

[warning] 63-63: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/superpowers/specs/2026-05-25-vouch-diff-design.md around lines 63 - 73,
The fenced code block showing the diff (the triple-backtick block containing
"diff claim → " and the lines starting with status:, confidence:,
evidence:, text:, --- a, +++ b, etc.) is missing a language tag and triggers
markdownlint MD040; update the opening fence from totext (or another
appropriate language like diff) so the block becomes ```text diff claim →
... to satisfy MD040 and preserve the displayed content.


</details>

<!-- fingerprinting:phantom:poseidon:hawk -->

<!-- This is an auto-generated comment by CodeRabbit -->

@plind-junior plind-junior merged commit 7d7a835 into test May 25, 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.

1 participant