Atrium
platform docsManifest lifecycle

Atrium platform docs

Manifest lifecycle

How CLI edits, dashboard edits, git, and resolved state avoid drifting from each other.

Updated 2026-08-30

One write path

The CLI and future dashboard are two clients of one validating control-plane API. Neither writes directly to Cloud Run, Neon, DNS, container registries, or the other client.

This is the same pattern Otto already uses for resume link content: visual editing and JSON editing are two views over one data shape, and saving always goes through one validation path.

Desired state

Desired state is the atrium.yaml checked into the agent repo. It contains only developer-owned intent:

  • metadata
  • service paths
  • build commands
  • allowed build env
  • requested scaling limits
  • hosting and CI intent

If a value should not be in git, it should not be in desired state.

Resolved state

Resolved state lives in the control plane. It starts with desired state, then adds platform-owned values:

  • API base URLs
  • database credentials
  • Cloud Run service names
  • regions
  • deployment status
  • resolved environment

atrium status and atrium env <service> read resolved state. The manifest does not.

Dashboard edits become commits

A dashboard edit should not become a hidden database row that diverges from the repo. The intended model is bot-authored commits or pull requests back to the agent repo, similar to Renovate or Dependabot.

The git file remains the durable record of what was requested, no matter which surface requested it.

Sync pulls

atrium sync

sync reconciles remote desired state into the local checkout. It should be explicit and one-way. It should not push local changes in the background and should not hide drift between local files and the control plane.

Deploy records a request

atrium deploy validates the manifest and creates a deployment request in the control plane. The backend can dispatch that request to a deploy worker when ATRIUM_DEPLOY_WEBHOOK_URL is configured.

Without a worker URL, the request can remain queued. That is expected during bring-up and should be visible through status.