Stages S7–S9 — Deploy, verify and revert
Purpose
In the Development module (id source), the platform prepares, requests, records and verifies; it does not run the estate's deployment mechanism. The estate's pipeline job runs the code deploy, resolved and triggered by the deployment agent under the per-environment rule (DG-8 as narrowed by D130); the write executor applies DDL under HW-ddl (D104), both from an approved packet. What the platform then does is the part that is usually skipped: check which commit actually serves, because a VALID database object can still be a stub and a green pipeline is not a running system.
Inputs → Outputs
In: the approved script set, the named environment, the packet hash. Out: the deploy request and what it ran, the runtime verification on the target, and — on a problem — the executed revert with its own evidence.
What happens
| Stage | What happens | Who |
|---|---|---|
| S7–S8 deploy | target gate → the deployment agent resolves the environment's serdica-infrastructure job by rule and triggers it with the packet hash (D130; bulstrad-staging/bulstrad-prod from v3.0.0, the rest from master) and the DDL packet goes to the write executor (DG-8: the platform does not run Ansible itself) → runtime verification on the target (which commit actually serves: stack lines, versions; a VALID DB object can still be a stub F: [release audit]) → open the port MR to master after the runtime check (D105) |
human gate; the deployment agent (it resolves and triggers the job — D130); write executor. Ablera DevOps keeps the rights and the compose units |
| S9 reversal | on a problem: the standing revert path executes — only on a human decision | human gate |
What runs this stage
| Agents | source.deployer · the Camunda developer where a process version is migrated |
| Isolated sub-agents | — |
| Memory domains it reads / proposes to | source/<repository> runtime facts — what serves, where, and how it is proved (Agents Memory) |
| Skills it runs | release audit — the four-layer comparison of what is deployed against what was built (Agents Memory and Skills) |
| Its branch of the graph | Development Module § 0 — the module's agent tree, its memory branch and its skills · the component list is Components — Development |
Every stage also uses source.root — the only profile that reaches the human — and the platform's write_executor and write_auditor (Gating).
Rules this stage carries, taken from real changes
- A non-production deploy is gated too (G4): QA is shared and not customer-facing, so it is H4 + the write auditor; STAGING/TEST and PROD are customer-facing, so they are H4 + H5 (D114).
- Operations actions — a container restart, a queue purge, a Camunda instance termination — are a case kind of their own, executed through a host/SSH or RabbitMQ connector under a gate, seeded from
ssh-mcp(G22, G31); a restart is a write. - A process change is a case type with effect classes for in-flight instances, a migration statement per version, and its teardown (G24, G26); the Camunda developer is a profile with a Camunda REST connector — read free, start/terminate/migrate gated (G25).
- S8 opens the port (D141): after PROD runtime verification — and within DG-9's one business day — the deployer opens the merge request for the port commit S6 prepared (or records the "no master counterpart" outcome as the DG-5 closure); the case is not done while the port MR is unopened and the brief has not said why. If the brief chose port-first (G18), S8 verifies the port's own deploy the same way.
2. The deployment procedure
P The deployer performs this sequence against the case's pinned branch set and per-environment job rule. It never substitutes a job or target from memory when the declared one cannot be resolved.
| Step | Action | Recorded evidence / failure |
|---|---|---|
| 1 | Load S5's reviewed MR head, S6's release packet, source tree hash, target set and revert | missing/stale evidence returns to S6; no trigger |
| 2 | At H4 approve the exact reviewed head, merge action, script set and expected build provenance | gate binds that packet; merge still uses the applicable effect permission |
| 3 | Merge by the estate process, then resolve the resulting commit and build | if the merged tree differs from the reviewed tree, reopen review/H4; a merge id alone is not proof |
| 4 | Capture immutable image/artifact digests, source commit, pipeline/job ids and script hashes | append a release-manifest paper derived from the approved source; never deploy a mutable latest tag |
| 5 | Resolve the target's infrastructure ref/job and input names by D130 | configuration includes infrastructure repository, ref, job selector, target and approved parameter mapping; absent/ambiguous match is a capability gap |
| 6 | Audit the exact target packet and satisfy H5 where customer-facing plus other effect requirements | fresh role/risk/grant/precondition/fence checks; reserve one journal call |
| 7 | Trigger once through the GitLab connector; apply database steps through the write executor in declared order | journal records intent first, then returned pipeline/job or write evidence; timeout is reconciled, never an immediate second trigger |
| 8 | Wait for the named job's terminal state using read operations | persist external_job wait and job reference; workers are released between polls |
| 9 | Verify every affected running service and database object | image digest and serving source revision match the release manifest; package signatures/status match; declared smoke call succeeds |
| 10 | Record target result and open the prepared port MR at the declared point | port MR id or explicit no-counterpart outcome; no claim of port completion merely from opening it |
| 11 | On failed target proof, prepare the standing compensation under H7 | compare current state with what this case changed; a newer external change is a conflict, not permission to overwrite |
P A pipeline success proves the job finished. Target proof additionally needs image/container provenance and a behaviour check on the affected surface. Stack-line evidence can corroborate a version but cannot replace an available image digest or source signature. A DB object being VALID is not proof its intended body serves.
P DDL is form E: capture the pre-image, establish the external-writer exclusion described in Planning § 3b, compare live signature, apply, re-read signature/status and test the named behaviour. A compensating replacement carries the same exclusion/precondition discipline. Without it, the operator/external owner performs the reviewed step and the platform verifies; no automatic replacement is claimed.
P WRITE_LOG records the mode/path and effect evidence; RUNTIME_CALLS stores immutable call identity and recovery state; the release-manifest/report papers hold source/build/target details; BUILD_STATE marks only completed plan steps. Broker events and UI progress are projections of these committed records. No infrastructure call is held open across a human gate.