docs: delivery contract for agents + record that the merge gate does not exist
gate / gate (push) Has been cancelled
gate / conformance (push) Has been cancelled
gate / gate (pull_request) Successful in 1m33s
gate / conformance (pull_request) Has been skipped

Going to land the plex claim wiring through the documented PR flow surfaced that
the flow has never run. PR #1 is the first pull request this repo has ever had.

Verified against the live Gitea, not inferred from the docs:
  * branch_protections is [] -- main is protected:false, enable_status_check:false,
    status_check_contexts:[], required_approvals:0, user_can_push:true
  * ZERO Actions runners registered at repo, org and site level

DECISIONS-LOG 2026-08-31 asserts a "required status check" and a runner
"incluster-dind online". Both are false of the live system. The gate is neither
enforced nor able to run, and that went unnoticed because the log claimed
otherwise -- the same fail-open class as the two holes found on 2026-09-18.

Adds CLAUDE.md, the first agent-facing delivery doc here: the
branch -> PR -> gate -> approval -> merge rule, stated alongside the honest fact
that enforcement is currently weaker than the rule, so agents follow the rule
rather than what they can get away with. Carries the toolbox gate invocation, the
two git-worktree workarounds, the rc 0/1/3 contract, and secret handling.

Records the ordering trap: enabling a required status check before a runner exists
deadlocks every PR permanently, including the one that would fix it.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
jakman85andClaude Opus 5 committed 2026-09-29 00:11:58 -05:00
1 parent d7f24d0a9e
commit 5a9e455149
2 files changed
+180

No files matched your search

+65
View File
@@ -4716,3 +4716,68 @@ asleep. `git worktree remove` preserves branches and their commits, so only that
6. **Five `public` services have no working public path** — waiting on WAN forwarding, deliberately.
7. Backlog cherry-picks: `feat/egress-gateway-staleness-alert`, two `rescued/*` fixes, two rendered
manifests nothing applies (the keycloak one would stand up a conflicting instance).
## 2026-09-29 — The CI/CD merge gate does not exist: no runner, no branch protection. **PM HANDOFF.**
Went to land the plex claim wiring through the documented PR flow and discovered the flow has
never run. **PR #1 is the first pull request this repository has ever had.** It is still queued.
### What is actually true of the live Gitea (verified via API, 2026-09-29)
| Claimed (DECISIONS-LOG 2026-08-31) | Measured |
|---|---|
| "required status check" on `main` | `branch_protections` returns `[]`. `protected: false`, `enable_status_check: false`, `status_check_contexts: []`, `required_approvals: 0`, `user_can_push: true` |
| "runner `incluster-dind` online (ns gitea-actions)" | **Zero runners registered** at repo, org and site level |
Both halves of that entry are false. Nothing enforces the gate, and the gate cannot run.
PR #1's two contexts (`gate / gate`, `gate / conformance`) sat `pending` for 14+ minutes with
nothing to execute them, and will sit there indefinitely.
This is a **fail-open governance hole**, the same class as the two found on 2026-09-18 — and it
was invisible precisely because the log asserted the opposite. Every "the gate is enforcing"
statement since 2026-08-31 rested on an unverified claim.
### Ordering trap — read before fixing
**Do not enable required status checks until a runner is live.** Requiring
`gate / gate (pull_request)` with no runner deadlocks every PR permanently, including the PR
that would fix it. Sequence: runner first, verify the gate actually runs and passes on a real
PR, *then* turn on enforcement with the context name CI actually reported.
Related: `gate.yml`'s `conformance` job is `if: false` by design (honest skip, never fake green),
but it still publishes a `gate / conformance (pull_request)` context. If that context is ever
listed as required, it deadlocks every PR for the same reason. Wire it or exclude it.
### Delivery contract written down
Added `CLAUDE.md` at the repo root — the first agent-facing delivery doc here. It states the
branch -> PR -> gate -> approval -> merge rule, records that enforcement is currently weaker than
the rule (so agents follow the rule rather than what they can get away with), and carries the
toolbox-gate invocation, the two git-worktree workarounds, the rc 0/1/3 contract, and the secret
handling rules.
It also flags that **37 of 39 runbooks still instruct `git push origin main`**. Those were
accurate before the PR flow and are stale now. Correcting them is tracked, not done.
### Also found, not fixed
- `gate.yml`'s push trigger lists `feature/**`; this repo's branches use `feat/**`, so branch
pushes get no fast-feedback run. PR trigger is unaffected.
- The gitea-actions runner is GitOps-managed (`apps/wave-1/gitea-actions.yaml` +
`gitea-actions-runner-secret.sops.yaml`), so it is deployed but not registering — most likely a
stale registration token in that SOPS secret. Needs in-cluster diagnosis (operator).
- **Plex is still unclaimed and it was never checked** whether it is already claimed. Do that
before spending a token — `runbooks/plex-claim.md` §First commands.
- `runbooks/plex-claim.md` asserts a "~4-minute TTL" for a plex.tv claim token in four places,
**uncited**, and the whole stopwatch procedure is built on it. Upstream `pms-docker`'s README
says nothing about expiry. The number is plausible community folklore, not a measured fact.
The authoritative reading is the countdown rendered on plex.tv/claim at issue time.
### Next steps
1. **Operator:** diagnose the gitea-actions runner; get one registered.
2. **Operator:** enable branch protection on `main` — push blocked, approvals required — and only
then add the gate as a required status check.
3. Land `feat/plex-claim-sops-secret` (PR #1) once the gate can actually run.
4. Claim plex, after checking it is not already claimed.
5. Correct the 37 runbooks' `git push origin main` wording.