docs(dev-backlog): Phase 3 — multi-track docs + integration-contract schema 2 (#295)#309
Conversation
…schema 2 (#295) Documentation flip off the single-active-sprint singleton, gated by the #294 human-run spec amendment (merged in #308): - references/integration-contract.md: actor JSON surface documented as schema_version 2 — active_sprints[] portfolio + retained v1 single- track fields (byte-compatible when N==1); "ambiguous active state is fail-loud" replaced by "portfolio for disjoint tracks, fail-loud only on overlapping scope (OVERLAPPING_TRACKS)"; component routing gains the track-scope-key rule ("two active tracks MUST NOT share a component:"); Relay-Merge Sprint Update Format and Capability Learnings Append Contract gain track-resolution paragraphs (sprint-state.js --component/--track, never guess across tracks); doctor section documents per-track fan-out + track tags and corrects the zero-active state from hard-failure to informational warn; Versioning updated (grammar unchanged, JSON additive). - SKILL.md: core contract, frontmatter table (+ scope: row), Orient/ Plan paths, script list, and eval prompts rewritten for "one active track per scope; disjoint tracks coexist"; the gated multi-track eval prompt is un-gated (behavior landed in #291/#293/#292). - references/process.md: Orient portfolio path, overlap-only Plan refusal, close --track, next --track, unplanned-work concurrent-track option. - references/scripts.md: full flag inventory updated (--track, --scope, sprint-state.js row); last "single active sprint" claim removed. - README.md: new "Multi-Track Sprints" section (when to open a second track, scope declaration, invariant, portfolio commands). - CHANGELOG.md: multi-track headline + phased entry (#291/#293/#292/ #294/#295) and the sprint-init.test.js cwd-rot fix note. No script changes; smoke 187/187, doctor 8/8 PASS. No residual "exactly one active sprint" claim outside the PRD's historical context. Refs #295, #289. Coordination comment to follow on dev-relay#954. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Walkthrough멀티 트랙 스프린트 모델을 계약서, 운영 프로세스, 스크립트 문서, README와 변경 이력에 반영했습니다. Disjoint scope의 active 트랙 공존, overlap 거부, Changes멀티 트랙 스프린트
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ 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: 2e94550024
ℹ️ 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".
| ``` | ||
|
|
||
| Both commands emit one JSON document to stdout with `schema_version: 1`. Tracker-neutral identity is an additive schema-v1 extension: existing consumers may ignore the new fields, and no existing field or GitHub value changes. Human-readable output remains the default when `--json` is absent. Snapshots are supported through normal shell redirection only, for example `status.sh --json > sprint-state.json`; dev-backlog does not create timestamped snapshot files or maintain a snapshot store. | ||
| Both commands emit one JSON document to stdout with `schema_version: 2`. Schema v2 (multi-track, PRD 2026-07) adds `active_sprints[]` — every active track in `started:`-ascending order — while retaining every v1 top-level field: `active_sprint` and the other singular fields hold the sole track's values when exactly one track is active (byte-compatible with v1 consumers) and are `null`/empty for a portfolio of N>1 tracks. `--track <slug>` (or `--component <slug>`) selects one track and emits the single-track shape. Human-readable output remains the default when `--json` is absent. Snapshots are supported through normal shell redirection only, for example `status.sh --json > sprint-state.json`; dev-backlog does not create timestamped snapshot files or maintain a snapshot store. |
There was a problem hiding this comment.
Remove unsupported --component from wrapper contract
This paragraph documents --component as an option for the two preferred JSON entry points (status.sh --json and next.sh --json), but both wrappers only parse --json and --track before forwarding to sprint-state.js (see scripts/status.sh lines 12-26 and scripts/next.sh lines 15-29). As a result, status.sh --json --component auth treats --component/auth as positional backlog-dir arguments instead of selecting a component, so actors following this contract can get an empty state or the full portfolio rather than the intended track. Either document the underlying sprint-state.js --component command here or add wrapper forwarding.
Useful? React with 👍 / 👎.
| When `relay-merge` completes a task, it updates the active sprint file in these specific formats: | ||
| When `relay-merge` completes a task, it updates the active sprint file in these specific formats. | ||
|
|
||
| **Track resolution:** with one active track, "the active sprint file" is unambiguous. With multiple active tracks, resolve the target sprint by track key — the task's owning `component:` (or track slug) selects the sprint file via `sprint-state.js --component <slug>` (or `--track <slug>`); never guess among tracks and never write one task's update into another track's sprint file. |
There was a problem hiding this comment.
Reject duplicate component matches before relay writes
This new relay-merge guidance says resolving by sprint-state.js --component <slug> prevents guessing, but sprint-state.js applies selectors before the overlap check and returns matches[0] when multiple active sprints share the same component (scripts/sprint-state.js lines 443-447). In the exact invalid state this contract says should be fail-loud, relay-merge would silently pick one matching sprint and could mark the wrong track; the contract should require an unselected overlap check/doctor pass first, or the resolver should refuse multiple component matches.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@README.md`:
- Around line 203-208: Update the “Declaring scope” YAML documentation example
so component and scope are shown as separate alternatives, with only one field
active in each example. Preserve the explanation that component is the primary
scope key when a capability axis exists and scope is used for explicit path
globs otherwise; do not present both keys as simultaneously declared.
In `@skills/dev-backlog/references/integration-contract.md`:
- Around line 29-31: Update the schema v2 compatibility wording in the command
output contract to remove the claim that the JSON is byte-compatible with v1.
State that v1 top-level fields and their semantics are retained, while the
document itself is not byte-compatible because schema_version changes to 2 and
active_sprints[] is added; limit compatibility to consumers that ignore unknown
fields.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5d26f591-4571-4048-be8f-b42ceb427191
📒 Files selected for processing (7)
CHANGELOG.mdREADME.mdbacklog/sprints/2026-07-multi-track-sprints.mdskills/dev-backlog/SKILL.mdskills/dev-backlog/references/integration-contract.mdskills/dev-backlog/references/process.mdskills/dev-backlog/references/scripts.md
| **Declaring scope** (explicit, never inferred — one axis per track): | ||
|
|
||
| ```yaml | ||
| component: "auth-system" # primary scope key when a capability axis exists | ||
| scope: ["src/auth/**"] # explicit path globs otherwise (sprint-init.js --scope) | ||
| ``` |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
scope 예제에서 두 축을 동시에 선언하지 마세요.
계약은 component:와 scope: 중 하나만 사용하도록 명시하지만, 현재 복사 가능한 YAML 예제는 두 필드를 모두 활성화합니다. component 축과 scope 축을 별도의 대안 예제로 분리해야 합니다.
수정 방향
component: "auth-system" # primary scope key when a capability axis exists
-scope: ["src/auth/**"] # explicit path globs otherwise (sprint-init.js --scope)
+# 또는 component 축이 없을 때만:
+# scope: ["src/auth/**"] # sprint-init.js --scope📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| **Declaring scope** (explicit, never inferred — one axis per track): | |
| ```yaml | |
| component: "auth-system" # primary scope key when a capability axis exists | |
| scope: ["src/auth/**"] # explicit path globs otherwise (sprint-init.js --scope) | |
| ``` | |
| **Declaring scope** (explicit, never inferred — one axis per track): | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` around lines 203 - 208, Update the “Declaring scope” YAML
documentation example so component and scope are shown as separate alternatives,
with only one field active in each example. Preserve the explanation that
component is the primary scope key when a capability axis exists and scope is
used for explicit path globs otherwise; do not present both keys as
simultaneously declared.
| Both commands emit one JSON document to stdout with `schema_version: 2`. Schema v2 (multi-track, PRD 2026-07) adds `active_sprints[]` — every active track in `started:`-ascending order — while retaining every v1 top-level field: `active_sprint` and the other singular fields hold the sole track's values when exactly one track is active (byte-compatible with v1 consumers) and are `null`/empty for a portfolio of N>1 tracks. `--track <slug>` (or `--component <slug>`) selects one track and emits the single-track shape. Human-readable output remains the default when `--json` is absent. Snapshots are supported through normal shell redirection only, for example `status.sh --json > sprint-state.json`; dev-backlog does not create timestamped snapshot files or maintain a snapshot store. | ||
|
|
||
| Ambiguous active sprint state is fail-loud in JSON mode: the command exits non-zero and writes the error to stderr instead of emitting partial JSON. Missing `## ` sections degrade to empty strings or arrays as shown below. | ||
| Multiple active tracks are a **portfolio**, not an error; only **overlapping-scope** tracks are fail-loud: when two active tracks overlap (`component:` equality or `scope:` path-prefix collision, via the one shared `scopesOverlap` predicate in `lib.js`), JSON mode exits non-zero with `OVERLAPPING_TRACKS` on stderr instead of emitting partial JSON. Missing `## ` sections degrade to empty strings or arrays as shown below. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
JSON 전체를 “byte-compatible”이라고 설명하지 마세요.
schema_version이 1에서 2로 바뀌고 active_sprints[]가 추가되므로 문서 바이트는 호환되지 않습니다. 유지되는 것은 v1 필드의 의미와, 알 수 없는 필드를 무시하는 소비자에 대한 제한적 하위 호환성입니다. 해당 문구를 “v1 필드를 유지하지만 JSON 문서 자체는 byte-compatible하지 않다”로 정정하세요.
수정 방향
-while retaining every v1 top-level field ... (byte-compatible with v1 consumers)
+while retaining every v1 top-level field; consumers that tolerate the new schema
+version and unknown fields can continue using the retained fields, but the JSON
+document itself is not byte-compatible with v1.Also applies to: 469-469
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 31-31: Spaces inside code span elements
(MD038, no-space-in-code)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/dev-backlog/references/integration-contract.md` around lines 29 - 31,
Update the schema v2 compatibility wording in the command output contract to
remove the claim that the JSON is byte-compatible with v1. State that v1
top-level fields and their semantics are retained, while the document itself is
not byte-compatible because schema_version changes to 2 and active_sprints[] is
added; limit compatibility to consumers that ignore unknown fields.
Summary
#295 (Phase 3) — the documentation half of the multi-track initiative (epic #289, PRD §6.4/§7), now unblocked by the #294 human-gated spec amendment (#308). No script changes.
references/integration-contract.mdschema_version: 2:active_sprints[](started-asc portfolio) plus every retained v1 field — single-track values byte-compatible, portfolio leaves singular fieldsnull/empty;--track/--componentselectors documented.OVERLAPPING_TRACKS, sharedscopesOverlap).component:is also the primary track-scope key; two active tracks MUST NOT share acomponent:."sprint-state.js --component <slug>/--track <slug>; never guess across tracks, never write one task's update into another track's sprint).tracktags; also corrects a pre-existing inaccuracy — the between-sprints zero-active state is an informational warn, not a hard failure.SKILL.md / process.md / scripts.md
Singleton prose flipped everywhere to "one active track per scope; disjoint tracks coexist": core contract bullet, frontmatter table (new
scope:row), Orient/Plan portfolio paths,--track/--scopeflag inventory, close/next/mirror rows, unplanned-work concurrent-track option. The formerly gated multi-track eval prompt is un-gated; the overlap-refusal eval replaces the old any-second-active refusal.grepconfirms no residual "exactly one active sprint" claim outside the PRD's historical context.README.md / CHANGELOG.md
sprint-init.test.jscwd-rot Fixed note.Coordination
The dev-relay-parsed checkbox/annotation grammar is untouched; the JSON surface change is additive with retained v1 fields. A coordination comment will be posted on
sungjunlee/dev-relay#954after merge (feeds #955–#957).Verification
bash smoke-test.sh→ 187/187 pass;backlog-doctor8/8 PASS (docs-only change)skills/, README, CHANGELOGRefs #295, #289.
🤖 Generated with Claude Code
Summary by CodeRabbit
새로운 기능
문서
버그 수정