feat(dev-backlog): Phase 1b — sprint lifecycle track-awareness (#292)#307
Conversation
Make init/close/mirror track-aware (PRD §5.2), all consuming the ONE shared scopesOverlap() from lib.js: - sprint-init.js: refusal changes from "any second active sprint" to "second active track whose scope overlaps an existing active track". New --scope "glob[,glob]" flag emits an explicit scope: frontmatter line (D2 — never inferred). Scopeless next to scopeless cannot be proven disjoint → warn-and-allow, matching the doctor's informational stance. Disjoint tracks are created without refusal. - sprint-close.sh: --track <slug> picks which track to close; the ambiguous no-flag refusal remains and now hints at --track; a no-match selector fails loud listing active tracks. - sprint-mirror.js: mirrors per track — --track passes through to sprint-state.js; a portfolio without --track refuses naming the active tracks; default unchanged when N==1. G4: single-track init and close verified byte-identical against origin/main (text, exit codes, and written/mutated files); the mirror's no-track sprint-state invocation is assert-pinned unchanged. Smoke grows Phase 1b fixtures (disjoint init, overlap refusal, close --track, ambiguous-close hint, G4 init anchor): 187/187 pass. Also fixes the pre-existing cwd-dependent sprint-init.test.js #13 ("produces frontmatter compatible with find_active_sprint") by pinning explicit hasCharter/hasCapabilities overrides (#258 rot, assigned here). Refs #292, #289. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 48 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 897fbb0f22
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| exit 1 | ||
| fi | ||
| ;; | ||
| --track=*) TRACK="${1#--track=}" ;; |
There was a problem hiding this comment.
Reject empty --track= selectors
When a caller supplies --track= from an empty shell variable, this branch sets TRACK to an empty string and the later [ -n "$TRACK" ] check treats the command as if no selector was provided. In a single-active-sprint repo that means sprint-close.sh backlog --track= proceeds to close the only active sprint instead of failing like the --track form does for a missing value, so an invalid selector can still mutate the sprint file.
Useful? React with 👍 / 👎.
| if (arg.startsWith("--track=")) { | ||
| options.track = arg.slice("--track=".length); | ||
| continue; |
There was a problem hiding this comment.
Reject empty --track= selectors
--track= currently parses as track: "", and resolveSprintState() treats that falsy value the same as omitting --track. With one active sprint, an invocation such as sprint-mirror.js backlog --track= can update/create the default sprint mirror rather than reporting the missing selector value, which is inconsistent with the guarded --track form and can publish the wrong track when an empty variable is expanded.
Useful? React with 👍 / 👎.
Summary
Implements #292 (Phase 1b) of the multi-track sprints initiative (epic #289, PRD §5.2): the sprint lifecycle — init, close, mirror — becomes track-aware. All overlap decisions consume the one shared
scopesOverlap()fromlib.js; no second overlap check exists.sprint-init.jsActive track overlaps on scope: <file>. …--scope "glob[,glob]"flag emits an explicitscope: ["…"]frontmatter line (D2 — scope is declared, never inferred). Omitted--scopeemits nothing.warnings[]in the JSON result,Warning:lines in text), matching the doctor's informational stance. Disjoint tracks create without refusal.sprint-close.sh--track <slug>(slug orcomponent:handle, via lib.shresolve_track) picks which track to close out of a portfolio.Refusing to close an ambiguous sprint) and now appendsPass --track <slug> to close one track.sprint-mirror.js--trackpasses through tosprint-state.js --mode status --track <slug>; the:98singular read is now selector-aware.--trackrefuses:Multiple active tracks (a, b). Pass --track <slug> …; a no-match selector refuses naming it. N==1 default path unchanged.Verification
bash smoke-test.sh→ 187/187 pass, 0 xfail (new Phase 1b fixtures: disjoint init, overlap refusal, close--trackfull cycle, ambiguous-close hint, single-track init G4 anchor)sprint-init.test.js, whose pre-existing cwd-dependent Expand test coverage for shared libraries and edge cases #13 failure ("produces frontmatter compatible with find_active_sprint", feat(dev-backlog): omit objectives/component frontmatter when spec files are absent (B3) #258 rot) is fixed here as assigned by the issueorigin/main: single-tracksprint-init(dry-run + real create, written file included) andsprint-close(dry-run + real close, mutated backlog tree included) diffed old-vs-new — byte-identical text, equal exit codes, identical files. The mirror's no-tracksprint-stateinvocation is assert-pinned unchanged in its test suite.2026-07-multi-track-sprints.mdticks Phase 1b: sprint lifecycle track-awareness (init/close/mirror) #292 in the same squash.Refs #292, #289.
🤖 Generated with Claude Code