Files
turnstone/tests
Patrick Buckley 98cee4d20c feat(storage): content-addressed refcounted attachments + in-memory upload buffer
Replace the persisted pending/reserved/consumed upload lifecycle (and its orphan-sweep
and per-user cap) with a content-addressed, refcounted blob store fronted by the per-node
in-memory pending buffer:

- Upload stages bytes in the buffer (keyed by sha256); send-commit drains the referenced
  handles, writes each blob content-addressed (INSERT-OR-IGNORE then refcount += 1, so a
  stored blob is born referenced and dedupes across messages/workstreams), and records the
  ordered conversations.attachments ref-list — the sole message->blob link.
- reconstruct rebuilds inline image_url/document multipart content from the ref-list,
  role-agnostically (so tool-produced images via _exec_read_image now persist + rehydrate
  instead of being flattened to text and lost). Output shape unchanged.
- GC is reference counting: delete_messages_after / delete_workstream decrement once per
  reference and prune a blob at 0; a deduped blob shared with a kept turn (or another ws)
  survives.
- get_content for a committed blob is gated by reference-ownership (the requester owns a
  turn in the ws whose ref-list names the id), replacing the dropped ws_id/user_id scope.
- Migration 060 re-keys legacy consumed attachments to their content hash, dedups, sets
  refcounts, writes the ref-lists, and drops message_id/reserved_*; pending legacy rows are
  dropped (pending now lives only in the buffer).

Both backends symmetric; the reservation methods, cap, and orphan-sweep are removed across
storage/facade/protocol/endpoints/coordinator. Wire harness byte-identical; full suite green.
2026-06-04 11:03:13 -07:00
..