|
| 1 | +# ADR-0007 — Local-first control node and image promotion seam |
| 2 | + |
| 3 | +Status: Proposed |
| 4 | + |
| 5 | +## Context |
| 6 | + |
| 7 | +We now have a concrete working control-node prototype on macOS that proves the operator-side envelope for SourceOS and SociOS Linux work: |
| 8 | + |
| 9 | +- nix-darwin-managed host configuration on the operator machine |
| 10 | +- Podman machine + OCI image build/push/run path |
| 11 | +- Artifact Registry push path for `node-commander` |
| 12 | +- user-scoped launchd agent wiring for a local control/runtime helper |
| 13 | + |
| 14 | +That work is valuable, but it is not yet canonically placed in the typed-contract stack. Without an explicit contract boundary, Linux image generation, image validation, node control, and issue/task promotion risk being implemented as local glue rather than shared SourceOS contract surfaces. |
| 15 | + |
| 16 | +The current repo topology already separates concerns: |
| 17 | + |
| 18 | +- `sourceos-spec` is the typed-contract / canonical spec lane |
| 19 | +- `SociOS-Linux/source-os` is the workstation/profile/bootstrap lane |
| 20 | +- `SocioProphet/agentplane` is the execution control-plane and evidence lane |
| 21 | +- `SocioProphet/prophet-platform` is the runtime / deployable service lane |
| 22 | + |
| 23 | +This ADR reserves the local-first control-node and image-promotion seam in that topology. |
| 24 | + |
| 25 | +## Decision |
| 26 | + |
| 27 | +### 1. Local-first is a contract rule, not a weak preference |
| 28 | + |
| 29 | +Control-node and image-validation placement follows a hard ordering: |
| 30 | + |
| 31 | +1. local operator machine / local eligible executor |
| 32 | +2. trusted private Linux builder or owned cluster |
| 33 | +3. attested fog executor |
| 34 | +4. burst cloud only when explicitly enabled by policy |
| 35 | + |
| 36 | +This ordering is part of the SourceOS/SociOS contract posture and should not be reduced to a mere cost-weighting preference. |
| 37 | + |
| 38 | +### 2. The control node is a distinct contract surface |
| 39 | + |
| 40 | +We reserve a contract family for the operator-side control node. The control node is responsible for: |
| 41 | + |
| 42 | +- building or dispatching candidate image builds |
| 43 | +- launching validation scenarios |
| 44 | +- staging the Node Commander runtime |
| 45 | +- emitting evidence that determines whether a candidate build may update a Git repository and mark a task complete |
| 46 | + |
| 47 | +This family is not fully machine-readable yet, but its first contract objects are expected to include: |
| 48 | + |
| 49 | +- `ControlNodeProfile` |
| 50 | +- `NodeCommanderRuntime` |
| 51 | +- `ImagePromotionGate` |
| 52 | +- `BuildValidationEvidenceBundle` |
| 53 | + |
| 54 | +### 3. Node Commander is a runtime role, not the canonical contract home |
| 55 | + |
| 56 | +`Node Commander` is the small operator-side runtime/agent responsible for local node command, OCI execution, and first-step orchestration. It may be packaged as a local binary or OCI image, but its canonical meaning belongs upstream in the spec lane, not only in host-specific bootstrap code. |
| 57 | + |
| 58 | +The initial runtime assumptions are: |
| 59 | + |
| 60 | +- user-scoped execution on the operator node |
| 61 | +- Podman / OCI first |
| 62 | +- explicit config, state, and evidence directories |
| 63 | +- no Docker-specific dependency in the canonical path |
| 64 | +- evidence-bearing execution suitable for downstream promotion gating |
| 65 | + |
| 66 | +### 4. Image promotion is evidence-gated |
| 67 | + |
| 68 | +A SourceOS or SociOS Linux candidate build may not update the relevant Git repository and may not mark an issue/task done until promotion gates pass. |
| 69 | + |
| 70 | +At minimum, the promotion seam must be able to express: |
| 71 | + |
| 72 | +- build identity and provenance |
| 73 | +- target profile / image identity |
| 74 | +- scenario results |
| 75 | +- validation receipts |
| 76 | +- policy decision inputs and outputs |
| 77 | +- promotion decision |
| 78 | +- reversal / rollback reference when applicable |
| 79 | + |
| 80 | +This ADR reserves that seam in the typed-contract lane even though the exact machine-readable schemas will follow in later PRs. |
| 81 | + |
| 82 | +### 5. Repo ownership split |
| 83 | + |
| 84 | +This ADR fixes the current ownership split: |
| 85 | + |
| 86 | +- `SourceOS-Linux/sourceos-spec` |
| 87 | + - canonical typed contracts and ADRs for control-node and image-promotion concepts |
| 88 | +- `SociOS-Linux/source-os` |
| 89 | + - workstation/bootstrap application of the operator-node profile |
| 90 | +- `SocioProphet/agentplane` |
| 91 | + - downstream execution, placement, validation, replay, and evidence consumption |
| 92 | +- `SocioProphet/prophet-platform` |
| 93 | + - deployable runtime implementations once Node Commander and adjacent services stabilize |
| 94 | + |
| 95 | +## Consequences |
| 96 | + |
| 97 | +### Positive |
| 98 | + |
| 99 | +- prevents local operator-node work from remaining orphaned implementation glue |
| 100 | +- gives Linux image generation and validation a canonical contract lane |
| 101 | +- gives `agentplane` a clear downstream seam for promotion/evidence consumption |
| 102 | +- gives `source-os` a clear downstream seam for workstation/control-node bootstrap |
| 103 | + |
| 104 | +### Constraints |
| 105 | + |
| 106 | +- this ADR does not itself add schemas |
| 107 | +- this ADR does not declare Docker helper behavior canonical |
| 108 | +- this ADR does not move runtime implementation ownership into `sourceos-spec` |
| 109 | + |
| 110 | +## Follow-on work |
| 111 | + |
| 112 | +1. Define the first machine-readable starter schemas for: |
| 113 | + - `ControlNodeProfile` |
| 114 | + - `NodeCommanderRuntime` |
| 115 | + - `ImagePromotionGate` |
| 116 | + - `BuildValidationEvidenceBundle` |
| 117 | +2. Bind the downstream execution/evidence consumption seam in `SocioProphet/agentplane`. |
| 118 | +3. Bind the workstation/bootstrap application seam in `SociOS-Linux/source-os`. |
| 119 | +4. Bind runtime implementation work in `SocioProphet/prophet-platform` once the real Node Commander implementation replaces the current bootstrap placeholder. |
0 commit comments