Skip to content

v2: define snapshot retention and disk GC policy #36093

Description

@opencode-agent

Background

V2 needs an explicit policy for pruning filesystem snapshots from disk. Today the legacy snapshot store writes Git tree objects under the per-project/worktree snapshot gitdir and runs git gc --prune=7.days on a background loop. That is age-based Git object cleanup, not reachability from durable session state.

If V2 stores snapshot hashes in session messages/revert metadata and sessions are indefinitely resumable from the database, Git does not know those DB references are live. A 7-day prune can therefore delete snapshot tree/blob objects that old-but-resumable sessions still need for diff/revert/undo.

Related prior evidence:

Question to settle

What guarantee should V2 make for snapshot-backed file history?

Options:

  1. Strong default: if a session is still in the DB and exposes snapshot-backed history, referenced snapshots remain available.
  2. Weak/cache default: old sessions remain resumable as chat, but old snapshot-backed file diff/revert/undo is best-effort and may disappear.
  3. Bounded default: snapshot history is retained for an explicit window/budget/session lifecycle, and the UI/API degrades clearly after that boundary.

Likely implementation direction if we choose the strong default

  • Treat the DB/session tables as the source of live snapshot hashes.
  • Add a SnapshotGC/maintenance job that scans reachable snapshot hashes from session messages, parts, revert state, summaries, etc.
  • Pin live hashes in the snapshot gitdir with Git refs so git gc can preserve them.
    • One possible shape: create a tiny commit pointing at the snapshot tree and update refs/opencode/snapshots/<hash> to that commit.
    • The DB can continue to store the original tree hash; the ref/commit is only a reachability pin.
  • Remove pins for hashes no longer referenced by retained session state.
  • Keep git gc --prune=7.days or similar only as orphan cleanup / race grace, not as the semantic retention guarantee.

Things to decide

  • Are all DB sessions considered retained forever, or do we have/need session archival/deletion semantics?
  • Does compaction ever deliberately drop old file-history capability? If yes, it should remove snapshot references or mark them collectible.
  • Should snapshot retention be user-configurable by age/size, and if so is that a weaker opt-in mode?
  • What should the product show when a snapshot reference is missing: unavailable diff/revert, degraded resume, repair prompt, etc.?
  • How do we migrate/handle existing snapshot hashes that may already be unpinned or missing?

Acceptance criteria

  • V2 has a documented snapshot retention guarantee.
  • The pruning job cannot collect snapshot objects still referenced by sessions under that guarantee.
  • Orphaned/unreferenced snapshot objects are eventually reclaimable.
  • Missing snapshot objects degrade explicitly rather than failing silently.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions