Skip to content

feat: sub-issue lifecycle model — the feature stops auto-closing (ADR 0005)#41

Merged
norrietaylor merged 2 commits into
mainfrom
feat/sub-issue-lifecycle
May 19, 2026
Merged

feat: sub-issue lifecycle model — the feature stops auto-closing (ADR 0005)#41
norrietaylor merged 2 commits into
mainfrom
feat/sub-issue-lifecycle

Conversation

@norrietaylor
Copy link
Copy Markdown
Owner

Problem

Two end-to-end runs showed the feature tracking issue auto-closing mid-pipeline. sdd-spec's spec PR and sdd-triage's architecture PR reference the tracking issue, and the agent slipped a closing keyword for it — Closes #2 in run 1, Fixes #17 in run 2 — despite ADR 0004's prompt rule forbidding exactly that. A prompt rule has failed twice. The fix has to be structural.

Model (ADR 0005)

A feature is a tree of sub-issues:

Feature tracking issue        kind:feature, sdd:* lifecycle anchor, human-closed
├── spec sub-issue            sdd-spec creates it
├── architecture sub-issue    sdd-triage phase A creates it
└── Unit sub-issue  (×N)      sdd-triage phase B creates one per demoable unit
    └── task sub-issue        sdd-triage phase C; impl PR `Closes` it

No pull request ever names the feature tracking issue with a closing keyword. A slipped Closes/Fixes now closes the correct sub-issue, not the feature — the failure mode is removed structurally, not re-worded.

Changes

  • sdd-spec — gains create-issue, link-sub-issue, update-issue. Creates the spec sub-issue; closes it when the spec PR merges. The spec PR closes nothing.
  • sdd-triage — gains update-issue. Phase A creates the architecture sub-issue (arch PR closes nothing); phase B closes it; phase C nests each task under its Unit, not the feature.
  • sdd-execute ×3 — gains update-issue. Step 8 closes a Unit when its task sub-issues are all closed, and moves the feature to sdd:done once the spec, architecture, and every Unit sub-issue is closed. A human still does the final close (ADR 0001).

Closing uses the update-issue safe-output with status enabled (verified against gh-aw pkg/workflow/update_issue.go). The leaf task sub-issue still closes via its implementation PR's Closes #<task> — the one correct closing keyword, because the task pre-exists the PR.

Acceptance

gh aw compile — 0 errors, all update-issue safe-outputs compiled into the locks. markdownlint — clean. End-to-end validation on a fixture is the next step.

🤖 Generated with Claude Code

… 0005)

Two end-to-end runs showed the feature tracking issue auto-closing
mid-pipeline: sdd-spec's and sdd-triage's pull requests reference it and the
agent slipped a closing keyword (Closes #N, then Fixes #N) despite the prompt
rule forbidding it. A prompt rule failed twice; the fix is structural.

A feature is now a tree of sub-issues (ADR 0005): a spec sub-issue, an
architecture sub-issue, and one Unit sub-issue per demoable unit, with task
sub-issues nested under their Unit. Every pull request closes its own
sub-issue; no pull request ever names the feature with a closing keyword, so a
slipped Closes/Fixes closes the correct sub-issue rather than the feature.

- sdd-spec gains create-issue, link-sub-issue, update-issue: it creates the
  spec sub-issue, and closes it when the spec pull request merges.
- sdd-triage gains update-issue: phase A creates the architecture sub-issue,
  phase B closes it, phase C nests each task sub-issue under its Unit.
- sdd-execute gains update-issue: step 8 closes a Unit once its task
  sub-issues are all closed, and moves the feature to sdd:done once the spec,
  architecture, and every Unit sub-issue is closed. A human still does the
  final close of the feature (ADR 0001).

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

coderabbitai Bot commented May 19, 2026

Review Change Stack

Warning

Rate limit exceeded

@norrietaylor has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 48 minutes and 56 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 20f631fe-1376-4d61-8d4e-efd1e4ef2eb3

📥 Commits

Reviewing files that changed from the base of the PR and between 5f17698 and 343c70c.

📒 Files selected for processing (6)
  • .github/workflows/sdd-execute-haiku.lock.yml
  • .github/workflows/sdd-execute-haiku.md
  • .github/workflows/sdd-execute-opus.lock.yml
  • .github/workflows/sdd-execute-opus.md
  • .github/workflows/sdd-execute-sonnet.lock.yml
  • .github/workflows/sdd-execute-sonnet.md
📝 Walkthrough

Walkthrough

This PR establishes a sub-issue lifecycle model for feature tracking and integrates the update_issue safe-output capability across all SDD agent workflows. The change clarifies which issues agents may close (Unit and architecture sub-issues only), introduces explicit sub-issue creation and management in the spec and triage workflows, and restructures task decomposition to a nested Feature → Unit → task hierarchy.

Changes

Sub-issue lifecycle and agent integration

Layer / File(s) Summary
Sub-issue lifecycle model architecture decision
decisions/0005-sub-issue-lifecycle-model.md
Introduces ADR 0005 defining a tree structure for feature tracking issues, prohibiting sdd-* PRs from closing the feature root, requiring per-deliverable closure via update-issue safe-output, and documenting verification/consequences across all workflows.
Execute workflows: Unit completion and update_issue support
.github/workflows/sdd-execute-{haiku,opus,sonnet}.lock.yml, .github/workflows/sdd-execute-{haiku,opus,sonnet}.md
All three execution tiers add update_issue to safe-output tools and clarify completion semantics: agents close completed Unit sub-issues, transition Features to sdd:done with needs-human hand-off, never close the feature tracking issue, and never directly close task sub-issues.
Spec workflow: spec sub-issue lifecycle
.github/workflows/sdd-spec.lock.yml, .github/workflows/sdd-spec.md
Extends sdd-spec to create a spec sub-issue (reusing on /revise), open exactly one PR with strict referencing (bare #<number>), close the sub-issue via update_issue on PR merge, then advance to sdd:triage. Adds created_issue_number and created_issue_url outputs.
Triage workflow: architecture sub-issue and nested task structure
.github/workflows/sdd-triage.lock.yml, .github/workflows/sdd-triage.md
Introduces architecture sub-issue creation in Phase A (reusing on /revise), closure in Phase B after PR merge, and changes task decomposition to nest implementation sub-tasks under Unit issues (not the tracking issue), establishing Feature → Unit → task hierarchy.

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • norrietaylor/spectacles#16: Implements the initial sdd-spec agent workflows whose sub-issue creation and closure behavior is directly extended by this PR.
  • norrietaylor/spectacles#18: Implements the sdd-triage workflow whose architecture sub-issue lifecycle and nested task structure are defined by this PR's changes.

Poem

🐰 A rabbit hops through issues and sub-trees,
Closes the Unit leaves, leaves the Feature free,
Architecture scaffolds nest task by task,
Safe outputs seal each sub-issue's last ask. 🌳

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changeset does not address the coding requirements from linked issues #2 and #17. Issue #2 requires labels.yml, issue templates, shared/sdd-interaction.md, and docs/sdd/index.md updates. Issue #17 requires shared/sdd-gates.md. None of these files appear in the changeset. Add required files from issues #2 and #17: labels.yml updates, issue templates (feature/bug/chore), shared/sdd-interaction.md, docs/sdd/index.md, and shared/sdd-gates.md. Ensure markdownlint compliance and test with a feature template issue.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: sub-issue lifecycle model — the feature stops auto-closing (ADR 0005)' clearly and concisely summarizes the main change: introducing a structural fix to prevent feature tracking issues from auto-closing by implementing a sub-issue lifecycle model defined in ADR 0005.
Description check ✅ Passed The description clearly relates to the changeset, explaining the problem (auto-closing features), the proposed model (feature-as-tree of sub-issues), detailed changes across all affected workflows, and acceptance criteria. It provides comprehensive context for the changes.
Out of Scope Changes check ✅ Passed All changes are in-scope: workflow files (sdd-execute, sdd-spec, sdd-triage) are updated to implement the sub-issue lifecycle model, and decisions/0005-sub-issue-lifecycle-model.md establishes the architectural decision. No unrelated or extraneous changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sub-issue-lifecycle

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 @.github/workflows/sdd-execute-haiku.md:
- Around line 306-308: Step 8 currently instructs performing "each" satisfied
transition in one run but conflicts with the workflow's safe-output caps (the
update-issue and add-comment actions are capped at 1). Update the Step 8 text to
require performing satisfied transitions only up to the workflow's safe-output
limits (or explicitly "perform at most one update-issue and at most one
add-comment per run"), leaving remaining satisfied transitions for the next run;
reference the Step 8 rule and the actions named update-issue and add-comment so
the wording aligns with those caps.

In @.github/workflows/sdd-execute-opus.md:
- Around line 306-308: Update the Step 8 text to reflect current tool
limitations: clarify that although multiple transitions may be satisfiable, the
runner can only perform one update-issue and one add-comment call per run, so it
should process at most one completed Unit (or perform only the first satisfiable
transition) and leave remaining transitions for subsequent runs; reference the
Step 8 description and the operations named update-issue and add-comment so
maintainers know to either implement batching support or explicitly limit each
run to a single transition.

In @.github/workflows/sdd-execute-sonnet.md:
- Around line 55-58: The completion-loop wording requires doing "each satisfied
transition in one run" but the `update-issue` action is capped at `max: 1`,
causing a mismatch; change the completion-loop instructions (the text around the
completion-loop / "perform each satisfied transition" sentence) to
single-transition-per-run semantics (e.g., "perform at most one satisfied
transition per run") so it matches the `update-issue` setting, and keep
`update-issue: max: 1` as the intended single-transition-per-run behavior;
update the text references to transitions in the same section so they no longer
imply multiple transitions per run.
🪄 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: 25e1167c-93ef-4937-98b2-3be96e4a51fa

📥 Commits

Reviewing files that changed from the base of the PR and between 3506a82 and 5f17698.

📒 Files selected for processing (11)
  • .github/workflows/sdd-execute-haiku.lock.yml
  • .github/workflows/sdd-execute-haiku.md
  • .github/workflows/sdd-execute-opus.lock.yml
  • .github/workflows/sdd-execute-opus.md
  • .github/workflows/sdd-execute-sonnet.lock.yml
  • .github/workflows/sdd-execute-sonnet.md
  • .github/workflows/sdd-spec.lock.yml
  • .github/workflows/sdd-spec.md
  • .github/workflows/sdd-triage.lock.yml
  • .github/workflows/sdd-triage.md
  • decisions/0005-sub-issue-lifecycle-model.md

Comment thread .github/workflows/sdd-execute-haiku.md Outdated
Comment thread .github/workflows/sdd-execute-opus.md Outdated
Comment thread .github/workflows/sdd-execute-sonnet.md
CodeRabbit flagged that step 8 told the agent to perform every satisfied
completion transition in one run, but the update-issue and add-comment
safe-outputs are each capped at max 1 — so two completed Units could not both
be closed in a single run, and the agent could emit an over-cap, invalid
output plan.

Step 8 now performs exactly one transition per run — feature completion
first, otherwise the oldest completed Unit — and leaves the rest for
subsequent runs, which fits the one-call cap.

Co-Authored-By: Claude Opus 4.7 (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