The Delivery Policy: What Each Promotion of a Release Requires
A delivery policy says what a release must show before it is promoted: to test when it is approved, and to production when it is released. The studio owner sets it in Trust Settings; an Enterprise organisation can set a floor under it; and before a merge, every member can read what it will find. With no policy, nothing is asked.
The two promotions
| Promotion | When | What happens |
|---|---|---|
| Test | Approve release | The policy is assessed after the DPIA and bill-of-materials checks. A rule not met refuses the approval before anything is written. Otherwise the approval records the assessment and issues the signed passport, with every rule as a required row of its release gate |
| Production | Release | The policy is assessed again against the commits the approval pinned, with the results read again, so what was reported after approval counts. A rule not met refuses the release before any repository is tagged. Otherwise a new signed passport version is issued, carrying the production assessment, before the first tag; the production pipeline’s passport check verifies that version |
A merge is never a promotion: dev is what every merge deploys. Before a merge the policy is a reading, which holds the merge only if the owner turns that on (below). If the version issued at release cannot be signed, nothing is tagged and releasing again assesses again.
Setting it
Open Trust Settings → Delivery policy. For each promotion — Test promotion (release approval) and Production promotion (release) — choose Add a rule and pick from the list below. Only the studio owner changes the policy; everyone else sees it, disabled. Each change is in the studio audit. A delivery policy of the studio’s own is on every Studio plan.
The rules
| Rule | You choose | Met when |
|---|---|---|
| A test or scan passed | Which category; where (each package’s head or the release’s cut); when (where it applies, or always); for a scan, the highest severity that may remain (medium by default: nothing high or critical) | The newest result of that category passed (a test) or completed with nothing above the severity (a scan) |
| No findings | A scan category; where; at or above which severity; in the whole codebase or in what is new since the last release | No finding at or above the severity |
| Line coverage | Where; at least what percentage | Line coverage of the whole codebase is at least that. A report that measured no lines is never counted as full coverage |
| Coverage of new code | Where; at least what percentage | Line coverage of the lines changed since the base is at least that. A change with no new lines meets it |
| A separate approver | — | The person promoting did not start a coding run on, merge, or open the pull request of any package on the release |
| A change request | — | The release carries a change request: its system (ServiceNow, Jira or other), its reference and a link, entered on the release page. It is recorded, not checked in the other system |
| Controls satisfied | Up to ten controls; whether a waiver counts as satisfied | Each control reads satisfied on every package’s passport (or waived, where you allowed it) |
| An artefact published | Which kind of artefact | A publish report of that kind, bound to its run, at each repository’s head in the cut |
| A protected base branch | — | Each repository’s base branch requires a pull request that nobody can bypass, as the Studio read it from GitHub at approval |
The rules your organisation’s policy already has — CI passing, a bill of materials, the approver’s roles, a DPIA for AI-built work — stay where they are and apply as before.
The controls a check evidences
A test or scan passed rule and a no findings rule can name up to ten controls they are evidence for (ISO 27001, SOC 2, NIST SSDF, SLSA or your own), picked in the rule’s editor. A test or scan passed rule that names none evidences the usual controls for its category, such as ISO 27001 A.8.29 for a dependency scan; those defaults are not stored in the policy.
The release’s passport then has controls of its own, taken from its delivery rows as a package’s come from its checklist items. A control reads satisfied only when the rule was met and the promotion’s assessment is in the release’s ledger; not satisfied when the rule was not met; unknown when it could not be read. A rule met on a result not bound to its workflow run (only where the owner counts those) says so on the control. The passport’s schema version is 6.
Each package’s head, or the release’s cut
A release with no check at the cut has no test or scan that covers the commits it ships from outside the Studio; its passport says when nothing was reported there.
Where a check applies
A check asked where it applies follows what the repository is at that commit, as the Studio reads it from its files: a container image scan where there is a Dockerfile, an infrastructure scan where there is infrastructure code, unit tests, static analysis and a dependency scan where there is code to build, and a secret scan always. Where it does not apply the rule asks nothing there. Whether integration tests, end-to-end tests or a dynamic scan are needed cannot be read from files, so those are asked always. If the repository could not be read, whether a check applies is unknown, and unknown refuses: it is never skipped. A repository too large to read in one request is unknown every time, so ask its checks always.
Your organisation’s rules
An organisation on an Enterprise contract can put delivery rules on its guardrail policy, in the same editor (Organisation → Guardrail Policies). They are a floor. At each promotion they join the studio’s own policy and the strictest of all applies: a rule either names is asked, and where both name one the stricter terms win. Results not bound to their run count only where every policy asking says they may.
Before a merge
A work package’s Ship panel and the Verify page (Pull requests) show the rules each package will be asked at its head — tests and scans, findings and coverage, from both promotions — read at the pull request’s head with the same check the promotions use: what was found (“passed, 412 of 412”; “not reported, so the test promotion will refuse this package”), which promotions ask it, and how to fix it. Anyone in the studio sees it.
The reading is not recorded as evidence: the promotions decide, and record what they decided.
productivity-workbench/delivery-policy on the pull request: passing when every rule is met at the head, failing when a result failed, found more than the policy allows or covered too little, and pending when a result was not reported, not bound or could not be read. It is for display only and holds nothing. The hold above is separate. To have GitHub hold the merge on it, the owner can require that status in the branch’s protection on GitHub. Where no package-scope rule is asked, nothing is posted. It is refreshed when the Studio next reads the pull request, not the moment a result is reported.When a promotion is refused
The release page lists each rule not met, where (the package or the repository) and why. Every member can read it and act on it.
| The page says | What to do |
|---|---|
| nothing was reported | Add the report for that category to the pipeline that runs there: the pull request’s runs for a package’s head, the runs on main for the cut |
| only results not bound to their workflow run were reported | Give the reporting job permissions: id-token: write and run it again, or the owner counts unbound results |
| the run failed or did not complete | Fix what failed and run the pipeline again |
| finding(s) above what the policy allows | Fix or upgrade what the scan found, and scan again. The findings are in the workflow run |
| (a percentage) is below (the threshold) | Add tests, or the owner lowers the threshold |
| the scan did not report what is new since the last release | Report new findings against a baseline, or ask the rule of the whole codebase |
| what the repository is could not be read | Check the repository connection still has read access, and try again |
| the person promoting worked on one of its packages | Someone else in the studio promotes it |
| a pull request … was opened by an account the Studio cannot compare with the person promoting | The person promoting connects GitHub under My Account → Source control |
| not satisfied: (controls) | Meet the controls on the package’s Definition of Ready or Done, or record an exception |
| the base branch does not require a pull request; or asks for one but can be bypassed | In the branch’s classic protection on GitHub, require a pull request, include administrators and let nobody bypass it, then approve again. A ruleset alone reads as bypassable: its bypass list cannot be read with the connection’s read access |
| whether the base branch requires a pull request was not read | Approve again: a rule added after approval has no reading until then |
| the reported results could not be read in time | Try again |
| the stored delivery policy could not be read | The studio owner saves the policy again in Trust Settings |
A required check is never waived on the gate: if a pipeline cannot run one, the owner changes the policy, and the change is in the audit.
On the passport
Each rule assessed at a promotion is a required row of the release gate on the passport — “Test promotion: …”, “Production promotion: …” — so every verifier, the pipeline’s passport check included, counts a row not met as unmet with nothing new to install. Each promotion is one entry in the release’s evidence ledger. The rows are built from what was assessed at the time, so tightening the policy later changes no passport already issued.
A studio of one
Nothing here needs two people unless you ask for it. A separate approver does: a studio of one that turns it on cannot promote, and the refusal says why. Leave it off until there is someone else to promote.