docs(603): backfill stale-after + Sources onto the three ci.* outside-world records
The mechanism shipped unused. First adopters are the records that encode measured host behavior, which is what drifts silently: - ci.runner-placement 2027-01-15 — bumblebee sizing (25 GiB/12 cores) + container caps. Premise has already partly moved: the media transcoders left for jazz on 2026-07-20 and the runners were retuned since. - ci.infra-shaped-red-under-load 2027-02-15 — a triage heuristic calibrated against load 243 on a host that has since been retuned. - ci.peak-anon-measurement 2027-03-15 — weakest of the three (mostly our own script) but it does assert that memory.peak is cache-inflated, a cgroup fact. Dates staggered so they don't all come due in the same week. Each Sources line cites the incident evidence already named in the record's own prose.
This commit is contained in:
+4
-2
@@ -1489,10 +1489,11 @@ weights) and SPA child #386 remain open under the #383 milestone.
|
||||
---
|
||||
|
||||
## 2026-07-17 — No persistent compiler servers in CI; every `services:` container gets an explicit cap; #390's small-lane move reversed (#406)
|
||||
`key: ci.runner-placement` · `status: active` · `since: 2026-07-17` · `supersedes: none` · `superseded-by: none`
|
||||
`key: ci.runner-placement` · `status: active` · `since: 2026-07-17` · `supersedes: none` · `superseded-by: none` · `stale-after: 2027-01-15`
|
||||
**Rule:** No persistent Roslyn compiler server survives a CI build (`UseSharedCompilation=false` etc., runner env + Dockerfile `ENV`); every `services:` container gets its own explicit `--memory`/`--memory-swap`/`--cpus` cap (it does not inherit the job container's).
|
||||
**Signals:** CI memory/swap thrash · paths: `.gitea/workflows/*.yml`, `docker/Dockerfile` · issues: #406, #390 (prose-reversed, no standalone record), server-management#604, server-management#570
|
||||
**Mechanics:** `docs/ci-cd.md` → CI build memory; `scripts/ci-peak-anon.sh`
|
||||
**Sources:** the 2026-07-17 bumblebee incident — load 340, 21 GiB swapped, ~238 MiB free, prod down until reboot (server-management#604) · host sizing at the time: 25 GiB / 12 cores
|
||||
|
||||
Three CI changes, all downstream of one incident: on 2026-07-17 bumblebee (the **prod media** Docker
|
||||
host, 25 GiB / 12 cores) hit load **340** with **21 GiB swapped** and ~238 MiB free, taking prod
|
||||
@@ -2301,10 +2302,11 @@ The blocking `format` CI job (and the matching Husky pre-commit hook) verify cha
|
||||
server-management capacity call — deliberately out of scope here.
|
||||
|
||||
## 2026-07-19 — CI `test` job reports a sampled true peak-anon, not cache-inflated `memory.peak` (#412)
|
||||
`key: ci.peak-anon-measurement` · `status: active` · `since: 2026-07-19` · `supersedes: none` · `superseded-by: none`
|
||||
`key: ci.peak-anon-measurement` · `status: active` · `since: 2026-07-19` · `supersedes: none` · `superseded-by: none` · `stale-after: 2027-03-15`
|
||||
**Rule:** The `test` job's headline memory figure is a sampled high-water mark of cgroup `anon`, produced by `scripts/ci-peak-anon.sh`; `memory.peak` and the end-of-job `anon`/`file` split are kept only as a cache-inflated reference.
|
||||
**Signals:** CI memory measurement · paths: `scripts/ci-peak-anon.sh`, `.gitea/workflows/*.yml` · issues: #412, #411 (prose-only predecessor, no standalone record — its `memory.peak`-headline approach is superseded by this record)
|
||||
**Mechanics:** `scripts/ci-peak-anon.sh` header; `docs/ci-cd.md` → CI build memory
|
||||
**Sources:** `scripts/ci-peak-anon.sh` (the sampler itself) · cgroup v2 `memory.peak` vs `memory.stat` `anon` accounting, measured on the bumblebee runners #412
|
||||
|
||||
**Decision.** The `test` job's memory instrument (added in #411) now reports a **sampled high-water
|
||||
mark of the cgroup's `anon` memory** as the headline figure, produced by `scripts/ci-peak-anon.sh`
|
||||
|
||||
@@ -169,3 +169,15 @@ the link for rationale. Superseded/retired history lives in `archive/`. Regenera
|
||||
| `testing.playwright-mcp-download-and-recovery` | In Playwright-MCP E2E, fetch file-download endpoints with curl — never a browser tab or `window.open` — and if browser tools stall repeatedly, `pkill -f ms-playwright-mcp` and drive a fresh session. | 2026-07-21 | [link](workflow-process.md#2026-07-21--playwright-mcp-curl-download-endpoints-never-open-a-tab-or-windowopen-542) |
|
||||
| `testing.scripted-playout-golden-deferred` | The `PlayoutBuildGoldenTests` in-memory golden net covers Sequential (YAML) as of #381. Scripted's *end-to-end pipeline* is excluded — `ScriptedPlayoutBuilder` runs a user-authored external program that drives the engine over HTTP loopback, which the in-memory harness can't pin — so that full-pipeline (integration) harness is deferred to #563. But the scheduling *behavior* those scripts drive lives entirely in the in-process `SchedulingEngine` (the `ScriptedScheduleController` is a 1:1 pass-through to it), which IS directly unit/golden-testable; the earlier "Scripted is un-golden-able by construction" framing overstated the constraint by conflating transport with engine. #395 extracts that shared switch to `ContentEnumeratorBuilder` and adds a direct regression net (`ContentEnumeratorBuilderTests`) over it. | 2026-07-22 | [link](../decisions.md#2026-07-22--sequential-yaml-playout-gets-a-golden-scripted-is-excluded-from-the-golden-net-by-construction-381) |
|
||||
| `testing.troubleshoot-path-cannot-test-branding` | Verify logo/watermark/bug changes through a real channel playout — a green troubleshoot run proves nothing about branding. | 2026-07-21 | [link](workflow-process.md#2026-07-21--channel-branding-is-not-testable-through-the-troubleshooting-playback-api-542) |
|
||||
|
||||
## Review due
|
||||
|
||||
Active records that assert facts about the outside world and carry a `stale-after` date.
|
||||
Once that date passes, re-confirm the fact and either extend the date or supersede the
|
||||
record. Sorted soonest-first.
|
||||
|
||||
| Stale after | Key | Record |
|
||||
| --- | --- | --- |
|
||||
| 2027-01-15 | `ci.runner-placement` | [link](../decisions.md#2026-07-17--no-persistent-compiler-servers-in-ci-every-services-container-gets-an-explicit-cap-390s-small-lane-move-reversed-406) |
|
||||
| 2027-02-15 | `ci.infra-shaped-red-under-load` | [link](workflow-process.md#2026-07-21--an-infra-shaped-red-under-host-load-is-not-a-code-failure-542) |
|
||||
| 2027-03-15 | `ci.peak-anon-measurement` | [link](../decisions.md#2026-07-19--ci-test-job-reports-a-sampled-true-peak-anon-not-cache-inflated-memorypeak-412) |
|
||||
|
||||
@@ -56,10 +56,11 @@ next session debugging a phantom. Split the two counts explicitly.
|
||||
|
||||
## 2026-07-21 — An infra-shaped red under host load is not a code failure (#542)
|
||||
|
||||
`key: ci.infra-shaped-red-under-load` · `status: active` · `since: 2026-07-21` · `supersedes: none` · `superseded-by: none`
|
||||
`key: ci.infra-shaped-red-under-load` · `status: active` · `since: 2026-07-21` · `supersedes: none` · `superseded-by: none` · `stale-after: 2027-02-15`
|
||||
**Rule:** When a job dies inside a setup/cache step before your code compiles, check the runner host's load before diagnosing the diff, and never file a CI bug off one sample under pressure.
|
||||
**Signals:** load average 243 · `Setup .NET` 11ms failure · `remove /root/.cache/act/…/.gitignore: no such file or directory` · buildx `DeadlineExceeded: failed to compute cache key` · `Build & push image` · `EF migration integrity` · `FactoryServer-L` game server · phantom CI bug · paths: n/a · issues: #542
|
||||
**Mechanics:** `uptime` on the runner host (bumblebee); Gitea Actions job step logs.
|
||||
**Sources:** 2026-07-17, bumblebee at load average 243 — `EF migration integrity` dead in ~11ms inside `Setup .NET`, main's `Build & push image` dead on buildx `DeadlineExceeded`; both green on re-run at normal load (#542)
|
||||
|
||||
On 2026-07-17, with bumblebee at load average **243**, two unrelated jobs died in ways that look like
|
||||
code bugs but weren't: `EF migration integrity` failed in ~11ms inside **`Setup .NET`** with
|
||||
|
||||
Reference in New Issue
Block a user