最新资讯
bloomberg.com Nvidia 加强东南亚芯片追踪以打击走私 thestack.technology 模型路由需求升温,Agent Router 推出开源替代方案 www.youtube.com Google DeepMind 的 Philipp Schmid:AI 同事需要具备的七个要素 unite.ai Cashfree 为 AI Agent 的托管结账加入 WebMCP 工具 dev.to 我们在 DolphinBench 上测试记忆检索:纯关键词搜索暴露了自身回归 dev.to 别再把 Agent 写成 while 循环,把它建模为状态机 analyticsindiamag.com 小语言模型可能重塑企业 AI 部署方式 bloomberg.com Rightmove 与 Scout24 借 AI 产品应对低迷房市并上调展望 stackoverflow.blog 欢迎来到芯片时代:半导体制造、AI 数据中心与芯片设计的未来 www.youtube.com AI Agent 总犯同样的错:CentralAgent AI 将记忆重构为经验系统 pub.towardsai.net Netflix 科学家建议重采样 LLM 评判:5 次仅将误差棒缩小 13% pub.towardsai.net Jev 作为 LLM 前的静默层:构建提示感知的模型路由器
多元动态
登录 注册
行业动态 dev.to · @Sohail Ahmad

以堆叠 PR 交付 AI 生成功能:Spec Kit + gh stack 完整教程

原文 我的收藏

该教程介绍如何将规格驱动开发与堆叠 PR 结合:Spec Kit(specify)为代理提供规格、计划、任务列表和写码前的检查门槛,gh stack 则把输出拆成多个小 PR(每个不超过 100 个文件),便于快速评审。文中以真实示例走完从 specify init 到功能合并的完整流程。

AI推荐理由 教程将 Spec Kit 的规格驱动开发与 gh stack 的堆叠 PR 结合,解决 AI 编码代理一次生成 180 个文件、难以评审的问题,要求每个 PR 不超过 100 个文件并在单元测试通过后才触发。对使用 AI 代理的工程团队有实际流程价值,但属方法教程,效果依赖具体团队实践,未提供量化验证。

68

正文

A step-by-step guide to pairing spec-driven development with stacked pull requests — from specify init all the way to a fully merged feature. Why this tutorial exists AI coding agents are fast. Dangerously fast. Point an agent at a feature request and ten minutes later you're staring at a pull request with 180 changed files. Nobody reviews that. It sits for days, goes stale, and gets merged with a LGTM and a prayer. The fix is two tools working together: Spec Kit (specify) gives the agent structure — a spec, a plan, a task list, and gates it must pass before writing code. gh stack gives the output structure — instead of one monster PR, the agent ships a stack of small PRs (each ≤ 100 files), each reviewable in minutes. This tutorial walks through the entire lifecycle with a real example. By the end you'll have: ✅ A working Spec Kit + gh stack setup ✅ A plan that is literally a stack layout ✅ An implement loop where gh stack only fires after unit tests pass ✅ Three open PRs stacked on each other ✅ A review/merge workflow that takes the stack from open → merged → cleaned up What we're building We're an e-commerce team. The business wants payments: charge cards, refund, webhooks. Estimated scope: ~135 files. That's one unreviewable PR — or a clean 3-PR stack: main ── 001-payments ── 001-payments-u2 ── 001-payments-u3 PR #1 PR #2 PR #3 Domain (~25f) API (~40f) Webhooks+UI (~70f) each ≤ 100 files — hard cap Enter fullscreen mode Exit fullscreen mode One feature. One stack. Three small reviews. Let's go. Part 0 — Prerequisites Tool Check Notes GitHub CLI ≥ 2.x gh --version Authenticated: gh auth login Git git --version uv (for Spec Kit) uv --version Or use pipx/pip An AI agent claude --version Works with codex, copilot, gemini, cursor-agent, etc. Node/Python + test runner project-specific We use npm run test:unit below — swap in yours Install the stack extension: gh extension install hmarr/gh-stack gh stack --help # should print submit / sync / checkout / view Enter fullscreen mode Exit fullscreen mode Part 1 — Project setup # Fresh project with Claude Code as the agent uvx --from git+https://github.com/github/spec-kit.git specify init payments-service --ai claude cd payments-service # Existing repo instead? # uvx --from git+https://github.com/github/spec-kit.git specify init --here --ai claude Enter fullscreen mode Exit fullscreen mode Spec Kit drops its templates into .specify/ and configures your agent's command slash-commands (/speckit.*). Now create the cap-enforcement gate — the script that makes the 100-file rule real rather than a suggestion the agent can ignore: scripts/check-stack-cap.sh #!/usr/bin/env bash # Hard cap: max changed files per stack unit. Usage: # scripts/check-stack-cap.sh e.g. main, or the unit below set -euo pipefail CAP="${STACK_FILE_CAP:-100}" PARENT="${1:?Usage: check-stack-cap.sh }" BASE="$(git merge-base "$PARENT" HEAD)" COUNT="$(git diff --name-only "$BASE" HEAD | sed '/^$/d' | wc -l | tr -d ' ')" echo "Files changed vs '$PARENT': $COUNT / $CAP" if (( COUNT > CAP )); then echo "❌ FILE CAP EXCEEDED — do NOT push or run gh stack. Split this unit." exit 1 fi echo "✅ Within cap — safe to push and submit." Enter fullscreen mode Exit fullscreen mode chmod +x scripts/check-stack-cap.sh git add scripts/ && git commit -m "chore: stack file-cap gate" && git push Enter fullscreen mode Exit fullscreen mode 🔑 Key idea: the gate runs before anything touches GitHub. If tests are red or the cap is blown, gh stack never runs. Bake this into your agent's rules in Part 2. Part 2 — Teach the agent the contract Run the constitution command and paste this addendum (it becomes project law the agent reads on every task): /speckit.constitution Enter fullscreen mode Exit fullscreen mode Add to the generated file: ## Delivery — Stacked PRs (non-negotiable) 1. One feature = one gh stack of units U1..Un, implemented strictly in order. 2. HARD CAP: each unit ≤ 100 changed files, verified by scripts/check-stack-cap.sh . Exceeding it ⇒ split the unit. 3. Unit sequence: implement → unit tests PASS → commit → cap check → git push -u → gh stack submit → create next unit branch. 4. NEVER run gh stack with failing tests or a failed cap check. 5. U1 branch = the spec-kit feature branch (parent: main). U(k) branch = -uk (parent: U(k-1)). No forward dependencies. 6. Merge bottom-up. Run gh stack sync after every merge. Enter fullscreen mode Exit fullscreen mode That's the whole contract. Everything below is this loop, repeated. Part 3 — /speckit.specify (and clarify) /speckit.specify Build payments: card charge, refund, and webhook ingestion. This branch is the bottom of a gh stack — spec docs ship in PR #1. Enter fullscreen mode Exit fullscreen mode Spec Kit creates the branch and commits the spec: ⏺ Created branch 001-payments ⏺ Created specs/001-payments/spec.md Enter fullscreen mode Exit fullscreen mode That branch — 001-payments — is now unit U1, the bottom of your stack. Add clarifications with /speckit.clarify if the spec has open questions, then commit any changes. Part 4 — /speckit.plan: plan the feature as a stack This is where the two tools fuse. Don't let the plan be prose — make it a stack layout: /speckit.plan Use PostgreSQL + NestJS + Stripe SDK. STACK CONSTRAINTS (mandatory): - Organize implementation as stacked units U1..Un. - U1 must build and test green alone; each U(k) depends only on U1..U(k-1). - Each unit ≤ 100 changed files — estimate files per unit, split proactively. - Add a "## Stack Layout" table: Unit | Branch | Purpose | Depends on | Est. files. Enter fullscreen mode Exit fullscreen mode The agent writes back into plan.md: ## Stack Layout | Unit | Branch | Purpose | Depends on | Est. files | |------|--------------------|----------------------------|------------|------------| | U1 | 001-payments | Domain model + migrations | main | ~25 | | U2 | 001-payments-u2 | REST API + contract tests | U1 | ~40 | | U3 | 001-payments-u3 | Webhooks + admin UI | U2 | ~70 | Enter fullscreen mode Exit fullscreen mode 💡 If any unit estimates > 100 files at this stage, the agent should split it now, in the plan — not mid-implementation. Part 5 — /speckit.tasks + /speckit.analyze Group every task under a unit, and give each unit an exit definition: /speckit.tasks STACK CONSTRAINTS (mandatory): - Group tasks under "## Unit N" headings; each task belongs to exactly one unit. - Per unit define: unit-test command and exit criteria: tests green + scripts/check-stack-cap.sh exit 0. - Estimated files > 100 for any unit ⇒ split it before finalizing. Enter fullscreen mode Exit fullscreen mode Resulting tasks.md (excerpt): ## Unit 1 — Domain Core (001-payments, parent: main) - [ ] T001 Payment schema migration - [ ] T002 Payment aggregate + state machine - [ ] T003 Unit tests **Exit:** `npm run test:unit` → commit → `scripts/check-stack-cap.sh main` → push → `gh stack submit` → checkout `001-payments-u2` ## Unit 2 — API (001-payments-u2, parent: 001-payments) - [ ] T004 POST /payments endpoint - [ ] T005 GET /payments/:id - [ ] T006 Contract tests **Exit:** same pattern, parent = `001-payments` Enter fullscreen mode Exit fullscreen mode Then sanity-check the structure: /speckit.analyze Also verify: every task maps to one unit; no gaps or forward deps in the unit chain; no unit's file estimate exceeds 100. Enter fullscreen mode Exit fullscreen mode Part 6 — /speckit.implement: the unit loop This is the heart of the tutorial. Kick off: /speckit.implement EXECUTION RULES (mandatory): - One unit at a time, in order U1..Un. - Unit complete ONLY when: unit tests pass AND scripts/check-stack-cap.sh exits 0. - Then: commit → push -u → gh stack submit → git checkout -b . - Never run gh stack with red tests or a failed cap check. - Cap exceeded mid-unit ⇒ stop, split remaining tasks into a new unit in tasks.md, finish the loop, continue. Enter fullscreen mode Exit fullscreen mode 🔁 Unit 1 The agent implements T001–T003. Then you (or the agent) run the loop: npm run test:unit # ✔ 42 tests passing ← GATE 1: tests green git add -A git commit -m "feat(u1): payment domain model + migrations" scripts/check-stack-cap.sh main # Files changed vs 'main': 25 / 100 # ✅ Within cap — safe to push and submit. ← GATE 2: cap green git push -u origin 001-payments gh stack submit --draft --fill ← NOW the stack command runs # ✔ Created https://github.com/acme/payments-service/pull/1 git checkout -b 001-payments-u2 ← stack the next unit on top Enter fullscreen mode Exit fullscreen mode PR #1 exists. Both gates were green first — that's the discipline. 🔁 Unit 2 You're now on 001-payments-u2, branched from U1. Implement T004–T006, then: npm run test:unit # ✔ 57 tests passing git add -A && git commit -m "feat(u2): payments REST API" scripts/check-stack-cap.sh 001-payments # Files changed vs '001-payments': 40 / 100 # ✅ Within cap. git push -u origin 001-payments-u2 gh stack submit --draft --fill # ✔ Created https://github.com/acme/payments-service/pull/2 git checkout -b 001-payments-u3 Enter fullscreen mode Exit fullscreen mode Note: gh stack submit is idempotent. Each run creates missing PRs and updates existing ones — so the whole stack stays fresh and CI keeps running on every PR while you build upward. 🔁 Unit 3 npm run test:unit git add -A && git commit -m "feat(u3): stripe webhooks + admin UI" scripts/check-stack-cap.sh 001-payments-u2 # Files changed vs '001-payments-u2': 70 / 100 # ✅ Within cap. git push -u origin 001-payments-u3 gh stack submit --fill # ✔ Created https://github.com/acme/payments-service/pull/3 Enter fullscreen mode Exit fullscreen mode The moment of truth — view the stack gh stack view Enter fullscreen mode Exit fullscreen mode main └─ 001-payments (#1, draft) └─ 001-payments-u2 (#2, draft) └─ 001-payments-u3 (#3, draft) Enter fullscreen mode Exit fullscreen mode Three PRs. Largest is 70 files. Every one had green tests before it was pushed. 🎉 Unit Exit Checklist (before touching the next unit): [ ] tasks.md boxes ticked for this unit [ ] npm run test:unit green [ ] check-stack-cap.sh → ✅ [ ] Committed & pushed [ ] gh stack submit ran clean [ ] Next unit branch created Part 7 — You have PRs. Now what? This is where most stacked-PR guides stop. Ours doesn't. 7.1 Move PR #1 out of draft when review starts gh pr ready 1 Enter fullscreen mode Exit fullscreen mode 7.2 Handling review feedback — mid-stack edits are normal A reviewer requests a change to the domain model… in U1, the bottom PR. With stacked PRs this is cheap: gh stack checkout # interactive picker: # ? Select a branch (…): 001-payments ← pick the bottom PR's branch # …apply the fix, with tests… npm run test:unit && git add -A && git commit -m "fix(u1): review feedback" scripts/check-stack-cap.sh main && git push gh stack sync # ✨ rebases U2 and U3 on top of your fix automatically Enter fullscreen mode Exit fullscreen mode Open PR #2 and #3 — GitHub now shows them updated with the fix. One commit, one push, one sync. No cherry-pick hell. 7.3 Merging: strictly bottom-up Never merge U2 before U1. The rhythm is merge → sync → repeat: # Merge the bottom PR gh pr merge 1 --squash gh stack sync # re-parents U2 onto main; PR #2 now targets main # Reviewers approve PR #2 (now reviewable standalone!) gh pr merge 2 --squash gh stack sync # PR #3 re-targets main gh pr merge 3 --squash gh stack sync # stack fully landed 🏁 Enter fullscreen mode Exit fullscreen mode Each PR gets smaller and more standalone as the stack dissolves from the bottom — reviewers see shrinking diffs, not growing ones. 7.4 Cleanup git checkout main && git pull git branch -D 001-payments 001-payments-u2 001-payments-u3 git push origin --delete 001-payments 001-payments-u2 001-payments-u3 # if not auto-deleted Enter fullscreen mode Exit fullscreen mode Feature landed. Next feature starts the cycle again at Part 3. Part 8 — When the 100-file cap bites mid-unit It will happen eventually. The agent is deep into U3, and: scripts/check-stack-cap.sh 001-payments-u2 # Files changed vs '001-payments-u2': 112 / 100 # ❌ FILE CAP EXCEEDED — do NOT push or run gh stack. Split this unit. Enter fullscreen mode Exit fullscreen mode The recovery procedure (the agent follows this automatically if you adopted the constitution): Stop. Do not push, do not run gh stack. If the overflow is in the last commit: git reset --soft HEAD~1 (keep the work staged). Open tasks.md: move unfinished/overflow tasks into a new unit (e.g., split U3 → U3a "Webhooks" / U3b "Admin UI"). Commit what fits within the cap → run the exit loop → push → submit. git checkout -b 001-payments-u3b and continue the loop. The stack becomes four PRs instead of three. That's the system working, not failing. Part 9 — Troubleshooting Symptom Cause Fix gh stack submit only creates one PR Child branch wasn't created from the parent — broken ancestry git checkout -b from scratch; never open stacked PRs manually PR targets main instead of the unit below PR created outside gh stack submit, or ancestry broken Delete PR, fix ancestry, re-submit Cap fails at push time Files added after planning Part 8 split procedure Conflicts during gh stack sync main or a lower unit moved Fix conflicts branch-by-branch → git rebase --continue → rerun gh stack sync Fixed U1, but U2's CI broke Legit stacked coupling — U2 built on old U1 gh stack checkout U2, fix, push, gh stack sync Agent runs gh stack with red tests Constitution rules not loaded Re-paste contract into the prompt; verify .specify/ constitution contains rule #4 Part 10 — Recap & cheat sheet The entire methodology in one line: Plan the stack → build a unit → tests green → cap green → gh stack submit → stack the next unit → merge bottom-up → sync. # ── Stack lifecycle ────────────────────────────── gh stack submit --draft --fill # create/update PRs (idempotent — run every unit) gh stack view # visualize the stack gh stack checkout # hop to any branch (for review fixes) gh stack sync # rebase/re-parent after fixes and merges gh pr merge --squash # merge bottom PR, then… # ── The gate (before EVERY submit) ─────────────── npm run test:unit # gate 1: tests scripts/check-stack-cap.sh # gate 2: ≤100 files # ── Overrides ──────────────────────────────────── STACK_FILE_CAP=50 scripts/check-stack-cap.sh main # tighter temporary cap Enter fullscreen mode Exit fullscreen mode Why this combination wins Problem Spec Kit's answer gh stack's answer Agent builds the wrong thing Spec + plan + clarify gates Small PRs get early feedback Unreviewable mega-PRs Tasks grouped into ≤100-file units Stacked PRs, auto-managed Agent "finishes" broken code Constitution: tests before anything gh stack literally cannot run until gates pass Merge-day pain Ordered units Bottom-up merge + gh stack sync Next steps: try it on your smallest real feature first. Tighten STACK_FILE_CAP to 50 and watch your review times drop. And put the Part 2 contract in your constitution today — it's the difference between an agent that follows the loop and one that ships you another 180-file PR.

来源报道 · 1 篇 · 以下链接均前往原始媒体

← 返回精选动态 原文

更多内容