fix(ci): docs-redirects-only commits fire a CI run so the release gate gets a verdict

The push/pull_request paths filters covered docs/panel/motion but not
docs-redirects/**, so a redirect-stub commit landing as the slave tip
produced no CI run and the fail-closed release-readiness gate read
"unknown" — blocking every release proposal until unrelated code landed.
This commit is contained in:
Renn F
2026-07-25 00:13:16 +02:00
parent 803638e8e9
commit 9b407d764d
2 changed files with 7 additions and 0 deletions
+5
View File
@@ -46,6 +46,10 @@ on:
# can still turn the gate red — without this it fires no run and a PR
# merges on a false green.
- 'motion/**'
# The Pages redirect stubs land on slave alone; a docs-redirects-only
# tip fired no run, and the fail-closed release gate read the missing
# conclusion as "unknown" — silently blocking every release proposal.
- 'docs-redirects/**'
pull_request:
branches:
- master
@@ -70,6 +74,7 @@ on:
- 'CHANGELOG.md'
- 'docs/**'
- 'motion/**'
- 'docs-redirects/**'
workflow_dispatch:
# A fleet branch that's also an open PR head can get both a `push` and a
+2
View File
@@ -30,10 +30,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
### Changed
- **The `opus` alias upgrades from Claude Opus 4.6 to Claude Opus 4.8.** `MODEL_MAP["opus"]` now resolves to `claude-opus-4-8` — the newest Opus tier, at the same price as 4.6 — so every Opus-routed role (PR reviewer, Auditor, Board, CEO, Intake, Secretary) rides it at next spawn. Pricing already covered the id via the `claude-opus-4` fragment; a new `test_opus_is_priced` guard keeps the alias from ever pointing at an unpriced model.
- **Panel dialogs converge on one shape: one disclosure primitive, DialogFooter everywhere, three dialog widths.** `collapsible-section` becomes the single sectioned-disclosure primitive — task dialogs' raw `Collapsible` and create-project's ad-hoc `showAdvanced` both move onto it; every hand-rolled dialog footer becomes `DialogFooter`; dialog widths collapse from ten ad-hoc classes to three named sizes, with deliberate outliers annotated. No behavioral change.
### Fixed
- **docs-redirects-only commits fire a CI run so the release gate gets a verdict.** The CI paths filter covered docs/panel/motion-only slave commits but not `docs-redirects/**`, so a redirect-stub commit landing as the slave tip produced no CI run at all — and the fail-closed release-readiness gate read the missing conclusion as "unknown", silently holding back every release proposal until an unrelated code commit happened to land.
- **Mix-mode routing gained its escape hatch (#663).** A fully-pinned fleet had no way back to a global mode: mode switches deliberately spare per-agent pins, but the server refused an empty mix map and the panel refused an empty save — so with every agent pinned, the mode buttons were permanent no-ops behind a success toast and the mode label read "mix" forever. An empty per-agent map is now the explicit clear-all, Save mix with nothing picked confirms and clears instead of erroring, a Clear-all button resets every agent to inherit-global in one click, and the Routing-mode section warns when per-agent overrides outrank the mode buttons.
- **The lazy DB engine rebinds per event loop (#663).** The global engine cache was loop-agnostic while its pooled connections are loop-bound, so a second event loop touching it (a test's `asyncio.run`, a second server thread, the eval bench's disposable stack) eventually drew a foreign-loop connection and died with "Future attached to a different loop" — the eval-bench smoke's flaky CI timeout. The engine/factory accessors now stamp the owning loop and discard-and-rebuild on cross-loop access; production runs one loop, so nothing changes there.
- **Expired-unacked notifications re-escalate with backoff instead of forever (#652).** The re-escalation sweep fired on every ~60s tick for every expired unacked row — 3 escalations/minute to the CEO in the live incident. Each row now carries a backoff schedule (first fire at expiry, doubling from a 1h base capped at 24h, permanently parked past 5 attempts), and the attempt slot is claimed by compare-and-set before any delivery, so racing sweep ticks can never double-send.