Specification: Guided Cut-Off and Release Orchestration
TLDR (Solution Summary)
- Build a guided GitLab pipeline entrypoint so release engineers choose
action, project, and confirm from one orchestration surface instead of scanning a static per-project job cockpit.
GitLab Run pipeline inputs + add explicit action, project, and confirm controls with clearer prompts and final action values bring-all-code-to-release-branch and deploy-release-branch-to-staging + operators choose the intended workflow safely from one root-pipeline entrypoint.
Single-project orchestration path + route a confirmed bring-all-code-to-release-branch or deploy-release-branch-to-staging selection to one selected repository + only the matching downstream orchestration signal runs for that project.
Bulk orchestration path + interpret project=all through a declared project matrix + one invocation fans out across the supported project set without manual per-project job starts.
Pipeline composition + move cut-off and release orchestration ownership into the root .gitlab-ci.yml while retaining bf-release/Changes.gitlab-ci.yml only for release-note workflows + the orchestration model stops depending on separate static include files.
Legacy automation compatibility + preserve the existing INVOKE_CUT_OFF, INVOKE_RELEASE, ORCHESTRATION_CUT_OFF, and ORCHESTRATION_RELEASE contracts where they already drive bulk or downstream behaviour + current automation entry points and downstream release-branch flows keep working.
Operational documentation set + update the CI/release reference and hotfix runbooks to the guided input-driven flow + operators stop following obsolete service-job instructions.
1. Summary
- Problem statement:
- The previous GitLab orchestration surface exposed a static list of cut-off and release jobs for every supported project, which made the pipeline UI feel like a cockpit of manual controls.
- The orchestration logic was also split across the root pipeline and dedicated
bf-release include files, making the behaviour harder to understand and maintain.
- The current documentation under
docs/operations/runbooks/ and docs/reference/platform/ still describes the old operator experience and therefore lags the analysed change.
- Goal and success criteria:
- Define one guided release-orchestration capability for
bf-dev where a release engineer selects an action, a target project, and explicit confirmation from the GitLab Run pipeline UI.
- Success is measured by:
- one root-pipeline operator entrypoint replacing the static per-project job catalogue;
- single-project and
all invocation paths both working through the same input-driven model;
- downstream repositories continuing to receive the established
ORCHESTRATION_CUT_OFF or ORCHESTRATION_RELEASE signals;
- legacy bulk invocation variables continuing to work;
- operator-facing docs reflecting the guided flow instead of obsolete job-name instructions.
- What will be built in this phase:
Run pipeline orchestration inputs + expose action, project, and confirm in the root pipeline + release engineers select the intended workflow without hunting through a long job list.
Root cut-off orchestration + trigger the selected repository or project matrix with ORCHESTRATION_CUT_OFF=true + the cut-off workflow remains available without a dedicated static job file.
Root release orchestration + trigger the selected repository or project matrix with ORCHESTRATION_RELEASE=true + staging release remains available from the same guided entrypoint.
Supported project matrix + declare the supported repositories once for project=all fan-out + fleet-wide orchestration stops relying on duplicated hand-authored jobs.
Legacy invocation compatibility + retain the existing bulk invocation variables for the all path + current automation entry points are not broken by the UI simplification.
Operational documentation + update the BFDev hotfix runbooks and CI/release reference to the guided pipeline model + operational guidance matches the orchestration surface.
- Scope (in/out) for this phase:
- In:
- GitLab
Run pipeline input design for release orchestration;
- single-project cut-off and release orchestration;
project=all fan-out across the supported project set;
- root-pipeline ownership of cut-off and release orchestration composition;
- compatibility with existing bulk invocation variables and downstream orchestration signals;
- BFDev reference and runbook follow-through for the new operator flow.
- Out:
- a working rollback orchestration flow;
- downstream repository implementation changes beyond preserving existing orchestration variables;
- broader release-process redesign outside cut-off and staging release entrypoints;
- separate repository-catalogue management tooling.
- Current baseline (as of April 15, 2026, and current
docs/ content):
- The historical orchestration UX exposed static per-project cut-off and release jobs directly in GitLab.
- Cut-off and release composition lived across
.gitlab-ci.yml, bf-release/.gitlab-ci.yml, bf-release/Cut-off.gitlab-ci.yml, and bf-release/Release.gitlab-ci.yml.
- Bulk orchestration depended on duplicated per-project declarations rather than one reusable matrix pattern.
- The analysed patch series captures staged prototyping, temporary dry-run scaffolding, controlled repo trials, broader project declaration, and final cleanup into a guided flow.
clarity.diff finalises the user-facing action names as bring-all-code-to-release-branch and deploy-release-branch-to-staging, updates the field descriptions to prompt-style copy, and removes the placeholder action.
- The operator docs initially lagged the pipeline change and needed follow-through so the hotfix runbooks and CI/release reference matched the final guided input model.
- Future evolution guardrails:
- This phase must keep future rollback or hotfix-specific orchestration easy to add on top of the same operator surface without reintroducing placeholder actions.
- This phase must keep the supported project set maintainable from one declared source rather than multiplying static jobs again.
- This phase must preserve explicit operator acknowledgement for release actions rather than hiding orchestration behind implicit defaults.
- This phase must avoid duplicating operator guidance across multiple docs with conflicting action labels or procedures.
- Not in scope:
- Technical design below the pipeline-contract level, such as GitLab parser quirks, YAML syntax experiments, or commit-by-commit prototyping detail, except where needed to explain the intended behaviour.
2. Users and Use Cases
- Primary personas:
- Release engineer running the normal weekly cut-off or staging release flow.
- Incident responder or operator running a targeted hotfix release for one repository.
- CI maintainer preserving existing automation entry points.
- Reviewer or stakeholder validating that the orchestration surface is safer and simpler than the previous cockpit model.
- High-level user stories:
- As a release engineer, I want one guided pipeline surface for cut-off and release so I can choose the intended action and target project without navigating dozens of manual jobs.
- As an operator, I want
project=all to fan out automatically so I do not have to start every project release job one by one.
- As a CI maintainer, I want existing bulk invocation variables and downstream orchestration signals to continue working so the UX improvement does not break automation.
- As an incident responder, I want the runbooks to describe the same guided orchestration flow that GitLab exposes so I can execute a targeted hotfix safely under pressure.
- Edge cases and failure modes:
confirm is not enabled, so the action must not run.
project=all is selected and must fan out without silently dropping supported projects.
- A single-project run must not also trigger the
all path.
- Legacy automation still invokes the
all path through INVOKE_CUT_OFF or INVOKE_RELEASE.
- A future supported-project change must update one declared list rather than multiple divergent job catalogues.
3. Conceptual Model Terms and Decisions
Key Terms
| Term |
Definition |
Notes |
| Guided Invocation |
One operator request made through Run pipeline inputs rather than through a hand-picked manual job |
The primary operator interaction in this phase |
| Action |
The operator-facing release-orchestration choice in GitLab, currently bring-all-code-to-release-branch or deploy-release-branch-to-staging |
The labels are intentionally task-oriented rather than shorthand |
| Project |
The target downstream repository or the special all selector |
The main routing input |
| Confirm |
An explicit acknowledgement that enables the orchestration action |
Safety gate for UI-driven invocation |
| Supported Project Set |
The declared repository catalogue available to the guided flow |
Used for both single-project selection and all fan-out |
| Bulk Fan-Out |
The project=all execution path that expands into a matrix of downstream triggers |
Replaces duplicated per-project bulk jobs |
| Downstream Orchestration Signal |
The existing variable sent to a target repository, such as ORCHESTRATION_CUT_OFF or ORCHESTRATION_RELEASE |
This contract remains stable |
| Legacy Bulk Invocation |
Existing root-pipeline automation paths driven by INVOKE_CUT_OFF or INVOKE_RELEASE |
Preserved for compatibility |
Decision Ledger
| ID |
Decision |
Rationale |
Alternatives Rejected |
Implications |
| D-001 |
Make the root .gitlab-ci.yml the single orchestration entrypoint for cut-off and release |
Operators should use one pipeline surface and one composition root |
Keep orchestration split across dedicated bf-release include files |
Root-pipeline docs must explain orchestration ownership clearly |
| D-002 |
Replace the static per-project job catalogue with action, project, and confirm inputs |
The operator task is choosing intent and target, not browsing dozens of job names |
Keep manual per-project jobs as the primary UI |
The GitLab Run pipeline screen becomes the canonical operator surface |
| D-003 |
Preserve the downstream ORCHESTRATION_CUT_OFF and ORCHESTRATION_RELEASE contracts |
The change is a UX and composition refactor, not a downstream workflow rewrite |
Introduce new downstream variables or repository-specific branching |
Target repositories continue to behave as before once triggered |
| D-004 |
Implement project=all through a parallel matrix driven by one supported-project list |
Bulk orchestration should remain easy to maintain and review |
Keep hand-maintained duplicated all jobs or separate bulk files |
Adding or removing a supported project happens in one declared set |
| D-005 |
Preserve INVOKE_CUT_OFF and INVOKE_RELEASE for the bulk path |
Existing automation entry points should survive the guided-flow change |
Force all callers onto the new UI path immediately |
Backward compatibility remains part of the build contract |
| D-006 |
Use clearer task-oriented action labels and remove placeholder actions from the UI |
Release engineers should not have to infer what cut-off or release mean, and the UI should not suggest unsupported rollback behaviour |
Keep shorthand action names and a visible placeholder action |
Docs, runbooks, and screenshots must use the exact final UI vocabulary |
| D-007 |
Treat runbook and platform-reference updates as part of the capability definition |
Operators rely on docs during hotfix and release work, and stale docs create operational risk |
Leave docs as a later untracked cleanup |
Delivery is incomplete until the key BFDev docs reflect the guided flow |
4. Domain Model and Eventstorming (Conceptual)
- Bounded context and ubiquitous language:
Release Orchestration UI governs the operator-visible action, project, and confirm inputs.
Pipeline Routing governs whether the invocation becomes a single-project trigger or a bulk fan-out.
Downstream Release Execution governs the target repository trigger and its existing orchestration variables.
Operational Guidance governs how BFDev documents tell operators to use the orchestration surface safely.
- Aggregates and entities:
Orchestration Invocation aggregate: selected action, selected project, confirmation state.
Supported Project Catalogue entity: allowed single-project targets plus the synthetic all selector.
Bulk Fan-Out Set entity: the derived list of downstream trigger jobs for project=all.
Operational Guidance Page entity: runbook or reference page that documents how to invoke the flow.
- Value objects:
Orchestration Action
Target Project
Invocation Confirmation
Downstream Signal
- Domain events and their triggers:
OrchestrationInputsSubmitted when the operator starts a guided invocation.
InvocationConfirmed when the operator sets confirm=true.
CutOffOrchestrationTriggered when the cut-off path starts for one project or a fan-out target.
ReleaseOrchestrationTriggered when the release path starts for one project or a fan-out target.
BulkFanOutExpanded when project=all resolves into the supported project matrix.
LegacyBulkInvocationAccepted when INVOKE_CUT_OFF or INVOKE_RELEASE activates the all path.
OperationalGuidanceUpdated when BFDev docs are brought into line with the new operator flow.
- Commands, actors, and policies:
SubmitOrchestrationInvocation by the release engineer.
ConfirmOrchestrationInvocation by the release engineer through the explicit confirmation control.
TriggerCutOff or TriggerRelease by policy once action, project, and confirmation satisfy the routing rules.
ExpandBulkFanOut by policy when project=all is selected or a legacy bulk variable is present.
UpdateOperationalGuidance by the BFDev documentation maintainer as part of delivery follow-through.
- Invariants and business rules:
- A UI-driven cut-off or release action must not start unless
confirm=true.
- A single invocation must resolve to either one project or the
all matrix, never both.
- The root pipeline must remain the operator-facing owner of cut-off and release orchestration composition in this phase.
- The downstream orchestration signals must keep their established meaning.
- The
action input must expose only implemented operator choices in this phase.
- Hotfix runbooks and CI/release reference pages must not instruct operators to use obsolete static job names once the guided flow is canonical.
- External systems and integrations:
- GitLab
Run pipeline is the input surface for guided invocations.
- Downstream GitLab repositories remain the execution targets on the
release branch.
- Existing repository-level release behaviour continues to be triggered through
ORCHESTRATION_CUT_OFF and ORCHESTRATION_RELEASE.
- BFDev runbooks and reference docs remain the operator-facing explanation layer for the orchestration surface.
Interaction Flow
flowchart LR
Operator["Release Engineer"] --> Inputs["Choose action, project, confirm"]
Inputs --> Confirmed{"confirm=true?"}
Confirmed -->|No| Stop["Do not start orchestration"]
Confirmed -->|Yes| Route{"project == all?"}
Route -->|No| Single["Trigger selected project"]
Route -->|Yes| FanOut["Expand supported project matrix"]
Single --> Action{"action"}
FanOut --> Action
Action -->|"bring-all-code-to-release-branch"| CutOff["Send ORCHESTRATION_CUT_OFF"]
Action -->|"deploy-release-branch-to-staging"| Release["Send ORCHESTRATION_RELEASE"]
Event Timeline
timeline
title Guided Cut-Off and Release Orchestration
OrchestrationInputsSubmitted: Operator starts the guided invocation
InvocationConfirmed: Explicit confirmation is enabled
BulkFanOutExpanded: Project all resolves into supported targets when needed
CutOffOrchestrationTriggered: Cut-off signal is sent to target project or projects
ReleaseOrchestrationTriggered: Release signal is sent to target project or projects
OperationalGuidanceUpdated: BFDev docs are aligned with the guided flow
Event Dictionary
OrchestrationInputsSubmitted: an operator submits the guided orchestration inputs | establishes the requested intent | action, project, confirm | enters routing logic.
InvocationConfirmed: the explicit acknowledgement gate is enabled | allows an operational action to proceed | action, project, confirmedAt | unlocks single-project or bulk routing.
BulkFanOutExpanded: the all selector expands into the supported project set | replaces manual job-by-job starts | action, targetProjects[] | starts one downstream trigger per supported project.
CutOffOrchestrationTriggered: the cut-off path begins for a downstream target | rebuilds the target repository's release branch using the existing contract | project, ORCHESTRATION_CUT_OFF=true | delegates execution downstream.
ReleaseOrchestrationTriggered: the release path begins for a downstream target | deploys the target repository's release branch into staging using the existing contract | project, ORCHESTRATION_RELEASE=true | delegates execution downstream.
LegacyBulkInvocationAccepted: an existing automation variable starts the all path | preserves backward compatibility | invocationVariable, action | triggers bulk fan-out without the UI.
OperationalGuidanceUpdated: a BFDev docs page is revised to the new operator flow | keeps instructions aligned with runtime behaviour | docPath, updatedAt | closes the documentation follow-through loop.
5. Requirements and Constraints
- Functional requirements:
FR-001: The GitLab Run pipeline UI for bf-dev shall expose explicit action, project, and confirm inputs for release orchestration, where action asks what do you need to do? and project asks what project/s need it?.
FR-002: When confirm=true, action=bring-all-code-to-release-branch, and a single project is selected, the root pipeline shall trigger only that project's downstream release branch pipeline with ORCHESTRATION_CUT_OFF=true.
FR-003: When confirm=true, action=deploy-release-branch-to-staging, and a single project is selected, the root pipeline shall trigger only that project's downstream release branch pipeline with ORCHESTRATION_RELEASE=true.
FR-004: When confirm=true, project=all, and action is bring-all-code-to-release-branch or deploy-release-branch-to-staging, the root pipeline shall fan out across the declared supported project set without requiring manual per-project job starts.
FR-005: When confirm=false, UI-driven cut-off and release orchestration shall not start.
FR-006: The cut-off and release orchestration composition shall live in the root .gitlab-ci.yml, and bf-release/Changes.gitlab-ci.yml shall remain the only retained bf-release include for this capability.
FR-007: Existing bulk invocation variables INVOKE_CUT_OFF and INVOKE_RELEASE shall continue to activate the matching all orchestration path.
FR-008: The guided flow shall preserve the established downstream ORCHESTRATION_CUT_OFF and ORCHESTRATION_RELEASE signal contract.
FR-009: The action input shall expose only the implemented operator choices bring-all-code-to-release-branch and deploy-release-branch-to-staging in this phase.
FR-010: BFDev documentation shall update the hotfix runbooks and platform CI/release reference so they describe the guided input-driven orchestration flow instead of obsolete service-specific job instructions.
- Non-functional requirements:
NFR-001: The default operator surface shall be materially simpler than the previous static per-project job catalogue.
NFR-002: The supported-project declaration for bulk orchestration shall remain maintainable from one canonical list rather than duplicated cut-off and release job catalogues.
NFR-003: The orchestration design shall remain consistent with ADR 0006 - Trunk-Based Development, especially the requirement that CI/CD orchestration stays environment-agnostic and release-branch promotion remains explicit.
NFR-004: The orchestration design shall remain consistent with ADR 0007 - Generalised principle for automation, especially the requirement that automation remains explicit and safety-gated before release actions run.
NFR-005: Documentation updates for this capability shall keep operator instructions and runtime behaviour aligned closely enough that a hotfix operator does not need to infer missing steps from pipeline internals.
- Constraints and assumptions:
- Downstream repositories already honour
ORCHESTRATION_CUT_OFF and ORCHESTRATION_RELEASE.
- The analysed change is a BFDev orchestration-surface change, not a downstream repo process redesign.
- Rollback or hotfix-specific automation beyond the current release-branch trigger model remains separate follow-up work.
- The supported project catalogue is declared inside CI configuration in this phase.
- No canonical challenge artifact exists yet; this specification starts with
challenge_ref: TBD.
- Build item coverage mapping:
Run pipeline orchestration inputs build item -> FR-001, FR-005, NFR-001, NFR-004
Root cut-off orchestration build item -> FR-002, FR-006, FR-008, NFR-003
Root release orchestration build item -> FR-003, FR-006, FR-008, NFR-003
Supported project matrix build item -> FR-004, FR-007, NFR-002
Legacy invocation compatibility build item -> FR-007, FR-008, NFR-003
Operational documentation build item -> FR-009, FR-010, NFR-005
- Verification notes:
FR-001 through FR-005: validate by running or reviewing the GitLab Run pipeline surface and confirming the gated routing behaviour for single-project, all, and confirm=false cases.
FR-006 through FR-008: validate by reviewing root-pipeline composition and downstream variable contracts in the final CI configuration.
FR-009 and FR-010: validate by reviewing BFDev docs against the final operator flow and ensuring no runbook still instructs operators to run obsolete per-service release jobs.
6. Interaction and Flow
- User journey:
- The release engineer opens
Run pipeline for bf-dev.
- The release engineer chooses an
action and project.
- The release engineer enables
confirm to acknowledge the operation.
- The root pipeline routes the invocation to one project or expands it into the supported project matrix.
- The root pipeline sends the matching downstream orchestration signal.
- The operator follows the downstream repository pipeline and environment checks as required by the target release or hotfix workflow.
- BFDev runbooks provide the operator with the same invocation model and safety checks used by the pipeline UI.
Flowchart: Guided Routing
flowchart TD
A[Open Run pipeline] --> B[Select action and project]
B --> C{confirm=true?}
C -->|No| D[Stop without orchestration]
C -->|Yes| E{project=all?}
E -->|No| F[Trigger selected project]
E -->|Yes| G[Expand project matrix]
F --> H{action}
G --> H
H -->|"bring-all-code-to-release-branch"| I[Trigger downstream cut-off]
H -->|"deploy-release-branch-to-staging"| J[Trigger downstream release]
Sequence Diagram: Single Project Release
sequenceDiagram
participant Engineer as Release Engineer
participant GitLab as GitLab Run Pipeline UI
participant Root as bf-dev root pipeline
participant Repo as Target repository pipeline
Engineer->>GitLab: Select action=deploy-release-branch-to-staging, project=<repo>, confirm=true
GitLab->>Root: Start guided invocation
Root->>Root: Evaluate confirm and routing rules
Root->>Repo: Trigger release branch pipeline with ORCHESTRATION_RELEASE=true
Repo-->>Engineer: Existing downstream release behaviour runs
Sequence Diagram: Bulk Cut-Off
sequenceDiagram
participant Engineer as Release Engineer
participant Root as bf-dev root pipeline
participant Matrix as Supported project matrix
participant Repos as Downstream repositories
Engineer->>Root: Start action=bring-all-code-to-release-branch, project=all, confirm=true
Root->>Matrix: Expand supported project set
Matrix->>Repos: Trigger one release branch pipeline per target
Repos-->>Engineer: Existing downstream cut-off behaviour runs in parallel
7. Non-Technical Implementation Approach
- Approach overview:
- Treat the change as a guided-orchestration capability definition, not merely a CI refactor.
- Keep the operator contract simple: choose intent, choose target, confirm.
- Keep the downstream contract stable: route to existing release-branch flows and variables instead of widening scope into downstream rewrites.
- Treat documentation follow-through as part of the delivery slice, especially for hotfix procedures.
- Design considerations:
- The primary trade-off is between operator simplicity and future extensibility. The chosen design simplifies the default operator surface while leaving room for later rollback-oriented work without exposing placeholder actions now.
- Bulk orchestration must remain explicit and reviewable, so
project=all is a deliberate input rather than an implicit side effect.
- Compatibility with existing automation matters because cut-off and release are operationally sensitive workflows.
- Docs must avoid overfitting to ephemeral job naming and instead describe the stable guided interaction model.
- Dependencies and prerequisites:
- Downstream repositories must continue to respect
ORCHESTRATION_CUT_OFF and ORCHESTRATION_RELEASE.
- Release operators must retain permission to start the orchestration pipeline and the downstream pipelines.
- BFDev docs owners must update the identified runbooks and platform reference pages as part of rollout.
- The work aligns with ADR
0006 - Trunk-Based Development and ADR 0007 - Generalised principle for automation; no ADR change is required by this specification.
8. Open Questions
- Should the supported project catalogue stay embedded in CI configuration long term, or should a later slice move it into a separate operational source of truth?
- Should hotfix orchestration eventually distinguish staging and production release actions explicitly instead of reusing the broader
release concept?
9. Appendices
Documentation Updated Alongside This Capability
| Path |
Why it was updated |
docs/reference/platform/ci-and-release.md |
Explains that root .gitlab-ci.yml owns cut-off and release orchestration, records the final action names, and clarifies the action / project / confirm prompts. |
docs/operations/runbooks/hotfix-release.staging.md |
Uses the final guided inputs action=deploy-release-branch-to-staging, project=<target repository>, and confirm=true for selective staging hotfix promotion. |
docs/operations/runbooks/hotfix-release.production.md |
Uses the same guided release invocation and explains that production promotion still continues in the downstream manual production deployment step. |
docs/operations/runbooks/index.md |
Summarises the hotfix runbooks with the final guided action names instead of obsolete service-job language. |
Docs Reviewed With No Direct Update Required From This Change
docs/process/workflows/product-engineering-delivery.md
docs/reference/system/service-matrix.md
docs/operations/index.md