Skip to content

feat(loop): milestone-scoped census — drain current version before wandering (issue #174) - #194

Merged
robercano-ghbot merged 4 commits into
mainfrom
feat/issue-174-milestone-scoped-census
Jul 28, 2026
Merged

feat(loop): milestone-scoped census — drain current version before wandering (issue #174)#194
robercano-ghbot merged 4 commits into
mainfrom
feat/issue-174-milestone-scoped-census

Conversation

@robercano-ghbot

Copy link
Copy Markdown
Collaborator

What

Milestones represent versions (SCRUM sprints). The census now scopes its ADVANCE candidate set to the CURRENT open milestone (lowest version-sorted open milestone with at least one qualifying planned+module-labeled issue) and idles once it drains, rather than wandering into a future milestone. Feedback/merge phases (open PRs) are unaffected — always serviced regardless of milestone.

Implementation

  • milestone=<title> / milestone_open=<n> census lines, emitted only when a milestone is genuinely in scope (byte-identical output preserved for repos with no milestones).
  • Fallback to today's unscoped behavior when no open milestone has a qualifying candidate.
  • Milestone data fetched via REST (gh api --paginate repos/{owner}/{repo}/milestones?state=open) per the gh 2.4.0 constraint (no gh milestone, no GraphQL).
  • milestone-complete event logged (via log-event.sh) when a milestone's own open_issues==0/closed_issues>=1 shows it genuinely drained. Idempotency is tracked in a dedicated, never-rotated sidecar ledger (.claude/state/milestone-complete-logged.json, keyed by milestone number) rather than scanning events.jsonl — the latter is capped/rotated by log-event.sh and would eventually re-log a duplicate over the multi-day idle gap this feature is built around. The check-then-log critical section is serialized with flock, guarded so a lock failure degrades to "skip this tick" rather than aborting census.

Testing

loop-census.test.sh: 86 checks, covering scoping (two open milestones, only the lower-versioned one advances), fallback, recompute-on-drain (idle and non-idle), milestone-complete event + idempotency + rotation-survival, sort -V regression, never-populated/un-drained negative guards, space-in-title titles, no-leak on milestone-less repos, and lock-failure-never-aborts-census.

Reviewed through the correctness and tests lenses (consensus required); two review-driven fixes applied for a rotation-durability bug and a lock-abort regression, both now covered by regression tests.

Fixes #174

🤖 Generated with Claude Code

robercano and others added 4 commits July 24, 2026 21:05
…ndering (issue #174)

Milestones represent versions/sprints; the PR-loop census now scopes its
ADVANCE candidate set to the lowest version-sorted OPEN milestone that has
a qualifying planned+module candidate, recomputed fresh every tick (no
persistent cursor), falling back to today's unscoped behavior when no open
milestone qualifies — byte-identical output for repos that don't use
milestones. Emits milestone=/milestone_open= census lines, and logs an
idempotent milestone-complete event (the one deliberate exception to
census's read-only/re-run-safe contract) when a milestone's open_issues
count drains to zero.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Tests reviewer follow-up: sort -V regression lock (v1.9/v1.10 lexical vs
version divergence), never-populated milestone-complete guard negative,
un-drained-milestone negative, and a no-leak assertion for the
milestone-less path. loop-census.sh source is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…otation (issue #174)

Reviewer-found bug: the milestone-complete guard scanned events.jsonl for a
prior marker line, but log-event.sh caps that file to the last 2000 lines —
over the multi-day idle gap a drained milestone sits in, the marker
eventually rotates out and census re-logs a duplicate on the next tick.
Track completion instead in a dedicated, never-rotated sidecar ledger
(.claude/state/milestone-complete-logged.json, keyed by milestone number),
serialized with flock against concurrent census/cockpit invocations. Also
adds --paginate to the milestones REST fetch and test coverage for rotation
survival and space-containing milestone titles.
…s (issue #174)

Reviewer-found regression: the flock guard added for the rotation fix opened
and acquired its lock fd with no failure handling under this script's own
set -euo pipefail, so a permission/missing-dir/disk-full failure on the lock
file killed the entire census run before it printed advance_ready=/
planned_issues=/etc. — the exact invariant this script promises to never
break. Guard both the exec/flock lines and the subshell invocation so a lock
failure degrades to "skip logging this tick" instead of aborting.
@robercano-ghbot robercano-ghbot added the needs-human Loop escalated: attempt budget exhausted, manual triage required label Jul 24, 2026
@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

feat(loop): milestone-scoped census — drain current version before wandering (issue #174) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

Resume-attempt 2/2 (issue #98/#154 stall recovery): re-attached to this branch's existing worktree, confirmed HEAD (afd9d2d) already matches this PR and CI is green/mergeable. No implementation gaps found against the issue #174 acceptance criteria.

Re-ran gates (GATES_FILE=.claude/self/gates.json): build, lint, test all pass (86/86 census checks + fan-out smoke).

Re-ran both review lenses fresh against the current diff (adapter consensus=all):

  • correctness: approve — verified the milestone-complete idempotency fix and the flock-guard fix both hold; traced scoping/fallback/sort-composition end to end. One cosmetic nit (harmless stderr leak on a failed lock-file redirect).
  • tests: approve — test gate green; bisected the rotation-survival, lock-failure, and scoping fixtures against this branch's own pre-fix commits to confirm they genuinely discriminate, not just pass.

No further changes needed — this PR is ready and waiting on owner review/approval.

@robercano-ghbot robercano-ghbot removed the needs-human Loop escalated: attempt budget exhausted, manual triage required label Jul 28, 2026
@robercano-ghbot
robercano-ghbot merged commit e4f5797 into main Jul 28, 2026
9 checks passed
@robercano-ghbot
robercano-ghbot deleted the feat/issue-174-milestone-scoped-census branch July 28, 2026 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Milestone-scoped census: the loop works one milestone (sprint) at a time

2 participants