Files
home-network-k3s/decisions/adr-0024-delivery-authority-ci-gate.md
jakman85andClaude Opus 5.5 250fb54154 docs: bring the specification in line with the accepted implementation
The operator ruled the implementation repo's main (50c8719) the latest
and accepted state. Sync the spec to it.

Accepted changes are reflected: one bare-metal environment, TrueNAS bulk
storage, R2 off-cluster backup, CloudNativePG, single-node VPN gateway
with Cilium fail-closed, inbound WireGuard, per-app auth sidecars,
Renovate, the CI gate as approver, and the pm-agent. New ADR-0017..0025;
ADR-0016 corrected and accepted; R-* IDs unchanged, eight amended.

Where the implementation has simply not met a requirement, the
requirement stands and the shortfall is recorded in docs/16-known-gaps.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-08 22:46:00 -06:00

3.8 KiB

ADR-0024 — Delivery authority: the CI gate is the approver; sensitive-path review; attributed admin override

  • Status: Accepted
  • Date: 2026-11-08
  • Serves: R-TEST-03, R-TEST-06, R-GITOPS-01, R-SEC-02
  • Supersedes: —
  • Accepted by: operator ruling of 2026-11-08 that the implementation is the accepted state; effective on merge.

Context

ADR-0010 makes the conformance suite gate merges but does not say who approves. The operator's stated principle (2026-09-29): the CI/CD pipeline is the approver, and if it is not good enough to be trusted for that, it is not good enough to do its job and needs improving. Manual approval belongs only on architecturally or security-relevant changes.

That has one structural hole: a change to the gate cannot be gated by the gate, since a PR that weakens a check would be approved by the weakened check.

There is also one human on this platform, and Gitea refuses to let an author approve their own pull request. Requiring one approval on the branch was a lock-out rather than a protection: a change with a green gate and no possible reviewer could never merge, including the change that would fix that.

Decision

  • The merge gate is the approver. It is the single required status check on main. Branch protection requires zero approvals, direct pushes are rejected, and a red gate is unmergeable by everyone, administrators included.
  • Sensitive paths need a non-author approving review. This covers the pipeline, the tests and harness, the Flux wiring, the admission policies, the SOPS recipients and secrets, the RBAC, and the delivery contract. The path list is data with a stated reason per entry, and is itself sensitive. The stage is fail-closed: if it cannot evaluate, it blocks, since a skip there would be a bypass.
  • An administrator may waive that review with an explicit directive on the PR. It must start a line and carry a reason. Permission is re-checked live when the gate runs. A newer commit invalidates it. The overrider, source, time and reason are printed in the gate output.
  • Agents never use the override on their own work, regardless of the permission their account holds. This is a rule of the delivery contract; the check itself authorises by live permission alone (operator decision, 2026-10-01).

Alternatives considered

  • Require one approval on the branch — unsatisfiable with one human and author self-approval refused. Rejected after a green PR proved unmergeable.
  • Allow administrators to merge past the gate — reopens the route by which PRs had merged with zero checks while settings read as enforced. Rejected; only the approval count was dropped.
  • Gate approves everything, including its own changes — a weakening PR would approve itself. Rejected.
  • No override — the sole administrator could not change the pipeline at all. Rejected.
  • Restrict the override to an allowlist of human accounts — stronger, and reachable later without logic changes. Not adopted at this time, with the consequence below accepted knowingly.

Consequences

  • Ordinary changes merge on green with no human step; a weak gate is a defect, not a reason for review.
  • For an administrator, "the gate cannot gate itself" is advisory, not structural. What is guaranteed is an attributed, reasoned, commit-scoped record of every waiver.
  • An agent account with administrator permission can clear the review on its own PR. Only the delivery contract prohibits it. Automated agents such as pm-agent (ADR-0025) therefore use non-administrator accounts.
  • Live Gitea settings sit outside git, so a gate stage compares them against a committed declaration.
  • The approver is only as good as what the gate runs (known gaps).