Goldens and imports

This is the deeper reference for curating golden snapshots: source connections, the import lifecycle, immutable versions, sharing, and delete semantics. For the linear walkthrough, see Getting started: admin.

Source connections

$ adj source create --host prod-replica.abcdef.us-east-1.rds.amazonaws.com \
    --dbname app --username adjoint_ro
Read-only DB password:
Source 3e6f0a2b-7c8d-4e1f-9a2b-3c4d5e6f7a8b registered (endpoint metadata only).
Credentials Secret adjoint-import/adjoint-src-app applied to the data-plane cluster.

Next: adj import run --source 3e6f0a2b-7c8d-4e1f-9a2b-3c4d5e6f7a8b --golden <name>

adj source create registers the connection endpoint and a credentials Secret name with the control plane — endpoint metadata only. The actual username and password are written straight into your data-plane cluster as a Kubernetes Secret (default name adjoint-src-<dbname>, namespace adjoint-import) via kubectl — they never transit or persist in the Adjoint control plane. If you need to (re)apply that Secret by hand (or you passed --skip-secret), adj import secret-template emits the manifest for kubectl apply.

adj source ls lists registered connections and their ids.

The import lifecycle

$ adj import run --source 3e6f0a2b-7c8d-4e1f-9a2b-3c4d5e6f7a8b --golden prod-pg16 --pg-major 16 --wait
waiting for import 5b9d7c31-2e4f-4a6b-8c0d-1e2f3a4b5c6d: Pending.. -> Probing -> Provisioning -> Importing..... -> Snapshotting -> Registering -> Cleaning -> Succeeded
ID:        5b9d7c31-2e4f-4a6b-8c0d-1e2f3a4b5c6d
Source:    3e6f0a2b-7c8d-4e1f-9a2b-3c4d5e6f7a8b
Golden:    prod-pg16
Version:   v1
PG Major:  16
Phase:     Succeeded
Message:
Size:      42.0Gi
Created:   2026-07-18T21:03:12Z
Finished:  2026-07-18T21:09:53Z

An import spins up an ephemeral Postgres in the data-plane cluster, streams a dump from the source into it, snapshots the resulting volume, and registers the snapshot as the next version of the --golden lineage. --source takes the source connection id (a UUID, from adj source ls), and --pg-major must match the source's Postgres major version (defaults to 16).

adj import run returns immediately with the job id and the version it reserved — the import runs asynchronously, and developers keep cloning older versions of the golden while it builds. Add --wait to poll until the job reaches Succeeded or Failed, printing each phase transition as it happens (the lifecycle runs PendingProbingProvisioningImportingSnapshottingRegisteringCleaningSucceeded/Failed; --timeout, default 24h, caps how long --wait polls).

Inspect jobs with adj import ls and adj import get <id>.

Re-run adj import run any time to build a fresh version from a new dump. Existing clones of older versions are unaffected — nothing re-clones or restarts under them.

Versions are immutable

Each import produces a new, numbered, immutable version of the golden lineage (v1, v2, …). Nothing ever mutates a version in place.

Sharing

Newly imported goldens are admin-private by default: visible and cloneable only by admins. Developers won't see them in adj catalog until you share them:

$ adj catalog share prod-pg16
Golden "prod-pg16" is now shared with the org.

--revoke reverts a golden to admin-private. Existing clones of it keep running either way — sharing only changes future visibility, not anything already cloned.

$ adj catalog share prod-pg16 --revoke
Golden "prod-pg16" is now private to admins.

Deleting a golden

$ adj catalog delete prod-pg16

By default this blocks with a 409 if any instances are still cloned from it:

Error: golden has live child instances (HTTP 409)
hint: destroy the child instances first, or re-run with --force to cascade them

Nothing is deleted in that case — the golden and its clones are untouched.

--force cascades: it destroys the golden and every running clone of it. You'll see a blast-radius confirmation prompt first (skip it with --yes); add --wait to block until the golden and its clones are actually gone (--timeout, default 15m).

$ adj catalog delete prod-pg16 --force --wait

One thing --force does not cascade: import history. A golden that was built by adj import run keeps its import record, and the control plane refuses the delete outright — even with --force — while that record (or a clone pool) still references it:

Error: conflict: golden is still referenced by an import record or clone pool (HTTP 409)
hint: a clone pool still references this golden — remove it first ('adj pool rm <pool>');
goldens created by an import keep their import record and cannot be catalog-deleted

If a clone pool pins the golden, remove the pool first (adj pool rm <pool-id>); a lingering import record means the golden lineage is meant to stay — delete individual versions is not supported from the CLI today.

Next