Record the card's position on write, tell a killed process from a failing one, and identify a phase's pull request by its branch #506
No reviewers
Labels
No labels
agent-ready
bug
contract
documentation
duplicate
enhancement
good first issue
help wanted
invalid
needs-human
needs-input
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
iterative-works/iw-cli!506
Loading…
Reference in a new issue
No description provided.
Delete branch "phase-gate-followups"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Three defects a consumer found in 0.11.0, and the two review warnings that
shipped with it.
review-state writerecords phase, step and branch (#505)#487put--phase,--stepand--branchonupdateonly. Everyworkflow's first transition creates the card with
write, so a card born atanalysis_readycarried none of the three and the resume fast path could notpass its sanity check at the one transition every workflow starts from.
writenow takes the same three flags with the same semantics. The value isstored verbatim as a JSON string —
--phase 3writes"3"— which is whatupdatealready did and is now stated in the write documentation as well.A consumer comparing
state.phaseagainst a phase number must compare strings.A killed child is distinguishable from a failing one (#468, fault (c))
ProcessAdapter.runcomputedtimedOutby comparing the exit code against143 alone. os-lib sends SIGTERM and escalates to SIGKILL when the child does
not go, so a child killed the hard way exits 137 and
run— the function thatwas supposed to get this right — answered
timedOut = false.runStreamingreturned the signal code with nothing to read it by, and theconstant was
private. A consumer that wanted to tell "our guard fired" from"the command said no" had to hardcode the two numbers; the kanon plugin did,
and until it did, a CI wait that outlived its guard was reported to the user
as a failing build.
killedBySignalnames both codes and is public.runuses it.runStreamingkeeps returning the code — that is what a caller alreadymatches on — and now says on stderr what it killed and how long it waited.
contract suites already get, names the suite that did not pass, and reports
a killed suite as killed rather than failed.
step that blocked the push instead of leaving the reader with the tail of
whichever suite ran last.
phase-pr identifies a pull request by its branch (#467 review follow-ups)
The guard added in 0.11.0 asked whether the pull request the card records
points at the commit just pushed. That is the wrong question twice over.
A forge publishes a merge request's head commit after it takes the push, so
the right pull request could report the commit before it and be refused — a
false refusal that stops
--batchand needs a human. And the refusal told thereader to clear
pr_url, destroying a good url to work around a lag.The branch a pull request is open on says which work it is for, and no lag
moves it.
fetchPrHeadBranchreads it from Forgejo, GitHub and GitLab, theguard compares it against the branch this phase pushed, and the refusal names
both branches and asks for the right url instead of the loss of the recorded
one. A forge that will not answer is still a refusal: guessing is the failure
this guard exists to stop.
API surface
TrackerOpsgainsfetchPrHeadBranch— a break for anything that implementsthe trait, and only for that.
ProcessAdapter.SigtermExitCodechanges fromprivate to public and gains
SigkillExitCodeandkilledBySignal; nothingthat compiled before stops compiling.
Not in this change
Faults (a) and (b) of #468 — the test-server port hijack and the BATS
isolation leaks — are a separate body of work and stay on that issue. One new
sighting of the flake class was recorded during this work.
Closes #505
🤖 Generated with Claude Code
https://claude.ai/code/session_013UpRzj7oiV1UDArn4hfu7U