docs(lore): batching, no "main checkout", trust the queue, diagnosing CI reds #417

Merged
timothy merged 1 commits from docs/lore-batching-rules into main 2026-07-17 18:43:34 +02:00
Owner

Docs-only. Standing-lore corrections from the #72 session, batched into one push (per the batching rule the PR itself adds).

Changes to docs/handoffs/chicorytv-issue-queue.md

  • BATCH PUSHES — cancellation is impossible agent-side on Gitea 1.25.4 (REST + MCP cancel_run both 404, web login won't script); an orphaned run holds a runner slot. Only the operator can cancel — say so if you must supersede a live run.
  • TRUST THE GITEA BUILD QUEUE — do not gate/throttle a push on host health; the runners were retuned for stability.
  • BOM-check touched .cs before pushing — the #311 gate only surfaces in CI. Corrects an earlier claim: dotnet format --include DOES work here; the apparent no-op was zsh lacking mapfile (bash-only).
  • THERE IS NO "main checkout" — /Users/timothy/ersatztv is a shared mutable tree, not a main mirror. Never commit there, never read its HEAD to learn about main; origin/main is the only truth. Bit two sessions on 2026-07-17 (a commit landed on another session's branch; another read main as "4 behind"). A design flaw, not a discipline failure — "check git status first" appears to confirm the false belief then goes stale.
  • Diagnosing CI reds — a killed job reports conclusion: failure (tell: log stops mid-step with no ❌ marker); cancelled ≠ failure (no verdict); an infra-shaped red under host pressure is not a code failure; Unable to pull refs/heads/v4 is act cache noise. Monitors must count FAILED and CANCELLED separately.
  • The cheap queue-selector also misses in-progress claim state and umbrella-vs-child, not just deps/priority.

No code, no convention/route/endpoint change — exempt from the same-PR-docs and API-regen rules.

🤖 Generated with Claude Code

Docs-only. Standing-lore corrections from the #72 session, batched into one push (per the batching rule the PR itself adds). ## Changes to `docs/handoffs/chicorytv-issue-queue.md` - **BATCH PUSHES** — cancellation is impossible agent-side on Gitea 1.25.4 (REST + MCP `cancel_run` both 404, web login won't script); an orphaned run holds a runner slot. Only the operator can cancel — say so if you must supersede a live run. - **TRUST THE GITEA BUILD QUEUE** — do not gate/throttle a push on host health; the runners were retuned for stability. - **BOM-check touched `.cs` before pushing** — the #311 gate only surfaces in CI. Corrects an earlier claim: `dotnet format --include` DOES work here; the apparent no-op was zsh lacking `mapfile` (bash-only). - **THERE IS NO "main checkout"** — `/Users/timothy/ersatztv` is a shared mutable tree, not a `main` mirror. Never commit there, never read its HEAD to learn about `main`; `origin/main` is the only truth. Bit two sessions on 2026-07-17 (a commit landed on another session's branch; another read `main` as "4 behind"). A design flaw, not a discipline failure — "check git status first" appears to confirm the false belief then goes stale. - **Diagnosing CI reds** — a *killed* job reports `conclusion: failure` (tell: log stops mid-step with no `❌` marker); `cancelled` ≠ `failure` (no verdict); an infra-shaped red under host pressure is not a code failure; `Unable to pull refs/heads/v4` is act cache noise. Monitors must count FAILED and CANCELLED separately. - The cheap queue-selector also misses `in-progress` claim state and umbrella-vs-child, not just deps/priority. No code, no convention/route/endpoint change — exempt from the same-PR-docs and API-regen rules. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
timothy added 1 commit 2026-07-17 18:16:02 +02:00
docs(lore): batching, no "main checkout", trust the queue, killed≠failed
Build ErsatzTV Image / CI image pin matches docker/ci (pull_request) Successful in 6s
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 5s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 4s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 7m1s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 19s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 16s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m54s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 14m5s
fe6e2722f8
Operator-requested after PR #405 pushed 5 times, orphaning live runs the
operator had to cancel by hand. Batches every standing-lore correction this
session produced into one commit (per the batching rule it adds).

New HARD CONSTRAINTS:
- BATCH PUSHES. Cancellation is impossible from the agent side on Gitea 1.25.4
  — REST .../runs/{id}/cancel and MCP cancel_run both 404, and the web-UI route
  needs a session+CSRF that doesn't script. Only the operator can cancel, so an
  orphaned run holds a runner slot until it finishes. If you must supersede a
  live run, SAY SO.
- TRUST THE GITEA BUILD QUEUE. Do not gate/throttle a push on host health; the
  runners were retuned for stability. Batch because you can't cancel what you
  orphan, not to protect the host.
- BOM-CHECK touched .cs before pushing. The #311 gate is fix-as-you-touch, and
  it bit two sessions the same day (PR #405 ×6; #70/PR #402 ×19 via Python
  utf-8-sig writing BOMs back). Verify your detector — an od-based grep reported
  all-clean while 19 files were dirty.
  Corrects a claim I nearly published: `dotnet format --include` DOES work here.
  The apparent no-op was the SHELL — CI's mapfile is bash-only, zsh has no
  mapfile → empty array → zero files → exit 0. Run it under bash -c.

THERE IS NO "main checkout" — the biggest correction here.
/Users/timothy/ersatztv is a shared mutable working tree whose HEAD is whatever
the last session left there. Its name lies, and it bit TWO sessions on
2026-07-17, both doing the obvious thing: one assumed main and committed onto
the #604/CI session's branch 24s after that session's own commit; another read
git log there and concluded main was "4 behind origin" — a phantom. Framed as a
design flaw, not a discipline failure: "check git status first" appears to
confirm the false assumption and then goes stale (it WAS on main at 12:46 and
wasn't by 14:17). Worktree discipline itself is healthy — 10 feature worktrees.

Diagnosing CI reds — three ways to misread one, all hit this session:
- A KILLED job reports conclusion=failure, not cancelled. The tell is a log that
  stops mid-step with NO error and NO failure marker. A runner retune killed run
  1006's migration + E2E on a BOM-only diff that couldn't break them. Log
  timestamps are UTC, host is UTC+2 — convert before correlating.
- cancelled ≠ failure: a cancel is NO verdict, and a run marked failure may hold
  a genuine job failure from BEFORE the cancel. Monitors must count FAILED and
  CANCELLED separately.
- "Unable to pull refs/heads/v4" is act refreshing its action cache and is
  followed by "Cloned …" — noise, not a cause. Grep the failure marker, not
  the word "error". An infra-shaped red (setup/cache step, before your code
  compiles) is not a code failure; don't file a CI bug off one sample.

Also: the cheap selector's failure modes are wider than deps+priority — it also
misses in-progress claim state and umbrella-vs-child.

Docs-only.
timothy scheduled this pull request to auto merge when all checks succeed 2026-07-17 18:16:10 +02:00
timothy merged commit 30415d12f9 into main 2026-07-17 18:43:34 +02:00
timothy deleted branch docs/lore-batching-rules 2026-07-17 18:43:34 +02:00
Sign in to join this conversation.