fix(actions): Lopu controller repair β control-plane CI's concurrency group is global, so unrelated PRs cancel each other into red checks - #626
Conversation
β Develop S3 preview failed
The ordinary generated Vercel Preview remains available on the shared development runtime. Re-run this workflow after correcting the deployment, DNS, or CORS configuration. Generic Vercel Preview deployments use the shared development runtime; this controller adds the stable exact-SHA alias and marker-scoped cleanup. |
π€ Lopu review β approve, no changes madeI compared The diagnosis holds up
Zero failed steps under a The fix does what it claimsSimulating the new expression over this workflow's real trigger set: Three things worth adding to the record1. The fix is complete, not partial. I scanned every workflow for the same bug shape β a constant group combined with 2. This was costing real coverage, not just a cosmetic red check β the PR undersells itself. The 3. Relaxing serialization introduces no race. ValidationBlocking The check that actually earns the new assertion its place: I reverted the group back to the constant and re-ran the contract β the regression is caught, failing with the intended message. So the guard blocks a silent return to global scope rather than merely matching today's text. Original file restored; Two notes, deliberately not changed
CodeQL: no open alerts on this head; dispositions left |
Lopu repository reviewLopu reviewed this PR against github-actions as Thingtime's principal PR and repository manager. Using Claude Opus 5. Lopu found no justified local change to publish from this review pass. Lopu review β PR #626 Β· control-plane CI concurrency group
What I compared
FindingsThe diagnosis holds, and it is the right size. I independently audited the
The group expression is well-defined for every trigger. This workflow fires Superseding is preserved where it is wanted. Nothing else in the diff: no permission change, no secret exposure, no new job. Interaction with the sibling controller PRs#624, #625 and #626 all branch from the same base and touch disjoint files Changes madeNone. The change is correct, minimal, and pinned by a contract assertion. No Validation runI also hand-checked the new assertion's regex against the literal YAML text RecommendationApprove and merge. Prefer merging this one first among the three open controller |
|
Lopu β reviewer update on the β preview comment above. I reviewed Why this PR shows β while every check is green
Root cause, straight from the worker log (job
It is already fixed in #625 β but #625 cannot clear it on its own#625 probes the head for One detail that matters for merge ordering: the I deliberately did not duplicate that fix here; it would collide with #625 on the same file for no gain. On this PR's own changeThe diagnosis holds up against the API rather than on trust: attempt 1 of run The fix is right, and it matches the repo's own convention rather than inventing one: Keeping The new contract assertion is load-bearing, not decorative: reverting the group to the old constant in a scratch copy makes Validation25 Recommendation: merge #625 first, then this. Separately, the fact that a failed preview is invisible to |
β Lopu β reviewed and validated; no changes neededCompared the full head ( A constant Keying on Pinning the exact group expression in Checks: 27 pass / 0 fail. Ready to merge β and worth landing promptly, Lopu Β· automated repository review |
π€ Lopu detected an out-of-date PR branchStatus: Work detected β Lopu is taking ownership. Current phase: Entering Lopu's serialized PR-resolution queue. Estimated completion: around 06:28 UTC (~20 minutes; this adjusts as the queue moves). Next automatic check-in: within 10 minutes while work remains active. You can stay on this PR; there is no need to find the Actions run. Time conversion (UTC source)
Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically. Lopu queue and PR pulse
Related PR context
Exact branch pair: Timeline
|
π΅οΈ Lopu β I audited every workflow's concurrency block; this is the only one that could do itThe diagnosis holds. Rather than just confirm it, I checked whether it was complete β because "constant group + All 15 workflows on
I also checked the new expression is total across this workflow's trigger surface. It fires on And the contract assertion isn't vacuous: I matched its regex against the literal YAML by hand, so it genuinely pins the expression rather than passing on a technicality. Merge order across the three controller repairs#624, #625 and #626 touch disjoint files β #624 I'd merge this one first anyway. It's the one that stops the cancellation noise, and that noise is precisely what made #624's and #625's own check surfaces hard to read while they were being diagnosed. Landing it first makes the other two easier to judge. All three verified green: #625 No changes made to this branch β nothing here justified an edit. |
Lopu controller check repair
Lopu identified a failed PR check whose root cause is in the protected controller/workflow code.
Lopu controller repair β control-plane CI's concurrency group is global, so unrelated PRs cancel each other into red checks
Woken as
lopu-review:issue-comment:5545037869:33907680878β the<!-- thingtime-develop-pr-preview -->status comment on PR #624 reportingβ Develop S3 preview failed for
a5465255.Reviewing PR #624 surfaced two independent control-plane defects. One is
already fixed by PR #625 and is not duplicated here (see "Not changed" below).
This repair covers the other.
Files changed (in
$GITHUB_WORKSPACE/trustedonly):.github/workflows/control-plane-ci.ymlβ theconcurrency.groupexpression..github/scripts/workflow-control-plane-contract.mjsβ a contract assertionpinning that group.
PR #624's worktree is unchanged and carries no controller edit. This repair does
not touch
deploy-develop-pr-preview.mjs, so it cannot conflict with PR #625.Diagnosis
gh pr checks 624reportsContract advisories (non-blocking) β¦ fail. It didnot fail. Both jobs in run 33909377070 finished every step successfully:
verifyβ 15/15 stepssuccessContract advisories (non-blocking)β 5/5 stepssuccess, with both joboutputs (
warnings,report_b64) setThe run conclusion is nevertheless
cancelled, andgh pr checksrenderscancelledasfail. So the red check on #624 reports a cancellation, not acontract regression β and not a defect in that PR.
Cause:
One global slot for every control-plane run in the repository. Run 33909377070
(PR #624) was created at 19:06:02; run 33909382726 for a different PR
(
lopu/workflow-check-fix-33907643740, #625) was created at 19:06:06 and tookthe slot. #624's run was cancelled at 19:06:34 β after its work had already
finished, which is why every step is green under a cancelled run.
Recurring, not a one-off. Each of these PR runs was cancelled by the run that
landed seconds later on an unrelated subject:
github-actions)github-actions)github-actions)The shape is systematic: a PR run and the push run that merges it (or a sibling
PR's run) contend for the same single slot, and the PR always loses.
A cancelled superseded run is not itself a code defect, so the immediate repair
was to re-run it: attempt 2 of 33909377070 completed green on all three jobs and
gh pr checks 624now reports no non-passing check. That confirms thecancellation was the only reason for the red, and nothing in #624 was broken.
The change below is the durable repair.
Nothing relies on serializing all control-plane CI. The
verifyandcontract-advisoriesjobs are read-only β they check outgithub-actionswithpersist-credentials: false, request onlycontents: read, and the workflowcarries no
secrets:block (pinned by an existing contract assertion). There isno shared mutable resource to protect. By contrast
develop-pr-preview.yml,which genuinely does need care here, scopes its group per PR and carries a
comment explaining exactly why. This group had no such comment β a global scope
looks like an oversight rather than a decision.
Fix
cancel-in-progressis deliberately kept: superseding an earlier push on thesame PR or branch is the intended behavior, and that is all this group was
ever meant to do. The subject is now distinct per PR (
pull_request.number),per pushed branch and per dispatched ref (
github.ref, e.g.refs/heads/github-actions), so cross-subject cancellation stops whilesame-subject superseding is unchanged.
Pinned by a new assertion in
workflow-control-plane-contract.mjs, in the samestyle as the existing control-plane-ci assertions, so the global scope cannot
silently return.
Not changed β the develop-preview failure is PR #625's, and its fix is better
The β comment that woke this session has a real, reproducible root cause: the
preview
buildjob checks the PR head intoproduct/and unconditionally runscorepack pnpm --dir product/remix install --frozen-lockfile, butgithub-actionscarries noremix/workspace, so it dies withENOENT β¦ /product/remixand the controller publishes the failure comment.Deterministic for this PR shape β every control-plane preview worker today
failed identically (33909394105, 33909387490, 33907615031, and 33888936460 /
33887678048 / 33886516079 / 33885726085 / 33885038530 / 33883924348 /
33882576994 for
codex/preview-manager-reliability), interleaved with successesfor product PRs. Spot-checked jobs 101075627620 and 101054590543: same step,
same error.
I diagnosed this independently and had written a fix, then found PR #625
(opened 19:06:01 by the previous Lopu session, run 33907643740) already repairs
it. Its approach is better than mine, so I reverted mine rather than open a
competing change:
remix/package.jsoninstead of filtering onbase.ref == 'github-actions'as I had β general to any product-less head,and it does not hardcode a branch name.
fault or token-scope problem cannot be silently misread as "nothing to
preview". My base-name gate never needed that distinction; the probe does, and
fix(actions): Lopu controller repair β control-plane PRs are authorized into a product build they cannot possibly runΒ #625 gets it right and pins it in its self-test.
prepareBuildPlanandmain(), with a commentexplaining that the reconcile/report step re-enters
main()and must classifybefore
deploy()is reached.Independently verified: fetched
.github/scripts/deploy-develop-pr-preview.mjsfromlopu/workflow-check-fix-33907643740,node --checkpasses, and--self-testreports 138/138 passed.Because that repair lives entirely in
deploy-develop-pr-preview.mjsand thisone lives in
control-plane-ci.ymlplus the control-plane contract, the twoLopu fix PRs touch disjoint files and can land in either order.
Validation
All commands run in
$GITHUB_WORKSPACE/trusted.Blocking lane (
verify), reproduced in fullnode --checkover every.github/scripts/**/*.mjsbash -nover every.github/scripts/**/*.shgit diff --check(patch hygiene)node --test graphify-cas.test.mjsstage-graphify-snapshots.mjs --self-testnode --test rebase-index-fingerprint.test.mjsnode --test rebase-related-edits.test.mjsnode --test resolve-canonical-instruction-type-conflicts.test.mjsnode --test lopu-pr-status.test.mjsnode --test resolve-pr-conflicts-routing-contract.test.mjsmerge-main-develop-sync-pr.mjs --self-testclassify-claude-credential-failure.mjs --self-testelectron-pr-release-contract.mjsAdvisory lane, all 12 contracts
deploy-develop-pr-preview.mjs120/120 (unmodified baseline),deploy-admin-pr-previews.mjs,extract-vercel-prebuilt.py,workflow-control-plane-contract.mjs,electron-pr-release-contract.mjs,Source Lopu workflow run