UAT: plan diff shows hash-based metadata instead of actual line-level unified diff — spec requires insertions/deletions/patch preview #5459

Open
opened 2026-04-09 06:54:55 +00:00 by HAL9000 · 1 comment
Owner

Bug Report

Feature Area: git-worktree-sandbox — agents plan diff
Severity: Priority/Backlog — diff output is functional but does not match spec format

What Was Tested

Code-level analysis of agents plan diff <PLAN_ID> output against the specification's required format.

Expected Behavior (from spec)

Per the specification (lines 15340–15380), agents plan diff <PLAN_ID> should display:

Diff Summary
  Plan: 01HXM8C2ZK4Q7C2B3F2R4VYV6J
  Project: local/api-service
  Files Changed: 2
  Insertions: 12
  Deletions: 4
  Net Change: +8 lines

Files
  Path                 Change  Status
  -------------------  ------  --------
  src/auth/session.py  +8 -2   modified
  src/auth/tokens.py   +4 -2   modified

Patch Preview
  --- a/src/auth/session.py
  +++ b/src/auth/session.py
  @@ -12,4 +12,10 @@
  - import jwt
  + import sessionlib
  ...

Risk Assessment
  API Compatibility: preserved
  Test Coverage: maintained
  Breaking Changes: none detected

The spec requires:

  1. Insertions/Deletions/Net Change counts (actual line counts)
  2. Per-file change summary with +N -M line counts
  3. Patch Preview with actual unified diff content (showing added/removed lines)
  4. Risk Assessment section

Actual Behavior

The _render_diff_plain() function in src/cleveragents/application/services/plan_apply_service.py (lines 121–152) renders:

ChangeSet: <changeset_id>
Plan: <plan_id>
Total changes: 2

--- a/src/auth/session.py
+++ b/src/auth/session.py
@@ modified @@
- hash: abc123def456...
+ hash: 789xyz012abc...

The implementation:

  1. Shows SHA-256 hashes of before/after file states instead of actual line-level diffs
  2. Does not compute insertions/deletions/net change counts
  3. Does not show actual file content changes (the +/- lines)
  4. Does not include a Risk Assessment section
  5. Does not show per-file +N -M line counts

The ChangeSetEntry model stores before_hash and after_hash (SHA-256 of the whole file) but does not store the actual diff content or line counts.

Code Locations

  • Diff rendering: src/cleveragents/application/services/plan_apply_service.py, _render_diff_plain() (line 121) and _render_diff_rich() (line 155)
  • ChangeSet model: src/cleveragents/tool/builtins/changeset.py, ChangeSetEntry (line 34) — stores hashes but not diff content
  • Domain model: src/cleveragents/domain/models/core/change.pyChangeEntry model

Root Cause

The ChangeSetCapture wrapper records before/after file hashes but not the actual diff content. To produce a proper unified diff, the implementation would need to either:

  1. Store the full file content before and after each change, or
  2. Read the actual file content from the sandbox at diff time and compare it to the original

The current approach of storing only SHA-256 hashes is insufficient for generating a unified diff.

Impact

  • Users cannot see what lines were actually changed before applying
  • The diff output is not useful for code review purposes
  • The spec's "Patch Preview" section is completely absent
  • Risk Assessment is absent

Fix Required

  1. Extend ChangeSetEntry to store before/after content (or at minimum, the unified diff text)
  2. Update ChangeSetCapture.wrap_tool() to capture file content before and after each write operation
  3. Update _render_diff_plain() and _render_diff_rich() to compute and display:
    • Actual unified diff using difflib.unified_diff()
    • Insertion/deletion/net change counts
    • Per-file +N -M summary

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: uat-tester

## Bug Report **Feature Area**: git-worktree-sandbox — `agents plan diff` **Severity**: Priority/Backlog — diff output is functional but does not match spec format ## What Was Tested Code-level analysis of `agents plan diff <PLAN_ID>` output against the specification's required format. ## Expected Behavior (from spec) Per the specification (lines 15340–15380), `agents plan diff <PLAN_ID>` should display: ``` Diff Summary Plan: 01HXM8C2ZK4Q7C2B3F2R4VYV6J Project: local/api-service Files Changed: 2 Insertions: 12 Deletions: 4 Net Change: +8 lines Files Path Change Status ------------------- ------ -------- src/auth/session.py +8 -2 modified src/auth/tokens.py +4 -2 modified Patch Preview --- a/src/auth/session.py +++ b/src/auth/session.py @@ -12,4 +12,10 @@ - import jwt + import sessionlib ... Risk Assessment API Compatibility: preserved Test Coverage: maintained Breaking Changes: none detected ``` The spec requires: 1. **Insertions/Deletions/Net Change** counts (actual line counts) 2. **Per-file change summary** with `+N -M` line counts 3. **Patch Preview** with actual unified diff content (showing added/removed lines) 4. **Risk Assessment** section ## Actual Behavior The `_render_diff_plain()` function in `src/cleveragents/application/services/plan_apply_service.py` (lines 121–152) renders: ``` ChangeSet: <changeset_id> Plan: <plan_id> Total changes: 2 --- a/src/auth/session.py +++ b/src/auth/session.py @@ modified @@ - hash: abc123def456... + hash: 789xyz012abc... ``` The implementation: 1. Shows **SHA-256 hashes** of before/after file states instead of actual line-level diffs 2. Does **not** compute insertions/deletions/net change counts 3. Does **not** show actual file content changes (the `+`/`-` lines) 4. Does **not** include a Risk Assessment section 5. Does **not** show per-file `+N -M` line counts The `ChangeSetEntry` model stores `before_hash` and `after_hash` (SHA-256 of the whole file) but does not store the actual diff content or line counts. ## Code Locations - **Diff rendering**: `src/cleveragents/application/services/plan_apply_service.py`, `_render_diff_plain()` (line 121) and `_render_diff_rich()` (line 155) - **ChangeSet model**: `src/cleveragents/tool/builtins/changeset.py`, `ChangeSetEntry` (line 34) — stores hashes but not diff content - **Domain model**: `src/cleveragents/domain/models/core/change.py` — `ChangeEntry` model ## Root Cause The `ChangeSetCapture` wrapper records before/after file hashes but not the actual diff content. To produce a proper unified diff, the implementation would need to either: 1. Store the full file content before and after each change, or 2. Read the actual file content from the sandbox at diff time and compare it to the original The current approach of storing only SHA-256 hashes is insufficient for generating a unified diff. ## Impact - Users cannot see what lines were actually changed before applying - The diff output is not useful for code review purposes - The spec's "Patch Preview" section is completely absent - Risk Assessment is absent ## Fix Required 1. **Extend `ChangeSetEntry`** to store before/after content (or at minimum, the unified diff text) 2. **Update `ChangeSetCapture.wrap_tool()`** to capture file content before and after each write operation 3. **Update `_render_diff_plain()` and `_render_diff_rich()`** to compute and display: - Actual unified diff using `difflib.unified_diff()` - Insertion/deletion/net change counts - Per-file `+N -M` summary --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
HAL9000 added this to the v3.4.0 milestone 2026-04-09 06:59:59 +00:00
Author
Owner

Label compliance fix applied:

  • Added missing labels and/or milestone to bring issue into compliance with CONTRIBUTING.md

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: backlog-groomer

Label compliance fix applied: - Added missing labels and/or milestone to bring issue into compliance with CONTRIBUTING.md --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: backlog-groomer
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
cleveragents/cleveragents-core#5459
No description provided.