Skip to content

feat(sdd): fast-path for single-session features (#82)#101

Merged
norrietaylor merged 8 commits into
mainfrom
feat/82-fastpath
May 20, 2026
Merged

feat(sdd): fast-path for single-session features (#82)#101
norrietaylor merged 8 commits into
mainfrom
feat/82-fastpath

Conversation

@norrietaylor
Copy link
Copy Markdown
Owner

Summary

Add a fast-path lane to the SDD pipeline for tracking issues that fit a one-session change (one or two files, no new dependency, no schema change, no new public API, no cross-cutting concern, no test scaffolding). The classifier in sdd-spec proposes /fastpath; on confirmation one agent run produces a structurally-complete stub spec PR plus an execution-plan comment on the tracking issue; /approve then dispatches a single sdd-execute-{tier} against the comment with no Unit or task sub-issue tree created. /dispatch is a noop on fast-path issues. ADR 0012 records the four decisions.

Stack

This PR is based on feat/81-dispatch-cascade (PR #97), which is based on feat/79-plan-comment-before-tree (PR #92). Merge order: #92#97 → this PR.

Changes

  • New ADR decisions/0012-fastpath.md (cross-links 0001, 0005, 0010, 0011).
  • Two new lifecycle labels: sdd:fastpath, sdd:fastpath-review. Both are exclusive with the existing sdd:* lifecycle labels.
  • sdd-spec.md: classifier step (six heuristics), proposal-only branch, fast-path authoring branch that produces a stub spec PR + execution plan comment in one run, and the <!-- sdd-spec:fastpath-plan --> sentinel for the comment. New /spec reset-from-fastpath semantics.
  • wrappers/sdd-spec.yml: handles /fastpath (passes command: 'fastpath' to the agent) and /approve on fast-path issues (deterministic fastpath-approve job: find sentinel comment, parse model:* tier, mint App token, dispatch sdd-execute-{tier}.yml with entry: 'fastpath', move sdd:fastpath → sdd:in-progress). Follows sdd-dispatch: add /dispatch on the tracking issue to cascade task execution with bounded parallelism; remove daily cron #81's wrapper-heavy deterministic pattern.
  • sdd-execute-{haiku,sonnet,opus}.md: new fast-path entry (entry: 'fastpath') reads the plan comment, runs against the tracking issue, and a misclassification-escalation step (needs-human with named failed heuristics). The wrappers add pull_request.closed to detect a merged fast-path implementation PR and re-fire the agent with entry: 'fastpath-complete' to move sdd:in-progress → sdd:done.
  • wrappers/sdd-triage.yml: carve-out so /approve on a sdd:fastpath issue is left to sdd-spec's wrapper.
  • wrappers/sdd-dispatch.yml + sdd-dispatch.md: noop branch for fast-path tracking issues (post one comment pointing at /approve; do not arm sdd:dispatched).
  • sdd-validate.md, sdd-review.md: fast-path awareness — the absence of an architecture record and a sub-task tree is not a finding on a fast-path issue; spec context resolves from the stub spec and the plan comment.
  • shared/sdd-interaction.md: lifecycle state machine extended with two fast-path states and one re-entry edge; command vocabulary adds /fastpath and restates /approve and /dispatch per path.
  • Issue templates (feature.md, bug.md): a "One-session change?" prose prompt pointing the reporter at /fastpath. GitHub Markdown templates do not support conditional labels, so the template prompts the user rather than applying sdd:fastpath automatically (recorded in ADR 0012 reasoning).
  • docs/sdd/index.md: new s_fast mermaid subgraph branching from s_spec, plus a parallel "Fast-path steps" table.
  • Spec 01-spec-issue-native-sdd.md: new Unit 12 with R12.1–R12.12 (continues sdd-dispatch: add /dispatch on the tracking issue to cascade task execution with bounded parallelism; remove daily cron #81's Unit-11 convention; renumbered against issue body's R8 framing per the issue note). R4.8 added to cross-reference.
  • All .lock.yml regenerated via gh aw compile.

Acceptance (high level)

  • Issue body fitting all six heuristics → one proposal comment, no spec PR. Lifecycle stays at sdd:spec.
  • /fastpath → one stub spec PR (problem, R-ID, proof artifacts, one Unit, fast-path note) + one execution plan comment. Lifecycle sdd:fastpath-review.
  • Merge stub PR → lifecycle returns to sdd:fastpath, comment points at /approve.
  • /approve → dispatches matching sdd-execute-{tier}, no sub-issues created, lifecycle sdd:in-progress.
  • Merge implementation PR → sdd:done + needs-human for the human's final close.
  • /dispatch on fast-path → one noop comment, sdd:dispatched not applied.
  • Misclassification during execution → needs-human with named failed heuristic(s); /spec resets to sdd:spec.
  • sdd-validate and sdd-review run cleanly against a fast-path issue.

Verification

  • gh aw compile — 0 errors, 0 warnings.
  • npx --yes markdownlint-cli2 "**/*.md" — 0 errors.
  • actionlint on all hand-authored wrappers — clean.
  • shellcheck on scripts/*.sh — clean.

References

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 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 7 minutes and 29 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: deb17edc-861e-4790-b6d8-bb08d7337230

📥 Commits

Reviewing files that changed from the base of the PR and between 88f38b7 and 846019f.

📒 Files selected for processing (9)
  • .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
  • wrappers/sdd-execute-haiku.yml
  • wrappers/sdd-execute-opus.yml
  • wrappers/sdd-execute-sonnet.yml
📝 Walkthrough

Walkthrough

Adds ADR-0012 fast-path: new lifecycle labels, sdd-spec fast-path classification/stub-spec + plan-comment sentinel, wrappers and sdd-execute agents supporting entry: fastpath and fastpath-complete, /dispatch noop short-circuit for fast-path issues, Safe Outputs allowlist updates, regenerated prompt/heredoc IDs, and docs/templates updates.

Changes

Fast-path pipeline implementation

Layer / File(s) Summary
Fast-path end-to-end changes
wrappers/*, .github/workflows/*, decisions/0012-fastpath.md, scripts/lifecycle-states.yml, templates/.github/*, docs/*, shared/sdd-interaction.md
Implements ADR-0012: adds sdd:fastpath / sdd:fastpath-review labels; sdd-spec fast-path classification, proposal, stub-spec PR and execution-plan comment sentinel; fastpath-approve dispatch path to sdd-execute-{tier} with aw_context.entry: fastpath; sdd-execute agents handle fast-path selection, misclassification escalation, PR conventions, and fastpath-complete; sdd-dispatch and related wrappers short-circuit /dispatch for fast-path (deterministic noop comment); Safe Outputs allowlists expanded and generated prompt/heredoc identifiers regenerated; docs and issue templates updated.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

"A rabbit's nibble on fast-path lore,
Stub specs sprout, the pipeline's less chore,
One plan, one approve, a tidy run,
Dispatch stays quiet when the fast-path's begun,
Hooray — lighter hops and fewer hops! 🐰"

@norrietaylor norrietaylor force-pushed the feat/81-dispatch-cascade branch from 53228ad to 8511dbd Compare May 20, 2026 22:23
@norrietaylor norrietaylor force-pushed the feat/82-fastpath branch 2 times, most recently from 16303fe to f761d1e Compare May 20, 2026 22:49
@norrietaylor
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

✅ Actions performed

Full review triggered.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
wrappers/sdd-execute-sonnet.yml (1)

338-423: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Tier gate can incorrectly skip fast-path PR review/revise runs.

For PR-driven triggers, ctx.entry is unset, so this block applies the non-fastpath model:sonnet gate to the issue parsed from sdd/<tracking>-.... Fast-path tracking issues generally aren’t model:* labeled, so the run is dropped before the agent can process review comments.

Suggested wrapper-side guard
+            // Detect fast-path PRs for review/revise flows and mark entry so
+            // tier gating is bypassed consistently.
+            if (run && !ctx.entry && ctx.item_type === 'pull_request') {
+              // resolve PR head ref -> sdd/<n>-...
+              // fetch issue `#n`; if tracking-issue-shaped fast-path, set:
+              // ctx.entry = 'fastpath'
+            }
+
             const fastpathEntry = ctx && (
               ctx.entry === 'fastpath' || ctx.entry === 'fastpath-complete');
🤖 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 `@wrappers/sdd-execute-sonnet.yml` around lines 338 - 423, The non-fastpath
tier gate runs for PR-driven triggers because ctx.entry is unset; change the
guard so the tier-check block only runs when there is no pull request payload.
Concretely, update the condition around the big tier-check block (the if that
currently reads "if (run && !fastpathEntry) {") to also require that
payload.pull_request is falsy (e.g. "if (run && !fastpathEntry &&
!payload.pull_request) {"), so functions like the PR body/ref extraction and the
issue-label check (logic around taskIssue, prBody/prHeadRef, and the
github.rest.issues.get label inspection) are skipped for PR-driven events.
wrappers/sdd-execute-opus.yml (1)

338-423: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Tier gate drops fast-path PR review/revise events.

For PR-triggered runs, Line 386/Line 396 derive the referenced issue and Line 410 requires model:opus on that issue. Fast-path PRs intentionally reference a tracking issue (not a task) and do not carry Closes #<task>, so this path resolves to a non-model:* item and Line 417 disables the run. Result: review-comment and /revise follow-ups on fast-path implementation PRs are skipped.

🤖 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 `@wrappers/sdd-execute-opus.yml` around lines 338 - 423, The tier gating logic
in the "if (run && !fastpathEntry)" branch is incorrectly rejecting fast-path PR
review/revise events; update that branch to skip the issue-label/tier check when
the run is a pull_request related to a fast-path variant (e.g., detect
payload.pull_request && ctx.entry && ctx.entry.startsWith('fastpath') or
similar) so it does not attempt to derive taskIssue or call
github.rest.issues.get for fast-path PRs; keep the existing behavior for
non-fastpath runs and continue to use TIER, ctx.item_type, ctx.item_number and
github.rest.issues.get for normal cases.
🧹 Nitpick comments (3)
decisions/0012-fastpath.md (2)

278-281: ⚡ Quick win

Consider clarifying the command sequence for fast-path entry.

The fast-path sequence shows /spec → /fastpath, but this might confuse readers because /spec is not a manual command in the typical case — it's auto-applied by the feature/bug template as the sdd:spec label. A human who knows the work is small either:

  • Waits for the agent's proposal, then comments /fastpath, or
  • Comments /fastpath immediately after opening (skipping the proposal).

Consider rewording to make it clear that the tracking issue starts with sdd:spec (from the template), not from a manual /spec command. For example:

Full path:  (sdd:spec) → /triage → /approve → /dispatch → cascade → /merge → /close
Fast path:  (sdd:spec) → /fastpath → merge-stub → /approve → dispatch-one → /merge → /close

Or add a note below the table explaining that sdd:spec is auto-applied by the template.

🤖 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 `@decisions/0012-fastpath.md` around lines 278 - 281, Update the fast-path
sequence wording so it reflects that the tracking issue begins with the sdd:spec
label (auto-applied by the feature/bug template) rather than a manual "/spec"
command: replace "/spec" with "(sdd:spec)" in both the Full path and Fast path
lines of the table (or alternatively keep "/spec" but add a short note
immediately below the table explaining that "sdd:spec" is automatically applied
by the template and not a user-issued "/spec" command); ensure you update the
exact lines that read "Full path:  /spec → ..." and "Fast path:  /spec → ..."
(refer to the existing strings /spec, sdd:spec, and /fastpath to locate the
changes).

248-248: 💤 Low value

Minor style: Capitalize "GitHub".

The word "github" in the path should be "GitHub" (capital H) for consistency with the official brand name.

✏️ Suggested fix
-- Two new lifecycle labels join `templates/.github/labels.yml`:
+- Two new lifecycle labels join `templates/.GitHub/labels.yml`:
🤖 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 `@decisions/0012-fastpath.md` at line 248, In the sentence that reads "Two new
lifecycle labels join `templates/.github/labels.yml`:" change the lowercase
token "github" to the official casing "GitHub" so the inline code snippet
becomes `templates/.GitHub/labels.yml`; update that exact snippet in the
document (look for the line starting "Two new lifecycle labels join") to correct
the capitalization.
templates/.github/ISSUE_TEMPLATE/feature.md (1)

30-30: ⚡ Quick win

Consider feature-oriented examples instead of "bugfix" in the feature template.

Line 30 says "a single-symbol bugfix" but this is the feature template. Consider using feature-oriented examples like "a label-color update," "a single-field addition," or "a small config change" instead of "bugfix" to better match the template's purpose.

✏️ Suggested rewording
-If this looks like a one-file copy change, a single-symbol bugfix, or
+If this looks like a one-file copy change, a label-color update, or
 similarly small, comment `/fastpath` on this issue after opening it. The
🤖 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 `@templates/.github/ISSUE_TEMPLATE/feature.md` at line 30, Replace the phrase
"a single-symbol bugfix" in the feature template with feature-oriented examples
to match the template's purpose; locate the string "a single-symbol bugfix" in
templates/.github/ISSUE_TEMPLATE/feature.md and change it to alternatives such
as "a label-color update", "a single-field addition", or "a small config change"
(or similar short feature-focused examples) and ensure the surrounding sentence
reads naturally with the new examples.
🤖 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 375-381: Update the fast-path ownership check described in "step
7" so it recognizes the fast-path branch naming convention
sdd/<tracking-issue>-<slug> and a bare tracking reference #<tracking> as
sufficient ownership instead of requiring a "Closes #<task>" token; change the
logic or prose that currently mandates "Closes #<task>" (the rules referenced
around lines 395-398 / step 7) to accept either a task-closing token for normal
flows or the fast-path branch name + bare tracking issue for fast-path flows,
ensuring fast-path PRs that omit "Closes #<tracking>" are not rejected.

In @.github/workflows/sdd-execute-opus.md:
- Around line 55-56: The workflow currently disallows removal of the
sdd:fastpath-review label while the transition logic expects to move from
sdd:fastpath (e.g., the lifecycle rule "sdd:fastpath → sdd:in-progress" at the
transition definitions) which can leave duplicate labels; update the allowed
label lists (the "allowed: [...]" arrays that currently contain sdd:ready,
sdd:review, sdd:fastpath, sdd:in-progress) to also include "sdd:fastpath-review"
and/or change the fast-path lifecycle transition entries to explicitly use
"sdd:fastpath-review → sdd:in-progress" so that the workflow can legally remove
the review label during the fast-path approval flow (make the change in the same
sections where the allowed arrays and the fast-path transition rules are
defined).
- Around line 375-386: Step 7's ownership check currently requires the PR body
to include "Closes #<task>", which breaks fast-path PRs that use branch names
like "sdd/<tracking>-<slug" and a bare "#<tracking>" reference; update the
ownership/validation logic (the code invoked by sdd-pr-sanitize and the step-7
check used by /revise handlers) to recognize fast-path indicators as valid
ownership: accept a bare "#<tracking>" reference, or infer ownership from the
branch name pattern "sdd/<tracking>-<slug" and the PR next-step line ("merging
this pull request advances the tracking issue...") in addition to the existing
"Closes #<task>" rule so that fast-path PRs pass ownership checks without a
closing keyword.

In @.github/workflows/sdd-execute-sonnet.md:
- Around line 375-386: The ownership heuristic still looks for a "Closes
#<task>" token (step 7) so fast-path PRs that use the branch convention
sdd/<tracking>-<slug> and reference the tracking issue as a bare "#<tracking>"
are misclassified; update the ownership detection (the logic in step 7 and/or
sdd-pr-sanitize) to also recognize fast-path PRs by (a) the branch name pattern
sdd/<tracking>-<slug> and a bare "#<tracking>" mention in the PR body, or (b)
explicitly accept bare "#<tracking>" when no task-subissue is present, so
agent-owned fast-path PRs are handled correctly instead of falling through to
noop.

In @.github/workflows/sdd-review.md:
- Around line 127-129: The fast-path sentinel is written as an HTML comment
(`<!-- sdd-spec:fastpath-plan -->`) which can be stripped during compilation;
change the sentinel to a plain-text marker (e.g., `sdd-spec:fastpath-plan` or a
bracketed/tokenized variant like `[sdd-spec:fastpath-plan]`) in the
documentation and update any detection logic that looks for `<!--
sdd-spec:fastpath-plan -->` so it instead searches for the new plain marker
string (reference the existing sentinel token and any code that parses plan
comments to ensure both doc and detection use the same new marker).

In @.github/workflows/sdd-spec.lock.yml:
- Around line 720-721: The compiled prompt is stripping the sentinel `<!--
sdd-spec:fastpath-plan -->` because it's included as raw inline code; edit the
Markdown source to encode the marker inside inline code using HTML entities
(e.g. use `&lt;!-- sdd-spec:fastpath-plan --&gt;` inside the backticks where the
sentinel appears) so the compiler preserves it, apply the same change to all
other occurrences of that sentinel, and then re-run `gh aw compile`.

In @.github/workflows/sdd-validate.md:
- Around line 182-184: The sentinel `<!-- sdd-spec:fastpath-plan -->` can be
removed by compilers; change the fast-path plan sentinel to a literal,
non-comment token (e.g. `SDD_SPEC_FASTPATH_PLAN:` or
`[[sdd-spec:fastpath-plan]]`) throughout the spec and update any lookup code
that searches for `<!-- sdd-spec:fastpath-plan -->` to search for the new
literal token instead so plan resolution remains deterministic; ensure the
README/docs and any parser/regex that referenced the HTML comment (the fast-path
plan lookup) are updated to the new marker.

In `@scripts/lifecycle-states.yml`:
- Around line 63-67: Add reset edges from the fast-path states back to sdd:spec
so misclassified items can be reset; specifically update the transitions for
sdd:fastpath and sdd:fastpath-review to include sdd:spec as a valid target
(e.g., add sdd:spec to the arrays for sdd:fastpath and sdd:fastpath-review) so
both fast-path states legally transition back to the sdd:spec state.

In `@shared/sdd-interaction.md`:
- Line 30: The table row for the fast-path `sdd:in-progress` is inconsistent
with the state machine: replace the `sdd-spec` writer with `sdd-execute` so the
row reads that `sdd-execute` sets `sdd:in-progress` for the fast path (matching
the lifecycle-states.yml source); keep the rest of the cell (trigger `/approve`
for fast path vs `sdd-dispatch` on first `/dispatch` for full path) unchanged.

In `@wrappers/sdd-spec.yml`:
- Around line 86-88: The labeled-event branch currently sets run = true for
action === 'labeled' when label is 'sdd:spec' or 'sdd:fastpath', which
incorrectly routes manually labeled sub-issues; modify the condition in that
branch (the check that sets run) to include the same parent/tracking-issue check
used by the 'needs-human' unlabeled logic so that 'sdd:fastpath' only triggers
when the issue is a tracking/parent issue—i.e., add the parent/tracking issue
existence check to the action === 'labeled' && label === 'sdd:fastpath' path so
only tracking issues proceed to sdd-spec.
- Line 417: The current fallback ref "refs/heads/main" in the assignment ref:
context.ref || 'refs/heads/main' risks using a non-existent branch; replace this
by either removing the fallback so ref is required (i.e., keep ref: context.ref)
or implement a lookup to the repository default branch via the GitHub API when
context.ref is falsy: call the REST/GraphQL API to retrieve
repository.default_branch and set ref to `refs/heads/{default_branch}`. Update
the code around the ref assignment (the expression ref: context.ref ||
'refs/heads/main') to use the API result or no fallback, and ensure the API call
handles errors and caching to avoid repeated requests.

In `@wrappers/sdd-triage.yml`:
- Around line 125-126: The carve-out currently checks only for
labels.includes('sdd:fastpath') and therefore misses issues in
'sdd:fastpath-review'; update the condition that sets skipFastpath so it also
detects 'sdd:fastpath-review' (e.g. change the test to check for either label
using labels.includes('sdd:fastpath') || labels.includes('sdd:fastpath-review')
or labels.some(l => ['sdd:fastpath','sdd:fastpath-review'].includes(l))),
ensuring the same skipFastpath assignment is used when either label is present.

---

Outside diff comments:
In `@wrappers/sdd-execute-opus.yml`:
- Around line 338-423: The tier gating logic in the "if (run && !fastpathEntry)"
branch is incorrectly rejecting fast-path PR review/revise events; update that
branch to skip the issue-label/tier check when the run is a pull_request related
to a fast-path variant (e.g., detect payload.pull_request && ctx.entry &&
ctx.entry.startsWith('fastpath') or similar) so it does not attempt to derive
taskIssue or call github.rest.issues.get for fast-path PRs; keep the existing
behavior for non-fastpath runs and continue to use TIER, ctx.item_type,
ctx.item_number and github.rest.issues.get for normal cases.

In `@wrappers/sdd-execute-sonnet.yml`:
- Around line 338-423: The non-fastpath tier gate runs for PR-driven triggers
because ctx.entry is unset; change the guard so the tier-check block only runs
when there is no pull request payload. Concretely, update the condition around
the big tier-check block (the if that currently reads "if (run &&
!fastpathEntry) {") to also require that payload.pull_request is falsy (e.g. "if
(run && !fastpathEntry && !payload.pull_request) {"), so functions like the PR
body/ref extraction and the issue-label check (logic around taskIssue,
prBody/prHeadRef, and the github.rest.issues.get label inspection) are skipped
for PR-driven events.

---

Nitpick comments:
In `@decisions/0012-fastpath.md`:
- Around line 278-281: Update the fast-path sequence wording so it reflects that
the tracking issue begins with the sdd:spec label (auto-applied by the
feature/bug template) rather than a manual "/spec" command: replace "/spec" with
"(sdd:spec)" in both the Full path and Fast path lines of the table (or
alternatively keep "/spec" but add a short note immediately below the table
explaining that "sdd:spec" is automatically applied by the template and not a
user-issued "/spec" command); ensure you update the exact lines that read "Full
path:  /spec → ..." and "Fast path:  /spec → ..." (refer to the existing strings
/spec, sdd:spec, and /fastpath to locate the changes).
- Line 248: In the sentence that reads "Two new lifecycle labels join
`templates/.github/labels.yml`:" change the lowercase token "github" to the
official casing "GitHub" so the inline code snippet becomes
`templates/.GitHub/labels.yml`; update that exact snippet in the document (look
for the line starting "Two new lifecycle labels join") to correct the
capitalization.

In `@templates/.github/ISSUE_TEMPLATE/feature.md`:
- Line 30: Replace the phrase "a single-symbol bugfix" in the feature template
with feature-oriented examples to match the template's purpose; locate the
string "a single-symbol bugfix" in templates/.github/ISSUE_TEMPLATE/feature.md
and change it to alternatives such as "a label-color update", "a single-field
addition", or "a small config change" (or similar short feature-focused
examples) and ensure the surrounding sentence reads naturally with the new
examples.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: fdf4d3b4-de13-44b6-9859-1efa32af8a9d

📥 Commits

Reviewing files that changed from the base of the PR and between 8e91f6a and f761d1e.

📒 Files selected for processing (28)
  • .github/workflows/sdd-dispatch.lock.yml
  • .github/workflows/sdd-dispatch.md
  • .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-review.lock.yml
  • .github/workflows/sdd-review.md
  • .github/workflows/sdd-spec.lock.yml
  • .github/workflows/sdd-spec.md
  • .github/workflows/sdd-validate.lock.yml
  • .github/workflows/sdd-validate.md
  • decisions/0012-fastpath.md
  • docs/sdd/index.md
  • docs/specs/01-spec-issue-native-sdd/01-spec-issue-native-sdd.md
  • scripts/lifecycle-states.yml
  • shared/sdd-interaction.md
  • templates/.github/ISSUE_TEMPLATE/bug.md
  • templates/.github/ISSUE_TEMPLATE/feature.md
  • templates/.github/labels.yml
  • wrappers/sdd-dispatch.yml
  • wrappers/sdd-execute-haiku.yml
  • wrappers/sdd-execute-opus.yml
  • wrappers/sdd-execute-sonnet.yml
  • wrappers/sdd-spec.yml
  • wrappers/sdd-triage.yml

Comment thread .github/workflows/sdd-execute-haiku.md
Comment thread .github/workflows/sdd-execute-opus.md
Comment thread .github/workflows/sdd-execute-opus.md
Comment thread .github/workflows/sdd-execute-sonnet.md
Comment thread .github/workflows/sdd-review.md
Comment thread shared/sdd-interaction.md Outdated
Comment thread wrappers/sdd-execute-haiku.yml
Comment thread wrappers/sdd-spec.yml
Comment thread wrappers/sdd-spec.yml Outdated
Comment thread wrappers/sdd-triage.yml Outdated
Base automatically changed from feat/81-dispatch-cascade to main May 20, 2026 23:06
Add a fast-path lane for tracking issues that fit a one-session change:
classifier in sdd-spec proposes /fastpath; on confirmation one run
produces a stub spec PR plus an execution-plan comment; /approve
dispatches one sdd-execute-{tier} against the comment with no Unit or
task sub-issue tree. /dispatch is a noop on fast-path issues. ADR 0012.

Closes #82
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: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
wrappers/sdd-execute-sonnet.yml (1)

257-423: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Persist the fast-path tier on the PR itself.

Fast-path review comments and /revise events fall back to the tracking issue number from sdd/<tracking>-…, then the normal tier gate looks for model:sonnet on that tracking issue and skips the run because tracking issues intentionally have no model:* label. fastpath-complete works around that by bypassing the gate entirely, so sibling tier wrappers can also wake on the same merged PR. Carry the selected tier forward on the PR body or a dedicated label and gate both follow-up and completion paths on that marker.

🤖 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 `@wrappers/sdd-execute-sonnet.yml` around lines 257 - 423, The fast-path flow
loses the chosen tier because the wrapper derives the task/tracking issue number
from the PR ref (headRef) but later the tier gate checks the tracking issue for
model:<TIER> which tracking issues intentionally lack; modify the fast-path
dispatch and completion handling so the selected tier is persisted on the PR
(either embed a normalized marker in the PR body like "sdd-tier: <TIER>" or add
a dedicated label such as "sdd-tier:<TIER>") when creating the fastpath entry
(where ctx is set for entry 'fastpath'), and update the fastpath-complete branch
(the code that sets isFastpath / ctx.entry === 'fastpath-complete' and the later
fastpathEntry check) to read that marker from the pull request (via
payload.pull_request.body or labels) and use it instead of consulting the
tracking issue labels so the tier gate correctly accepts or rejects the run.
wrappers/sdd-execute-opus.yml (1)

257-423: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Persist the fast-path tier on the PR itself.

Fast-path review comments and /revise events fall back to the tracking issue number from sdd/<tracking>-…, then the normal tier gate looks for model:opus on that tracking issue and skips the run because tracking issues intentionally have no model:* label. fastpath-complete works around that by bypassing the gate entirely, so sibling tier wrappers can also wake on the same merged PR. Carry the selected tier forward on the PR body or a dedicated label and gate both follow-up and completion paths on that marker.

🤖 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 `@wrappers/sdd-execute-opus.yml` around lines 257 - 423, When detecting a
fast-path merged PR in the headRef / headMatch block (where isFastpath is set
and ctx.entry is 'fastpath' or 'fastpath-complete'), persist the selected tier
onto the PR (e.g. add a label like 'fastpath-tier:<TIER>' or append a hidden
marker to the PR body) via the GitHub REST API so downstream checks can read it;
then update the tier-gate logic (the fastpathEntry check and the subsequent
tier-match code that uses planTier/TIER and the taskIssue label check) to also
inspect the PR's persisted marker for both 'fastpath' and 'fastpath-complete'
flows and only skip the run when the persisted PR tier mismatches this variant's
TIER. Ensure changes reference the same symbols:
headRef/headMatch/refNumber/isFastpath, ctx.entry
('fastpath'/'fastpath-complete'), planTier/TIER, and the tierMatch logic that
reads issue labels.
🤖 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.lock.yml:
- Around line 938-950: Add a durable machine-readable fast-path marker to the PR
body so downstream tooling (e.g., sdd-pr-sanitize and review/revise/completion
routers) can recover the tracking issue and tier; update the PR body generator
to include a stable tag like "sdd-fast-path: tracking=<tracking-number>
tier=<tier-slug>" (or similar JSON/YAML snippet) whenever the fast-path branch
pattern `sdd/<tracking>-<slug>` is detected, ensure sdd-pr-sanitize recognizes
and preserves this marker, and update any parsers that read the PR body to parse
this marker to identify the work item and selected tier reliably.

In @.github/workflows/sdd-execute-haiku.md:
- Around line 55-56: The workflow's removable lifecycle labels omit
"sdd:fastpath-review", causing fast-path /approve transitions to leave multiple
sdd:* labels; update each allowed list (the arrays currently containing
"sdd:ready", "sdd:review", "sdd:in-progress") to also include
"sdd:fastpath-review" wherever label-removal rules appear (the allowed arrays
near the blocks that also reference transitions from "sdd:fastpath"), so that
the remove-label step cleans up "sdd:fastpath-review" on fast-path starts and
produces a single lifecycle label.

In @.github/workflows/sdd-execute-sonnet.md:
- Around line 55-56: The workflow only handles the single label sdd:fastpath but
not sdd:fastpath-review, so update the label lists and removal logic (the YAML
"allowed" array and any steps that remove labels when transitioning to
sdd:in-progress) to include both sdd:fastpath and sdd:fastpath-review; ensure
any rule or step that currently strips sdd:fastpath also strips
sdd:fastpath-review so the prior fast-path-review state cannot remain after
moving to sdd:in-progress.

In @.github/workflows/sdd-spec.md:
- Around line 520-523: Update the verification bullet that currently mandates
"at least one `(informed by` citation" in the Demoable Units section so that the
citation is only required when the spec includes load-bearing retrieval;
specifically, change the bullet text that mentions "Demoable Units" and "at
least one `R1.1` requirement and at least one `(informed by` citation" to
require an `(informed by ...)` citation only if the Demoable Units or R1.1
requirements depend on prior-work retrieval (i.e., are load-bearing); leave the
citation optional/omitted when no load-bearing retrieval is present.
- Around line 80-82: The procedure text "A tracking issue gained the `sdd:spec`
label. Classify the work (step 2 of the procedure)." incorrectly references step
2; update this cross-reference to point to the fast-path classification
definition in step 3a instead. Edit the sentence to read "Classify the work
(step 3a of the procedure)." so the phrase referencing the `sdd:spec` label
correctly directs readers to the fast-path classification rules (step 3a).

In `@docs/specs/01-spec-issue-native-sdd/01-spec-issue-native-sdd.md`:
- Around line 885-910: The document adds "Unit 12: Fast-path for single-session
features and bugs" but leaves downstream count references inconsistent; search
for the literal strings "Units 2 to 11" and "all eleven demoable units" (and any
similar numeric phrases) and update them to refer to Unit 12—e.g. change "Units
2 to 11" → "Units 2 to 12" and "all eleven demoable units" → "all twelve
demoable units" (and update any other ordinal/count wording to include Unit 12)
so the spec's counts and acceptance/verification language remain consistent with
the new header.

In `@scripts/lifecycle-states.yml`:
- Around line 68-69: The lifecycle graph entry for sdd:in-progress only lists
sdd:review as a next state; add sdd:done to its transitions so fast-path
completion is allowed. Update the mapping for the key sdd:in-progress to include
both sdd:review and sdd:done (e.g., sdd:in-progress: [sdd:review, sdd:done]) so
that the state machine recognizes the direct transition to sdd:done.

In `@wrappers/sdd-dispatch.yml`:
- Around line 120-130: The fast-path detection only checks labels for
'sdd:fastpath' and 'sdd:fastpath-review' so issues labeled 'sdd:in-progress' are
misrouted; update the isFastpath logic (the labels mapping and isFastpath
variable) to also check for 'sdd:in-progress' (i.e., include
labels.includes('sdd:in-progress') in the boolean expression) so that when
labels contains 'sdd:in-progress' the code sets kind = isFastpath ?
'fastpath_noop' : 'command' as intended.

In `@wrappers/sdd-spec.yml`:
- Around line 374-425: The labels are moved (github.rest.issues.removeLabel /
addLabels) before calling github.rest.actions.createWorkflowDispatch so a failed
dispatch can leave the issue stuck; either move the createWorkflowDispatch call
(variable workflow, awContext) to run before the label changes or, if you keep
the current order, wrap the createWorkflowDispatch try/catch to roll the labels
back on error by re-adding 'sdd:fastpath' and removing 'sdd:in-progress' for the
same tracking issue (use the same owner/repo/issue_number calls), and surface
the original error via core.setFailed; update the error-handling branches
accordingly to ensure the planComment.id/awContext dispatch is atomic with the
label transition.
- Around line 165-185: The current check only recognizes the 'sdd:fastpath'
label so `/approve` on issues labeled 'sdd:fastpath-review' is ignored; update
the label detection logic (the block that builds labels and sets
isFastpathTracking) to treat either 'sdd:fastpath' OR 'sdd:fastpath-review' as
fastpath tracking (i.e., change the labels.includes(...) test to check for both
values), leaving the existing core.setOutput('fastpath_approve', ...) and
fastpath_tracking behavior unchanged.

---

Outside diff comments:
In `@wrappers/sdd-execute-opus.yml`:
- Around line 257-423: When detecting a fast-path merged PR in the headRef /
headMatch block (where isFastpath is set and ctx.entry is 'fastpath' or
'fastpath-complete'), persist the selected tier onto the PR (e.g. add a label
like 'fastpath-tier:<TIER>' or append a hidden marker to the PR body) via the
GitHub REST API so downstream checks can read it; then update the tier-gate
logic (the fastpathEntry check and the subsequent tier-match code that uses
planTier/TIER and the taskIssue label check) to also inspect the PR's persisted
marker for both 'fastpath' and 'fastpath-complete' flows and only skip the run
when the persisted PR tier mismatches this variant's TIER. Ensure changes
reference the same symbols: headRef/headMatch/refNumber/isFastpath, ctx.entry
('fastpath'/'fastpath-complete'), planTier/TIER, and the tierMatch logic that
reads issue labels.

In `@wrappers/sdd-execute-sonnet.yml`:
- Around line 257-423: The fast-path flow loses the chosen tier because the
wrapper derives the task/tracking issue number from the PR ref (headRef) but
later the tier gate checks the tracking issue for model:<TIER> which tracking
issues intentionally lack; modify the fast-path dispatch and completion handling
so the selected tier is persisted on the PR (either embed a normalized marker in
the PR body like "sdd-tier: <TIER>" or add a dedicated label such as
"sdd-tier:<TIER>") when creating the fastpath entry (where ctx is set for entry
'fastpath'), and update the fastpath-complete branch (the code that sets
isFastpath / ctx.entry === 'fastpath-complete' and the later fastpathEntry
check) to read that marker from the pull request (via payload.pull_request.body
or labels) and use it instead of consulting the tracking issue labels so the
tier gate correctly accepts or rejects the 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4a4d69a2-ccdf-429f-95ae-0d1c60be6467

📥 Commits

Reviewing files that changed from the base of the PR and between f761d1e and 785dfbf.

📒 Files selected for processing (29)
  • .github/workflows/sdd-dispatch.lock.yml
  • .github/workflows/sdd-dispatch.md
  • .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-review.lock.yml
  • .github/workflows/sdd-review.md
  • .github/workflows/sdd-spec.lock.yml
  • .github/workflows/sdd-spec.md
  • .github/workflows/sdd-triage.lock.yml
  • .github/workflows/sdd-validate.lock.yml
  • .github/workflows/sdd-validate.md
  • decisions/0012-fastpath.md
  • docs/sdd/index.md
  • docs/specs/01-spec-issue-native-sdd/01-spec-issue-native-sdd.md
  • scripts/lifecycle-states.yml
  • shared/sdd-interaction.md
  • templates/.github/ISSUE_TEMPLATE/bug.md
  • templates/.github/ISSUE_TEMPLATE/feature.md
  • templates/.github/labels.yml
  • wrappers/sdd-dispatch.yml
  • wrappers/sdd-execute-haiku.yml
  • wrappers/sdd-execute-opus.yml
  • wrappers/sdd-execute-sonnet.yml
  • wrappers/sdd-spec.yml
  • wrappers/sdd-triage.yml
✅ Files skipped from review due to trivial changes (2)
  • .github/workflows/sdd-dispatch.md
  • docs/sdd/index.md

Comment thread .github/workflows/sdd-execute-haiku.lock.yml
Comment thread .github/workflows/sdd-execute-haiku.md
Comment thread .github/workflows/sdd-execute-sonnet.md
Comment thread .github/workflows/sdd-spec.md
Comment thread .github/workflows/sdd-spec.md Outdated
Comment thread docs/specs/01-spec-issue-native-sdd/01-spec-issue-native-sdd.md
Comment thread scripts/lifecycle-states.yml Outdated
Comment thread wrappers/sdd-dispatch.yml
Comment thread wrappers/sdd-spec.yml
Comment thread wrappers/sdd-spec.yml Outdated
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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
wrappers/sdd-execute-haiku.yml (1)

292-297: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Include sdd:review in the fast-path label checks.

A clean fast-path implementation is moved to sdd:review before merge, so the current label set misses the normal happy path. In that state this wrapper will skip both the fastpath-complete rerun on merge and any later PR review/revise reruns on the same implementation PR.

Suggested fix
-                  const fastpathSignal = labels.includes('sdd:fastpath')
-                    || labels.includes('sdd:fastpath-review')
-                    || (!parentUrl
-                      && labels.includes('sdd:in-progress')
-                      && !labels.includes('sdd:dispatched'));
+                  const fastpathSignal = labels.includes('sdd:fastpath')
+                    || labels.includes('sdd:fastpath-review')
+                    || labels.includes('sdd:review')
+                    || (!parentUrl
+                      && labels.includes('sdd:in-progress')
+                      && !labels.includes('sdd:dispatched'));
@@
                   const isFastpathTracking = isTracking && (
                     labels.includes('sdd:fastpath')
                     || labels.includes('sdd:fastpath-review')
                     || labels.includes('sdd:in-progress')
+                    || labels.includes('sdd:review')
                     || labels.includes('sdd:done'));

Also applies to: 421-437

🤖 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 `@wrappers/sdd-execute-haiku.yml` around lines 292 - 297, The fast-path label
detection (variable fastpathSignal) currently checks labels 'sdd:fastpath',
'sdd:fastpath-review' and a branch with 'sdd:in-progress'/'sdd:dispatched' but
omits 'sdd:review', so update the label checks to include
labels.includes('sdd:review') wherever fastpathSignal is computed (the shown
fastpathSignal declaration and the analogous one later in the file), ensuring
both the initial check and the later rerun/merge logic consider 'sdd:review' as
a fast-path label.
.github/workflows/sdd-spec.lock.yml (1)

1087-1089: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

hide_comment(max:5) conflicts with “hide every prior plan comment.”

The prompt requires every earlier fast-path plan comment to be hidden as OUTDATED, but the safe-output config only permits five hide_comment calls. On the sixth /revise, stale plan comments will remain visible and this workflow can no longer satisfy its own contract. Because this file is generated, please raise the limit in .github/workflows/sdd-spec.md or relax the prompt to hide only the immediately previous plan comment.

Also applies to: 1388-1390, 1526-1549, 2640-2640

🤖 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 @.github/workflows/sdd-spec.lock.yml around lines 1087 - 1089, The
safe-output configuration uses hide_comment(max:5) which allows only five
hide-comment calls but the prompt requires hiding every prior plan comment on
each /revise; increase the max value used for hide_comment (or switch to an
unbounded/large value) in the generated workflow generator, or change the
prompt/logic so it hides only the immediately previous plan comment instead of
all prior ones; update references where hide-comment safe-outputs are emitted
(search for hide_comment(max:5), hide-comment safe-outputs, and the /revise
handling) and apply the chosen fix consistently across all instances.
♻️ Duplicate comments (3)
scripts/lifecycle-states.yml (1)

68-70: ⚠️ Potential issue | 🟠 Major

Add the fast-path sdd:in-progress -> sdd:done edge.

Fast-path completion now skips sdd:review, but this source-of-truth graph still rejects that transition. That leaves the validator out of sync with the wrappers and the interaction contract.

🤖 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 `@scripts/lifecycle-states.yml` around lines 68 - 70, The lifecycle graph is
missing the fast-path edge allowing sdd:in-progress to transition directly to
sdd:done; update the state transitions in the lifecycle-states.yml by adding
sdd:done to the sdd:in-progress adjacency list so that "sdd:in-progress:
[sdd:review]" becomes "sdd:in-progress: [sdd:review, sdd:done]" (ensuring the
node names sdd:in-progress and sdd:done are used exactly as in the file).
wrappers/sdd-spec.yml (2)

199-208: ⚠️ Potential issue | 🟠 Major

Handle /approve in sdd:fastpath-review too.

This check still recognizes only sdd:fastpath. With wrappers/sdd-triage.yml now carving out /approve for both fast-path labels, /approve on the normal sdd:fastpath-review state falls through both wrappers and never reaches the deterministic fast-path handler.

🤖 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 `@wrappers/sdd-spec.yml` around lines 199 - 208, The label check only looks for
'sdd:fastpath' so it misses the alternative fast-path label used by the review
wrapper; update the logic around isFastpathTracking (the labels extraction and
includes call in the async github.rest.issues.get block) to treat both labels as
fast-path—e.g., check labels.includes('sdd:fastpath') ||
labels.includes('sdd:fastpath-review')—so that /approve invoked in the
sdd:fastpath-review state is recognized and routed to the deterministic
fast-path handler.

408-481: ⚠️ Potential issue | 🟠 Major

Don't move to sdd:in-progress before dispatch succeeds.

If createWorkflowDispatch fails here, the tracking issue is left in sdd:in-progress with no execute run, and a retry /approve no longer re-enters the fast-path approval path. Dispatch first or roll the label move back on failure.

🤖 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 `@wrappers/sdd-spec.yml` around lines 408 - 481, The code moves the tracking
issue from sdd:fastpath to sdd:in-progress before calling
github.rest.actions.createWorkflowDispatch, which can leave the issue stuck if
dispatch fails; either perform the createWorkflowDispatch call first (use
workflow, dispatchRef, inputs: { aw_context: awContext }) and only on success
call github.rest.issues.removeLabel/removeLabel and github.rest.issues.addLabels
to set sdd:in-progress, or keep the current order but wrap
createWorkflowDispatch in a try/catch that on failure reverts the label change
by calling github.rest.issues.removeLabel for 'sdd:in-progress' and
github.rest.issues.addLabels with ['sdd:fastpath'] (and log/report errors),
ensuring core.setFailed is still called if dispatch ultimately fails.
🤖 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 `@wrappers/sdd-execute-opus.yml`:
- Around line 357-363: The fast-path fallback currently allows
inferredFastpathFromPr && isFastpathTracking to bypass the TIER check; fix by
resolving the tier from stable PR/tracking metadata first (e.g., compute a
prTier or trackingTier from the PR/tracking stable metadata) and require prTier
=== TIER (or otherwise match ownership) before treating a fast-path tracking
issue as a match; apply the same change to the other identical block(s) around
the 403-437 region so all sdd-execute-* wrappers enforce tier ownership rather
than allowing PR-side fast-path events to bypass it.

In `@wrappers/sdd-execute-sonnet.yml`:
- Around line 357-363: Fast-path PR-side events currently bypass tier ownership
because the inferredFastpathFromPr && isFastpathTracking fallback ignores TIER;
resolve the stable PR/tracking issue's tier before accepting a fast-path match
and require the resolved tier to equal the current TIER. Update the logic around
inferredFastpathFromPr and isFastpathTracking so you first call the routine that
extracts stable PR/tracking metadata (the same resolver used elsewhere for
tracking issues) to obtain resolvedTier, then change the conditional to require
resolvedTier === TIER && isFastpathTracking && inferredFastpathFromPr; apply the
same change to the other instances in the file (around the 403–437 block) and in
all sdd-execute-* wrapper usages so fast-path events only pass for the owning
tier.

---

Outside diff comments:
In @.github/workflows/sdd-spec.lock.yml:
- Around line 1087-1089: The safe-output configuration uses hide_comment(max:5)
which allows only five hide-comment calls but the prompt requires hiding every
prior plan comment on each /revise; increase the max value used for hide_comment
(or switch to an unbounded/large value) in the generated workflow generator, or
change the prompt/logic so it hides only the immediately previous plan comment
instead of all prior ones; update references where hide-comment safe-outputs are
emitted (search for hide_comment(max:5), hide-comment safe-outputs, and the
/revise handling) and apply the chosen fix consistently across all instances.

In `@wrappers/sdd-execute-haiku.yml`:
- Around line 292-297: The fast-path label detection (variable fastpathSignal)
currently checks labels 'sdd:fastpath', 'sdd:fastpath-review' and a branch with
'sdd:in-progress'/'sdd:dispatched' but omits 'sdd:review', so update the label
checks to include labels.includes('sdd:review') wherever fastpathSignal is
computed (the shown fastpathSignal declaration and the analogous one later in
the file), ensuring both the initial check and the later rerun/merge logic
consider 'sdd:review' as a fast-path label.

---

Duplicate comments:
In `@scripts/lifecycle-states.yml`:
- Around line 68-70: The lifecycle graph is missing the fast-path edge allowing
sdd:in-progress to transition directly to sdd:done; update the state transitions
in the lifecycle-states.yml by adding sdd:done to the sdd:in-progress adjacency
list so that "sdd:in-progress: [sdd:review]" becomes "sdd:in-progress:
[sdd:review, sdd:done]" (ensuring the node names sdd:in-progress and sdd:done
are used exactly as in the file).

In `@wrappers/sdd-spec.yml`:
- Around line 199-208: The label check only looks for 'sdd:fastpath' so it
misses the alternative fast-path label used by the review wrapper; update the
logic around isFastpathTracking (the labels extraction and includes call in the
async github.rest.issues.get block) to treat both labels as fast-path—e.g.,
check labels.includes('sdd:fastpath') ||
labels.includes('sdd:fastpath-review')—so that /approve invoked in the
sdd:fastpath-review state is recognized and routed to the deterministic
fast-path handler.
- Around line 408-481: The code moves the tracking issue from sdd:fastpath to
sdd:in-progress before calling github.rest.actions.createWorkflowDispatch, which
can leave the issue stuck if dispatch fails; either perform the
createWorkflowDispatch call first (use workflow, dispatchRef, inputs: {
aw_context: awContext }) and only on success call
github.rest.issues.removeLabel/removeLabel and github.rest.issues.addLabels to
set sdd:in-progress, or keep the current order but wrap createWorkflowDispatch
in a try/catch that on failure reverts the label change by calling
github.rest.issues.removeLabel for 'sdd:in-progress' and
github.rest.issues.addLabels with ['sdd:fastpath'] (and log/report errors),
ensuring core.setFailed is still called if dispatch ultimately fails.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 49c456e1-bfff-41d6-be20-68c7fb733acc

📥 Commits

Reviewing files that changed from the base of the PR and between 785dfbf and 6d1628f.

📒 Files selected for processing (15)
  • .github/workflows/sdd-review.lock.yml
  • .github/workflows/sdd-review.md
  • .github/workflows/sdd-spec.lock.yml
  • .github/workflows/sdd-spec.md
  • .github/workflows/sdd-validate.lock.yml
  • .github/workflows/sdd-validate.md
  • decisions/0012-fastpath.md
  • docs/specs/01-spec-issue-native-sdd/01-spec-issue-native-sdd.md
  • scripts/lifecycle-states.yml
  • shared/sdd-interaction.md
  • wrappers/sdd-execute-haiku.yml
  • wrappers/sdd-execute-opus.yml
  • wrappers/sdd-execute-sonnet.yml
  • wrappers/sdd-spec.yml
  • wrappers/sdd-triage.yml
✅ Files skipped from review due to trivial changes (3)
  • .github/workflows/sdd-review.md
  • docs/specs/01-spec-issue-native-sdd/01-spec-issue-native-sdd.md
  • decisions/0012-fastpath.md

Comment thread wrappers/sdd-execute-opus.yml
Comment thread wrappers/sdd-execute-sonnet.yml
@norrietaylor
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

✅ Actions performed

Full review triggered.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/sdd-spec.lock.yml (2)

1055-1071: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add verification: to the fast-path plan schema.

The plan comment defined here never emits a verification: block, but the fast-path execute prompt later parses verification: from the plan comment and step 6 uses that block to run proofs before opening the PR. As written, /approve can dispatch an implementation without the verification contract the executor expects.

🤖 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 @.github/workflows/sdd-spec.lock.yml around lines 1055 - 1071, The fast-path
plan comment emitted under the marker [sdd-spec:fastpath-plan] currently omits a
required verification: block, which later prompts (the fast-path execute prompt
and /approve wrapper) parse and use to run proofs; update the plan-emission
logic to include a verification: field in the plan body (alongside Title, repo:,
requirements:, files in scope:, proof artifacts:, depends on:, and model:*) and
populate it with the verification steps or artifacts the executor will run;
ensure the add-comment payload that creates the [sdd-spec:fastpath-plan] comment
includes this verification: block so downstream parsing and step 6 proof
execution receive the expected contract.

705-710: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

/spec can’t recover an execute-time fast-path misclassification.

This reset path only matches sdd:fastpath / sdd:fastpath-review, but the new fast-path execute flow moves the tracking issue to sdd:in-progress before its heuristic re-check runs. If execution then escalates with needs-human, a human /spec comment no longer matches the documented reset branch, so the issue cannot deterministically re-enter the full pipeline.

Also applies to: 885-893

🤖 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 @.github/workflows/sdd-spec.lock.yml around lines 705 - 710, The workflow
currently only treats a `/spec` comment as a reset when the tracking issue has
labels `sdd:fastpath` or `sdd:fastpath-review`, but misses execute-time
fast-path cases which move the issue to `sdd:in-progress`; update the
conditional logic that handles the `/spec` comment (the reset branch referenced
by ADR 0012) to also accept `sdd:in-progress` as a valid fast-path state so a
human `/spec` can re-enter the full-path flow; apply the same change to the
equivalent block that appears later (the second reset handling referenced in the
comment) so both locations recognize `sdd:in-progress` alongside `sdd:fastpath`
and `sdd:fastpath-review`.
♻️ Duplicate comments (2)
.github/workflows/sdd-execute-sonnet.md (1)

388-397: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fast-path routing marker and ownership heuristic are still out of sync.

Fast-path PRs intentionally avoid closing keywords, but ownership text still relies on Closes #<task>. That can cause fast-path review/revise events to fall through. Please add a fast-path ownership path (branch + routing marker) in step 7, in addition to full-path Closes #<task>.

🤖 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 @.github/workflows/sdd-execute-sonnet.md around lines 388 - 397, Step 7's
ownership heuristic currently only recognizes full-path PRs via the "Closes
#<task>" text; add a fast-path branch that detects the literal routing marker
`[sdd-fastpath: tracking=<N> tier=<tier>]` as the first line of the PR body
(and/or a branch name convention if used) so review/revise events route
fast-path PRs without the "Closes #" keyword. Update the step 7 logic to check
for the exact marker string on its own line (and a fast-path branch indicator if
your workflow uses one) in addition to the existing "Closes #<task>" check, and
ensure the marker accepts tiers `haiku`, `sonnet`, `opus` and a numeric tracking
ID.
.github/workflows/sdd-execute-haiku.md (1)

388-397: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fast-path marker was added, but PR ownership rules still describe full-path-only detection.

With fast-path PRs explicitly avoiding Closes #<tracking>, step 7’s ownership check can still reject agent-owned fast-path PRs during review/revise handling. Please update the ownership rule to accept fast-path ownership (for example, sdd/<tracking>-<slug> + [sdd-fastpath: tracking=<N> tier=<tier>]) alongside full-path Closes #<task>.

🤖 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 @.github/workflows/sdd-execute-haiku.md around lines 388 - 397, Step 7's PR
ownership check currently only recognizes full-path closure semantics (e.g.,
"Closes #<task>") and must be extended to also accept fast-path PRs that include
the literal marker "[sdd-fastpath: tracking=<N> tier=<tier>]" on the first line
of the PR body and agent-created branches like "sdd/<tracking>-<slug>"; modify
the ownership validation logic (the "ownership check" invoked in step 7) to
parse the PR body for the exact fast-path marker and/or match branch names
against the "sdd/<tracking>-<slug>" pattern and treat those as valid owner
proofs in addition to existing "Closes #<task>" detection so agent-owned
fast-path PRs are not rejected during review/revise handling.
🤖 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-opus.lock.yml:
- Around line 951-960: Ownership check currently requires a `Closes #<task>` PR
body line (step 7) which rejects fast-path PRs that instead include the
machine-readable marker `[sdd-fastpath: tracking=<N> tier=<tier>]`; update the
ownership verification logic to treat that marker (exact literal on its own
first line) as equivalent proof of identity so `/revise` and review comments
will route to the existing branch. Locate the step that parses PR body lines
(the code referencing the `Closes #` check and any includes()/substring scan)
and add a branch that parses the first-line marker form `[sdd-fastpath:
tracking=\d+ tier=(haiku|sonnet|opus)]`, extracting the tracking number and tier
and using them to establish ownership instead of requiring `Closes #<task>`.
Ensure the marker match is exact (on its own line) and falls back to the
original `Closes #` behavior when absent.

---

Outside diff comments:
In @.github/workflows/sdd-spec.lock.yml:
- Around line 1055-1071: The fast-path plan comment emitted under the marker
[sdd-spec:fastpath-plan] currently omits a required verification: block, which
later prompts (the fast-path execute prompt and /approve wrapper) parse and use
to run proofs; update the plan-emission logic to include a verification: field
in the plan body (alongside Title, repo:, requirements:, files in scope:, proof
artifacts:, depends on:, and model:*) and populate it with the verification
steps or artifacts the executor will run; ensure the add-comment payload that
creates the [sdd-spec:fastpath-plan] comment includes this verification: block
so downstream parsing and step 6 proof execution receive the expected contract.
- Around line 705-710: The workflow currently only treats a `/spec` comment as a
reset when the tracking issue has labels `sdd:fastpath` or
`sdd:fastpath-review`, but misses execute-time fast-path cases which move the
issue to `sdd:in-progress`; update the conditional logic that handles the
`/spec` comment (the reset branch referenced by ADR 0012) to also accept
`sdd:in-progress` as a valid fast-path state so a human `/spec` can re-enter the
full-path flow; apply the same change to the equivalent block that appears later
(the second reset handling referenced in the comment) so both locations
recognize `sdd:in-progress` alongside `sdd:fastpath` and `sdd:fastpath-review`.

---

Duplicate comments:
In @.github/workflows/sdd-execute-haiku.md:
- Around line 388-397: Step 7's PR ownership check currently only recognizes
full-path closure semantics (e.g., "Closes #<task>") and must be extended to
also accept fast-path PRs that include the literal marker "[sdd-fastpath:
tracking=<N> tier=<tier>]" on the first line of the PR body and agent-created
branches like "sdd/<tracking>-<slug>"; modify the ownership validation logic
(the "ownership check" invoked in step 7) to parse the PR body for the exact
fast-path marker and/or match branch names against the "sdd/<tracking>-<slug>"
pattern and treat those as valid owner proofs in addition to existing "Closes
#<task>" detection so agent-owned fast-path PRs are not rejected during
review/revise handling.

In @.github/workflows/sdd-execute-sonnet.md:
- Around line 388-397: Step 7's ownership heuristic currently only recognizes
full-path PRs via the "Closes #<task>" text; add a fast-path branch that detects
the literal routing marker `[sdd-fastpath: tracking=<N> tier=<tier>]` as the
first line of the PR body (and/or a branch name convention if used) so
review/revise events route fast-path PRs without the "Closes #" keyword. Update
the step 7 logic to check for the exact marker string on its own line (and a
fast-path branch indicator if your workflow uses one) in addition to the
existing "Closes #<task>" check, and ensure the marker accepts tiers `haiku`,
`sonnet`, `opus` and a numeric tracking ID.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1c27c87a-1b25-45fa-a6ee-364f8d922ae4

📥 Commits

Reviewing files that changed from the base of the PR and between 6d1628f and 88f38b7.

📒 Files selected for processing (15)
  • .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
  • docs/specs/01-spec-issue-native-sdd/01-spec-issue-native-sdd.md
  • scripts/lifecycle-states.yml
  • wrappers/sdd-dispatch.yml
  • wrappers/sdd-execute-haiku.yml
  • wrappers/sdd-execute-opus.yml
  • wrappers/sdd-execute-sonnet.yml
  • wrappers/sdd-spec.yml

Comment thread .github/workflows/sdd-execute-opus.lock.yml
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.

sdd: add fast-path for single-session features/bugs (agent proposes, human confirms, /approve runs)

1 participant