Skip to content

Soft-delete all entities + configurable data retention policy #834

@vybe

Description

@vybe

Summary

Replace hard-delete operations platform-wide with soft-delete (setting deleted_at) and introduce a configurable, independently-running data retention policy that controls when soft-deleted records are permanently purged.

Context

Currently Trinity hard-deletes most entities (agents, schedules, users, etc.) immediately on request. This causes two problems:

  1. No recovery window — accidental agent deletion loses all associated schedules, sharing config, permissions, and metadata. The container is gone too, but the relational state is unrecoverable.
  2. Operator has no control over data lifecycle — Trinity decides when data disappears. Operators running sovereign infrastructure should own that decision.

The target architecture (docs/planning/TARGET_ARCHITECTURE.md) already describes PostgreSQL with partitioned tables and configurable retention windows per entity type. This issue formalizes the pattern across the platform.

The existing cleanup_service.py already runs retention sweeps for executions, health checks, and audit log rows — this issue generalizes that into a unified, operator-configurable policy.

Acceptance Criteria

  • deleted_at TEXT column added to key entity tables: agent_ownership, agent_schedules, users, agent_shared_files, agent_sessions, chat_sessions
  • All DELETE operations on those tables set deleted_at = utc_now_iso() instead of removing the row
  • All read queries (list, get, joins) filter WHERE deleted_at IS NULL by default
  • Retention policy is configurable per entity type via system_settings table (e.g. agent_soft_delete_retention_days, default 30)
  • The existing cleanup_service.py retention sweep is extended to hard-delete soft-deleted rows past their retention window (same 5000-row/cycle cap and WAL checkpoint pattern)
  • GET /api/agents/{name} returns 404 (not a deleted-agent response) — soft-delete is transparent to API consumers
  • Agent name remains reserved for the retention period (cannot create a new agent with the same name until the soft-deleted row is purged)
  • Admin endpoint or settings UI surface to list soft-deleted agents with their purge date
  • Schema migration (Alembic-compatible DDL) for all new columns

Technical Notes

Priority entities for Phase 1: agent_ownership (most impactful — agent recovery), agent_schedules, users (deactivate vs delete).

Agent name reservation: The unique constraint on agent_name naturally blocks reuse during the retention window. This is intentional — it prevents accidental name collision with a deleted agent's lingering Redis state.

Docker containers remain ephemeral: Soft-delete does not recover the container. It preserves chat history, schedules, permissions, credentials config, and relational metadata — exactly what is hard to recreate and was previously lost immediately.

Existing retention sweeps: cleanup_service.py already handles schedule_executions, agent_health_checks, and audit_log with per-type configurable retention days and row caps. The new agent/user sweeps should follow the exact same pattern.

Relation to target architecture: The move to PostgreSQL + Alembic (TARGET_ARCHITECTURE.md) is the natural moment to introduce this uniformly. The soft-delete columns and retention policy should be part of the baseline schema, not retrofitted.

Metadata

Metadata

Assignees

Type

No type
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