Skip to content

feat(orchestrate): C5b — wire the real up-saga phases (spec 09) - #9

Merged
gustavobertoi merged 1 commit into
mainfrom
nightly/C5b
Jun 29, 2026
Merged

feat(orchestrate): C5b — wire the real up-saga phases (spec 09)#9
gustavobertoi merged 1 commit into
mainfrom
nightly/C5b

Conversation

@gustavobertoi

Copy link
Copy Markdown
Contributor

Chunk C5b (M2-remainder) — concrete up phases

Assembles the real up phases over the C5a engine (BuildUp → []Phase), driven by the resumable/compensating Saga.

preflight → network → generate → shared(health-gated) → compose-up(per project) → hooks(postUp, per project)

Phases

  • preflight — docker daemon reachable (full doctor matrix is X6).
  • network — idempotent EnsureNetwork(devstack_shared) under the flock; never auto-removed (no compensation).
  • generateGenerateAll + writeIfChanged; runs before the compose phases (files must exist to up); re-armed by a config edit.
  • sharedRegisterUp ref rows + compose up -d only the shared services the requested projects uses, then health-gate each (Healthy if it declares a healthcheck, else Started) via internal/health. Compensation drops the refs.
  • compose-up (per project) — compose up -d (+ optional --build); compensation compose down (never -v — a failed up never drops volumes).
  • hooks (per project) — postUp via internal/hooks (OSExecer + DB ledger + flock).

Engine refinement

A failed mutating phase now runs its own compensation too (it may have partially applied — e.g. compose-up created containers) while its saga_phase row is kept failed (so status can surface it); succeeded phases still unwind in reverse with rows cleared.

Deferred + flagged

Slot in as more phases with no engine change: clone (gitx), provision (needs the shared-Postgres host-port coupling — the flagged design item), secrets (M4/S6), trust (N5), firstRun hooks (need the provisioned-volume scope_key).

Tests

Mock docker client + fake compose runner + real temp ledger + real temp workspace over the embedded templates: full happy path (network ensured, refs added, both stacks up'd, files written, postUp ran), near-instant re-run (all skips bar AlwaysRun preflight/hooks), and a project compose-up failure → shared refs compensated to zero + project downed.

The real end-to-end daemon test lands with G1's isolation harness (the saga must not touch a real devstack_shared; G1 parameterizes a devstack-it-<pid> network/prefix).

Gate

make ci + make determinism green (race included).

🤖 Generated with Claude Code

Assemble the concrete up phases over the C5a engine (BuildUp → []Phase):

  preflight → network → generate → shared(health-gated) →
  compose-up(per project) → hooks(postUp, per project)

- preflight: docker daemon reachable (full doctor matrix is X6).
- network: idempotent EnsureNetwork(devstack_shared) under the flock — never
  auto-removed (no compensation).
- generate: GenerateAll + writeIfChanged; runs BEFORE the compose phases (the
  files must exist to `up`) and re-arms on a config edit (fingerprint = the
  on-disk workspace/devstack yaml).
- shared: RegisterUp ref rows + `compose up -d` only the shared services the
  requested projects `uses`, then health-gate each (Healthy if it declares a
  healthcheck, else Started) via internal/health. Compensation drops the refs.
- compose-up (per project): `compose up -d` (+ optional --build); compensation
  `compose down` (never -v — a failed up never drops volumes). Re-armed by a
  devstack.yaml edit.
- hooks (per project): postUp via internal/hooks (OSExecer + the DB ledger +
  flock).

Engine refinement: a FAILED mutating phase now runs its OWN compensation too
(it may have partially applied — e.g. compose-up created containers), while its
saga_phase row is KEPT failed (so `status` can surface it); succeeded phases
still unwind in reverse with their rows cleared.

Deferred + flagged (slot in as more phases, no engine change): clone (gitx),
provision (needs the shared-Postgres host-port coupling), secrets (M4/S6),
trust (N5), firstRun hooks (need the provisioned-volume scope_key).

Wiring is unit-tested with a mock docker client + a fake compose runner + a real
temp ledger + a real temp workspace over the embedded templates: full happy
path (network ensured, refs added, both stacks up'd, files written, postUp ran),
near-instant re-run (all skips bar AlwaysRun preflight/hooks), and a project
compose-up failure that compensates the shared refs to zero and downs the
project. The real end-to-end daemon test lands with G1's isolation harness
(parameterized devstack-it-<pid> network/prefix — the saga must not touch a real
devstack_shared).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gustavobertoi
gustavobertoi merged commit 301061a into main Jun 29, 2026
9 checks passed
@gustavobertoi
gustavobertoi deleted the nightly/C5b branch June 29, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant