main became a protected branch today, so the direct push that 37 of 39 runbooks
instructed is now rejected. That wording was merely stale before; it is now actively
wrong — and it is the line an operator reads mid-incident.
Every occurrence now describes the real path: push a branch, open a PR, merge once the
gate is green; that merge is the deploy. 35 files shared one identical block; flux-reconcile.md, README.md and plex-claim.md each phrased it their own way and
were corrected individually. Zero occurrences of git push origin main remain.
runbooks/plex-claim.md
Rewritten around the delivery loop, and it records that the server is now claimed — PlexOnlineToken is present in /config on the plex-config PVC, so PLEX_CLAIM is a
permanent no-op and the page only applies after a /config wipe.
Adds infra/plex/claim-ship.sh, which drives the whole loop with a stopwatch. Three
steps are easy to lose under time pressure and two are silent when skipped:
--with-source — without it the Kustomization applies the previously-fetched revision
the mandatoryrollout restart — only the ciphertext changes, so the pod template is
byte-identical and nothing restarts itself
the feat/ branch prefix — act_runner capacity is 1, and a prefix inside gate.yml's
push trigger fires a redundant run that serialises ahead of the PR run
Drops the "~4-minute TTL" the page asserted in four places. It was uncited, and upstream pms-docker documents no expiry at all. The countdown on plex.tv/claim is the authority.
Measured loop end to end: ~2m45s.
DECISIONS-LOG.md
PM handoff: both halves of the 2026-08-31 CI claim were false, the stale-.runner root
cause, the four-deep Flux dependency cascade that delayed recovery, and the correction that
a skipped Gitea job reports success rather than hanging.
`main` became a protected branch today, so the direct push that **37 of 39 runbooks**
instructed is now **rejected**. That wording was merely stale before; it is now actively
wrong — and it is the line an operator reads mid-incident.
Every occurrence now describes the real path: push a branch, open a PR, merge once the
gate is green; that merge is the deploy. 35 files shared one identical block;
`flux-reconcile.md`, `README.md` and `plex-claim.md` each phrased it their own way and
were corrected individually. **Zero occurrences of `git push origin main` remain.**
### `runbooks/plex-claim.md`
Rewritten around the delivery loop, and it records that **the server is now claimed** —
`PlexOnlineToken` is present in `/config` on the `plex-config` PVC, so `PLEX_CLAIM` is a
permanent no-op and the page only applies after a `/config` wipe.
Adds **`infra/plex/claim-ship.sh`**, which drives the whole loop with a stopwatch. Three
steps are easy to lose under time pressure and **two are silent when skipped**:
- `--with-source` — without it the Kustomization applies the previously-fetched revision
- the **mandatory** `rollout restart` — only the ciphertext changes, so the pod template is
byte-identical and nothing restarts itself
- the `feat/` branch prefix — `act_runner` capacity is 1, and a prefix inside `gate.yml`'s
push trigger fires a redundant run that serialises ahead of the PR run
Drops the **"~4-minute TTL"** the page asserted in four places. It was uncited, and upstream
`pms-docker` documents no expiry at all. The countdown on plex.tv/claim is the authority.
Measured loop end to end: **~2m45s**.
### `DECISIONS-LOG.md`
PM handoff: both halves of the 2026-08-31 CI claim were false, the stale-`.runner` root
cause, the four-deep Flux dependency cascade that delayed recovery, and the correction that
a skipped Gitea job reports `success` rather than hanging.
Gate: `./ci/gate.sh` — **PASS, rc 0, 78s**.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
main became a protected branch on 2026-09-29, so the direct push that 37 of 39 runbooks
instructed is REJECTED. The wording was merely stale before; it is now actively wrong,
and it is the line an operator reads mid-incident.
Every occurrence now describes the real path: push a branch, open a PR, merge once the
gate is green -- that merge is the deploy. 35 files shared one identical block;
flux-reconcile.md, README.md and plex-claim.md each said it their own way and were
corrected individually.
plex-claim.md is rewritten around the delivery loop and records that THE SERVER IS NOW
CLAIMED (PlexOnlineToken present in /config), so PLEX_CLAIM is a permanent no-op and the
page only applies after a /config wipe.
Adds infra/plex/claim-ship.sh, which drives branch -> commit -> push -> PR -> gate ->
merge -> reconcile -> pod roll -> verdict with a stopwatch. Three steps are easy to lose
under time pressure and two are SILENT when skipped: --with-source (without it the
Kustomization applies the previously-fetched revision), the mandatory rollout restart
(only the ciphertext changes, so the pod template is byte-identical and nothing restarts
itself), and the feat/ branch prefix (act_runner capacity is 1, and a prefix inside
gate.yml's push trigger fires a redundant run that serialises ahead of the PR run).
Drops the "~4-minute TTL" the page asserted in four places. It was uncited, and upstream
pms-docker documents no expiry at all. The countdown on plex.tv/claim is the authority.
Measured loop: ~2m45s.
DECISIONS-LOG carries the PM handoff: both halves of the 2026-08-31 CI claim were false,
the stale-.runner root cause, the four-deep Flux dependency cascade, and the correction
that a skipped Gitea job reports success rather than hanging.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
A systematic grep for the TTL assertion found it still in runbooks/README.md and in
runbooks/kustomization.yaml, outside the page being rewritten. Same correction: the
countdown on plex.tv/claim is the authority, not a number in our tree.
README.md also now records that the server is CLAIMED and points at claim-ship.sh with
the measured ~2m45s loop, rather than describing a push-based sequence that no longer
exists.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
mainbecame a protected branch today, so the direct push that 37 of 39 runbooksinstructed is now rejected. That wording was merely stale before; it is now actively
wrong — and it is the line an operator reads mid-incident.
Every occurrence now describes the real path: push a branch, open a PR, merge once the
gate is green; that merge is the deploy. 35 files shared one identical block;
flux-reconcile.md,README.mdandplex-claim.mdeach phrased it their own way andwere corrected individually. Zero occurrences of
git push origin mainremain.runbooks/plex-claim.mdRewritten around the delivery loop, and it records that the server is now claimed —
PlexOnlineTokenis present in/configon theplex-configPVC, soPLEX_CLAIMis apermanent no-op and the page only applies after a
/configwipe.Adds
infra/plex/claim-ship.sh, which drives the whole loop with a stopwatch. Threesteps are easy to lose under time pressure and two are silent when skipped:
--with-source— without it the Kustomization applies the previously-fetched revisionrollout restart— only the ciphertext changes, so the pod template isbyte-identical and nothing restarts itself
feat/branch prefix —act_runnercapacity is 1, and a prefix insidegate.yml'spush trigger fires a redundant run that serialises ahead of the PR run
Drops the "~4-minute TTL" the page asserted in four places. It was uncited, and upstream
pms-dockerdocuments no expiry at all. The countdown on plex.tv/claim is the authority.Measured loop end to end: ~2m45s.
DECISIONS-LOG.mdPM handoff: both halves of the 2026-08-31 CI claim were false, the stale-
.runnerrootcause, the four-deep Flux dependency cascade that delayed recovery, and the correction that
a skipped Gitea job reports
successrather than hanging.Gate:
./ci/gate.sh— PASS, rc 0, 78s.Co-Authored-By: Claude Opus 5 (1M context) [email protected]
🤖 Generated with Claude Code
git push origin main-- that instruction is now blocked