phase-pr and ci-gate write the ci_pending card from two hand-copied definitions #568

Open
opened 2026-09-16 09:02:00 +00:00 by claude · 4 comments
Member

Found while working IW-566.

The ci_pending review-state card is written from two places that must agree, and nothing makes them agree.

CiGate.markPending (core/commands/CiGate.scala:254-268) is private, so PhasePr.handOffWait cannot call it. The --no-wait path therefore copies the same five fields by hand. Both writers must set the same status, the same display text and the same clearCiWaitStarted, or BatchImplement.decideOutcome maps one of them to the wrong outcome — and a test passing against one writer proves nothing about the other.

PROPOSED FIX. Extract one builder for the ci_pending card shape and have both CiGate and PhasePr call it, so the card contract has a single definition.

WHILE THERE. PhasePr.handOffWait and the pre-existing PhasePr.handOver differ by one word but sit at different points in the lifecycle — handOver after the wait, handOffWait before it. Renaming the latter to deferCiWait would stop the two reading as variants of one thing.

Found while working IW-566. The `ci_pending` review-state card is written from two places that must agree, and nothing makes them agree. `CiGate.markPending` (`core/commands/CiGate.scala:254-268`) is `private`, so `PhasePr.handOffWait` cannot call it. The `--no-wait` path therefore copies the same five fields by hand. Both writers must set the same status, the same display text and the same `clearCiWaitStarted`, or `BatchImplement.decideOutcome` maps one of them to the wrong outcome — and a test passing against one writer proves nothing about the other. PROPOSED FIX. Extract one builder for the `ci_pending` card shape and have both `CiGate` and `PhasePr` call it, so the card contract has a single definition. WHILE THERE. `PhasePr.handOffWait` and the pre-existing `PhasePr.handOver` differ by one word but sit at different points in the lifecycle — `handOver` after the wait, `handOffWait` before it. Renaming the latter to `deferCiWait` would stop the two reading as variants of one thing.
Author
Member

Found during IW-601 phase 2 (composition review): the same two writers also duplicate the ci_failed card. PhasePr.stop/reportRed and CiGateCommand.stop/reportRed build the same ci_failed update and red report in two copies (PhasePr.scala:553-590, CiGateCommand.scala:282-313). The single-builder fix should cover this card too.

Found during IW-601 phase 2 (composition review): the same two writers also duplicate the `ci_failed` card. `PhasePr.stop`/`reportRed` and `CiGateCommand.stop`/`reportRed` build the same `ci_failed` update and red report in two copies (`PhasePr.scala:553-590`, `CiGateCommand.scala:282-313`). The single-builder fix should cover this card too.
Author
Member

Intake: agent-ready
Workflow: waterfall
Reason: all gates passed
Analysis: project-management/issues/IW-568/analysis.md on branch IW-568

Intake: agent-ready Workflow: waterfall Reason: all gates passed Analysis: project-management/issues/IW-568/analysis.md on branch IW-568
Author
Member

Implement: needs-human
Reason: batch-implement exit 1 — the kanon plugin did not compile against this worktree's iw-cli core, so no phase ran

batch-implement stopped before it wrote batch-implement.log. The lines below are its console output. The installed kanon plugin (lib/batch/ForgeCatchUp.scala:143) expects Either[String, …] from tracker.fetchPullRequestForBranch. iw-cli main (#778–#780) changed the tracker port to return Either[TrackerError, …]. This failure is not specific to this issue: every batch-implement in iw-cli fails the same way until the plugin follows the port change.

[error] /home/mph/.local/share/iw/plugins/kanon/lib/batch/ForgeCatchUp.scala:143:7
[error] Found:    Either[iw.core.model.TrackerError, Option[batch.ForgeState]]
[error] Required: Either[String, Option[batch.ForgeState]]
Compilation failed
Implement: needs-human Reason: batch-implement exit 1 — the kanon plugin did not compile against this worktree's iw-cli core, so no phase ran `batch-implement` stopped before it wrote `batch-implement.log`. The lines below are its console output. The installed kanon plugin (`lib/batch/ForgeCatchUp.scala:143`) expects `Either[String, …]` from `tracker.fetchPullRequestForBranch`. iw-cli `main` (#778–#780) changed the tracker port to return `Either[TrackerError, …]`. This failure is not specific to this issue: every `batch-implement` in iw-cli fails the same way until the plugin follows the port change. ``` [error] /home/mph/.local/share/iw/plugins/kanon/lib/batch/ForgeCatchUp.scala:143:7 [error] Found: Either[iw.core.model.TrackerError, Option[batch.ForgeState]] [error] Required: Either[String, Option[batch.ForgeState]] Compilation failed ```
Author
Member

Release: the implement loop failed this issue for a reason outside it. The kanon plugin did not compile against iw-cli main, because the tracker port now returns TrackerError (iw-cli #778). The plugin fix is dev-docs #484, and iw-cli 0.22.1 carries the core change. The issue goes back to the implement loop.

Release: the implement loop failed this issue for a reason outside it. The kanon plugin did not compile against iw-cli main, because the tracker port now returns TrackerError (iw-cli #778). The plugin fix is dev-docs #484, and iw-cli 0.22.1 carries the core change. The issue goes back to the implement loop.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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#568
No description provided.