Config deployment
Configuration in System9 is declarative desired state, not a set of files an operator edits on each box. An administrator declares intent once, as a Deployment preset or a hand-authored Worker Policy, the platform signs it, and every cell resolves it, reconciles to it, and attests what it actually ran. Code moves the same way: as signed packages rolled out to named cohorts ring by ring, with drift observed rather than assumed. This page is the full cycle and the operator surfaces that drive it.
Three surfaces participate, and they are deliberately different tools for different jobs:
- The Deployment console, turnkey presets that author config for a whole cell at once.
- The Fleet Releases console, moving signed code across a fleet.
- The administrator portal, provisioning the cells that config then targets.
The declarative config cycle
Figure: the declarative config cycle. Cells are provisioned from the portal; config is declared either as a Deployment preset or by authoring Worker Policy directly, and both converge on one signed desired state (green). Each cell resolves that state through its scope ladder, reconciles to it, and attests what it ran, the attestations feed the drift view the operator authors against. Code moves on a parallel track: Fleet Releases ships signed packages that roll out ring by ring (cyan) behind a health/drift gate.
Table equivalent
| Step | Surface | What it declares / does | Result |
|---|---|---|---|
| Provision | Portal → Deployments | Name, cell count, target regions | Cells exist, bound to a license |
| Declare (preset) | Console → Deployment | Apply a turnkey archetype | Authors a signed Worker Policy |
| Declare (direct) | Console → Worker Policy | Author scope + capability switches | A signed Worker Policy |
| Resolve | Every cell | Merge the scope ladder | A per-cell EffectiveConfig |
| Reconcile | Every cell | Diff and revert drift each tick | Running state matches desired |
| Attest | Every cell | Sign digest + observed state | Fleet drift dashboard |
| Ship code | Console → Fleet Releases | Signed package → track → cohort → rings | Rolled-out release, gated per ring |
Deployment presets: turnkey config for a cell
The fastest way to configure a cell is to apply a Deployment preset: a named, turnkey archetype that bundles a cell profile, an AI profile, vertical platforms, and a sizing hint into a working starting config the operator then refines.
In the console: Deployment
The Deployment console lives in the Core System console at /core/deployment
(the "Deployment" nav entry, turnkey preset archetypes). It shows:
- Deployment preset, a card grid of archetypes (each with its cell profile, AI profile, and verticals), an active-preset badge, and an Apply preset action. When a preset touches high-consequence feature groups, apply first opens a confirm dialog citing the net-potential-gain gate.
- Feature groups: when viewing the active preset, each group is a live toggle ("toggle a group to deviate from the preset"), with a per-group reset to the preset default and high-consequence badges.
Applying a preset authors Worker Policy. This is the key linkage: apply a preset, or toggle a feature group, and the platform authors (or re-authors) the underlying signed Worker Policy for that scope, the console proves it by refreshing the Worker Policy view after every deployment mutation. The signing and the value-gate enforcement happen at the backend control plane, exactly as described in Worker Policy → apply is governed. A preset is therefore a convenience layer over the same signed-policy engine, not a separate deploy path.
Both surfaces are gated at the backend BFF (under the public admin/deployment/*
path); the console pages perform no client-side capability check.
Fleet Releases: moving code across a fleet
Where Deployment presets and Worker Policy declare a cell's config, Fleet Releases moves its code: signed packages and manifests, release tracks, named cohorts, and ring-by-ring rollout with a health-and-drift gate between rings. The mechanics are documented in Edge & fleet management; this section ties them to the operator surface.
In the console: Fleet Releases
The Fleet console is a tree under /core/fleet in the Core System console:
| Route | Nav label | What it does |
|---|---|---|
/core/fleet | Fleet | Rollouts, drift, peer-relay, sneakernet, packages, bays & tracks |
/core/fleet/devices | Devices | Enrolled devices; per-device detail |
/core/fleet/topology | Fleet topology | The fleet's shape |
/core/fleet/install-tokens | Install tokens | Issue single-use enrollment tokens |
/core/fleet/brought-online | Brought online | Cells and devices as they come online |
/core/fleet/policy | Fleet policy | Edge/fleet policy |
/core/fleet/policy-bundles | Policy bundles | Bundled edge policy |
Unlike the Worker Policy console, several Fleet surfaces self-gate on explicit
capability strings (mirrored from the backend's system.fleet.* namespace):
| Action / surface | Gating capability |
|---|---|
| Issue an install token | system.fleet.deploy.write |
| Read fleet / edge policy | system.fleet.policy.read |
| Edit fleet / edge policy | system.fleet.policy.write |
| Edit a policy bundle | system.fleet.bundle.write |
| Read "brought online" | system.fleet.brought_online.read |
On the main Fleet page, the Rollouts tab carries the write actions, Start / Pause / Resume / Cancel / Roll back per rollout, plus an Override gate action that submits a signed reason and is audit-logged. The Drift, Peer-Relay, Sneakernet, Packages, and Bays & Tracks tabs are read-only views.
Publishing a package is an operator action: a form takes the signed manifest and
the bundle, and the resulting package id and signature come back on success. The
button is absent unless the operator holds system.fleet.package.publish.
GitOps apply is an action too: paste the desired-state YAML, preview the
reconciler's diff as a dry run, then apply against the live fleet behind a
confirmation, with the signed-in operator recorded as the actor. Reading that
editor needs system.fleet.deploy.read and applying needs
system.fleet.deploy.write, so an operator with read alone sees the diff and no
Apply. A policy-bundle YAML editor is present, validated against a schema.
Two capabilities are defined with no UI action behind them:
system.fleet.package.yank and system.fleet.drift.remediate. A yanked package
shows a status badge, but nothing in the console yanks one, and the Drift tab
reports drift without a remediate button. Both are reachable only through the API.
Provisioning from the portal
Before there is a fleet to configure, cells are provisioned from the administrator portal. The provisioning surface is org-scoped and separate from the operator console.
In the portal: Deployments
| Route | Access | What it does |
|---|---|---|
/deployments | Any authenticated org member | Lists the org's deployments as status cards |
/deployments/new | Org member (the write is role-gated at the API) | A form: deployment name, cell count (1–100), and target regions |
/deployments/[id] | Org member; org-scoped | Read-only detail: cells, region, last sync, and the bound license |
The portal's authority model layers three gates: the portal layout requires
authentication; role helpers (canManageDeployments = owner or admin) gate the
mutating API; and org scoping ensures a caller only ever sees their own org's
deployments. See Administration & Configuration
for the full portal gating model.
The target regions offered in /deployments/new are a hardcoded list in the
page, and the deployment list/detail views are not role-gated (any org member can
view); the role check (canManageDeployments) is enforced on the create API, not
on the page. These are current implementation facts, not the intended end state.
Attestation closes the loop
Declaring config is only half of it; the platform also proves the fleet ran it. Every cell ships a signed attestation of its resolved config digest and observed worker state, and those attestations drive the Fleet drift view an operator authors against. The mechanism is described in full under Worker Policy → attestation: config deployment is not write-only, so an operator can always see the difference between what was declared and what is actually running.
Across the deployment matrix
| Corner | How config deployment behaves |
|---|---|
| Single-cell | Provision one cell, apply a preset or author policy locally; resolve, reconcile, and attest happen on the box; a rollout has one ring. |
| Multi-cell (elastic) | One signed desired state targets many cells; each resolves it from the shared scope ladder; releases roll out ring by ring across cohorts with a gate between rings. Ephemeral cells resolve config and stand up at boot. |
| Sovereign / air-gapped | Presets, policy, and package verification are offline; packages arrive over air-gapped bundles outside the transport ladder; attestations move cell-to-cell with no coordinator. |
| Cloud-enabled | The same declarative cycle; connectivity changes propagation speed, not the contract. |
Related topics
- Worker Policy, the signed-policy engine a Deployment preset authors, and the drift/attestation model.
- Config Policy, the unified plane the preset's config resolves through: nine sections plus services, topology-scoped, with tiered delegated authz and a config-change audit.
- Edge & fleet management, the transport ladder and the release mechanics behind Fleet Releases.
- Deployment topology, the deployment matrix and the region → zone → rack → cell hierarchy config targets.
- The licensing lifecycle, the license a provisioned deployment binds to.