opbox

The setup.* family (13 verbs). Every verb enters through the one front door: it is capability-checked, permission-checked, scope-checked and audited before it runs (see Security & permissions). Each entry below lists its capability, risk class (which fixes the minimum autonomy level), the minimum caller permission, its availability tier, whether it is idempotent, and any outbound egress.

Adoptsetup.adopt

PropertyValue
Capabilitysetup.write
Risk classDestructive - autonomy L3
Min. permissionOwner
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)

(catalogue L471). Adopt a generic/published vertical as the basis for a workspace setup (the consume side of setup.publish). The repo-provided template bundle is supplied as sourceManifest (the OCF-style portable contents) + its sourceKey/sourceVersion provenance; adopt lands it as a LOCAL bundle keyed key, PINNING the adopted version (R11 - the adopting box keeps its pinned version even if the source later publishes a newer one). IDEMPOTENT (re-adopt = no-op): re-adopting the SAME source key+version onto the SAME local key is a no-op-shaped success; adopting a DIFFERENT version updates the pin + manifest. The adopted bundle lands PUBLISHED at version 1 (it is an adoptable artifact), ready for setup.apply (ADR-0011).

Input { key, sourceKey?, sourceManifest?, sourceVersion? } (fields ending in ? are optional)

Call POST /v/setup.adopt with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Applysetup.apply

PropertyValue
Capabilitysetup.write
Risk classDestructive - autonomy L3
Min. permissionOwner
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)

The ADR-0011 reconcile-from-PG edge: instantiate/activate the defined vertical onto THIS workspace by recording the applied version = the bundle’s current_version. IDEMPOTENT (the catalogue’s load-bearing property): re-applying the already-applied version is a NO-OP-SHAPED success (applied=false, “nothing to reconcile”), never a re-instantiation. A DRAFT-only bundle (current_version 0) cannot be applied (there is no pinned version to reconcile from). Any derived projection (a board materialisation, a Policy activation) is FIRE-AND-FORGET off this record (INV-2): the applied_version stamp is the transition; the constituents are reconciled off-band from the pinned snapshot, never gating this write.

Input

FieldTypeRequiredDescription
keystringyes

Call POST /v/setup.apply with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Archivesetup.archive

PropertyValue
Capabilitysetup.write
Risk classDestructive - autonomy L3
Min. permissionOwner
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)

(catalogue L469). Withdraw the bundle from new adoption/instantiation: state -> ARCHIVED. PRESENT-IFF-AUTHORED BECOMES ABSENT-BY-ARCHIVE (ADR-0034): an archived vertical’s verbs are then denied by absence (INV-11 still denies an un-authored verb by absence). REVERSIBLE only via a new version (re-author + publish); history + any in-flight matters pinned to a superseded version are RETAINED/immutable (R11, INV-8 - never a hard delete). Idempotent: archiving an already-ARCHIVED bundle is a no-op-shaped success.

Input { key } (fields ending in ? are optional)

Call POST /v/setup.archive with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Definesetup.define

PropertyValue
Capabilitysetup.write
Risk classDestructive - autonomy L3
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)

Author or edit a vertical’s config bundle: a named set of constituent refs (verb-packs / matter+doc templates / Policy rule-sets / SOULs). UPSERT on (workspace, key): re-defining the same key edits the bundle IN PLACE (idempotent re-author - never a duplicate). A define always lands the bundle in DRAFT-editable terms (it does NOT auto-publish; INV-9 - publish is the separate gated promotion). The manifest shape is validated at the verb (the keys it accepts are the constituent arrays); an unknown top-level manifest key is rejected (fail-closed lint).

Input

FieldTypeRequiredDescription
keystringyes
namestringno
descriptionstringno
manifestobjectno{verbPacks, matterTemplates, docTemplates, policies, souls}

Call POST /v/setup.define with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool setup.define.

Diffsetup.diff

PropertyValue
Capabilitysetup.read
Risk classRead - autonomy L0
Min. permissionAdmin
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - drives an inline chat artefact and a GUI panel

What would change: diff the bundle’s CURRENT authored manifest against a TARGET. The default target is the LIVE-APPLIED state (the snapshot at applied_version, or empty if never applied) - so the diff answers “what would setup.apply reconcile?”. A caller may instead supply an explicit target manifest to diff against (a pre-flight comparison). The diff is a per-constituent-bucket add/remove/keep set over the manifest arrays (verbPacks / matterTemplates / docTemplates / policies / souls). Pure-PG read, no mutation.

Input { key, target?: applied|<manifest> } (fields ending in ? are optional)

Call POST /v/setup.diff with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Exportsetup.export

PropertyValue
Capabilitysetup.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - drives an inline chat artefact and a GUI panel

Serialize the bundle into a portable, self-describing envelope (the transfer twin of setup.status, but shaped for setup.import / cross-box adoption rather than the ops console). The envelope carries the bundle’s KEY, name/description, current state + version, the authored manifest, and the adoption provenance - everything setup.import needs to re-create the bundle on another box. It is a PURE-PG read (no mutation): RLS-scoped, so another workspace’s bundle reads back not-found (anti-enumeration). The envelope is the wire format - it carries NO ids/timestamps (a re-imported bundle gets a fresh local id), only the workspace-portable authoring content.

Input { key } (fields ending in ? are optional)

Call POST /v/setup.export with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool setup.export.

Getsetup.get

PropertyValue
Capabilitysetup.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - drives an inline chat artefact and a GUI panel

Read a single vertical-setup bundle by setupId: the bundle’s core (id, key, name, description, state, currentVersion, appliedVersion), the authored manifest, adoption provenance (adoptedFromKey, adoptedFromVersion), and the immutable changelog (version snapshots, newest first). RLS-scoped; a bundle in another workspace reads back not-found (anti-enumeration, the matter.get / permission shape). Pure-PG read, no mutation.

Call POST /v/setup.get with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Importsetup.import

PropertyValue
Capabilitysetup.write
Risk classDestructive - autonomy L3
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)

The consume side of setup.export: re-create (or re-author) a bundle on THIS workspace from a portable envelope. An envelope (the setup.export output) supplies key/name/description/manifest in one blob; explicit top-level fields override the envelope (a caller may rename on import). UPSERT on (workspace, key) - importing onto an existing key edits it IN PLACE (idempotent re-import - never a duplicate). An import always lands the bundle in DRAFT-editable terms (it does NOT auto-publish; INV-9 - publish is the separate gated promotion, exactly as setup.define). The manifest is validated at the verb (fail-closed lint - an unknown bucket / non-array is a BadInput). It does NOT carry the source state/version: an imported bundle is a fresh local DRAFT, re-published locally (R11 - the importing box owns its own version line), never silently re-stamped PUBLISHED from the wire.

Input { key?, name?, description?, manifest?, envelope? } (fields ending in ? are optional)

Call POST /v/setup.import with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool setup.import.

Listsetup.list

PropertyValue
Capabilitysetup.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - drives an inline chat artefact and a GUI panel

List the workspace’s vertical-setup bundles, optionally filtered by status (DRAFT/PUBLISHED/ARCHIVED). Returns an array of bundle summaries: id, key, name, version, state, createdAt. Paginated (limit resolved from input). RLS-scoped; a workspace cannot see another’s bundles (anti-enumeration). Pure-PG read, no mutation.

Input

FieldTypeRequiredDescription

Call POST /v/setup.list with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Publishsetup.publish

PropertyValue
Capabilitysetup.write
Risk classDestructive - autonomy L3
Min. permissionOwner
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)

Promote the bundle’s authored manifest to a PUBLISHED version: bump current_version, flip state to PUBLISHED, and MINT an immutable version snapshot (ADR-0027, the reuse-the-Version-spine seam - NOT a new versioning engine). The snapshot is the exact manifest at publish time, so an adopter pins a real immutable cut. publish is the precondition for adopt (a DRAFT bundle is not adoptable - L240 “promote a version to the adoptable catalogue”). An ARCHIVED bundle cannot be published (un-archive is via a new define+publish cycle); re-publishing a PUBLISHED bundle cuts the NEXT version (history-preserving).

Input

FieldTypeRequiredDescription
keystringyes
changelogstringno

Call POST /v/setup.publish with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool setup.publish.

Rollbacksetup.rollback

PropertyValue
Capabilitysetup.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)

The reconcile-recovery edge (ADR-0011): roll the live workspace back to a PRIOR published version by re-applying the snapshot at version. The target version must be a real, already-minted version snapshot for this bundle (1 <= version <= current_version) - a version with no snapshot, or a future/zero version, is a fail-closed BadInput (you cannot reconcile from a cut that was never published). This does NOT mutate current_version or the published history (R11 - the version line is immutable); it only re-points applied_version at the chosen prior snapshot, so the live workspace reconciles to it (the constituents are reconciled off-band, INV-2, never gating this write). IDEMPOTENT: rolling back to the already-applied version is a no-op-shaped success (rolledBack:false), never a re-reconcile.

Input { key, version } (fields ending in ? are optional)

Call POST /v/setup.rollback with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool setup.rollback.

Statussetup.status

PropertyValue
Capabilitysetup.read
Risk classRead - autonomy L0
Min. permissionAdmin
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - drives an inline chat artefact and a GUI panel

The TTS-measurable bundle artifact read: the bundle’s state, currentVersion, appliedVersion, DRIFT (is the live workspace reconciled to the current version?), the manifest contents, and the changelog (the immutable version history). RLS-scoped; a bundle in another workspace reads back not-found (anti-enumeration).

Input { key } (fields ending in ? are optional)

Call POST /v/setup.status with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Unpublishsetup.unpublish

PropertyValue
Capabilitysetup.write
Risk classDestructive - autonomy L3
Min. permissionOwner
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)

Withdraw a PUBLISHED bundle from the adoptable catalogue by demoting it back to DRAFT (the reverse of setup.publish, the milder twin of setup.archive). A DRAFT bundle is not adoptable (setup.adopt / a fresh setup.apply key off PUBLISHED), so unpublish takes the bundle off the catalogue WITHOUT archiving it - it stays editable (setup.define) and re-publishable. The minted version snapshots + current_version are RETAINED (R11 - the immutable history is never rewound); any in-flight matter pinned to a published version is unaffected. ONLY a PUBLISHED bundle can be unpublished: a DRAFT bundle is a fail-closed Conflict (nothing to demote), and an ARCHIVED bundle is a Conflict (un-archive is a new define+publish cycle, ADR-0034). Not idempotent: a re-unpublish of a now DRAFT bundle is the same Conflict (it is no longer PUBLISHED).

Input { key } (fields ending in ? are optional)

Call POST /v/setup.unpublish with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool setup.unpublish.