Mapping · 03 of 07 · The contract

cicd.yaml, and what actually runs

Five blocks, each driving one part of the pipeline. Only build is required, and only its agent field inside it. The file is validated against a JSON Schema on every run.

cicd.yaml, and what actually runs Mapping from cicd.yaml blocks to what the platform runs. The build block (agent and optional script) drives validate, unit tests, a kaniko image build and a Chains signature. The test block names a Testkube TestWorkflow. The deploy block lists lower environments, which get a committed env file, and upper environments, which get a release pull request. The governance block switches on Semgrep, Trivy, SBOM and provenance gates. The pipelines block sets triggers and order through Pipelines-as-Code over a fixed stage DAG. CICD.YAML · THE ONE FILE YOU EDITWHAT THE PLATFORM RUNSbuild:agent: nodejs-22script: ./build.shbuildvalidate · unit test · kaniko image · Chains signaturetest:name: integrationtestTestkube TestWorkflow in the shared namespacedeploy:lowerEnvironments: [dev]upperEnvironments: [prod]deploy + releasecommit the dev env file · open a PR per upper envgovernance:sast: trueimageScan: truegovernance gatesSemgrep · Trivy · SBOM · provenancepipelines:ci: { event: push, branch: main }triggers and orderPipelines-as-Code · a fixed stage DAGA block you leave out is a stage that never runs. Everything on the right is the platform's job.LEGENDThe one required blockPlatform stage

Scaffolded, not hand-written

Airframe commits a minimal, build-only cicd.yaml when an app is onboarded, so the first push already runs a pipeline (ADR-0017).

What it cannot say

Identity (app name, gitops repo, owner) lives in an operator-reviewed identity file, never in cicd.yaml. The schema rejects it, so a developer's commit can never change where a release goes.

Honest toggles

governance.sast runs a real Semgrep scan; each gate says whether it is real or a stub, and a stub never reports as a pass.

Hangar · Glidepath