The defect
deliver() in packs/basics/tasks/baselining/worker.mjs destructured only json from the PR-open POST and never read status:
({ json: pr } = await gh(token, `/repos/${repo}/pulls`, { method: 'POST', ... }));
When that POST fails, the error body lands in pr. pr.node_id is undefined so the auto-merge arm is skipped silently, the CI dispatch has no PR to attach to, and the run still logs preprocessing basics/baselining: ok.
Why it compounds
openMaintenancePull reuses by open PR, not by branch. A cycle that pushes its branch but fails to open the PR therefore finds nothing to reuse next cycle and mints a fresh branch — nightly — while the stamp never advances and nothing surfaces the failure.
Observed fleet state (2026-07-29/30)
Eleven of twelve consumers were frozen on canon ref 7e89c0cf (2026-07-28), each carrying claudinite/maintenance-2026-07-29-* and -07-30-* branches with no PR behind either — several carried two branches for a single day. 27 orphan maintenance branches in total. GoogleCalendarEventCreator, the pilot and the one repo with the Actions PR permission enabled, opened and merged its maintenance PRs normally throughout.
The usual cause is repo-level and invisible from inside the Action: Settings → Actions → General → "Allow GitHub Actions to create and approve pull requests" is off, so the POST 403s.
Fix
PR #584 — pullCreateError(status, json) as a pure predicate, null only on a 201 carrying a PR number; deliver() throws on it and the message names the repo setting. See-it-fail coverage for the 403, a 201 with no PR number, and the no-message fallback.
This stops the silence. It does not enable the setting — that stays an owner action on each consumer, and until it is done #584 converts a silent stall into a loud nightly failure.
Related gaps this surfaced
The defect
deliver()inpacks/basics/tasks/baselining/worker.mjsdestructured onlyjsonfrom the PR-open POST and never readstatus:When that POST fails, the error body lands in
pr.pr.node_idis undefined so the auto-merge arm is skipped silently, the CI dispatch has no PR to attach to, and the run still logspreprocessing basics/baselining: ok.Why it compounds
openMaintenancePullreuses by open PR, not by branch. A cycle that pushes its branch but fails to open the PR therefore finds nothing to reuse next cycle and mints a fresh branch — nightly — while the stamp never advances and nothing surfaces the failure.Observed fleet state (2026-07-29/30)
Eleven of twelve consumers were frozen on canon ref
7e89c0cf(2026-07-28), each carryingclaudinite/maintenance-2026-07-29-*and-07-30-*branches with no PR behind either — several carried two branches for a single day. 27 orphan maintenance branches in total. GoogleCalendarEventCreator, the pilot and the one repo with the Actions PR permission enabled, opened and merged its maintenance PRs normally throughout.The usual cause is repo-level and invisible from inside the Action: Settings → Actions → General → "Allow GitHub Actions to create and approve pull requests" is off, so the POST 403s.
Fix
PR #584 —
pullCreateError(status, json)as a pure predicate,nullonly on a 201 carrying a PR number;deliver()throws on it and the message names the repo setting. See-it-fail coverage for the 403, a 201 with no PR number, and the no-message fallback.This stops the silence. It does not enable the setting — that stays an owner action on each consumer, and until it is done #584 converts a silent stall into a loud nightly failure.
Related gaps this surfaced
ruleRoutingGuidanceblocks every consumer whose local pack still declares barerules— and sincenormalizeManifestrebuildsrulesfrom the scoped lists, such a pack's checks silently stop running. Eleven local packs across ten repos were migrated by hand this session.pull_requestCI at all, and TLDR's is path-filtered away from.claudinite/**, so their maintenance PRs are never gated by the world sweep.