I3902 — A hung Pages build is replaced by a declared bound, and the right tree is rebuilt, never redeployed
GitHub's own Pages build that stays `building` or `queued` longer than deploy.build_hung_after (.ai/repo/ci/pages.yaml) is hung: `scripts/pages rebuild` replaces it and says why, a younger one is waited on with its own exit (13), and the scheduled publisher hands a build in flight of the right tree to the rebuild instead of redeploying an identical tree.
BLOCKED wave 0 · p0 · implementation profile · parallel safe
Blocked. This issue cannot start until milestone:the-runtime-supervises-itself is done. The status is derived from that, not declared.
Objective
GitHub's own Pages build that stays `building` or `queued` longer than deploy.build_hung_after (.ai/repo/ci/pages.yaml) is hung: `scripts/pages rebuild` replaces it and says why, a younger one is waited on with its own exit (13), and the scheduled publisher hands a build in flight of the right tree to the rebuild instead of redeploying an identical tree.
Why
On 2026-10-22 the deploy of 355a0cee79a pushed gh-pages at 20:28Z. GitHub's build of it was still `building` 47 minutes later while majordomus.dev served 2034d4a3f0b, and the deploy run ended success with a warning. `scripts/pages rebuild` refused every request while any build was in flight, so a hung build could never be replaced. The scheduled `owed` job chose `deploy` for it: forty minutes of rustdoc, UI and Cockpit snapshots to push the same tree, every thirty minutes. The owner, in Czech, asked for it to be solved rock-solid and the Majordomus way, because it is a critical feature: stuck builds must be watched, timed out and killed automatically, because they burn compute minutes and delivery time, and this must be in Majordomus's DNA.
Current state
A hung GitHub Pages build blocks publication until it ends on its own; nothing replaces it.
Desired state
A build in flight past its declared bound is replaced within one schedule; a right tree is never redeployed to get past its own build; every refusal says which of not-yet, unreadable or refused it is.
Scope
- .ai/repo/ci/pages.yaml
- scripts/pages
- .github/workflows/pages.yml
- test/cases/625_a_rebuild_is_asked_only_when_it_helps.sh
- .ai/repo/project/issues/I3902.yaml
- .ai/repo/project/issues/I3903.yaml
Out of scope
- Stuck or stale GitHub Actions runs: I3903.
- Serving the site from a Pages artifact instead of the gh-pages branch, which would remove GitHub's second build: an ADR first, because gh-pages is also the evidence store (ADR 0087).
Dependencies
None. This issue is a root of the graph.
What waits on this
Acceptance criteria
- A build of this commit in flight past deploy.build_hung_after is replaced, and the output says it was hung
- A hung build of another commit is replaced as well; a young build of either is waited on with exit 13 and no request
- A build whose start time cannot be read is never taken for an old one
- The scheduled remedy hands an errored or in-flight build of the trunk's own tree to the rebuild, and deploys only a stale tree
Validation
- bash test/run.sh 625_a_rebuild_is_asked_only_when_it_helps
Evidence required
- case_625
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Timeline
- started
- —
- verified
- —
- completed
- —
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I3902.yaml. Read it back with majordomus plan show I3902.