The 2026-09-29 session found the merge gate did not exist — no branch protection, no runner
— while the tree confidently asserted both. This corrects the documents that carried, and in
several cases caused, that belief.
The important one
CLAUDE.md gains §2b: never infer platform state from this repository. It carries the
specific API and kubectl checks for protection, runners, CI status, workloads and Flux
revisions, and the rule that a green tick is not proof anything ran (a skipped Gitea job
reports success). This is the rule whose absence produced every other finding in the session.
Stale plans read as statements of fact
.gitea/workflows/README.md and merge-gate.yaml both said "there is no remote git host,
this file is dormant." Gitea had been live for weeks. Both were written as plans and never
revisited once the plan completed. Transition is now marked COMPLETE, and says what genuinely
remains (CLUSTER_AVAILABLE unset → L2/L3 never runs in CI).
DECISIONS-LOG.md 2026-08-31 annotated in place. Reading chronologically, you previously
hit "required status check; runner incluster-dind online" with nothing marking it false
until a month later. The correction now sits on the bullet itself.
ci/README.md, clusters/README.md and both conformance READMEs get a status banner. They
speak as though no cluster exists, which makes a live L2/L3 coverage gap read as an expected
phase. That framing is why the gap went unexamined.
Doc/reality mismatches
gitea-actions-runner-secret.sops.yaml — wrong path; advice to sops -d into a terminal
(which CLAUDE.md forbids) replaced with the rotation script; records that a fresh token
alone does not re-register a runner holding a stale /data/.runner.
plex-claim-secret.sops.yaml — header claimed the file ships the placeholder. It hasn't since
the claim; it holds the spent token, inert and deliberately left.
catalog/plex.yaml + the plex secret — both asserted a "~4-minute TTL" as fact. Uncited,
upstream documents no expiry, and it was the basis for a since-disproven claim that the
pipeline was too slow to fit. Measured: ~2m45s.
Verification
Both .sops.yaml files confirmed to still decrypt after the comment edits
(sops -d > /dev/null — nothing printed), and render==golden confirms the catalog comment
does not propagate into the rendered manifest.
The 2026-09-29 session found the merge gate did not exist — no branch protection, no runner
— while the tree confidently asserted both. This corrects the documents that carried, and in
several cases **caused**, that belief.
### The important one
**`CLAUDE.md` gains §2b: *never infer platform state from this repository*.** It carries the
specific API and `kubectl` checks for protection, runners, CI status, workloads and Flux
revisions, and the rule that **a green tick is not proof anything ran** (a skipped Gitea job
reports `success`). This is the rule whose absence produced every other finding in the session.
### Stale plans read as statements of fact
- `.gitea/workflows/README.md` and `merge-gate.yaml` both said *"there is no remote git host,
this file is dormant."* Gitea had been live for weeks. Both were written as plans and never
revisited once the plan completed. Transition is now marked COMPLETE, and says what genuinely
remains (`CLUSTER_AVAILABLE` unset → L2/L3 never runs in CI).
- **`DECISIONS-LOG.md` 2026-08-31 annotated in place.** Reading chronologically, you previously
hit *"required status check; runner incluster-dind online"* with nothing marking it false
until a month later. The correction now sits on the bullet itself.
- `ci/README.md`, `clusters/README.md` and both conformance READMEs get a status banner. They
speak as though no cluster exists, which makes a **live L2/L3 coverage gap read as an expected
phase**. That framing is why the gap went unexamined.
### Doc/reality mismatches
- `gitea-actions-runner-secret.sops.yaml` — wrong path; advice to `sops -d` into a terminal
(which `CLAUDE.md` forbids) replaced with the rotation script; records that a fresh token
alone does **not** re-register a runner holding a stale `/data/.runner`.
- `plex-claim-secret.sops.yaml` — header claimed the file ships the placeholder. It hasn't since
the claim; it holds the spent token, inert and deliberately left.
- `catalog/plex.yaml` + the plex secret — both asserted a **"~4-minute TTL" as fact**. Uncited,
upstream documents no expiry, and it was the basis for a since-disproven claim that the
pipeline was too slow to fit. Measured: **~2m45s**.
### Verification
Both `.sops.yaml` files confirmed to **still decrypt** after the comment edits
(`sops -d > /dev/null` — nothing printed), and `render==golden` confirms the catalog comment
does not propagate into the rendered manifest.
Gate: **PASS, rc 0, 79s**.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The 2026-09-29 session found the merge gate did not exist -- no branch protection, no
runner -- while the tree asserted both. This corrects the documents that carried, and in
several cases CAUSED, that belief.
CLAUDE.md gains section 2b: never infer platform state from this repository. It carries
the specific API and kubectl checks for protection, runners, CI status, workloads and
Flux revisions, and the rule that a green tick is not proof anything ran (a skipped Gitea
job reports success). This is the rule whose absence produced every other finding.
.gitea/workflows/README.md and merge-gate.yaml both said "there is no remote git host,
this file is dormant". Gitea had been live for weeks. Both were written as plans and never
revisited once the plan completed. The Transition section is now marked COMPLETE and says
what is genuinely still outstanding (CLUSTER_AVAILABLE unset, so L2/L3 never runs in CI).
DECISIONS-LOG 2026-08-31 is annotated IN PLACE. Anyone reading chronologically previously
hit "required status check; runner incluster-dind online" with nothing marking it false
until a month later. The correction now sits on the bullet itself.
ci/README.md, clusters/README.md and both conformance READMEs carry a status banner: they
speak as though no cluster exists, which makes a live L2/L3 coverage gap read as an
expected phase. That framing is why the gap went unexamined.
apps/wave-1/gitea-actions-runner-secret.sops.yaml: fixed a wrong path, replaced advice to
`sops -d` into a terminal (which CLAUDE.md forbids) with the rotation script, and recorded
that a fresh token alone does not re-register a runner holding a stale /data/.runner.
apps/wave-0/plex-claim-secret.sops.yaml: the header claimed the file ships the placeholder.
It has not since the claim -- it holds the spent token, which is inert and deliberately
left in place.
catalog/plex.yaml and the plex secret both asserted a "~4-minute TTL" as fact. It was
uncited, upstream documents no expiry, and it was the basis for a since-disproven claim
that the pipeline was too slow to fit inside it. Measured: ~2m45s.
Both .sops.yaml files were verified to still decrypt after the comment edits
(`sops -d > /dev/null`), and render==golden confirms the catalog comment does not
propagate into the rendered manifest.
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.
The 2026-09-29 session found the merge gate did not exist — no branch protection, no runner
— while the tree confidently asserted both. This corrects the documents that carried, and in
several cases caused, that belief.
The important one
CLAUDE.mdgains §2b: never infer platform state from this repository. It carries thespecific API and
kubectlchecks for protection, runners, CI status, workloads and Fluxrevisions, and the rule that a green tick is not proof anything ran (a skipped Gitea job
reports
success). This is the rule whose absence produced every other finding in the session.Stale plans read as statements of fact
.gitea/workflows/README.mdandmerge-gate.yamlboth said "there is no remote git host,this file is dormant." Gitea had been live for weeks. Both were written as plans and never
revisited once the plan completed. Transition is now marked COMPLETE, and says what genuinely
remains (
CLUSTER_AVAILABLEunset → L2/L3 never runs in CI).DECISIONS-LOG.md2026-08-31 annotated in place. Reading chronologically, you previouslyhit "required status check; runner incluster-dind online" with nothing marking it false
until a month later. The correction now sits on the bullet itself.
ci/README.md,clusters/README.mdand both conformance READMEs get a status banner. Theyspeak as though no cluster exists, which makes a live L2/L3 coverage gap read as an expected
phase. That framing is why the gap went unexamined.
Doc/reality mismatches
gitea-actions-runner-secret.sops.yaml— wrong path; advice tosops -dinto a terminal(which
CLAUDE.mdforbids) replaced with the rotation script; records that a fresh tokenalone does not re-register a runner holding a stale
/data/.runner.plex-claim-secret.sops.yaml— header claimed the file ships the placeholder. It hasn't sincethe claim; it holds the spent token, inert and deliberately left.
catalog/plex.yaml+ the plex secret — both asserted a "~4-minute TTL" as fact. Uncited,upstream documents no expiry, and it was the basis for a since-disproven claim that the
pipeline was too slow to fit. Measured: ~2m45s.
Verification
Both
.sops.yamlfiles confirmed to still decrypt after the comment edits(
sops -d > /dev/null— nothing printed), andrender==goldenconfirms the catalog commentdoes not propagate into the rendered manifest.
Gate: PASS, rc 0, 79s.
Co-Authored-By: Claude Opus 5 (1M context) [email protected]
🤖 Generated with Claude Code