phase-pr exits 0 on a green gate, then pushes a commit the gate never validated #536

Closed
opened 2026-09-05 19:07:13 +00:00 by mph · 1 comment
Owner

Observed on MEDECA-374 phase 1, GitLab (gitlab.e-bs.cz), MR !448.

WHAT HAPPENED
'./iw phase-pr' waited ~20 minutes, reported CI green, and exited 0. The GitLab API then showed two different pipelines on that MR:
pipeline.id=5316, sha a1fb61c65, status: success <- the run the gate actually read
head_pipeline.id=5318, sha c0cd0afb2, status: pending, started_at: None
The second was still unstarted two hours later.

c0cd0afb2 is phase-pr's OWN bookkeeping commit ('chore: update review-state for phase 01'), pushed AFTER the gate passed, touching only review-state.json. So at the exact moment the workflow declared the phase ready for review, the MR head carried an unvalidated pipeline.

WHY IT SURVIVES UNNOTICED
The pushed commit touches only review-state.json, which is the common case and is harmless. The gap is invisible until someone repeats the gate's 'CI is green' as a claim about the branch rather than about one sha.

SUGGESTED FIX (either one)

  • Commit and push the review-state update BEFORE the CI wait, so the gated sha IS the head sha; or
  • Re-check head_pipeline for the MR's current sha after pushing it, and only then exit 0.

WORKAROUND USED
Verified head_pipeline against the MR sha via the GitLab API before reporting the phase's CI state.


Type: bug
Filed from: /home/mph/Devel/projects/medeca-modul-poptavky-MEDECA-374 on branch MEDECA-374

Observed on MEDECA-374 phase 1, GitLab (gitlab.e-bs.cz), MR !448. WHAT HAPPENED './iw phase-pr' waited ~20 minutes, reported CI green, and exited 0. The GitLab API then showed two different pipelines on that MR: pipeline.id=5316, sha a1fb61c65, status: success <- the run the gate actually read head_pipeline.id=5318, sha c0cd0afb2, status: pending, started_at: None The second was still unstarted two hours later. c0cd0afb2 is phase-pr's OWN bookkeeping commit ('chore: update review-state for phase 01'), pushed AFTER the gate passed, touching only review-state.json. So at the exact moment the workflow declared the phase ready for review, the MR head carried an unvalidated pipeline. WHY IT SURVIVES UNNOTICED The pushed commit touches only review-state.json, which is the common case and is harmless. The gap is invisible until someone repeats the gate's 'CI is green' as a claim about the branch rather than about one sha. SUGGESTED FIX (either one) - Commit and push the review-state update BEFORE the CI wait, so the gated sha IS the head sha; or - Re-check head_pipeline for the MR's current sha after pushing it, and only then exit 0. WORKAROUND USED Verified head_pipeline against the MR sha via the GitLab API before reporting the phase's CI state. --- **Type:** bug **Filed from:** `/home/mph/Devel/projects/medeca-modul-poptavky-MEDECA-374` on branch `MEDECA-374`
Member

Intake: duplicate of #491 — closing this one.

#491 ("phase-pr pushes a commit after reading CI, so its green can describe a stale head", filed 2026-09-01) names the same code path, still present on main: finish dispatches CiVerdict.Green(_, sha) to handOver, which calls updateReviewStateForReview and then persist; persist commits the review-state file and pushes the phase branch, moving the head past the gated sha. See core/commands/PhasePr.scala:403-462 and :526-541.

The two reports differ only in the forge and in the symptom that followed the late push — #491 saw it start a run that went red, this one saw it leave the head pipeline unstarted. The cause is identical and both propose the same two options (push the card before the wait, or re-read CI for the new head after the push). Fixing #491 closes this.

Checked and ruled out: IW-517 (6c2baaad) changed only core/adapters/GitLabClient.scala, making the GitLab gate read every pipeline at a commit instead of head_pipeline. It does not touch the gate/commit/push order, so it does not fix this.

#485 (gate concludes before a pipeline exists) and #513 (forge down vs forge refused) are separate defects in the same command and stay open.

Intake: duplicate of #491 — closing this one. #491 ("phase-pr pushes a commit after reading CI, so its green can describe a stale head", filed 2026-09-01) names the same code path, still present on `main`: `finish` dispatches `CiVerdict.Green(_, sha)` to `handOver`, which calls `updateReviewStateForReview` and then `persist`; `persist` commits the review-state file and pushes the phase branch, moving the head past the gated sha. See `core/commands/PhasePr.scala:403-462` and `:526-541`. The two reports differ only in the forge and in the symptom that followed the late push — #491 saw it start a run that went red, this one saw it leave the head pipeline unstarted. The cause is identical and both propose the same two options (push the card before the wait, or re-read CI for the new head after the push). Fixing #491 closes this. Checked and ruled out: IW-517 (`6c2baaad`) changed only `core/adapters/GitLabClient.scala`, making the GitLab gate read every pipeline at a commit instead of `head_pipeline`. It does not touch the gate/commit/push order, so it does not fix this. #485 (gate concludes before a pipeline exists) and #513 (forge down vs forge refused) are separate defects in the same command and stay open.
claude 2026-09-15 01:44:15 +00:00
  • closed this issue
  • added the
    duplicate
    label
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
iterative-works/iw-cli#536
No description provided.