You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Agents accumulate runtime data — SQLite databases, large incremental files, working datasets — that cannot live in the git-synced template repo (it bloats fast and doesn't belong in version control), yet must survive container recreate, template re-pulls, and subscription auto-switch, and must move with the agent when it migrates to another Trinity instance.
Proposed model: agent = code (git) + credentials (.credentials.enc) + data (declared volume). Runtime data becomes a third declared artifact class, parallel to the existing credential pattern.
Context
Today the only options are committing data to the template repo (bloat, churn, merge conflicts) or leaving it in the container filesystem (lost on recreate — exactly the events that already destroy runtime state today: template re-pull, subscription auto-switch, image upgrade). Neither is acceptable for database-backed or data-heavy agents.
Per-agent named volumes (agent-{name}-public, FILES-001; shared-folder volumes)
Backend-side Docker SDK file extraction (get_archive) that never mounts the agent workspace (src/backend/services/agent_shared_files_service.py)
The ~/.trinity/pre-check hook pattern for agent-side lifecycle hooks
Credential export/import as the portability surface
Design Sketch
Declare — data_paths: section in template.yaml (or an extension of the S4 persistent-state allowlist) listing runtime-data paths, e.g. ~/data/, ~/db/agent.sqlite. Gitignored by convention.
Mount — Trinity mounts declared paths from a named per-agent volume (agent-{name}-data), same pattern as agent-{name}-public. Survives recreate/re-pull/auto-switch.
Durability — a backend snapshot job tars the volume on a schedule into the existing trinity-data bind mount (e.g. /data/agent-data-snapshots/) with retention. For SQLite, snapshot via a quiesce hook (~/.trinity/pre-snapshot, shebang-selected like pre-check) or sqlite3 .backup to avoid mid-write corruption.
Portability — "move agent to another Trinity" = template URL + .credentials.enc + data snapshot tar. Extends the existing export/import surface.
Acceptance Criteria
template.yaml (or persistent-state allowlist) supports declaring runtime data paths
Declared paths are backed by a named per-agent volume that survives container recreate, template re-pull, and subscription auto-switch
Backend snapshot job with configurable schedule + retention; snapshots stored under the existing trinity-data bind mount
SQLite-safe snapshotting (quiesce hook or .backup-based copy), documented for template authors
Export/import flow covers the data volume alongside credentials (agent fully reconstructable on another instance without git carrying data)
Agent delete / rename cascades handle the data volume and snapshots (manual cascade per platform convention)
No new agent-side privileges: snapshot path is backend-side Docker SDK, agents stay off the platform network
Technical Notes
Replica-group interaction (Replica groups: horizontal scaling for single agents #927): a declared mutable data volume is precisely what makes an agent NOT replica-safe. data_paths should feed the template.yaml replica-safety declaration in docs/planning/TARGET_ARCHITECTURE.md — one declaration serving both features.
Aligns with target-architecture principle security: Fix token logging and add HTML reports to gitignore #7 (data exchange over conversation) and the sovereign-infrastructure principle — explicitly avoid per-agent S3/MinIO (new service), git-LFS (still bloats, wrong tool), or storing blobs in the platform DB (agents must not reach it; blobs don't belong there).
Volume ownership must be fixed to UID 1000 (developer), same as shared-folder volumes (Invariant Client/Viewer User Role (AUTH-002) #17, non-root containers).
Persistent state allowlist (S4) #383 (closed) — S4 persistent-state allowlist (.trinity/persistent-state.yaml): the existing "paths that survive reset" primitive; data_paths either extends it or must stay consistent with it. Flow doc: docs/memory/feature-flows/persistent-state-allowlist.md
Reset-preserve-state operation (S3) #384 (closed) — reset-to-main-preserve-state (S3): the recovery reset that snapshots/overlays allowlisted paths — must treat declared data paths correctly (they live on the volume, so reset should not touch them at all)
Replica groups: horizontal scaling for single agents #927 — Replica groups: a declared mutable data volume is the canonical replica-UNSAFE marker. data_paths should feed the template.yaml replica-safety declaration (docs/planning/TARGET_ARCHITECTURE.md §Replica Groups) — one declaration serving both features
Spike: evaluate Mesa filesystem for agent artifact storage #583 — Mesa filesystem spike: overlapping problem space (versioned non-code artifact storage). This issue is the boring-volume baseline; the spike's "replaces/complements/overlaps" assessment should evaluate against it
Bug classes to design against
P1: Duplicate mount point error on agent restart with custom_mounts #689 — duplicate mount point on container recreate when mounts are both inherited from old container metadata and re-added from config. Mount assembly for agent-{name}-data must be idempotent per destination path on the recreate path
Documentation that must follow (tiered-docs rule: new capability)
docs/memory/requirements.md — new capability entry before implementation
docs/memory/architecture.md + a docs/memory/feature-flows/ slice
Summary
Agents accumulate runtime data — SQLite databases, large incremental files, working datasets — that cannot live in the git-synced template repo (it bloats fast and doesn't belong in version control), yet must survive container recreate, template re-pulls, and subscription auto-switch, and must move with the agent when it migrates to another Trinity instance.
Proposed model: agent = code (git) + credentials (
.credentials.enc) + data (declared volume). Runtime data becomes a third declared artifact class, parallel to the existing credential pattern.Context
Today the only options are committing data to the template repo (bloat, churn, merge conflicts) or leaving it in the container filesystem (lost on recreate — exactly the events that already destroy runtime state today: template re-pull, subscription auto-switch, image upgrade). Neither is acceptable for database-backed or data-heavy agents.
The platform already has the adjacent primitives:
.trinity/persistent-state.yaml(S4, Persistent state allowlist (S4) #383) — the "paths that survive reset" allowlistagent-{name}-public, FILES-001; shared-folder volumes)get_archive) that never mounts the agent workspace (src/backend/services/agent_shared_files_service.py)~/.trinity/pre-checkhook pattern for agent-side lifecycle hooksDesign Sketch
data_paths:section intemplate.yaml(or an extension of the S4 persistent-state allowlist) listing runtime-data paths, e.g.~/data/,~/db/agent.sqlite. Gitignored by convention.agent-{name}-data), same pattern asagent-{name}-public. Survives recreate/re-pull/auto-switch.trinity-databind mount (e.g./data/agent-data-snapshots/) with retention. For SQLite, snapshot via a quiesce hook (~/.trinity/pre-snapshot, shebang-selected like pre-check) orsqlite3 .backupto avoid mid-write corruption..credentials.enc+ data snapshot tar. Extends the existing export/import surface.Acceptance Criteria
template.yaml(or persistent-state allowlist) supports declaring runtime data pathstrinity-databind mount.backup-based copy), documented for template authorsTechnical Notes
data_pathsshould feed thetemplate.yamlreplica-safety declaration indocs/planning/TARGET_ARCHITECTURE.md— one declaration serving both features.developer), same as shared-folder volumes (Invariant Client/Viewer User Role (AUTH-002) #17, non-root containers).src/backend/services/agent_service/capabilities.pyalongside the existing tmpfs/TMPDIR spec so create/recreate/system-agent can't drift (fix: agent /tmp is a 100MB noexec tmpfs — starves pip/npm/build scratch; default TMPDIR to home volume #1098 precedent).Related Work & Crosslinks
Building blocks (precedents this design reuses)
.trinity/persistent-state.yaml): the existing "paths that survive reset" primitive;data_pathseither extends it or must stay consistent with it. Flow doc:docs/memory/feature-flows/persistent-state-allowlist.mdagent-{name}-public) + backend-sideget_archiveextraction without mounting the agent workspace — the exact mount + extraction pattern this feature generalizessrc/backend/services/agent_service/capabilities.pyso create/recreate/system-agent can't drift — the data-volume mount spec must live there tooInteracting / gated work
data_pathsshould feed thetemplate.yamlreplica-safety declaration (docs/planning/TARGET_ARCHITECTURE.md§Replica Groups) — one declaration serving both features~/.trinity/pipelines/+~/.trinity/pipeline-state/#919 — Agent pipelines (~/.trinity/pipelines/,~/.trinity/pipeline-state/): pipeline state is exactly the kind of runtime data that should ride the data volume so it survives recreateBug classes to design against
agent-{name}-datamust be idempotent per destination path on the recreate pathDocumentation that must follow (tiered-docs rule: new capability)
docs/memory/requirements.md— new capability entry before implementationdocs/memory/architecture.md+ adocs/memory/feature-flows/slicedocs/agent-validation-spec.md(implemented by feat: Agent deployment compatibility validation — server-side checks with auto-fix offers #668) — new checks oncedata_pathsexists, e.g.:data_pathsentry is excluded in.gitignore(the whole point is keeping it out of git)data_pathsentries don't overlap Trinity-managed paths (.trinity/,.claude/,.env) orgit.commit_pathsdata_pathspresent ⇒ replica-safety declaration consistent (not marked replica-safe)~/.trinity/pre-snapshot(if present) is executable with a valid shebang — analog of A-004 for pre-checkdocs/TRINITY_COMPATIBLE_AGENT_GUIDE.md— template-author documentation fordata_paths+ snapshot hooks