Skip to content

docs(dev-backlog): Phase 3 — multi-track docs + integration-contract schema 2 (#295)#309

Merged
sungjunlee merged 1 commit into
mainfrom
docs/multitrack-phase3
Jul 12, 2026
Merged

docs(dev-backlog): Phase 3 — multi-track docs + integration-contract schema 2 (#295)#309
sungjunlee merged 1 commit into
mainfrom
docs/multitrack-phase3

Conversation

@sungjunlee

@sungjunlee sungjunlee commented Jul 12, 2026

Copy link
Copy Markdown
Owner

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.md

  • Actor JSON surface documented as schema_version: 2: active_sprints[] (started-asc portfolio) plus every retained v1 field — single-track values byte-compatible, portfolio leaves singular fields null/empty; --track/--component selectors documented.
  • "Ambiguous active sprint state is fail-loud" → "Multiple active tracks are a portfolio; overlapping-scope tracks are fail-loud" (OVERLAPPING_TRACKS, shared scopesOverlap).
  • Component routing gains the track-scope-key rule: "When multiple sprints are active, component: is also the primary track-scope key; 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 <slug> / --track <slug>; never guess across tracks, never write one task's update into another track's sprint).
  • Doctor section documents per-track check fan-out + track tags; also corrects a pre-existing inaccuracy — the between-sprints zero-active state is an informational warn, not a hard failure.
  • Versioning: checkbox/annotation grammar explicitly unchanged; JSON change is additive.

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/--scope flag 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. grep confirms no residual "exactly one active sprint" claim outside the PRD's historical context.

README.md / CHANGELOG.md

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#954 after merge (feeds #955–#957).

Verification

  • bash smoke-test.sh → 187/187 pass; backlog-doctor 8/8 PASS (docs-only change)
  • Residual-claim grep clean across skills/, README, CHANGELOG

Refs #295, #289.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 새로운 기능

    • 서로 다른 범위의 스프린트를 여러 개 동시에 활성화할 수 있습니다.
    • 범위가 겹치는 활성 스프린트는 생성이 거부됩니다.
    • 상태 조회에서 여러 트랙을 포트폴리오 형태로 확인할 수 있으며, 특정 트랙을 선택해 작업할 수 있습니다.
    • 단일 트랙 사용 시 기존 상태 정보와의 호환성이 유지됩니다.
  • 문서

    • 멀티 트랙 스프린트 운영 규칙, 작업 흐름 및 JSON 상태 형식을 문서화했습니다.
  • 버그 수정

    • 스프린트 초기화 테스트의 특정 디렉터리 존재 의존성을 제거했습니다.
    • 스프린트 종료 옵션 처리와 다중 트랙 선택 규칙을 보완했습니다.

…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>
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

멀티 트랙 스프린트 모델을 계약서, 운영 프로세스, 스크립트 문서, README와 변경 이력에 반영했습니다. Disjoint scope의 active 트랙 공존, overlap 거부, schema_version: 2, --track 선택 규칙이 추가되었습니다.

Changes

멀티 트랙 스프린트

Layer / File(s) Summary
트랙 및 JSON 계약
skills/dev-backlog/SKILL.md, skills/dev-backlog/references/integration-contract.md
Active 트랙의 disjoint scope 규칙, 포트폴리오 JSON의 schema_version: 2active_sprints[], doctor 및 relay-merge의 트랙 해석 규칙을 정의했습니다.
트랙 실행 워크플로
skills/dev-backlog/SKILL.md, skills/dev-backlog/references/process.md, skills/dev-backlog/references/scripts.md
트랙 탐색·생성·종료·다음 작업 선택과 관련 스크립트의 --track, --scope, overlap 및 포트폴리오 동작을 갱신했습니다.
README·변경 이력·진행 기록
README.md, CHANGELOG.md, backlog/sprints/2026-07-multi-track-sprints.md
멀티 트랙 사용법, 관련 문서 작업 완료 상태, 변경 내역 및 테스트 경로 수정 사항을 기록했습니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • #289 — 동일한 disjoint-scope 멀티 트랙 모델과 트랙 인식 스크립트·schema v2 문서화를 다룹니다.
  • #295 — 동일한 문서 및 integration-contract의 schema_version: 2 변경을 직접 다룹니다.

Possibly related PRs

  • sungjunlee/dev-backlog#297 — 멀티 트랙 overlap 테스트와 SKILL.md 평가 시나리오를 추가해 이번 계약 문서 변경과 직접 연결됩니다.

Poem

깡충 토끼가 트랙을 열고
겹치면 멈춰, 갈라지면 달려
--track을 콕 찍어 길을 찾네
두 스프린트도 나란히 춤추고
문서에는 새 발자국 반짝! 🐇

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning PR 변경은 [#39]의 progress 댓글 재조정이 아니라 multi-track 문서/계약 업데이트라 직접 요구사항을 충족하지 않습니다. [#39]의 hidden progress-comment 마커, 결정적 entry key, reconcile create/update/repair 로직과 관련 테스트를 구현하세요.
Out of Scope Changes check ⚠️ Warning 링크된 [#39] 요구사항과 무관한 multi-track 문서·schema 업데이트만 포함되어 있어 범위를 벗어납니다. 링크된 [#39]를 다루도록 progress comment reconciliation 변경으로 범위를 맞추거나, 해당 이슈를 링크에서 분리하세요.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 multi-track 문서화와 integration-contract schema 2 변경을 간결하게 요약해 변경사항과 잘 맞습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/multitrack-phase3

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between e5c61de and 2e94550.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • README.md
  • backlog/sprints/2026-07-multi-track-sprints.md
  • skills/dev-backlog/SKILL.md
  • skills/dev-backlog/references/integration-contract.md
  • skills/dev-backlog/references/process.md
  • skills/dev-backlog/references/scripts.md

Comment thread README.md
Comment on lines +203 to +208
**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)
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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.

Suggested change
**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.

Comment on lines +29 to +31
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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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.

@sungjunlee sungjunlee merged commit 0b9eea7 into main Jul 12, 2026
2 checks passed
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.

1 participant