How-to
Change your release policy
Updated
On this page
Change the rules every pull request is checked against, test the change on recent pull requests, and publish it. It takes about 10 minutes, and you need to be a company admin in Zof and an admin of your GitHub organization.
One policy is live at a time. Your edits stay in a draft until you publish, and the saved draft is shared with every admin. For how Zof applies the live policy, see How Zof decides.
Before you start
- A connected organization can start with no policy. Choose Start from a template or Start from scratch. A template opens as a draft; only publishing makes it live. Until then, pull requests show No release policy yet and need action.
- Your GitHub account is connected in Integrations. Saving and publishing need you to be both a company admin and a GitHub org admin. Anyone who isn't a GitHub org admin sees the policy read-only, without the draft. A GitHub org admin who isn't a company admin sees the draft and the edit controls, but Zof refuses the save or publish with "Couldn't save: You need to be a company admin to do this. Ask a company admin." or "Couldn't publish: You need to be a company admin to do this. Ask a company admin."
- The Zof GitHub App isn't suspended or waiting on GitHub. Otherwise the page says "Changes are off while the Zof GitHub App is suspended or waiting on GitHub."
Edit a rule
- In the sidebar, open Release policies. The Rules tab lists every rule.
- On the rule you want to change, click Edit. To add a rule, click Add rule.
- Make your change.
- In the rule's panel, click Save to draft.
The bar above the tabs now says "Draft · not live" and counts your changes.
To start again from a template, click Use a template. A template replaces the draft's rules. Your agents and branches stay as they are.
Older checks
The picker offers only checks Zof makes available today:
- Unit tests: Zof runs your tests in its sandbox: JavaScript/TypeScript (Jest, Vitest), Python (pytest) and PHP (PHPUnit, Pest).
- Code review ran on this commit: Zof must finish a complete review of the exact commit.
- A person signed off the code review: a person signs off the complete review of the exact commit.
Python unit tests run with Python 3.13. If a unit check reports unit_no_test_framework, Zof couldn't find a test setup or runtime it supports on the base branch. Add or fix it there first, then update the pull request's branch.
A Unit tests requirement also sets Changed-code coverage: the share of the lines a change touches that your own tests must run. Pick a Target (%) from 0 to 100, and under When it falls short choose Block the release or Advise only. A new unit requirement starts at 80% and advises only. An older one with no setting shows "Not set: Zof blocks unless your tests run every changed line." Lowering the target or switching from block to advise counts as loosening the policy.
Older requirements remain unchanged and show “Not available for new policies”. A required check can hold matching pull requests until it passes, is made optional, or is removed. An optional check doesn't stop them. Make optional opens the rule for review before saving. If it also requires approval or agent permissions, remove those requirements explicitly first. Remove opens the deletion confirmation. Keep a required baseline for every change.
New rules and agent grants offer merge actions. Stored deploy conditions remain visible and can be removed. Approval sources are the owners of affected services or the owners of the highest-tier affected services. The count is across the selected owners, not a separate count per service. Teams and people are assigned through Release approvers.
If Zof has not supplied its supported vocabulary, new checks are unavailable. Existing rules remain readable. Publishing a draft that adds an unavailable requirement is refused; replace or remove that requirement, save, and replay the draft again.
Preview prerequisites
The rule editor and Review changes show Preview prerequisites for required rules that need a running app, or whose prerequisites cannot be confirmed. Review checks every rule in the saved draft, including rules you did not change.
The warning uses recent deployment reports for the repositories the rule covers. No detected previews, production-only deployments, a shared environment or unavailable information can mean matching pull requests wait for an eligible preview. A shared staging deployment can qualify for a promotion pull request only when it runs that pull request's exact latest commit; a feature pull request with a different commit needs its own matching deployment. Production is never a preview target.
Even Per-PR previews detected does not prove a check passed or that the current commit has a usable preview. Running-app checks must also be enabled. Follow Set up previews for deployment reporting and access requirements.
When offered in the editor, Make it optional changes only the rule you are editing. Review the change, choose Save to draft, then test and publish normally to apply it. Cancel leaves the saved draft unchanged. If the rule also requires approval or agent permissions, review those requirements explicitly; the shortcut does not remove them. Keep a required baseline for every change.
These warnings do not change your rules or prevent publishing by themselves. The normal draft validation, test and confirmation requirements still apply.
Delete a rule
On the rule card, click Delete. Check the named rule in the confirmation, then click Delete rule. This saves the deletion to the shared draft; it takes effect only after you publish. A previously live rule appears under Removed in draft. Cancel leaves the draft as it was.
The last required rule that applies to every change and asks for a check cannot be deleted. Add another baseline before deleting it. If the draft changes while the confirmation is open, close it and review the rule again.
Branches and environments
The Branches & environments tab says which environment a pull request into each branch counts as: production or staging. Rules that apply to one environment use it.
- Open the Branches & environments tab.
- Click Add branch.
- Type a branch name or a pattern, and pick its environment.
- Click Save to draft in the bar above the tabs.
A single star matches within one part of the branch name, between slashes. A double star matches across slashes:
release/* covers release/1.2, but not release/1/hotfix
release/** covers release/1.2 and release/1/hotfix
The default branch is unmapped unless you list it. An unmapped branch matches every rule that applies to an environment, and no agent grant covers it.
Agents
The Agents tab lists the GitHub bot and App accounts that open or push changes on their own, and what each one is granted. People using AI tools aren't agents, and their changes follow your normal rules. Edits on this tab are saved with Save to draft too. For how grants and takeovers work, see Agents and accountable people.
What each field means
The "?" beside a field in the rule panel, on the Branches and Agents tabs, and in the template picker shows the same words as its entry here.
What it requires, in plain words
These words explain the rule to the people whose change it holds up, on the change's page in the console. They don't change what the rule checks.
When you change its evidence without updating these words, the editor prompts you to check the description. For example, replacing unit tests with code review does not automatically rewrite a description that still mentions unit tests. The reminder does not block saving.
Applies to
Which changes this rule covers: tier, environment, risk, who wrote it and the action. A change must match every group you fill in, and an empty group matches any change.
More conditions narrows a rule to repos, entity types and entities. Pick from the list or type a value. A repo matches as owner/name in any case. An entity type or entity matches exactly, and an entity matches by its full ID, like service:repo/name, not its name.
A value that isn't on the list stays on the rule and shows Not found. You can still save it, for a repo you'll connect later, but a misspelled value never matches, so a change could skip the rule. If a list can't load, the values show Unchecked and you can still type them. Select Retry to check them.
The Rules list puts required rules that ask for checks on every change under "Baseline: required checks for every change". Everything else is under "Other rules", including optional rules that apply to every change. This grouping does not alter a rule's match or severity.
A change that no other rule covers still has the baseline rule. See What if no rule matches?
Capability
The test or check whose result this rule needs on the pull request's latest commit. Under a required rule the change waits for the result, and a failing result blocks it until a new commit passes.
While the result is missing, the check gives missing_blocking_evidence.
Metric limits
Metric limits on older rules are preserved. They are unavailable for new checks; remove the stored evidence requirement to replace it.
A result outside a limit gives insufficient_evidence.
Maximum evidence age
Age limits on older rules are preserved. They measure the evidence assessment age, not when the test ran, so the editor does not offer this setting for new checks.
A result that is too old gives stale_evidence.
Human approval
The change also needs this many approvals on GitHub, from the owners you pick in the From field. Who can approve for each owner is set in Release approvers; the author and anyone who pushed commits to it never count.
To set who approves for each owner, see Choose who can approve.
Agent permissions
When an agent opened or pushed the change, it must stay within its grant on the Agents tab. Otherwise the change waits for a person's approval.
For what a grant covers, see What may an agent do on its own?
Required or optional
Required holds the change until this rule passes. Optional is reported on the change and its check but never stops the release, and an optional rule can only ask for checks.
On the Zof / Control check and in the console, required is the default and isn't labelled; an optional check carries an "Optional" tag. A required check that didn't pass blocks the release, and the summary under the check's title names it. An optional rule isn't the same as an advisory branch. See What does advisory mean?
Branch environments
Rules limited to production or staging use this map to decide whether they apply to a pull request. A branch you don't list matches every such rule, and no agent grant covers it.
For branch patterns, see Branches and environments.
Agent grants
What each agent may do without a person: which actions, in which environments and up to which tier. A change outside its grant waits for a person's approval.
For how grants and takeovers work, see Agents and accountable people.
Templates
Each template is a complete set of rules to start from, and you can edit any rule before you publish. If a template replaced a saved draft, Undo puts that draft back.
Publish the draft
In the bar above the tabs, click Review & publish. It shows once the draft is saved.
In Publish this draft, read Review changes. It shows each rule, branch environment and agent that was added, changed or removed, and any loosening compared with a live policy. For the first policy there is no published policy to compare with, so it lists the rules, branch environments and agents the policy sets. Click Next.
In Test on recent PRs, click Run the test. Zof decides the pull requests of the last 30 days again under your draft, and shows which results would change. Click Next.
Under Publish, write a Note saying why the policy changed. It's required, and kept with the version; Publish turns on once it has one.
If the dialog shows This needs your confirmation, read each reason, then type this in the box:
publishClick Publish.
The dialog asks for publish when the draft is looser than the live policy, when the test found results that would be less strict, when some pull requests couldn't be replayed, or when only the newest 500 were tested.
Until Zof serves the new version, the dialog says "Publishing: waiting for Zof to serve" it. You can close the dialog. While a version is pending, you can abandon it from History. After 15 minutes the dialog stops waiting and points you there.
Check that it worked
- On Release policies, the header badge shows the new version number, marked live.
- On the History tab, the new version is marked "Live".
- Open pull requests are checked again once the version is live, and their
Zof / Controlchecks update on GitHub.
Company admins also get a notification in the console's bell that the policy was published.
Undo a change
| To | Do this |
|---|---|
| Throw away a saved draft based on a live policy | In the bar above the tabs, click Discard draft. Zof asks first, because every admin shares the draft. |
| Go back to an earlier version | On History, click Restore as new draft on that version. It becomes your draft, and you publish it like any other. |
| Stop a version that is stuck pending | On History, click the button for the pending version, such as "Abandon v3", write why, and click Abandon. Another version can then be published. |