Addresses #6 (3mwcn6q5k3w22), replacing the closed documentation-only proposal.
After a committed compaction, elide images absent from the exact prepared request. This includes old user uploads: retain message text and append [image elided and is no longer available]. Preserve images still in the verbatim tail (including older copies with the same hash), and images referenced by another session/fork or pinned context. Direct view_code/view_diff/show_image results additionally require a matching completed Python cell; rewrite that cell and its tool-output row atomically, preserving their text. Reclaim content-addressed bytes only after reference checks. Other Python results and legacy inline images are left alone. This is irreversible for images with no remaining references; no live database was modified.
Read-only prior inventory: 581 image payloads / 152.0 MB (14 user uploads / 19.0 MB; 194 view_code / 43.4 MB; 371 view_diff / 84.6 MB; 2 show_image / 5.0 MB), plus 135.1 MB of inline cell-image data. The direct-call matcher is deliberately conservative; eligible rows are swept after their next successful compaction, not at startup.
Verified in isolated worktree: gleam test (116 passed), gleam check, gleam format --check src test, python3 test/e2e/run.py compaction_test.py (3 passed, one daemon boot), git diff --cached --check. E2E proves old user-upload reclamation, recent user-upload preservation, and generated-image elision; DB fixtures cover pinned/shared references and atomic cell/transcript rewrite. Gleam test emitted a non-failing Python-kernel cleanup timeout warning.