## Summary Teach the SDD flow about **inter-feature dependencies**, and let the existing `pr-stack` skill turn those dependencies into stacked PRs automatically — no new stack tooling, just SDD-driven orchestration. > **Declare that one feature depends on another — Spec Kit and stacked PRs do the rest.** ## The problem Spec Kit walks users through one feature at a time. But real features often build on each other: Feature B needs code from Feature A. Today that means: - **Wait** for Feature A to be reviewed and merged before starting Feature B (blocks parallel work). - **Start B anyway** without visibility into A''s code, inventing placeholders that get thrown away. - **Combine both** into one giant PR that reviewers can''t follow. Real example — issues logged on `github/spec-kit`: - [#4210](https://github.com/github/spec-kit/issues/4210) — Add deterministic contribution IDs and stack lookup IDs for resolved artifacts - [#4212](https://github.com/github/spec-kit/issues/4212) — Add `specify artifact` command exposing composition stacks as JSON #4212 depends on #4210. Running each in its own Copilot session today, the #4212 session branched off `main` and had no visibility into #4210''s in-flight work. ## What already exists - **[Stacked pull requests](https://github.blog/changelog/2026-07-30-stacked-pull-requests-are-now-in-public-preview/)** — GitHub feature that lets PR B target PR A before A is merged; reviews happen in parallel; upstream changes auto-rebase; merging the top lands the whole stack. - **`pr-stack` skill** — already ships in the Copilot app; wraps `gh-stack` for creating/managing stacks. - **Spec Kit + `spec-kit-copilot`** — handle intra-feature dependency ordering (phases, `[P]` markers, `Dependencies & Execution Order` in `tasks.md`) but have **no first-class notion of feature-to-feature dependencies**. ## Gap Spec Kit has no way to say *"Feature #4212 depends on Feature #4210"* such that any command acts on it. The `spec.md` "Assumptions" section is prose, not machine-readable, and assumes the dependency is already merged. ## Proposal Extend the existing `spec-kit-copilot` SDD skills (primarily `speckit-workflow-step` / `speckit-workflow`) to be stacks-aware. Delegate all Git/PR mechanics to the existing `pr-stack` skill. **No new skill, no new user-visible commands in the MVP, no changes to core spec-kit.** ### Dependency declaration (any of these, unified internally) Read whichever is available, in priority order: 1. Explicit prompt at kickoff — *"stack on #4210."* 2. GitHub sub-issue / tracked-by links on the issue. 3. `Depends on: #NNNN` line in the issue body. 4. `dependencies:` frontmatter in `spec.md` (persists after issue is closed). All resolve to `{feature_id, upstream_prs, upstream_branches}`. ### Hooks into each SDD phase | Phase | New behavior when a dependency exists | |---|---| | **Session kickoff** | Detect deps → if unmerged upstream PR exists, prompt to stack → call `pr-stack` to check out on top of upstream branch. | | **`/specify`** | Load upstream `spec.md` as context. Write structured `## Dependencies` into new spec. | | **`/plan`** | Load upstream `plan.md` and contracts. Do not re-plan interfaces upstream owns. | | **`/tasks`** | Skip tasks upstream delivers; tag consuming tasks with `[upstream:#NNNN]`. | | **`/analyze`** | Cross-check assumptions against upstream contracts. Flag drift. | | **`/implement`** | Runs against a working tree that already includes upstream code — real APIs, no stubs. | | **PR creation** | Call `pr-stack submit` → PR targets upstream branch; stack map included in body. | | **Upstream changes** | Auto-call `pr-stack restack` → rerun `/analyze` to flag invalidated assumptions. | ### SDD canvas changes - **Stack lane** — features in a stack render as connected columns in dependency order. - **Layer badge** on each card: *"Layer 2 of 3, base: #4210"*. - **Merge-readiness indicator** per layer. - **Base preview** — clicking the base opens the upstream feature''s canvas in a side panel. ## Worked example — #4210 → #4212 1. #4212 issue body says `Depends on: #4210`. 2. Session opens on #4212. Plugin detects the dep, calls `pr-stack` to base the branch on #4210''s branch. 3. `/specify` runs with #4210''s spec as context. 4. `/plan` and `/tasks` reference #4210''s `ContributionId` API directly. 5. `/implement` writes real code against real APIs. 6. `pr-stack submit` opens PR #4212 targeting #4210''s branch. 7. #4210 reviewer renames `ContributionId` → `ArtifactRef`; force-pushes. 8. Plugin auto-triggers `pr-stack restack` on #4212 → reruns `/analyze` → flags affected tasks → `/implement` patches them. 9. #4210 merges. #4212 auto-retargets to `main`. Merge queue lands it. ## Delivery plan **MVP (small)** - Extend `speckit-workflow-step` to read deps from issue body + `spec.md` frontmatter. - Auto-call `pr-stack add` at kickoff, `pr-stack submit` at end of `/implement`. - Write `dependencies:` into `spec.md`. **Phase 2** - Upstream context injection into `/specify`, `/plan`, `/tasks`, `/analyze`. - Auto `pr-stack restack` + `/analyze` rerun on upstream change. **Phase 3** - SDD canvas stack lane. - Sub-issue / tracked-by detection. - Content-based inference fallback in `/analyze`. - Optional `/speckit.stack` escape hatch command if users request explicit control. ## Non-goals - No changes to core `spec-kit` templates or commands. - No reimplementation of stack mechanics — `pr-stack` owns that. - No new user-visible skill or command surface in the MVP. - No non-GitHub host support (stacked PRs are GitHub-only). ## Framing > Spec Kit already handles dependencies *inside* a feature. This makes it aware of dependencies *between* features — and lets stacked PRs carry that awareness all the way through review and merge.