task new waits for a milestone the listing has not caught up with (#243) - #247
Conversation
…UND (#243) The open-milestone listing is label-filtered and eventually consistent: three task new calls seconds after milestone new were refused NOT_FOUND and the fourth succeeded (#234). When the listing lacks M<n>, task new now reads the hub's newest issues regardless of label, accepting an open M<n>: issue that carries cc:milestone, then waits 2s and reads both again, three reads in all, before refusing — with a detail that says the listing can lag. The sleeper is a func var so the tests record the waits. Adopts #234 (M12-R2). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsJKZXNhs7rsovhb6jXCRE
…s itself (#243) The coordinator contract's back-to-back milestones line says task new resolves the number through a listing that can lag and retries itself, so nobody scripts a pause around it; SPEC's task new row and the introduction's NOT_FOUND line describe the resolution; CHANGELOG entry under Unreleased. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsJKZXNhs7rsovhb6jXCRE
There was a problem hiding this comment.
Approved. I reviewed the diff before the PR body, then checked task #243, milestone #241/M12-R2, historical milestone #207 context, and capture #234 including its Correction comment. The implementation matches the requirement: bounded retry/fallback before NOT_FOUND, injectable sleep, no test waits, and fallback validation rejects closed or non-cc:milestone issues. Record and docs are in step: task plan and Decision precede the commits, PR body closes #243 and #234, coordinator/SPEC/introduction/changelog are updated, and the changelog entry is under the new Unreleased heading ending (#243). Verification run with repo-local caches: go test ./..., go vet ./..., gofmt -l ., go build -o ./gh-codecrew ./cmd/codecrew, plus read-only probes of the changed NOT_FOUND path and status.
Closes #243
Closes #234
What was done
task new --milestone <n>no longer trusts a single read of the open-milestone listing. When the listing lacksM<n>it:RecentIssues, in the tracker since milestone new never reuses a milestone number #209) and accepts an openM<n>:issue that carriescc:milestone— confirmed on the issue itself through the existingTask(ref)fetch, since that listing is unfiltered and shows closed issues;refused[NOT_FOUND], whose detail now says the listing can lag a milestone created seconds ago.A milestone found by either fallback is printed as a note, so the run's output records that the listing lagged. The sleeper is a package func var (
sleep = time.Sleep, theghVersionpattern) so the tests record the waits instead of taking them. The common case — the number is in the listing — is unchanged at one read.Tests (
internal/cli/task_test.go, fake tracker with successive listing answers): fresh listing → one read, no wait, no note; stale-then-fresh → success after two recorded 2s waits with the note; found among the newest issues → success with no wait, and a closedM<n>:milestone or a plain issue titledM<n>:is not accepted; never found →NOT_FOUNDafter exactly three reads with the two waits recorded, nothing created.Docs:
roles/coordinator.md(the back-to-back milestones line: atask newright aftermilestone newmay take a moment and retries itself; do not script a pause around it),SPEC.md§6task newrow,docs/introduction.mdNOT_FOUNDline,CHANGELOG.mdunder[Unreleased].Requirements
M12-R2 (milestone #241).
Record
Task, bounded retries, the rejected alternatives): task new waits for a milestone the listing has not caught up with #243 (comment)🤖 Generated with Claude Code
https://claude.ai/code/session_01QsJKZXNhs7rsovhb6jXCRE