e87285c33de783d86dae381aff0c217a6d35722b
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c8e79f49f4 |
chore(586,594,485): PID-scoped E2E cleanup, ci-image-pin length guard, .gitignore core fix
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 11s
PR Gates / Docs update reminder (pull_request) Successful in 11s
PR Gates / decisions lifecycle (pull_request) Successful in 12s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 21s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 15s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 6m22s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 21m9s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m55s
Three independent CI/repo-hygiene fixes swept together; disjoint file sets. fixes #586 — E2E cleanup is scoped by PID, never a pattern-wide pkill - New decision record `testing.e2e-cleanup-scope-by-pid`. - docs/e2e-local.md states the constraint where a BRIEF-WRITER sees it (the #586 root cause was a delegation gap, not agent error). - scripts/e2e-local.sh: reviewed against e2e-ui.sh's trap lifecycle and deliberately does NOT adopt it — its contract is to hand a running instance back to its caller, so an EXIT trap would kill the server the instant the launcher returned (both callers use `OUT="$(e2e-local.sh ...)"`). Recorded. - Instead it gains what actually prevents the incident: an lsof pre-flight that NAMES a foreign listener's PID rather than letting Kestrel fail its bind and surface as "process N exited before becoming ready". - Pre-flight probes BOTH bound ports, and ETV_STREAMING_PORT now defaults to ETV_UI_PORT. Program.cs binds a second listener whose port defaults to 8409 independently of ETV_UI_PORT, so `ETV_UI_PORT=8420` alone still bound 8409 and died against a foreign holder — i.e. the documented escape hatch was a dead end that led straight back to the confusion behind the pattern kill. fixes #594 — ci-image-pin accepts any hex length - Length is a separate invariant from correctness: the resolve/staleness checks compare resolved shas, so an 8-char pin of the right commit passes green while matching NO registry tag, and all five container: jobs then die at image-pull with `manifest unknown` (reads like a registry outage). - Guard fails at the gate and prints the exact tag to use. Verified against doctored pins: 7 green; 6/8/10 red. - Uses a literal 7 rather than a derived `--short=7`: in a full clone git may widen an ambiguous abbreviation, demanding a pin ci-image.yml can never publish. Escape hatch documented inline. - Also fixes a pre-existing misdiagnosis: zero pins reported "MORE THAN ONE". - docs/ci-cd.md documents the 7-char rule and `git rev-parse --short=7 HEAD`. fixes #485 — .gitignore `core` silently ignored `*/Core/` files - A bare `core` matched any path component named `core`; case-insensitively on macOS that swallowed every `*/Core/` SOURCE dir, so new untracked files were dropped by `git add -A` while tracked ones stayed fine — a clean local build and a CI checkout that fails to compile. - Now `/core` + `/core.[0-9]*`, both anchored (an unanchored `core.[0-9]*` would re-introduce the same silent-exclusion class this fixes). - Verified by diffing the full ignored-file set before/after: identical, and the three real Core/ dirs are trackable without -f. Docs updated in-PR: docs/e2e-local.md, docs/ci-cd.md, docs/decisions/ workflow-process.md (+ regenerated catalog), docs/handoffs/chicorytv-issue-queue.md. Follow-ups filed: #596 (the same shared-host reap in the Playwright-MCP recovery record) and the ci-image.yml `--short=7` publisher-side fix, which cannot ride this PR — editing ci-image.yml re-points ci-image-pin's `expected` at this commit and reds the gate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
2fee3f0b94 |
docs(592): record that a skipped CI context is not red [decisions-edit]
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 11s
PR Gates / Docs update reminder (pull_request) Successful in 12s
PR Gates / decisions lifecycle (pull_request) Successful in 25s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 40s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 23s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 20s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 21s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 13s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Amends ci.monitor-armed-at-pr-open (prose + Signals only; heading and key unchanged, no supersession) with the monitor-classification rules that were missing. Landing #436/#583 today, my CI monitor filtered per-context statuses on `!= "success"` and announced "NOT all green" on two fully green PRs, because `Build & push image (amd64)` reports `skipped`. Nothing was blocked — Gitea's combined /status already treats skipped as non-blocking and reported overall=success — but a false red costs a diagnosis cycle every time. Two corrections recorded: - The image job is skipped on EVERY PR (job-level `if: github.event_name != 'pull_request'`; images build only on push-to-main and tags), NOT because of the docs-only mechanism. Misattributing it to docs-only is a plausible-sounding wrong diagnosis, since docs-only gates STEPS precisely so required jobs still report success. decisions.md already stated the fact from the branch-protection angle; the monitor-authoring consequence was missing. - skipped / failure / cancelled are three distinct meanings and must not be collapsed. Prefer gating on the combined `.state`. The documented filter is verified in BOTH directions: silent on a green PR carrying a skipped build, and still dirty on a genuinely pending run. My first draft of it was itself broken — `select(.status != …)` after the pipeline had renamed `.status` to `.st`, so it compared against null and reported a green PR as nine failures. That failure is recorded in the note, per the "verify your detector" rule. fixes #592 |
||
|
|
7e5d20be98 |
fix(583): gate every model-less dispatch, not just implementer-looking ones
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 14s
PR Gates / Docs update reminder (pull_request) Successful in 16s
PR Gates / decisions lifecycle (pull_request) Successful in 17s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 7m37s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 55s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 17s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 6m23s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 16m22s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Independent review of
|
||
|
|
d221a06522 |
chore(583): make per-agent model routing a hard constraint + PreToolUse gate
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 9s
PR Gates / Docs update reminder (pull_request) Successful in 12s
PR Gates / decisions lifecycle (pull_request) Successful in 14s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m42s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 8s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 6s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 21m53s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 15m2s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
The kickoff tells the orchestrator to route agents by capability, but that rule lived only in a prose paragraph. On 2026-07-25 a session dispatched two implementers (#436, #440) with `model` omitted, silently inheriting the orchestrator tier — while following every bullet in HARD CONSTRAINTS in the same session. The bulleted list is what functions as the checklist; prose above it reads as background. - HARD CONSTRAINTS: keyed routing bullet requiring the tier to be stated in the dispatch itself, so an invisible omission becomes visible output. Prose paragraph tightened to point at the key rather than restate the table (the kickoff is pasted into every session — duplication is a per-session tax, #542). - .claude/hooks/pretooluse-agent-model.sh: PreToolUse on Agent, `ask` when a committing agent is dispatched with no explicit `model`. Narrow by design — passes through read-only/recon types, `fork` (model override ignored by the tool), and any dispatch already naming a tier, because a gate that fires on every fan-out trains one-shot dismissal. `ask` not `deny`: routing is a judgment call with no derivable right answer, unlike the H6/H10 merge gate. - New decision record `process.per-agent-model-routing`; catalog regenerated. Decision matrix verified against 9 payloads incl. a replay of the dispatch that missed. decisions-validate: OK. fixes #583 |
||
|
|
12e5c3d26f |
docs(542): record the workflow lore, then prune the kickoff doc to instructions
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 10s
PR Gates / Docs update reminder (pull_request) Successful in 13s
PR Gates / decisions lifecycle (pull_request) Successful in 22s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 16s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 13s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m44s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 15m11s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 20m14s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Timothy asked why the kickoff handoff doc stores historical narrative when it should be instructions. It shouldn't — its own lore section is chartered as "STANDING workflow/orchestration rules only" with the why belonging in docs/decisions.md. But an inventory of every bullet against the decision corpus inverted the premise: only ~8 of ~38 were actually covered. 19 had no record anywhere and 11 more were half-covered, so that single file was the ONLY copy of the mandatory review rubric, the whole CI-triage vocabulary, the build-concurrency policy, the H12 session-end audit, and the plumbing-merge recipe. Pruning first would have destroyed them. So the records come first. New topic file docs/decisions/workflow-process.md carries 32 records (ci.*, process.*, testing.*) covering every NONE and PARTIAL the inventory found, including the Gitea `?milestones=` no-op bug whose only copy was the archived selector section this prune deletes. Only then the prune: HARD CONSTRAINTS and the lore section become one- or two-line rules, each citing the decision key that holds its evidence, and the 40-line "Archived — do not follow" section is gone. 636 -> 353 lines, with every cited key verified to resolve against the corpus. The aggregate corpus budget is re-baselined 4800 -> 5600 with the reason in the code: the corpus grew because knowledge MOVED into it, which is the system working, not drift. refs #542 |