Skip to content

Context Rot Cleanup: detect and remove degraded context #14

@sunnypatneedi

Description

@sunnypatneedi

Problem

The Familiar context folder accumulates "rot" indefinitely: failed extractions, empty OCR results, orphaned files, and stale captures that degrade the signal-to-noise ratio of the context provided to AI. No mechanism currently exists to detect or remediate this.

Proposed Solution

Add a Cleanup section to the Settings dashboard where users can identify and safely remove degraded context.

Rot Taxonomy (6 Categories)

# Category Detection Signal Action
1 failed stills_queue.status = 'failed' Retry (requeue → pending)
2 empty_ocr markdown file contains only NO_TEXT_DETECTED Delete image + markdown + DB row
3 orphaned_db status = 'done', file missing on disk Delete DB row
4 orphaned_file image on disk, no matching DB row Delete file
5 temporal_rot captured_at older than retention threshold (default 30 days) Delete image + markdown + DB row
6 excluded_app app_bundle_id in user's excluded bundle IDs Delete image + markdown + DB row

Key asymmetry: Category 1 (failed) is safe to retry — worst case it fails again. Categories 2–6 involve irreversible deletion. The UI must make this asymmetry clear.

New Files

src/context-cleanup/analyzer.js        # Read-only rot detection
src/context-cleanup/cleaner.js         # Destructive operations (delete/requeue)
src/ipc/cleanup.js                     # IPC handlers
src/dashboard/bootstrap/cleanup.js     # UI wiring

Modified Files

src/dashboard/index.html               # "Cleanup" sidebar + content pane
src/dashboard/preload.js               # Expose cleanup:* IPC
src/ipc/index.js                       # Register handlers
src/dashboard/renderer.js              # Load bootstrap module

IPC API

cleanup:analyze         → { categories: { failed: N, empty_ocr: N, ... }, totalBytes: N }
cleanup:retryFailed     → { requeued: N }
cleanup:deleteByCategory({ category }) → { deleted: N, bytesFreed: N }
cleanup:deleteAll       → { deleted: N, bytesFreed: N }

UX Flow

  1. User opens Cleanup section → analysis runs lazily on first visit
  2. Results shown per-category with counts
  3. "Retry All" button for failed extractions (primary, safe)
  4. Per-category "Delete" buttons (danger style, requires confirm dialog)
  5. "Delete All Rot" button at bottom (danger, requires confirm)
  6. Re-analyzes after every action to keep counts accurate

Key Design Decisions

  • Lazy analysis: only runs on user action, no startup cost
  • Retry as primary action: asymmetric UX — retry is reversible, delete is final
  • File deleted before DB row: if file delete fails, row survives for retry
  • Graceful column absence: app_bundle_id may not exist on older installs
  • No auto-deletion: user always initiates cleanup, never silent
  • Reuse existing retry machinery: markPending() → markdown worker handles automatically

Acceptance Criteria

  • cleanup:analyze returns accurate counts for all 6 categories
  • cleanup:retryFailed requeues all failed rows; markdown worker picks them up
  • cleanup:deleteByCategory safely deletes files then DB rows (file-first ordering)
  • cleanup:deleteAll deletes all non-retryable categories in one pass
  • Cleanup section visible in sidebar, analysis lazy-loads on first open
  • Counts refresh after each action
  • Unit tests for analyzer and cleaner against in-memory SQLite
  • Graceful handling of missing app_bundle_id column (older installs)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions