This was generated by AI during triage.
Why
The durable event store has no bounded-retention policy. Event.remove(aggregateID) deletes event_sequence and event rows only when a session is explicitly removed through the supported session path; retained sessions keep their full ordered event history indefinitely.
SQLite is initialized without auto_vacuum, so deleting rows does not by itself return allocated pages to the filesystem. The source fixes in #522, #523, and #525 reduce future write amplification but do not define retention or reclamation semantics.
Confirmed current behavior
packages/core/src/event.ts:621-630 is the production aggregate-event deletion path.
packages/opencode/src/session/session.ts:735-736 invokes event removal during supported session deletion.
packages/core/src/event.ts:661-668 exposes ordered incremental replay (seq > after, ascending), so event folding or sequence gaps cannot be assumed safe.
packages/core/src/database/database.ts:27-33 configures WAL and related pragmas but no auto_vacuum mode.
- Existing databases require an explicit migration strategy; switching to incremental auto-vacuum cannot silently run a blocking full
VACUUM at normal startup.
Required decisions
Before implementation, approve an ADR that defines:
- Retention eligibility: what constitutes an inactive or terminal aggregate without breaking session history or sync replay.
- Retention bounds: age, size, event count, configuration surface, and defaults.
- Scheduling and failure semantics: when cleanup runs, concurrency behavior, retry/warning behavior, and observability.
- SQLite reclamation: behavior for new databases, opt-in migration for existing databases, exclusive-access requirements, and rollback.
- Compatibility: effects on
readAfter, workspace replay, sync cursors, backup/restore, and downgrade behavior.
Scope
- Technical design and ADR for bounded event retention and SQLite space reclamation.
- A disposable-database prototype or benchmark proving the selected SQLite path.
- After the decision checkpoint, the narrow runtime implementation and focused tests.
Out of scope: deleting historical user sessions or running VACUUM against the live local database. That destructive operator procedure is tracked separately in the linked human-only issue. Event snapshot folding is also out of scope unless separately designed against replay contracts.
Acceptance
- The ADR resolves all five decisions above and documents alternatives, rollout, rollback, and non-goals.
- Tests prove active/retained session replay is unchanged and only eligible aggregates are removed.
- Tests cover cleanup failure without blocking the main application path.
- Disposable-file tests demonstrate page reclamation and the new/existing database migration behavior without startup-time full
VACUUM.
bun run test:dag-core, focused event/session tests, package typecheck, and migration freshness checks pass.
Relations
Why
The durable event store has no bounded-retention policy.
Event.remove(aggregateID)deletesevent_sequenceandeventrows only when a session is explicitly removed through the supported session path; retained sessions keep their full ordered event history indefinitely.SQLite is initialized without
auto_vacuum, so deleting rows does not by itself return allocated pages to the filesystem. The source fixes in #522, #523, and #525 reduce future write amplification but do not define retention or reclamation semantics.Confirmed current behavior
packages/core/src/event.ts:621-630is the production aggregate-event deletion path.packages/opencode/src/session/session.ts:735-736invokes event removal during supported session deletion.packages/core/src/event.ts:661-668exposes ordered incremental replay (seq > after, ascending), so event folding or sequence gaps cannot be assumed safe.packages/core/src/database/database.ts:27-33configures WAL and related pragmas but noauto_vacuummode.VACUUMat normal startup.Required decisions
Before implementation, approve an ADR that defines:
readAfter, workspace replay, sync cursors, backup/restore, and downgrade behavior.Scope
Out of scope: deleting historical user sessions or running
VACUUMagainst the live local database. That destructive operator procedure is tracked separately in the linked human-only issue. Event snapshot folding is also out of scope unless separately designed against replay contracts.Acceptance
VACUUM.bun run test:dag-core, focused event/session tests, package typecheck, and migration freshness checks pass.Relations