UAT: CheckpointService.create_workspace_snapshot diff metadata (diff_paths, diff_based, diff_hash) is added after database persistence — metadata is lost on restart #3003

Open
opened 2026-04-05 03:30:34 +00:00 by freemo · 2 comments
Owner

Metadata

  • Branch: fix/checkpoint-service-diff-metadata-persistence
  • Commit Message: fix(checkpoint): persist diff metadata before DB write in create_workspace_snapshot
  • Milestone: v3.3.0
  • Parent Epic: #362

Description

The CheckpointService.create_workspace_snapshot method adds diff metadata to checkpoint.metadata.extra after the checkpoint has already been persisted to the database via self._repository.create(checkpoint). This means the diff_paths, diff_based, and diff_hash metadata fields are only stored in-memory and are not persisted to the database. After a service restart, these fields will be missing from the checkpoint.

Expected Behavior (from spec)

The diff manifest stored in checkpoint metadata under "diff_paths", "diff_based", and "diff_hash" keys should be persisted to the database along with the checkpoint.

Actual Behavior

In src/cleveragents/application/services/checkpoint_service.py lines 408–466:

def create_workspace_snapshot(self, plan_id, sandbox_ref, decision_id, ...):
    # ...
    checkpoint = self.create_checkpoint(  # ← This persists to DB
        plan_id=plan_id,
        sandbox_ref=sandbox_ref,
        ...
        checkpoint_type="pre_decision",
    )

    # Store diff manifest in metadata extra
    checkpoint.metadata.extra["diff_paths"] = diff_paths  # ← AFTER DB persist!
    checkpoint.metadata.extra["diff_based"] = True         # ← AFTER DB persist!
    checkpoint.metadata.extra["diff_hash"] = hashlib.sha256(...)  # ← AFTER DB persist!

The create_checkpoint method (lines 161–257) calls self._repository.create(checkpoint) when a repository is configured. At that point, checkpoint.metadata.extra is empty. The subsequent mutations to checkpoint.metadata.extra are in-memory only and are never written back to the database.

Code Locations

  • src/cleveragents/application/services/checkpoint_service.py lines 408–466 (create_workspace_snapshot)
  • src/cleveragents/application/services/checkpoint_service.py lines 161–257 (create_checkpoint)

Steps to Reproduce

  1. Configure a CheckpointService with a database-backed CheckpointRepository
  2. Call create_workspace_snapshot(plan_id, sandbox_ref, decision_id)
  3. Restart the service
  4. Retrieve the checkpoint from the database
  5. Observe that checkpoint.metadata.extra is empty (no diff_paths, diff_based, diff_hash)

Fix Direction

The diff metadata should be computed before calling create_checkpoint, and passed via the metadata parameter (or a new extra parameter) so it is included in the initial database write.

Subtasks

  • Write a failing Behave scenario that reproduces the bug (TDD — failing test first)
  • Compute diff_paths, diff_based, and diff_hash before calling create_checkpoint
  • Pass the computed diff metadata into create_checkpoint via metadata.extra or a dedicated parameter so it is included in the initial _repository.create(checkpoint) call
  • Verify the metadata is correctly persisted by retrieving the checkpoint from the repository after creation
  • Ensure the Behave scenario now passes
  • Run nox -e typecheck and confirm no type errors
  • Run nox -e lint and confirm no lint errors
  • Run nox -e coverage_report and confirm coverage >= 97%

Definition of Done

  • All subtasks above are checked
  • A Behave scenario exists that reproduces the original bug and now passes
  • diff_paths, diff_based, and diff_hash are persisted to the database in the same write as the checkpoint creation
  • Retrieving a checkpoint after a simulated restart returns the correct diff metadata
  • All nox stages pass
  • Coverage >= 97%
  • Commit created with message: fix(checkpoint): persist diff metadata before DB write in create_workspace_snapshot
  • PR merged and issue closed

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/checkpoint-service-diff-metadata-persistence` - **Commit Message**: `fix(checkpoint): persist diff metadata before DB write in create_workspace_snapshot` - **Milestone**: v3.3.0 - **Parent Epic**: #362 ## Description The `CheckpointService.create_workspace_snapshot` method adds diff metadata to `checkpoint.metadata.extra` **after** the checkpoint has already been persisted to the database via `self._repository.create(checkpoint)`. This means the `diff_paths`, `diff_based`, and `diff_hash` metadata fields are only stored in-memory and are **not** persisted to the database. After a service restart, these fields will be missing from the checkpoint. ### Expected Behavior (from spec) The diff manifest stored in checkpoint metadata under `"diff_paths"`, `"diff_based"`, and `"diff_hash"` keys should be persisted to the database along with the checkpoint. ### Actual Behavior In `src/cleveragents/application/services/checkpoint_service.py` lines 408–466: ```python def create_workspace_snapshot(self, plan_id, sandbox_ref, decision_id, ...): # ... checkpoint = self.create_checkpoint( # ← This persists to DB plan_id=plan_id, sandbox_ref=sandbox_ref, ... checkpoint_type="pre_decision", ) # Store diff manifest in metadata extra checkpoint.metadata.extra["diff_paths"] = diff_paths # ← AFTER DB persist! checkpoint.metadata.extra["diff_based"] = True # ← AFTER DB persist! checkpoint.metadata.extra["diff_hash"] = hashlib.sha256(...) # ← AFTER DB persist! ``` The `create_checkpoint` method (lines 161–257) calls `self._repository.create(checkpoint)` when a repository is configured. At that point, `checkpoint.metadata.extra` is empty. The subsequent mutations to `checkpoint.metadata.extra` are in-memory only and are never written back to the database. ### Code Locations - `src/cleveragents/application/services/checkpoint_service.py` lines 408–466 (`create_workspace_snapshot`) - `src/cleveragents/application/services/checkpoint_service.py` lines 161–257 (`create_checkpoint`) ### Steps to Reproduce 1. Configure a `CheckpointService` with a database-backed `CheckpointRepository` 2. Call `create_workspace_snapshot(plan_id, sandbox_ref, decision_id)` 3. Restart the service 4. Retrieve the checkpoint from the database 5. Observe that `checkpoint.metadata.extra` is empty (no `diff_paths`, `diff_based`, `diff_hash`) ### Fix Direction The diff metadata should be computed **before** calling `create_checkpoint`, and passed via the `metadata` parameter (or a new `extra` parameter) so it is included in the initial database write. ## Subtasks - [ ] Write a failing Behave scenario that reproduces the bug (TDD — failing test first) - [ ] Compute `diff_paths`, `diff_based`, and `diff_hash` before calling `create_checkpoint` - [ ] Pass the computed diff metadata into `create_checkpoint` via `metadata.extra` or a dedicated parameter so it is included in the initial `_repository.create(checkpoint)` call - [ ] Verify the metadata is correctly persisted by retrieving the checkpoint from the repository after creation - [ ] Ensure the Behave scenario now passes - [ ] Run `nox -e typecheck` and confirm no type errors - [ ] Run `nox -e lint` and confirm no lint errors - [ ] Run `nox -e coverage_report` and confirm coverage >= 97% ## Definition of Done - [ ] All subtasks above are checked - [ ] A Behave scenario exists that reproduces the original bug and now passes - [ ] `diff_paths`, `diff_based`, and `diff_hash` are persisted to the database in the same write as the checkpoint creation - [ ] Retrieving a checkpoint after a simulated restart returns the correct diff metadata - [ ] All nox stages pass - [ ] Coverage >= 97% - [ ] Commit created with message: `fix(checkpoint): persist diff metadata before DB write in create_workspace_snapshot` - [ ] PR merged and issue closed --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.3.0 milestone 2026-04-05 03:33:02 +00:00
Author
Owner

Label compliance fix applied:

  • Added missing labels: Priority/Medium, State/Unverified, Type/Bug
  • Reason: Issue was missing all required labels per CONTRIBUTING.md. Inferred Type/Bug from the "UAT:" prefix. Applied Priority/Medium and State/Unverified as defaults.

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

Label compliance fix applied: - Added missing labels: `Priority/Medium`, `State/Unverified`, `Type/Bug` - Reason: Issue was missing all required labels per CONTRIBUTING.md. Inferred `Type/Bug` from the "UAT:" prefix. Applied `Priority/Medium` and `State/Unverified` as defaults. --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: ca-backlog-groomer
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Confirmed
  • MoSCoW: Should Have

Valid finding verified during batch triage.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Confirmed - **MoSCoW**: Should Have Valid finding verified during batch triage. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
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.

Blocks
#362 Epic: Security & Safety Hardening
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3003
No description provided.