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
- User opens Cleanup section → analysis runs lazily on first visit
- Results shown per-category with counts
- "Retry All" button for failed extractions (primary, safe)
- Per-category "Delete" buttons (danger style, requires confirm dialog)
- "Delete All Rot" button at bottom (danger, requires confirm)
- 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
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)
stills_queue.status = 'failed'NO_TEXT_DETECTEDstatus = 'done', file missing on diskcaptured_atolder than retention threshold (default 30 days)app_bundle_idin user's excluded bundle IDsKey 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
Modified Files
IPC API
UX Flow
Key Design Decisions
app_bundle_idmay not exist on older installsmarkPending()→ markdown worker handles automaticallyAcceptance Criteria
cleanup:analyzereturns accurate counts for all 6 categoriescleanup:retryFailedrequeues all failed rows; markdown worker picks them upcleanup:deleteByCategorysafely deletes files then DB rows (file-first ordering)cleanup:deleteAlldeletes all non-retryable categories in one passapp_bundle_idcolumn (older installs)