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:
- 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.
- 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
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.
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:
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.pyalready 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 TEXTcolumn added to key entity tables:agent_ownership,agent_schedules,users,agent_shared_files,agent_sessions,chat_sessionsdeleted_at = utc_now_iso()instead of removing the rowWHERE deleted_at IS NULLby defaultsystem_settingstable (e.g.agent_soft_delete_retention_days, default 30)cleanup_service.pyretention 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 consumersTechnical 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_namenaturally 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.pyalready handlesschedule_executions,agent_health_checks, andaudit_logwith 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.