Skip to content

Persistence Model

EdgePlane uses three complementary persistence layers. Each serves a specific role in the information lifecycle. Understanding the boundaries prevents architectural confusion.

PostgreSQL + pgvector — Structured State

Section titled “PostgreSQL + pgvector — Structured State”

The operational database. All structured entities live here:

  • Domains, missions, tasks, meshtasks
  • Artifacts (metadata — bytes are in S3)
  • Agents, mesh agents, agent runs
  • Roles and domain memberships
  • Governance policies and approval records
  • Ledger events
  • Publication records

Postgres is the coordination substrate — fast, queryable, role-scoped, vector-indexed for semantic search. Coordination truth stays in Postgres, not Git.

pgvector enables hybrid search across all entities — tasks, documents, and missions are indexed for similarity queries alongside standard relational lookups.

S3-Compatible Object Storage — Working File Store

Section titled “S3-Compatible Object Storage — Working File Store”

Artifact bytes, document content, workspace files, and skill bundles are stored in S3-compatible object storage, not inline in the database.

Storage path layout:

domains/{domain_id}/missions/{mission_id}/{entity}/{filename}

Agents can read, write, and iterate on file content without polluting the structured state database. Storage scales independently. Any S3-compatible backend works — AWS S3, MinIO, or self-hosted alternatives — with no code changes.

S3 is not optional infrastructure. It is where active work lives.

The Docker Compose development stack ships with an S3-compatible backend bundled. No external infrastructure is required to run locally with full file persistence.

When a mutation is approved and published, it is committed to Git. Artifact provenance metadata (repo, branch, path, commit hash) is written back to Postgres, creating a permanent link between the operational record and the historical record.

Git is a projection sink, never the authority for domain ownership, approvals, or governance. Those live in Postgres.

1. Mutation enters ledger (status: pending) in Postgres
2. Approval / policy checks run in EdgePlane
3. Route resolver picks binding / repo / branch / path from domain policy
4. Provider adapter acquires server-side credential
5. Publisher writes canonical file(s) to Git
6. Commit provenance recorded — repo, branch, path, commit hash
7. Ledger / publication records marked and queryable via API / MCP

The data model supporting this:

TablePurpose
repo_connectionsGit provider credentials
repo_bindingsDomain → repo mappings
domain_persistence_policiesGovernance rules for publication
domain_persistence_routesEntity-type → path routing
publication_recordsCompleted publication audit trail
Agent produces artifact
S3 (working store)
domains/{domain_id}/missions/{mission_id}/...
│ Mutation recorded
Postgres (structured state)
missions, tasks, artifacts, roles, ledger
│ Approval granted
Git (memory of record)
commit → provenance written back → full chain of custody

Postgres for coordination: structured entities need transactions, role-based access, vector indexing, and fast point queries. File storage in Postgres doesn’t scale.

S3 for working files: artifact bytes are large, frequently mutated during active work, and need to be scoped per domain/mission. Postgres blobs don’t scale; S3 does.

Git for memory of record: Git provides immutable, auditable, reproducible history outside the control plane. If the Postgres instance were lost, Git contains the full audit trail of every approved, published mutation. This creates an organizational knowledge base that survives infrastructure changes.

Terminal window
edgeplane daemon mission ls --json
edgeplane daemon task ls --json
# or via MCP tools: list_pending_ledger_events, get_entity_history

All entities are indexed in pgvector. Use search_tasks, search_missions, or the --search flag on CLI commands for hybrid full-text + vector search.

Terminal window
edgeplane data sync status --mission-id <id>
# or via MCP: get_publication_status, resolve_publish_plan