Skip to content

ADR 0001: Durable Single-Replica State

Status: accepted · Tracking: AB#7671, AB#7672

Decision

Project Marvin uses versioned JSON state on one durable filesystem mounted by exactly one active runtime replica. Local development uses the repository-local .marvin directory. Azure Container Apps mounts one Azure Files share at /data and is fixed at minReplicas: 1 and maxReplicas: 1.

Token and provider-secret files use AES-256-GCM authenticated encryption. Local development creates a permission-restricted data-protection key under .marvin/keys. Hosted mode refuses credential access unless MARVIN_DATA_PROTECTION_KEY is supplied from the deployment secret store.

All runtime state writes use a same-directory temporary file, flush it, and atomically rename it over the previous version. Each state document records _schemaVersion; the runtime rejects versions newer than it understands.

Why this design

  • Reliability: atomic replacement prevents an interrupted write from corrupting the last valid document.
  • Operating cost: Azure Files and one Container App replica match the initial single-workspace product without adding a database service.
  • Consistency: one writer avoids distributed locking and split-brain mapping updates.
  • Security: provider credentials are not readable from persisted JSON or portal responses.
  • Portability: the engine uses the same storage interface locally and in Azure.

Constraints

  • Scaling above one active replica is unsupported until state moves to a transactional database or distributed locking is implemented.
  • The data-protection key must be backed up separately from encrypted state and preserved during deployment upgrades.
  • Filesystem snapshots or Azure Files backup provide point-in-time recovery; copying live files individually is not a consistent backup procedure.
  • Schema migrations must be forward-only, tested from the oldest supported version, and performed before the runtime begins provider work.

Rejected alternatives

  • In-memory state: loses sessions, mappings, subscriptions, and activity on restart.
  • Plain JSON secrets: exposes refresh tokens and app passwords in the mounted share.
  • Multiple writable replicas on Azure Files: requires coordination that the current product does not provide.
  • A managed database in the first release: stronger scaling characteristics but unnecessary cost and operational complexity for one workspace.

Recovery

Restore the Azure Files snapshot and its matching data-protection key, deploy the same or a migration-compatible application version, validate state schemas, run Diagnostics, and only then resume synchronization.