-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Description
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_idmay 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:analyzereturns accurate counts for all 6 categories -
cleanup:retryFailedrequeues all failed rows; markdown worker picks them up -
cleanup:deleteByCategorysafely deletes files then DB rows (file-first ordering) -
cleanup:deleteAlldeletes 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_idcolumn (older installs)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels