plan-task-breakdown
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePlan task breakdown
计划任务拆分
Convert an implementation plan into an ordered, phase-grouped, dependency-annotated, checkbox-tracked task list that an implementer (Claude or human) can work through one task at a time, committing after each one. Each task records which other tasks it depends on — and dependency-free tasks are flagged — so a single implementer can go top-to-bottom while multiple implementers can fan out on independent tasks in parallel.
The output isn't documentation — it's an execution contract. Done right, the user (or a future agent) can open the tasks doc, pick the first unchecked box, implement only that, tick the box, and commit the code + tick together as one commit before moving on.
将实现计划转换为有序的、按阶段分组的、带有依赖标注的、支持复选框追踪的任务列表,供实现者(Claude或人类)逐个完成,完成每个任务后提交。每个任务会记录它所依赖的其他任务——无依赖任务会被标记出来,这样单个实现者可以从上到下依次完成,而多个实现者可以并行处理独立任务。
输出结果不是文档——而是一份执行契约。如果操作正确,用户(或未来的Agent)可以打开任务文档,选择第一个未勾选的任务,仅实现该任务,勾选复选框,然后将代码变更与勾选操作一起提交为一个单独的提交,之后再进行下一个任务。
Where the output lives
输出文件的位置
Default path: alongside the source plan, with swapped for .
-plan.md-tasks.md- Plan at → tasks at
docs/budgets-page-plan.mddocs/budgets-page-tasks.md - Plan at → tasks at
docs/auth-rewrite-plan.mddocs/auth-rewrite-tasks.md
If the plan has no suffix, drop the file next to it with a name derived from the feature (ask only if the slug isn't obvious — otherwise pick the reasonable name and proceed).
-plan.md-tasks.mdIf a tasks file already exists at the target path, do not overwrite without checking. Either ask the user, or — if they clearly want a regeneration — read the existing file first to preserve any checkboxes already ticked. Re-ticking finished work is annoying.
默认路径:与源计划文件同级,将文件名中的替换为。
-plan.md-tasks.md- 计划文件位于→ 任务文件位于
docs/budgets-page-plan.mddocs/budgets-page-tasks.md - 计划文件位于→ 任务文件位于
docs/auth-rewrite-plan.mddocs/auth-rewrite-tasks.md
如果计划文件没有后缀,则在其旁边创建一个以结尾的文件,文件名基于功能命名(仅在文件名不明确时询问用户,否则选择合理的名称继续)。
-plan.md-tasks.md如果目标路径已存在任务文件,未经确认请勿覆盖。要么询问用户,要么——如果用户明确希望重新生成——先读取现有文件以保留已勾选的复选框。重新勾选已完成的工作很麻烦。
Document structure
文档结构
Use this template exactly. The intro paragraph, the auto-commit callout, and the test-coverage callout are non-negotiable — they teach the next agent how to use the doc.
markdown
undefined严格使用以下模板。介绍段落、自动提交提示框和测试覆盖提示框是必不可少的——它们会指导后续Agent如何使用该文档。
markdown
undefined<Feature name> — task list
<功能名称> — 任务列表
Step-by-step execution order for . Tick each task as it lands. Order is intentional: <one short sentence naming the slice order, e.g. "view first, then edit, then delete — each slice ships its types, action, UI, copy, and tests together so the app boots and the slice works after every commit">.
<relative-path-to-plan>.mdWorkflow: Each task is one logical commit. When you finish a task: (1) tick its checkbox in this file, (2) stage the implementation changes plus the ticked checkbox together, and (3) create a single commit covering both. Never create a "tick-only" commit separate from the implementation — the box moves in lockstep with the code. Do not batch multiple tasks into one commit either; the per-task granularity is what makes this list resumable and reviewable.
Working app (non-negotiable): every task must leave the app runnable and the slice it touches end-to-end functional. If a task adds UI, it adds the i18n keys, types, server actions, styles, and routes that UI needs in the same task. Never split a slice across tasks such that an intermediate commit leaves the app with missing translations (raw keys rendered), undefined imports, unimplemented action calls, dead components, or a half-wired flow. Layer-first ordering ("all types → all actions → all UI → all i18n") is wrong: prefer vertical slices that each ship one working increment.
t("…")Test coverage (non-negotiable): every task must leave the suite green AND meaningfully exercised. Before ticking a task, (a) re-run the relevant existing tests and confirm they still cover the touched behavior, and (b) add new unit/integration tests for any new function, action, branch, or UI state the task introduces. A task that adds code without adding or extending tests is not done — extend the assertions, add a new , or document in the commit message why no new test is warranted (e.g. pure type-only change). Reviewer will reject task ticks that ship untested logic.
*.test.ts(x)Dependencies & parallelism: Every task line ends with a marker listing the lower-numbered tasks that must land before it, or if it has no prerequisites. Tasks marked are independent and can be picked up in parallel by separate implementers (people or agents) from the start; any other task becomes available the moment all the tasks it names are done. Ordering is topological — a task never depends on a higher number — so working strictly top-to-bottom is always valid for a single implementer, while the markers let multiple implementers fan out safely. See the Parallelizable now line under each phase for the independent entry points.
_(deps: …)__(deps: none)_none<相对路径到计划文件>.md的分步执行顺序。完成每个任务后勾选复选框。顺序是经过精心设计的:<一句话说明切片顺序,例如“先实现查看功能,再实现编辑,最后实现删除——每个切片都会同时交付其类型、动作、UI、文案和测试,因此每次提交后应用都能正常启动且切片功能可用”>。
工作流程: 每个任务对应一个逻辑提交。完成任务后:(1) 勾选此文件中的复选框,(2) 将实现变更和勾选的复选框一起暂存,(3) 创建一个包含两者的单独提交。绝不要创建与实现分离的“仅勾选”提交——复选框的状态必须与代码同步变更。也不要将多个任务合并到一个提交中;每个任务的粒度是使该列表可恢复和可审查的关键。
可运行应用(必不可少): 每个任务完成后必须保证应用可运行,且所涉及的切片端到端可用。如果任务添加了UI,则必须在同一任务中添加该UI所需的i18n键、类型、服务器动作、样式和路由。绝不要将一个切片拆分为多个任务,导致中间提交后应用出现缺失翻译(渲染原始键)、未定义导入、未实现的动作调用、无用组件或半完成流程的情况。按层排序(“所有类型 → 所有动作 → 所有UI → 所有i18n”)是错误的:优先选择垂直切片,每个切片交付一个可用的增量功能。
t("…")测试覆盖(必不可少): 每个任务完成后必须保证测试套件全部通过且功能得到充分验证。勾选任务之前,(a) 重新运行相关的现有测试并确认它们仍然覆盖所修改的行为,(b) 为任务引入的任何新函数、动作、分支或UI状态添加新的单元/集成测试。添加代码但未添加或扩展测试的任务不算完成——要么扩展断言,要么添加新的文件,要么在提交信息中说明无需新增测试的原因(例如纯类型变更)。审查者会拒绝未测试逻辑的任务勾选。
*.test.ts(x)依赖关系与并行性: 每个任务行末尾都带有标记,列出必须先完成的编号更小的任务,如果没有前置条件则标记为。标记为的任务是独立的,从一开始就可以由不同的实现者(人员或Agent)并行处理;任何其他任务只有在其所有依赖任务完成后才能开始。任务按拓扑顺序排列——任务绝不会依赖编号更大的任务——因此单个实现者严格从上到下执行总是可行的,而标记可以让多个实现者安全地并行处理任务。查看每个阶段下的当前可并行处理行,获取独立的任务入口点。
_(deps: …)__(deps: none)_nonePhase 1 — <slice name, e.g. "View budgets"> (<optional: why this slice is first>)
阶段1 — <切片名称,例如“查看预算”>(<可选:此切片优先的原因>)
Parallelizable now: 1, 2 (no prerequisites).
- 1. <Action verb> <file path in backticks> — <what changes, including i18n keys, types, tests, and any other cross-cutting bits the slice needs to be runnable>. (deps: none)
- 2. <…> (deps: none)
当前可并行处理:1, 2(无前置条件)。
- 1. <动作动词> <反引号包裹的文件路径> — <变更内容,包括i18n键、类型、测试以及切片可用所需的任何其他跨领域内容>。 (deps: none)
- 2. <…> (deps: none)
Phase 2 — <next slice, e.g. "Edit budget">
阶段2 — <下一个切片,例如“编辑预算”>
Parallelizable now: 3 (depends only on Phase 1, which is independent of this slice's siblings).
- 3. <…> (deps: 1)
...
当前可并行处理:3(仅依赖阶段1,与该切片的同级切片无关)。
- 3. <…> (deps: 1)
...
Phase N — Verification
阶段N — 验证
- <n>. clean. (or the project's lint command)
pnpm lint - <n+1>. clean.
pnpm typecheck - <n+2>. green.
pnpm test - <n+3>. Manual smoke: <one sentence per user-visible flow to click through>.
- <n>. 检查通过。(或项目的lint命令)
pnpm lint - <n+1>. 检查通过。
pnpm typecheck - <n+2>. 全部通过。
pnpm test - <n+3>. 手动冒烟测试:<每个用户可见流程的一句话说明,需点击验证>。
Phase N+1 — Wrap-up
阶段N+1 — 收尾
- <n>. <any status-tracking the project uses, e.g. closing an issue or flipping a status to Done>.
undefined- <n>. <项目使用的任何状态跟踪操作,例如关闭问题或将状态改为完成>。
undefinedHow to break a plan into tasks
如何将计划拆分为任务
1. Read the plan carefully
1. 仔细阅读计划
Read the whole plan before writing anything. Note the sections, the "Critical files" list if present, the verification section, and any "Out of scope" callouts. The tasks list must cover everything the plan promises to ship — nothing more, nothing less.
在开始编写任何内容之前,通读整个计划。注意章节、“关键文件”列表(如果存在)、验证部分以及任何“超出范围”的提示。任务列表必须涵盖计划承诺交付的所有内容——不多不少。
2. Slice by user-visible increment, not by code layer
2. 按用户可见的增量切片,而非按代码层
Each task is a vertical slice — a small, working increment of user-visible behavior. A task that adds a button also adds the action it calls, the i18n keys for its label, the types its props need, and the tests for its behavior. After the commit, the app boots and the slice works end-to-end. No "we'll add the i18n later" task — the strings ship with the markup that consumes them.
Wrong (layer-first): Phase 1 all types → Phase 2 all actions → Phase 3 all UI → Phase 4 all i18n. This leaves the app in a non-working intermediate state for many commits — buttons render with returning the raw key, components import actions that don't exist yet, pages 404, fixtures reference fields the type doesn't expose.
t("budgets.edit")Right (slice-first):
- Phase 1 — View budgets (component + read action + types + i18n + tests)
- Phase 2 — Edit budget (component + update action + types + i18n + tests)
- Phase 3 — Delete budget (component + delete action + types + i18n + tests)
Each phase ships a fully working slice. After Phase 1's commit, you can boot the app and view budgets. After Phase 2's commit, you can view and edit. No intermediate broken state.
Within a slice, dependencies still matter — write the type before the consumer, the action before the component that calls it. But the slice is the shipping unit, and everything the slice needs to be runnable lands together in its task (or in adjacent tasks of the same phase, if the slice is genuinely large enough to split).
Cross-cutting phases stay separate at the end: Verification (lint, typecheck, tests, manual smoke) and Wrap-up (any status-tracking the project uses, e.g. issue closure).
If the plan inverts something (e.g., a refactor that must land before any new slice is added), follow the plan. The governing principle: after every committed task, boots, the touched flow works, and nothing renders raw i18n keys or throws on missing imports.
pnpm dev每个任务都是一个垂直切片——一个小的、可用的用户可见行为增量。 添加按钮的任务还需添加其调用的动作、标签的i18n键、属性所需的类型以及行为的测试。提交后,应用可以正常启动且切片端到端可用。不要有“稍后添加i18n”的任务——文案必须与使用它们的标记一起交付。
错误(按层划分): 阶段1 所有类型 → 阶段2 所有动作 → 阶段3 所有UI → 阶段4 所有i18n。这会导致应用在多次提交后处于不可用的中间状态——按钮渲染时返回原始键,组件导入不存在的动作,页面404,测试数据引用类型未暴露的字段。
t("budgets.edit")正确(按切片划分):
- 阶段1 — 查看预算(组件 + 读取动作 + 类型 + i18n + 测试)
- 阶段2 — 编辑预算(组件 + 更新动作 + 类型 + i18n + 测试)
- 阶段3 — 删除预算(组件 + 删除动作 + 类型 + i18n + 测试)
每个阶段交付一个完全可用的切片。阶段1提交后,你可以启动应用并查看预算。阶段2提交后,你可以查看并编辑预算。没有中间的崩溃状态。
在一个切片内,依赖关系仍然重要——先编写类型再编写消费者,先编写动作再编写调用它的组件。但切片是交付单元,切片可用所需的所有内容都要在其任务(或同一阶段的相邻任务,如果切片确实大到需要拆分)中一起交付。
跨领域阶段在末尾单独保留:验证(lint、类型检查、测试、手动冒烟测试)和收尾(项目使用的任何状态跟踪操作,例如关闭问题)。
如果计划有特殊要求(例如,必须先完成重构才能添加任何新切片),则遵循计划。基本原则:每次提交任务后,可以启动,所涉及的流程可用,且没有渲染原始i18n键或因缺失导入而报错的情况。
pnpm dev3. Choose the right task granularity
3. 选择合适的任务粒度
One task = one logical commit that leaves the app working. That's the test. The commit bundles the implementation diff and the ticked checkbox; never split the tick into its own follow-up commit.
A right-sized task can — and often should — span layers: types + action + component + i18n keys + tests, all in one task, as long as it stays a single coherent slice. The slice is what makes it commitable; the layers are just the parts the slice needs.
A task is too big if:
- It bundles multiple user-visible slices ("add edit and delete and duplicate").
- The user would want to review it as multiple PRs.
- It touches many unrelated areas of the codebase.
A task is too small if:
- It leaves the app non-functional after the commit (e.g. adds an i18n key with no markup using it, adds a component that's never rendered, adds an action with no caller).
- It's "add an import statement" or "rename a single variable" with no behavior change.
- Splitting it from the next task produces a commit where the app between commits is broken or the change makes no sense on its own.
Wrong-shape tasks (avoid entirely):
- ❌ "Add all i18n keys for the feature" — layer-task; UI added in earlier tasks renders raw keys until this lands.
- ❌ "Add all server actions" — layer-task; UI calling them is broken in the meantime.
- ❌ "Add types" as a standalone task with no consumer — dead code at commit time.
- ❌ "Wire up i18n" as a final step — every UI task should already have wired its own keys.
The layer-shaped task is the one to watch out for: anything phrased as "all X" or "wire up X across the feature" is a smell. Convert it into per-slice work and fold it into the slice tasks.
Good granularity examples:
- Right-sized: "Build inline budget editing — add (client; display + edit modes, inline name/amount inputs), wire to
src/components/budget-edit-row.tsx, add i18n keysupdateBudgettobudgets.edit.{label,save,cancel,error}+messages/en.json, addmessages/de.jsoncovering both modes." — one slice, one commit, app is runnable and editing works after it lands.budget-edit-row.test.tsx - Right-sized (foundational): "Add to
updateBudget({ id, name, amount, categories })(zod schema =src/actions/budgets.ts+createBudgetSchema, throwsid, revalidates"NOT_FOUND"+/[locale]/budgets) paired with the component task in the same slice so no commit ships an action with no caller."/[locale]/budgets/manage - Too big (avoid): "Build the manage page" — bundles three slices (view + edit + delete) into one commit; should be three tasks.
- Layer-shaped (avoid): "Add i18n keys for budgets manage page" as its own task at the end — split the keys across the slice tasks that actually use them.
一个任务 = 一个使应用保持可用的逻辑提交。 这是判断标准。提交包含实现变更和勾选的复选框;绝不要将勾选操作拆分为单独的后续提交。
大小合适的任务可以——而且通常应该——跨多个层:类型 + 动作 + 组件 + i18n键 + 测试,都在一个任务中,只要它保持为一个连贯的切片。切片是使其可提交的原因;层只是切片所需的组成部分。
任务过大的情况:
- 包含多个用户可见切片(“添加编辑和删除和复制功能”)。
- 用户希望将其拆分为多个PR进行审查。
- 涉及代码库中许多不相关的区域。
任务过小的情况:
- 提交后应用不可用(例如,添加了i18n键但没有使用它的标记,添加了从未渲染的组件,添加了没有调用者的动作)。
- 只是“添加导入语句”或“重命名单个变量”且没有行为变更。
- 将其与下一个任务拆分后,中间提交的应用处于崩溃状态,或者变更本身没有意义。
错误形状的任务(完全避免):
- ❌ “添加功能的所有i18n键”——按层划分的任务;之前任务添加的UI在完成此任务前会渲染原始键。
- ❌ “添加所有服务器动作”——按层划分的任务;调用它们的UI在此期间会崩溃。
- ❌ “添加类型”作为没有消费者的独立任务——提交时的无用代码。
- ❌ “连接i18n”作为最终步骤——每个UI任务都应该已经连接了自己的键。
要特别注意按层划分的任务:任何表述为“所有X”或“在整个功能中连接X”的任务都是不良信号。将其转换为每个切片的工作,并合并到切片任务中。
合适粒度的示例:
- 大小合适: “构建内联预算编辑功能——添加(客户端;显示+编辑模式,内联名称/金额输入框),连接到
src/components/budget-edit-row.tsx,在updateBudget+messages/en.json中添加i18n键messages/de.json,添加budgets.edit.{label,save,cancel,error}覆盖两种模式。”——一个切片,一个提交,提交后应用可运行且编辑功能可用。budget-edit-row.test.tsx - 大小合适(基础功能): “在中添加
src/actions/budgets.ts(zod schema =updateBudget({ id, name, amount, categories })+createBudgetSchema,抛出id,重新验证"NOT_FOUND"+/[locale]/budgets)与同一切片中的组件任务配对,这样就不会提交没有调用者的动作。”/[locale]/budgets/manage - 过大(避免): “构建管理页面”——将三个切片(查看+编辑+删除)合并到一个提交中;应该拆分为三个任务。
- 按层划分(避免): “为预算管理页面添加i18n键”作为单独的最终任务——将键拆分到实际使用它们的切片任务中。
4. Write each task as a concrete instruction
4. 将每个任务编写为具体指令
Each bullet should answer: what file, what change, what constraints.
Pattern:
- [ ] **<N>.** <Verb> <file in backticks> — <one sentence of what changes, including any tricky constraint in parens>.Verbs that work well: , , , , , , , .
AddBuildUpdateRewriteExtractWire upExtendFlipInclude in parens any constraint that matters for correctness: zod schemas, revalidation paths, error codes, props, edge cases. The implementer should not have to re-read the plan to get the task right — but the plan should remain the source of truth for design rationale.
Example transformations (plan prose → task line):
Plan: "Add — zod schema mirrors plus . Throw if missing. Revalidate and ."
updateBudget({ id, name, amount, categories })createBudgetSchemaid"NOT_FOUND"/[locale]/budgets/[locale]/budgets/manageTask: updateBudget({ id, name, amount, categories })src/actions/budgets.tscreateBudgetSchemaid"NOT_FOUND"/[locale]/budgets/[locale]/budgets/manage
- [ ] **7.** Add to(zod schema =+, throws , revalidates +).Plan: ": Add optional prop (default ). Replace the hard-coded path with ."
src/components/budget-period-picker.tsxbasePath?: string"/budgets"${basePath}?year=&month=Task: basePath?: string"/budgets"src/components/budget-period-picker.tsx${basePath}?year=&month=
- [ ] **18.** Add optional prop (default) to ; replace the hard-coded path with .每个项目符号应回答:什么文件,什么变更,什么约束。
格式:
- [ ] **<N>.** <动词> <反引号包裹的文件> — <一句话说明变更内容,包括括号中的任何复杂约束>。适用的动词:、、、、、、、。
AddBuildUpdateRewriteExtractWire upExtendFlip括号中包含对正确性重要的任何约束:zod schemas、重新验证路径、错误代码、属性、边缘情况。实现者无需重新阅读计划即可正确完成任务——但计划仍然是设计理由的来源。
示例转换(计划文本 → 任务行):
计划:“添加——zod schema镜像并添加。如果不存在则抛出。重新验证和。”
updateBudget({ id, name, amount, categories })createBudgetSchemaid"NOT_FOUND"/[locale]/budgets/[locale]/budgets/manage任务:src/actions/budgets.tsupdateBudget({ id, name, amount, categories })createBudgetSchemaid"NOT_FOUND"/[locale]/budgets/[locale]/budgets/manage
- [ ] **7.** 在中添加(zod schema = +,抛出,重新验证+)。计划:“:添加可选属性(默认值)。将硬编码路径替换为。”
src/components/budget-period-picker.tsxbasePath?: string"/budgets"${basePath}?year=&month=任务:src/components/budget-period-picker.tsxbasePath?: string"/budgets"${basePath}?year=&month=
- [ ] **18.** 为添加可选属性(默认值);将硬编码路径替换为。5. Number tasks globally, group by phase
5. 全局编号任务,按阶段分组
Numbers run 1..N across all phases (don't restart per phase). The number is what people quote when discussing a task ("I'm on task 14"). Phase headers exist for grouping and ordering rationale, not for numbering.
编号在所有阶段中从1到N连续(每个阶段不重新开始编号)。编号是人们讨论任务时引用的标识(“我正在处理任务14”)。阶段标题用于分组和说明顺序理由,而非编号。
6. Annotate dependencies and mark parallelizable tasks
6. 标注依赖关系并标记可并行任务
Every task carries a marker so a reader can tell, at a glance, what must land first and what can be built independently. This is what lets the work fan out across multiple implementers instead of forcing a single serial chain.
_(deps: …)_What a dependency is. Task B depends on task A when B's code cannot be written, compiled, or tested without A already in place — B imports a type A defines, calls an action A adds, renders a component A builds, or asserts against a fixture A creates. If B can be implemented and its tests pass with A absent, B does not depend on A, even if they live in the same feature.
What is not a dependency. Don't manufacture edges from mere thematic grouping ("both touch budgets") or from preferred review order. Two independent slices in the same phase should each read or point only at a shared foundation — not at each other. Over-declaring dependencies silently kills parallelism, so be strict: list an edge only when removing it would break the build or the tests.
_(deps: none)_How to derive the markers:
- List the concrete artifacts each task produces (a type, an action, a component, a route, a set of i18n keys, a migration).
- For each task, find which of those artifacts it consumes. The producing tasks are its dependencies.
- Record them as the lower task numbers: . A task that consumes nothing produced by an earlier task is
_(deps: 4, 7)_._(deps: none)_
Ordering. Sort tasks so the graph is topological — every dependency has a lower number than the task that needs it (no forward references). Within that constraint, keep vertical slices contiguous (don't interleave Phase 2's tasks into Phase 1) and put independent, prerequisite-free tasks early so implementers can start them immediately.
Mark the parallel entry points. Under each phase header, add one italic line — — naming the tasks in that phase whose dependencies are all satisfied by the time the phase opens (i.e. everything they need is either or in an already-completed earlier phase). These are the tasks a second implementer can pick up without waiting. If a phase has a single strictly-serial chain, say so:
_Parallelizable now: <task numbers> (<why>)._none_Sequential: 5 → 6 → 7 (each builds on the last)._Worked example. A "Manage budgets" feature:
- 1. Add type +
BudgettobudgetSchema. (deps: none)src/types/budget.ts - 2. Add keys
messages/{en,de}.json. (deps: none) — pure copy, needs nothing.budgets.manage.* - 3. Add to
listBudgets()+ test. (deps: 1) — returnssrc/actions/budgets.ts.Budget[] - 4. Add to
updateBudget()+ test. (deps: 1) — independent of 3; both only need the type.src/actions/budgets.ts - 5. Build (renders
budget-list.tsx, useslistBudgets) + test. (deps: 2, 3)budgets.manage.* - 6. Build (calls
budget-edit-row.tsx, usesupdateBudget) + test. (deps: 2, 4)budgets.manage.*
Tasks 1 and 2 are parallel from the start. Once 1 lands, 3 and 4 run in parallel. 5 and 6 are independent of each other and each unblock as soon as their own deps finish. A single implementer still just goes 1→6 top to bottom.
Keep the dependency annotation aligned with the same correctness rule the rest of this skill enforces: a task and its dependencies must still, when committed in order, leave the app runnable after each commit. Parallelism is about who can work simultaneously — it never licenses an intermediate commit that breaks the build.
每个任务都带有标记,这样读者可以一眼看出必须先完成哪些任务,哪些任务可以独立构建。这使得工作可以由多个实现者并行处理,而不是强制串行执行。
_(deps: …)_什么是依赖关系。 当任务B的代码无法在任务A未完成的情况下编写、编译或测试时,任务B依赖于任务A——B导入A定义的类型,调用A添加的动作,渲染A构建的组件,或断言A创建的测试数据。如果在A不存在的情况下B仍然可以实现且测试通过,则B不依赖于A,即使它们属于同一功能。
什么不是依赖关系。 不要仅仅因为主题分组(“都涉及预算”)或首选审查顺序而创建依赖关系。同一阶段的两个独立切片应分别标记为或仅指向共享基础——而非彼此。过度声明依赖关系会悄无声息地扼杀并行性,因此要严格:只有移除依赖关系会导致构建或测试失败时才列出。
_(deps: none)_如何生成标记:
- 列出每个任务产生的具体产物(类型、动作、组件、路由、i18n键集合、迁移)。
- 对于每个任务,找出它消耗的那些产物。产生这些产物的任务就是它的依赖项。
- 将它们记录为编号更小的任务:。如果任务不消耗任何早期任务产生的产物,则标记为
_(deps: 4, 7)_。_(deps: none)_
排序。 对任务进行排序,使其形成拓扑图——每个依赖项的编号都小于需要它的任务(没有向前引用)。在这个约束下,保持垂直切片连续(不要将阶段2的任务插入到阶段1中),并将独立的、无前置条件的任务放在前面,以便实现者可以立即开始处理。
标记并行入口点。 在每个阶段标题下,添加一行斜体文本————列出该阶段中所有依赖项在阶段开始时已满足的任务(即它们需要的所有内容要么是,要么在已完成的早期阶段中)。这些是第二个实现者无需等待即可处理的任务。如果阶段是单一的严格串行链,则说明:
_当前可并行处理:<任务编号>(<原因>)。_none_串行:5 → 6 → 7(每个任务都基于前一个构建)。_示例。 “管理预算”功能:
- 1. 在中添加
src/types/budget.ts类型 +Budget。 (deps: none)budgetSchema - 2. 在中添加
messages/{en,de}.json键。 (deps: none) — 纯文案,无需依赖。budgets.manage.* - 3. 在中添加
src/actions/budgets.ts+ 测试。 (deps: 1) — 返回listBudgets()。Budget[] - 4. 在中添加
src/actions/budgets.ts+ 测试。 (deps: 1) — 独立于3;两者都只需要类型。updateBudget() - 5. 构建(渲染
budget-list.tsx,使用listBudgets) + 测试。 (deps: 2, 3)budgets.manage.* - 6. 构建(调用
budget-edit-row.tsx,使用updateBudget) + 测试。 (deps: 2, 4)budgets.manage.*
任务1和2从一开始就可以并行处理。任务1完成后,任务3和4可以并行处理。任务5和6彼此独立,各自在其依赖项完成后即可开始。单个实现者仍然可以按1→6的顺序从上到下执行。
依赖标注必须与本技能所遵循的正确性规则保持一致:按顺序提交任务及其依赖项后,每次提交后应用都必须保持可用。并行性是关于谁可以同时工作——绝不允许中间提交导致构建失败。
7. Always include verification and wrap-up phases
7. 始终包含验证和收尾阶段
- Verification phase: Whatever the project uses for static checks (lint, typecheck) + tests + a one-line manual smoke covering the user-visible flow. If the plan has a "Verification" section, base this on it. If it doesn't, derive checks from the project's conventions (look at scripts, CLAUDE.md, etc.).
package.json - Wrap-up phase: Anything that marks the feature done in the project's tracking system, if it uses one — e.g. closing a GitHub issue, updating a CHANGELOG, flipping a status to Done.
- 验证阶段: 项目使用的任何静态检查(lint、类型检查)+ 测试 + 涵盖用户可见流程的一句话手动冒烟测试。如果计划有“验证”部分,则基于该部分。如果没有,则根据项目惯例推导检查内容(查看脚本、CLAUDE.md等)。
package.json - 收尾阶段: 如果项目使用跟踪系统,则包含任何标记功能完成的操作——例如关闭GitHub问题、更新CHANGELOG、将状态改为完成。
8. Don't invent scope
8. 不要新增范围
The task list must not introduce work the plan didn't agree to. If the plan says something is "Out of scope," don't add tasks for it. If the plan is vague on a detail, leave the task line aligned with the plan's level of detail — don't fabricate constraints.
If the plan has a gap that blocks task generation (e.g., no acceptance criteria for a non-trivial flow), flag it back to the user instead of guessing.
任务列表不得引入计划未约定的工作。如果计划说明某内容“超出范围”,则不要为其添加任务。如果计划在某个细节上模糊不清,则任务行应与计划的详细程度保持一致——不要编造约束。
如果计划存在阻碍任务生成的缺口(例如,非 trivial 流程没有验收标准),则向用户指出该缺口,而非猜测。
Self-check before saving
保存前的自我检查
Before writing the file, run this mental checklist:
- Every "Critical files" entry in the plan appears in at least one task.
- Each task fits in one logical commit (not too big, not too small).
- Every task line ends with a marker listing its lower-numbered prerequisites, or
_(deps: …)_if it has none._(deps: none)_ - All declared dependencies point to lower task numbers — the order is topological, no forward references.
- Dependency edges are real (an artifact a task consumes is produced by the task it names); no edges invented from mere theme or review order.
- Every phase has a (or
_Parallelizable now: …_) line naming the tasks that can start once the phase opens._Sequential: …_ - At least the genuinely independent, prerequisite-free tasks are marked and ordered early.
_(deps: none)_ - After every task, boots and the slice that task touches is functional end-to-end — no dangling i18n keys rendered as raw
pnpm dev, no unimplemented action calls, no orphan components, no broken imports.t("…") - No layer-shaped tasks (no standalone "add all i18n keys", "add all actions", "wire up types"); cross-cutting concerns are folded into the slice tasks that need them.
- Phases are named by slice/user-visible increment (e.g. "View budgets"), not by code layer (e.g. "Types", "Actions").
- Verification phase covers the project's static checks + tests + a manual smoke.
- Wrap-up phase reflects the project's tracking conventions, if any.
- The intro names the plan file and states the slice order in one sentence.
- The auto-commit workflow callout is present and unmodified — and it tells the implementer to tick the box and commit the tick together with the code in a single commit (never a separate tick-only commit).
- The working-app callout is present and unmodified.
- The test-coverage callout is present and unmodified.
- Task numbers run 1..N globally; no gaps, no restarts per phase.
在写入文件之前,运行以下心理检查清单:
- 计划中的每个“关键文件”条目都出现在至少一个任务中。
- 每个任务都适合作为一个逻辑提交(不过大,不过小)。
- 每个任务行末尾都带有标记,列出其编号更小的前置条件,或标记为
_(deps: …)_(如果没有)。_(deps: none)_ - 所有声明的依赖项都指向编号更小的任务——顺序是拓扑顺序,没有向前引用。
- 依赖关系是真实的(任务消耗的产物由它所引用的任务产生);没有仅仅基于主题或审查顺序而创建的依赖关系。
- 每个阶段都有(或
_当前可并行处理:…_)行,列出阶段开始时可以启动的任务。_串行:…_ - 至少真正独立的、无前置条件的任务被标记为并排在前面。
_(deps: none)_ - 每个任务完成后,可以启动且该任务涉及的切片端到端可用——没有渲染为原始
pnpm dev的悬空i18n键,没有未实现的动作调用,没有孤立组件,没有缺失导入导致的崩溃。t("…") - 没有按层划分的任务(没有独立的“添加所有i18n键”“添加所有动作”“连接类型”任务);跨领域关注点被合并到需要它们的切片任务中。
- 阶段按切片/用户可见增量命名(例如“查看预算”),而非按代码层命名(例如“类型”“动作”)。
- 验证阶段涵盖项目的静态检查 + 测试 + 手动冒烟测试。
- 收尾阶段反映项目的跟踪惯例(如果有)。
- 介绍部分命名了计划文件,并以一句话说明了切片顺序。
- 自动提交工作流程提示框存在且未修改——它告诉实现者要将勾选复选框的操作与代码一起提交为一个单独的提交(绝不单独提交仅勾选的操作)。
- 可运行应用提示框存在且未修改。
- 测试覆盖提示框存在且未修改。
- 任务编号从1到N全局连续;无空缺,每个阶段不重新开始编号。
After saving
保存后
State briefly: "Saved task list to . <N> tasks across <K> phases. Start with task 1." Don't dump the whole list back into chat — the user will open the file.
<path>简要说明:“任务列表已保存到。共<K>个阶段,<N>个任务。从任务1开始。”不要将整个列表重新发送到聊天中——用户会打开文件查看。",
<路径>