UAT: CleanupReport.as_dict() omits stale_items — machine-readable scan output is incomplete #3976

Open
opened 2026-04-06 08:11:40 +00:00 by freemo · 0 comments
Owner

Metadata

  • Branch: fix/cleanup-report-as-dict-stale-items
  • Commit Message: fix(cleanup): include stale_items list in CleanupReport.as_dict() output
  • Milestone: (backlog — no milestone assigned)
  • Parent Epic: #365 (Epic: Concurrency & Cleanup — closed; no active replacement epic found)

Backlog note: This issue was discovered during autonomous operation
on milestone v3.7.0. It does not block milestone completion and has been
placed in the backlog for human review and future milestone assignment.

Background and Context

The CleanupReport.as_dict() method in src/cleveragents/application/services/cleanup_models.py serializes the cleanup report for CLI output and machine-readable formats (JSON/YAML). However, it omits the stale_items list — a collection of StaleItem objects containing resource_type, path, age_description, and optional plan_id — from its return value.

Per features/garbage_collection.feature, the scan report is expected to include stale item paths and details. Any caller consuming report.as_dict() (e.g., for JSON/YAML output) loses the full list of stale items, making programmatic consumption of scan results impossible.

Current Behavior

CleanupReport.as_dict() returns per-resource-type summary counts but omits the stale_items list:

def as_dict(self) -> dict[str, Any]:
    """Serialize the report for CLI output."""
    return {
        "dry_run": self.dry_run,
        "sandboxes": {
            "scanned": self.sandboxes.scanned,
            "removed": self.sandboxes.removed,
            "skipped": self.sandboxes.skipped,
        },
        # ... other resource types ...
        # MISSING: "stale_items": [...]
    }

The scan CLI command does print stale items in rich mode by iterating report.stale_items directly, so the human-readable output is correct. However, since as_dict() omits stale_items, any caller using the dict representation (e.g., for JSON/YAML output) loses this information entirely.

Steps to reproduce:

  1. Create a stale sandbox directory (older than 48 hours)
  2. Run: agents cleanup scan — rich output shows stale items correctly
  3. Inspect CleanupReport.as_dict()stale_items key is absent
  4. Any code consuming report.as_dict() cannot access the stale item paths

Expected Behavior

Per features/garbage_collection.feature:

  • Scenario: "Dry-run reports stale paths" — expects the scan report to include the sandbox path
  • Scenario: "CleanupReport as_dict returns correct structure" — tests the dict structure

CleanupReport.as_dict() should include a stale_items key containing a list of serialized StaleItem objects:

"stale_items": [
    {
        "resource_type": item.resource_type,
        "path": item.path,
        "age_description": item.age_description,
        "plan_id": item.plan_id,
    }
    for item in self.stale_items
],

Acceptance Criteria

  • CleanupReport.as_dict() includes a stale_items key containing a list of dicts, each with resource_type, path, age_description, and plan_id fields.
  • Existing Behave scenarios for CleanupReport as_dict returns correct structure pass with the updated structure.
  • The agents cleanup scan command produces correct JSON/YAML output including stale item paths when using machine-readable output formats.
  • No regression in existing rich-mode CLI output.

Supporting Information

Code location:

  • src/cleveragents/application/services/cleanup_models.pyCleanupReport.as_dict() method (lines ~50–75)

Related issues:

  • #3941CleanupService session scan/purge stubs (same CONC3 area)
  • #3843 — Architecture guard issue for TODO(CONC3) comments

Subtasks

  • Add stale_items serialization to CleanupReport.as_dict() in cleanup_models.py
  • Verify StaleItem fields (resource_type, path, age_description, plan_id) are all included
  • Tests (Behave): Update/add scenario for CleanupReport as_dict returns correct structure to assert stale_items key and contents
  • Tests (Behave): Verify "Dry-run reports stale paths" scenario passes with updated dict structure
  • Tests (Robot): Add integration test for agents cleanup scan JSON/YAML output including stale item paths
  • Verify coverage ≥ 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • CleanupReport.as_dict() includes stale_items in its return value with all required fields.
  • Behave scenarios covering the dict structure pass.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage ≥ 97%.

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

## Metadata - **Branch**: `fix/cleanup-report-as-dict-stale-items` - **Commit Message**: `fix(cleanup): include stale_items list in CleanupReport.as_dict() output` - **Milestone**: *(backlog — no milestone assigned)* - **Parent Epic**: #365 (Epic: Concurrency & Cleanup — closed; no active replacement epic found) > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.7.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. ## Background and Context The `CleanupReport.as_dict()` method in `src/cleveragents/application/services/cleanup_models.py` serializes the cleanup report for CLI output and machine-readable formats (JSON/YAML). However, it omits the `stale_items` list — a collection of `StaleItem` objects containing `resource_type`, `path`, `age_description`, and optional `plan_id` — from its return value. Per `features/garbage_collection.feature`, the scan report is expected to include stale item paths and details. Any caller consuming `report.as_dict()` (e.g., for JSON/YAML output) loses the full list of stale items, making programmatic consumption of scan results impossible. ## Current Behavior `CleanupReport.as_dict()` returns per-resource-type summary counts but omits the `stale_items` list: ```python def as_dict(self) -> dict[str, Any]: """Serialize the report for CLI output.""" return { "dry_run": self.dry_run, "sandboxes": { "scanned": self.sandboxes.scanned, "removed": self.sandboxes.removed, "skipped": self.sandboxes.skipped, }, # ... other resource types ... # MISSING: "stale_items": [...] } ``` The `scan` CLI command does print stale items in rich mode by iterating `report.stale_items` directly, so the human-readable output is correct. However, since `as_dict()` omits `stale_items`, any caller using the dict representation (e.g., for JSON/YAML output) loses this information entirely. **Steps to reproduce:** 1. Create a stale sandbox directory (older than 48 hours) 2. Run: `agents cleanup scan` — rich output shows stale items correctly 3. Inspect `CleanupReport.as_dict()` — `stale_items` key is absent 4. Any code consuming `report.as_dict()` cannot access the stale item paths ## Expected Behavior Per `features/garbage_collection.feature`: - Scenario: "Dry-run reports stale paths" — expects the scan report to include the sandbox path - Scenario: "CleanupReport as_dict returns correct structure" — tests the dict structure `CleanupReport.as_dict()` should include a `stale_items` key containing a list of serialized `StaleItem` objects: ```python "stale_items": [ { "resource_type": item.resource_type, "path": item.path, "age_description": item.age_description, "plan_id": item.plan_id, } for item in self.stale_items ], ``` ## Acceptance Criteria - `CleanupReport.as_dict()` includes a `stale_items` key containing a list of dicts, each with `resource_type`, `path`, `age_description`, and `plan_id` fields. - Existing Behave scenarios for `CleanupReport as_dict returns correct structure` pass with the updated structure. - The `agents cleanup scan` command produces correct JSON/YAML output including stale item paths when using machine-readable output formats. - No regression in existing rich-mode CLI output. ## Supporting Information **Code location:** - `src/cleveragents/application/services/cleanup_models.py` — `CleanupReport.as_dict()` method (lines ~50–75) **Related issues:** - #3941 — `CleanupService` session scan/purge stubs (same CONC3 area) - #3843 — Architecture guard issue for `TODO(CONC3)` comments ## Subtasks - [ ] Add `stale_items` serialization to `CleanupReport.as_dict()` in `cleanup_models.py` - [ ] Verify `StaleItem` fields (`resource_type`, `path`, `age_description`, `plan_id`) are all included - [ ] Tests (Behave): Update/add scenario for `CleanupReport as_dict returns correct structure` to assert `stale_items` key and contents - [ ] Tests (Behave): Verify "Dry-run reports stale paths" scenario passes with updated dict structure - [ ] Tests (Robot): Add integration test for `agents cleanup scan` JSON/YAML output including stale item paths - [ ] Verify coverage ≥ 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - `CleanupReport.as_dict()` includes `stale_items` in its return value with all required fields. - Behave scenarios covering the dict structure pass. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly. - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. - All nox stages pass. - Coverage ≥ 97%. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
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
#365 Epic: Concurrency & Cleanup
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3976
No description provided.