ADR-0107: Hosted verification is automatic on main and on request elsewhere¶
- Status: Proposed
- Date: 2026-09-17
- Related: ADR-0025, ADR-0035, ADR-0048, ADR-0049, ADR-0074
- Supersedes in part: ADR-0035's consequence that every branch push receives the verification partitions
- Detailed design:
docs/plan/development-toolchain.md
Context¶
ADR-0035 gave every branch push the hosted verification partitions. That was
cheap while the workflow held three Linux jobs. ADR-0049 and ADR-0074 later
added two macOS test jobs and a macOS signing smoke, and dev became the
branch that receives every finished change directly.
In the seven days before 2026-09-17 the project ran 122 pipelines: 96 on
dev, 24 on main and 2 elsewhere. A dev pipeline cost roughly 3,900
credits, estimated from job durations and CircleCI's published rates, and the
three macOS jobs were about 96% of it. All five Linux jobs together were about
140 credits. Of the 97 dev verification workflows, 59 passed, 16 failed and
22 were cancelled by a newer push after their macOS executors had already
billed minutes.
The repository already has a cheaper gate for the same checks.
.chunk/config.json runs make check on a disposable CircleCI sidecar, and
docs/plan/development-toolchain.md records that a passing remote make check
satisfies the same criterion as a local run.
Decision¶
- The
verifyworkflow starts by itself only onmain. The condition reads the pipeline's branch, not what created the pipeline, so a push tomainand a pipeline requested formainboth run it. There it still gates packaging, deployment and TestFlight delivery exactly as ADR-0048 and ADR-0074 define. - On every other branch a pipeline starts no workflow by itself. The workflow
runs there only when the pipeline is triggered with the boolean parameter
run_verify: true.run_live: truestill selects the live workflow and wins when both are set, onmainas well. - The gate for a change entering
devischunk validateon the sidecar, plus the local suites the sidecar cannot run when the change touches them: integration against the disposable PostgreSQL, the sandbox gates, and the Xcode suites. - A change proposed for
mainstill needs hosted verification on its exact final head. The proposer requests onerun_verifypipeline for that commit and the pull request shows its statuses, whichmainbranch protection requires before the merge. The repository contract's review gate is unchanged in strength; only the way the run starts changes. - The Apple signing smoke keeps its
dev-only filter and therefore runs in a requesteddevpipeline. The restricted signing context still excludes unversioned configuration; a requested pipeline uses the committed file. - The rule is one workflow condition in
.circleci/config.yml, pinned bytests/unit/test_toolchain.py. No job list is duplicated and no CircleCI project setting carries the policy.
Consequences¶
- Hosted credits are spent once per promotion and once per
mainpush instead of once per push to any branch. - A failure only the hosted jobs can see, such as an iPhone UI regression, surfaces at the requested run rather than minutes after the push that caused it. The cause is then one of several commits, not one.
- A push to
devno longer proves anything by itself. Evidence recorded for adevcommit names the sidecar or local run that produced it. - A requested pipeline has no previous revision, so the reading-lane floor
falls back to
origin/mainas its base, which is the range a promotion should be judged on. - GitHub enforces the requested run's verification jobs.
maincarried no branch protection under ADR-0035, so the exact-head gate was procedural; on 2026-09-17 the owner enabled protection requiring the seven verification contexts as status checks, and a pull request whose head has no requested run can no longer merge. The Apple signing smoke is not one of those contexts: it is not a verification partition and runs only in a requesteddevpipeline (decision 5), so its required pass on the exact revision proposed formainremains a check of the review gate, not of branch protection. The owner keeps an admin override for an emergency, and themainpipeline, which verifies before it delivers, remains the backstop behind it. The setting lives in the repository host, outside the configuration this repository can test, so no gate test observes it.
Alternatives considered¶
- Keep the Linux jobs automatic and put only macOS on request. It keeps about 96% of the saving and automatic integration and sandbox coverage. Rejected by the owner in favor of one rule; it also needs a second workflow that repeats the job list.
- No hosted verification before the merge. The
mainpipeline already verifies before delivery. Rejected because it weakens the contract's exact-head requirement and turnsmainred for failures a requested run would have caught. - CircleCI's "only build pull requests" project setting. Rejected because a
dev-to-mainpull request is open much of the time, so most pushes would still build, and the policy would live outside the repository where no test can pin it. - An approval job ahead of the workflow. Rejected because job requirements cannot differ by branch inside one workflow, so it needs a duplicated workflow, and every push would leave a pending status on the commit.
- Skip the macOS jobs when no Apple file changed. A separate saving that
also applies to
main. It needs dynamic configuration and a decision about the release gate in ADR-0049, so it is not part of this change.