Skip to content

spec: amend capabilities singleton invariant to track disjointness (#294)#308

Merged
sungjunlee merged 1 commit into
mainfrom
spec/multitrack-capability-amend
Jul 12, 2026
Merged

spec: amend capabilities singleton invariant to track disjointness (#294)#308
sungjunlee merged 1 commit into
mainfrom
spec/multitrack-capability-amend

Conversation

@sungjunlee

Copy link
Copy Markdown
Owner

Summary

#294 (Phase 1e, HUMAN-GATED) — the spec-grill amendment pass for the multi-track invariant flip, run 2026-07-12 on explicit operator instruction. This is the governance step that lets #295 flip the SKILL/process prose.

Governed edits (spec/capabilities.md, via spec-grill)

Contract line Change
sprint-execution Expected Behavior 1 "Exactly one sprint file with status: active … concurrent actives fail loud" → no two active tracks with overlapping scope (one shared scopesOverlap predicate: component: equality / scope: path-prefix collision; fail-loud surfaces named); disjoint tracks coexist as a portfolio; single active unchanged; scopeless pairs = informational warn
backlog-sync sprint-mirror behavior "exits non-zero when there is no single unambiguous active sprint" → per-track mirror semantics: one track needs no flag, a portfolio requires --track (refuses naming tracks), no-match/zero exit non-zero, never guesses, still single-parser
Header component: prose single-slug routing kept; now also documented as the track-scope key (one axis per track, never both — D1)

Append-only ### Decisions rows added in both capabilities recording the flip and what it supersedes. In-scope bullets updated to name the track key and resolve_track.

Descriptive prose (not governed)

spec/system-map.md Core Flows 4/5 de-singularized (--track selection noted). Note: the :36 line cited in the issue ("writes one active file…") no longer existed — the tracker-adapter refactor rewrote system-map.md; Flows 4/5 were the surviving singular-active phrasing.

Compatible, unchanged

charter.md O1 (single execution state) untouched, per the issue.

3-axis predicate check

  • Authority: fail-loud-on-overlap + mirror-never-guesses encode the intent (no silent collision, no guessed selection).
  • Distributional: predicates are defined over frontmatter, environment-independent.
  • Manipulability: both predicates name the single shared scopesOverlap implementation, structurally guarded by the enforced smoke gates GATE_MT_DISJOINT/GATE_MT_OVERLAP and the G4 byte-identity fixtures.

Verification

Refs #294, #289. Unblocks #295.

🤖 Generated with Claude Code

)

Human-gated spec-grill pass (run 2026-07-12 on operator instruction) —
the three governed capabilities.md edits from #294:

- sprint-execution Expected Behavior: "exactly one status: active sprint"
  → "no two active tracks with overlapping scope" via the one shared
  scopesOverlap predicate; disjoint tracks coexist as a portfolio,
  single-track behavior unchanged, scopeless pairs warn informationally.
- backlog-sync sprint-mirror predicate: "exits non-zero when there is no
  single unambiguous active sprint" → per-track mirror semantics
  (--track selects; portfolio without --track refuses naming tracks).
- Header component: prose: single-slug routing kept, now also documented
  as the track's scope key (component: equality, else scope: globs —
  one axis per track, never both).
- Decisions rows appended in sprint-execution and backlog-sync recording
  the invariant flip and its supersession.

Descriptive (non-governed) prose: system-map Core Flows 4/5 lose the
singular-active phrasing (--track selection noted). The :36 line cited
in #294 no longer existed after the tracker-adapter refactor rewrote
system-map.md; Flows 4/5 were the surviving equivalent.

3-axis check: predicates are frontmatter-defined (distribution-safe),
name the single shared implementation guarded by enforced smoke gates
GATE_MT_DISJOINT/GATE_MT_OVERLAP (manipulation-resistant), and encode
fail-loud-on-overlap + never-guess intent (authority). Doctor: all 8
checks pass, capability spec within budget (5 capabilities, 198 lines);
smoke 187/187.

Refs #294, #289. Unblocks #295.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@sungjunlee, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 18 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 61f194d1-3634-4c8f-9516-4e9050ac0d8e

📥 Commits

Reviewing files that changed from the base of the PR and between fa97ab5 and 1d0200d.

📒 Files selected for processing (3)
  • backlog/sprints/2026-07-multi-track-sprints.md
  • spec/capabilities.md
  • spec/system-map.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch spec/multitrack-capability-amend

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.

@sungjunlee sungjunlee merged commit e5c61de into main Jul 12, 2026
2 checks passed

@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: 1d0200dd41

ℹ️ 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".

Comment thread spec/capabilities.md

### Expected Behaviors
- Exactly one sprint file with `status: active` exists per `backlog/sprints/` at all times — concurrent actives fail loud (find_active_sprint surfaces the conflict).
- No two sprint files with `status: active` declare overlapping scope — overlap fails loud through the one shared `scopesOverlap` predicate (`component:` equality or `scope:` path-prefix collision; surfaced by `sprint-init` refusal, `sprint-state` `OVERLAPPING_TRACKS`, and the doctor's `Active tracks overlap on scope` verdict). Disjoint-scope tracks coexist as a portfolio; a single active track behaves exactly as before; two scopeless actives cannot be proven disjoint and surface an informational doctor warning.

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 Guard mixed scope axes before promising disjointness

When one active track uses component: and another uses scope:, the implementation does not run either equality or prefix overlap check (scopesOverlap falls through to false, and the doctor only warns when both tracks are scopeless), so backlog-doctor reports mixed-axis portfolios as scopes disjoint. This new invariant promises active overlap is fail-loud and only documents two scopeless tracks as uncertain, so users can mix axes and lose the promised warning/failure. Please either require a single portfolio-wide axis or document/implement a mixed-axis warning.

Useful? React with 👍 / 👎.

sungjunlee added a commit that referenced this pull request Jul 12, 2026
…schema 2 (#295) (#309)

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