Summary
In carry-forward mode, ci-status ends its wait as soon as the newest ci-lanes status is success, failure or error. It does not check whether the full run that wrote that status is being re-run. After a full run fails and someone re-runs it, a contract-only event on the same SHA (a body edit, a label flip) reads the old failure at once and goes red. It never waits for the re-run, which is the run the wait exists for.
The failure message also sends people the wrong way. It always says re-run the full workflow. Once ci-lanes on the SHA is success, re-running the red contract-only run is enough, but the message never says so. A new commit (every lane again) is the natural reaction.
Evidence
Reproduced in melodic-software/claude-code-plugins#4670 with a throwaway pull request (claude-code-plugins#5581, closed). Consumer pin 4610c31e (v0.27.1). run.sh on main differs from the pin only in comments. Head SHA ad99ed0ce859b0fa1071d48f30c410528ee331f8, all times 2026-09-30 UTC.
| Time |
Event |
| 05:56:46 |
Full run 36673988526, attempt 1, fails. ci-lanes=failure recorded (status 55241522644, target_url .../actions/runs/36673988526). |
| 05:57:10 |
Attempt 2 of 36673988526 starts (run_started_at). |
| 05:57:16 |
A body edit creates contract-only run 36675804726. |
| 06:00:01 |
Its ci-status logs ::error::no successful ci-lanes status on ad99ed0c...; re-run the full workflow with no Waiting line, while attempt 2 is still in flight. |
| 06:12:49 |
Attempt 2 passes and records ci-lanes=success (status 55242254969). |
Re-running 36675804726 after that logged Carried forward: ci-lanes is success and replaced the stale check run in the same check suite. So re-running the contract-only run is the right remedy once ci-lanes is success.
Proposed fix
- A settled
failure or error ends the wait only when no full-run re-run whose current attempt started after that status's created_at is in flight. A success still ends it at once.
- When the verdict is not
success, the message keeps re-run the full workflow and also says to re-run this run once ci-lanes on the SHA is success.
Constraints:
- Do not bring back mutual waiting between contract-only siblings. Reading the settled status each poll is what releases them today.
- Keep every path fail-closed. A timeout, a missing status or a skipped lane never passes.
Related
Summary
In carry-forward mode,
ci-statusends its wait as soon as the newestci-lanesstatus issuccess,failureorerror. It does not check whether the full run that wrote that status is being re-run. After a full run fails and someone re-runs it, a contract-only event on the same SHA (a body edit, a label flip) reads the oldfailureat once and goes red. It never waits for the re-run, which is the run the wait exists for.The failure message also sends people the wrong way. It always says
re-run the full workflow. Onceci-laneson the SHA issuccess, re-running the red contract-only run is enough, but the message never says so. A new commit (every lane again) is the natural reaction.Evidence
Reproduced in melodic-software/claude-code-plugins#4670 with a throwaway pull request (claude-code-plugins#5581, closed). Consumer pin
4610c31e(v0.27.1).run.shon main differs from the pin only in comments. Head SHAad99ed0ce859b0fa1071d48f30c410528ee331f8, all times 2026-09-30 UTC.ci-lanes=failurerecorded (status 55241522644,target_url.../actions/runs/36673988526).run_started_at).ci-statuslogs::error::no successful ci-lanes status on ad99ed0c...; re-run the full workflowwith noWaitingline, while attempt 2 is still in flight.ci-lanes=success(status 55242254969).Re-running 36675804726 after that logged
Carried forward: ci-lanes is successand replaced the stale check run in the same check suite. So re-running the contract-only run is the right remedy onceci-lanesissuccess.Proposed fix
failureorerrorends the wait only when no full-run re-run whose current attempt started after that status'screated_atis in flight. Asuccessstill ends it at once.success, the message keepsre-run the full workflowand also says to re-run this run onceci-laneson the SHA issuccess.Constraints:
Related