IW-491: phase-pr pushes a commit after reading CI, so its green can describe a stale head #596

Merged
mph merged 23 commits from IW-491 into main 2026-09-21 16:32:13 +00:00
Member

Summary

The CI gate in phase-pr, phase-merge and ci-gate now judges the commit that is the pull request head.

Defects fixed

Phase 1 — the wait budgets were measured from a head that was gone (false red). The card has a new root field ci_wait_sha, the head that a wait measures. CiGate.poll seeds the wait from it. When the pull request head is not the recorded head, both budgets (run appearance and --timeout) start again. ci_wait_started and ci_wait_sha are written and cleared together. Before this fix, a resumed phase-pr, a phase-merge recovery retry or a ci-gate after a manual push could read "CI did not run" and stop a batch with no retry. (PR #590)

Phase 2 — the Green path committed and pushed the card after the verdict (false green). After a green verdict, phase-pr writes the card to disk. It does not commit or push it. ci_gated_sha is now the pull request head when the command exits. (PR #591)

Testing

  • Harness tests in CiGateHarnessTest, PhasePrHarnessTest, PhaseMergeHarnessTest and CiGateCommandHarnessTest reproduce each defect: a recovery push late in a wait, a resumed wait 61 minutes after the stamp (the IW-583 gap), and no commit or push after green.
  • Unit tests in CiGateTest, ReviewStateUpdaterTest, ReviewStateValidatorTest and ReviewStateSchemaTest cover the new card field.
  • Each phase PR passed CI. The pre-push hook ran the unit suite on this branch.

Follow-ups filed

iw-cli #592, #593, #594, #595; dev-docs #317 (the review-state-schema skill entry for ci_wait_sha). Comments added to #585 and #586.

Release notes

See project-management/issues/IW-491/release-notes.md (Czech).

🤖 Generated with Claude Code

Closes #491

## Summary The CI gate in `phase-pr`, `phase-merge` and `ci-gate` now judges the commit that is the pull request head. ## Defects fixed **Phase 1 — the wait budgets were measured from a head that was gone (false red).** The card has a new root field `ci_wait_sha`, the head that a wait measures. `CiGate.poll` seeds the wait from it. When the pull request head is not the recorded head, both budgets (run appearance and `--timeout`) start again. `ci_wait_started` and `ci_wait_sha` are written and cleared together. Before this fix, a resumed `phase-pr`, a `phase-merge` recovery retry or a `ci-gate` after a manual push could read "CI did not run" and stop a batch with no retry. (PR #590) **Phase 2 — the Green path committed and pushed the card after the verdict (false green).** After a green verdict, `phase-pr` writes the card to disk. It does not commit or push it. `ci_gated_sha` is now the pull request head when the command exits. (PR #591) ## Testing - Harness tests in `CiGateHarnessTest`, `PhasePrHarnessTest`, `PhaseMergeHarnessTest` and `CiGateCommandHarnessTest` reproduce each defect: a recovery push late in a wait, a resumed wait 61 minutes after the stamp (the IW-583 gap), and no commit or push after green. - Unit tests in `CiGateTest`, `ReviewStateUpdaterTest`, `ReviewStateValidatorTest` and `ReviewStateSchemaTest` cover the new card field. - Each phase PR passed CI. The pre-push hook ran the unit suite on this branch. ## Follow-ups filed iw-cli #592, #593, #594, #595; dev-docs #317 (the `review-state-schema` skill entry for `ci_wait_sha`). Comments added to #585 and #586. ## Release notes See `project-management/issues/IW-491/release-notes.md` (Czech). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Closes #491
phase-pr pushes a commit after reading CI, so its green can describe a stale head

Artifacts:
- analysis.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The first analysis (56475c05) covered defect 1 only. Defect 2 — the
appearance budget measured from a ci_wait_started stamp an earlier head
left behind — lived in an issue comment, and triage reads the issue body.

The body now carries defect 2 and Michal's F1 decision on the CLARIFY, and
the issue points the next analysis at 56475c05 so it reuses the work that
ruled out the format flake.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179JhvXg4eopsQNmDLUSuim
phase-pr pushes a commit after reading CI, so its green can describe a stale head

Covers both defects: the Green path pushes the card after the verdict
(fix decided as F1), and the appearance budget and timeout are measured
from a ci_wait_started stamp that an earlier head left behind.

Artifacts:
- analysis.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A wait belongs to one head. When the head differs from the one the card
records, the appearance budget and the total --timeout both restart and the
stamp is rewritten, inside one invocation as well as across invocations.

An appearance-only fix would leave the observed failure under a different
word: on IW-583 the stamp was 61 minutes old against a 30-minute timeout, so
the gate would answer "CI timed out" in place of "CI did not run", write
ci_failed either way, and halt the batch either way.

Cost: --timeout means per head, not per wait. e935bd21, the ci_wait_started
schema description and the CiGateTarget doc state the old meaning and change
with the fix. phase-merge's total wall clock becomes bounded by
(--max-retries + 1) x --timeout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179JhvXg4eopsQNmDLUSuim
phase-pr pushes a commit after reading CI, so its green can describe a stale head

Artifacts:
- tasks.md
- review-state.json (tasks_ready)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Issue: IW-491
Phase: 1 - The appearance budget and the timeout are measured from a head that is gone

This commit marks the checkpoint for phase 1 context generation.
Use dx-fix IW-491 to return to this point.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The appearance budget and the timeout are measured from a head that is gone

Artifacts:
- phase-01-tasks.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Issue: IW-491
Phase: 2 - The Green path commits and pushes the card after the verdict

This commit marks the checkpoint for phase 2 context generation.
Use dx-fix IW-491 to return to this point.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Green path commits and pushes the card after the verdict

Artifacts:
- phase-02-tasks.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Filed as iw-cli #592-#595 and dev-docs #317; commented on #585 and #586.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
docs(IW-491): add release notes
Some checks failed
CI / changes (pull_request) Successful in 4s
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 9s
CI / lint (pull_request) Successful in 15s
CI / test (pull_request) Has been cancelled
CI / dashboard-build (pull_request) Has been cancelled
CI / compile (pull_request) Has been cancelled
d0b06a05a3
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
chore(IW-491): update review-state to all_complete
All checks were successful
CI / changes (pull_request) Successful in 4s
CI / contract (pull_request) Has been skipped
CI / format (pull_request) Successful in 10s
CI / lint (pull_request) Successful in 12s
CI / compile (pull_request) Successful in 1m37s
CI / dashboard-build (pull_request) Successful in 1m14s
CI / test (pull_request) Successful in 15m26s
4b41aaf6b4
mph merged commit d58f788083 into main 2026-09-21 16:32:13 +00:00
Sign in to join this conversation.
No description provided.