关于 write-tasks
Write Tasks 是一项将产品定义及可用的技术规格转为可执行任务图的技能。它生成任务文件和供实现 Agent 或调度器使用的清单,并明确依赖、范围和前置检查。
主要功能
- 01生成任务文件与图清单
- 02项目约束前置检查
- 03明确依赖关系的归属
- 04声明任务范围与路径
- 05按纵向切片拆分任务
- 06检查技能覆盖情况
适用场景
- 01将已批准的规格拆分为实现任务
- 02定义任务依赖以安排执行批次
- 03拆分规格前检查工具授权
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ marcioaltoe/ skills --skill write-tasks安装后在 Claude Code 中输入/write-tasks确认已加载。
附带文件references/task-template.md
详细介绍
编写任务
将 docs/specs/<slug>/_prd.md(以及存在时的 _techspec.md)转化为可执行的任务图:每个任务对应一个 task_NN.md,另有 _tasks.md,作为 implement-task、implement-spec 及任何未来守护进程据以安排工作的清单。这些产物就是约定——全新的 Agent 会话必须能够仅凭规格文件夹中的内容,拿起任意一个任务文件并完成构建。
轻量级规划
complexity: low 且非 QA、不声明任何 Governed Path 的任务使用轻量级层级。作者可以在规划 Pull Request 合并前运行 roundfix spec judge <slug> --stage tasks,获取供参考的层级建议;该建议不会控制任务分派。
前置条件
$ARGUMENTS 指定规格。_prd.md 必须存在。如果某项具有实际架构影响的功能缺少 _techspec.md,先运行 write-techspec,然后再分解任务——补写缺失产物才是解决方法,绝不是停止并请求许可的理由。在自主工作中无需确认:根据 docs/agents/autonomous-work.md,指示开展自主工作即授权为已批准队列中的每份 Spec 完成整个编写链。只有在明确要求不编写技术规格就进行分解时,才请求确认;此时应在分解前深入探索代码库作为补偿。
Project 约束预检
在制定或批准任务拆分前运行此预检:
- 对 Spec 进行分类。位于已解析归档目录下的 Spec(内置
docs/specs根目录对应docs/history/specs/,外部或非默认根目录对应<spec-root>/_archived/),或经证实在本约定生效前已完成的 Spec,均属于已完成或已归档的旧版 Spec。所有旧版产物必须保持字节级不变:不得补录、重新格式化、重新生成或以其他方式改写。 - 对于每个仍处于活动状态、未归档且尚未完成的 Spec,要求 PRD 和所有已存在的 TechSpec 都包含完整的
Project Constraints章节。每个章节必须按适用情况记录Identifier strategy、Authentication and HTTP、Active ADR obligations和Tooling authority,或注明不适用及其原因;每一行都必须引用其所依据的docs/agents/源路径。 - 如果任一活动文档缺失或不完整,则拒绝创建或更新
_tasks.md或任何 Task 文件。列明所有缺失的条目、原因或源路径,并将 Spec 退回给负责的作者技能。 - 检查拟议切片是否涉及创建、编辑、重命名、移动或删除仓库工具配置、脚本、忽略文件、插件声明或版本固定项。只有当 PRD 和已存在的 TechSpec 明确记录维护者授权,并列出该授权涵盖的确切仓库相对路径时,才允许此类工作。笼统的实现请求、设置批准或 Task 指派均不构成授权。若缺少授权或限定路径,则拒绝拆分。
- 对于每个工具相关切片,解析
<spec-root>/<slug>/_authorization.md中的有效记录。记录缺失、状态为proposed或没有授权日期,均不构成授权;在有效授权生效前拒绝拆分。新的授权或扩大后的授权必须先进入目标提交历史,之后才能进行使用该授权的 squash 交付;不得将授权或其修订合并到它所授权的变更中。 - 将限定的文件列表复制到每个获准的工具相关 Task 的范围和验收标准中。Task 除自身 Task 文件外,只能修改这些路径;需要不同边界的工作必须拆分。
- 记录中的
operations列表必须授权 Spec 将使用的每种交付操作。若记录缺少implement、commit、push、pull_request或merge中的任一项,roundfix deliver start将拒绝执行;没有 Governed Path 的 Spec 应记录paths: []。
依赖关系仍仅由 _tasks.md 负责;Task 状态仍仅由各 Task 文件负责。预检不会转移这两项职责。
通过为目标系统构建非测试代码来验证面向其他操作系统的代码,例如 GOOS=windows go build -buildvcs=false ./<package>;不得使用 go vet,因为它也会编译为主机编写的测试。
归属规则(内容放在哪里,以及原因)
- 依赖关系只存在于
_tasks.md图中。 绝不要放在任务文件中。边的两个副本会导致图逐渐偏离。 - 状态只存在于各任务文件的 frontmatter 中。
_tasks.md管理拓扑结构,而非进度——调度器会重新读取任务文件以获取状态。 - 每个任务文件都必须指定 Task Type。 必须且只能使用
backend、frontend、data、infra、docs、test、chore或qa之一。将qa保留给清单qa:字段指定的唯一、编写完成的终端门禁。 Implement Command 会使用此值进行路由,并拒绝缺失或未知的值;绝不要留下占位符,也不要等到之后再推断类型。 - 引用内容,不要重复内容。 任务文件按名称指向 PRD/TechSpec 章节;重复说明规范的任务会在规范首次修订时过时。在所属 Spec 中,采用的源文件必须通过采用后的路径链接,并使用相对于该任务文件的目标路径,绝不要链接到采用前的来源路径。次级 Spec 链接到主归属方的副本,不采用任何内容。
所属方的归档会执行 Archive Relink:将该副本提升到
docs/references/,并重写次级 Spec 的链接,因此源文件只有一个归属方,次级 Spec 无需副本(ADR-0260、ADR-0083)。 - Context 条目是带标签的路径。 仅当任务需要标准 Spec 包之外的特定指令或接口路径时,才添加
## Context。使用以下项目符号格式:- instruction: <path>、- interface: <path>、- creates: <path>或- deletes: <path>。路径必须整洁、 相对于仓库,且不重复; 每个任务最多可声明 50 个唯一条目。Daemon 会先预留这些路径, 再用之前更改过的文件填充 200 路径的 Spec Context Bundle。 - 声明的编辑内容和受管路径必须明确列出。 任务编辑的每个路径都必须在
interface:或creates:下声明;删除的每个路径都必须在deletes:下声明,绝不能放在instruction:下。删除操作会跳过未解析引用检查,并计入范围、Governed Path 和 Wave 冲突审计。如果已声明的删除路径仍然存在,Daemon 会在 Verification 前拒绝结算,并报错deletes: <path> still exists。instruction:路径是只读的,绝不会导致两个任务冲突。每个更改命令的任务都必须声明其更改的那个命令文件:.agents/skills/roundfix/references/<command>.md及其镜像文件,以及docs/user-guide/commands/<command>.md;除非更改的是入口文件本身,否则绝不要声明技能的SKILL.md或commands.md。声明相同文件的两个任务不能处于同一个 Wave,因此,更改不同命令的任务可以同时运行,而更改同一命令的任务之间必须有一条边。 声明的或 Verification 读取的 Governed Path 必须出现在 Spec 的_authorization.md的paths:中,以及两行bounded files:中,否则会拒绝编写,并报错SC-TOOLING-UNDECLARED。提及 CLI 界面的任务必须通过自身或其依赖的任务列出对应技能或指南;否则会报告SC-CLI-UNDOCUMENTED。
Daemon 会在提交时将任务更改但未在 ## Recorded paths 下声明的路径记录下来。QA 范围审计会将记录的路径视为已声明,而记录仅披露更改,不会预留路径。规则仍然是声明所有可预见的路径。
两个任务都可能更改的测试辅助工具、伪对象、夹具或黄金文件,都是可预见路径。在每个可能更改它的任务中,都要在 interface: 下声明该路径,这样 roundfix spec check --strict 就能在 Spec 仍处于编写阶段时报告 SC-WAVE-COLLISION,而其指出的 needs 边会让这些任务依次运行。记录不会预留路径,但任务的结算提交是冲突证据:当同一 Wave 中的两个任务都更改了同一个未声明文件时,QA 门禁的前置条件会在两个任务均已运行后,以 SC-WAVE-COLLISION 拒绝此次 Run。
已变更行为界面的技能任务
如果存在,请阅读仓库的技能覆盖映射 docs/references/skill-coverage.json。对于任何被覆盖的行为界面,若某个非 QA 任务在 interface:、creates: 或 deletes: 下声明了其源,则必须包含一个非 QA 技能任务,在 interface: 或 creates: 下声明其涵盖的技能文件之一。SC-SKILLS-UNTASKED 会报告没有此类任务的界面。
当变更不需要技能文本时,在 PRD 的可选 ## Skills 部分记录 - unchanged: <surface id> — <reason>,并包含一个在 interface: 或 creates: 下声明该映射的非 QA 任务,以记录覆盖审查。仅有该条目不能豁免该界面。SC-SKILLS-MALFORMED 会报告格式不符的条目、未知界面或空白原因。这两条规则从添加映射的提交开始生效;没有映射的仓库跳过这两条规则。
在 interface:、creates: 或 deletes: 下声明 docs/user-guide/ 下 Markdown 页面的一项非 QA 任务,也必须在 interface: 或 creates: 下声明 docs/references/behavior-surfaces.json,并在需求中注明 -record-skill-coverage 步骤。其他任务不能代为覆盖:指南任务自身的验收检查会核对其指纹。对于已包含该记录的仓库,SC-SURFACE-RECORD-UNTASKED 会在 Tasks 阶段报告任一缺漏,且不设期限。
分解规则
要验证针对另一种操作系统的代码,应为该系统构建其非测试代码,例如 GOOS=windows go build -buildvcs=false ./<package>,绝不能使用 go vet,因为它也会编译为主机编写的测试。
-
垂直切片。 每项任务都要在其涉及的每一层交付一条范围狭窄但完整的路径,可独立演示或验证——即追踪弹,而不是分层任务(“所有架构”是错误的任务;“过期导入会重试并显示其状态”是正确的任务)。
-
先做预构造。 如果某个切片需要先打好基础,就将其作为单独的前置任务:先让变更容易做,再做容易的变更。
-
编写 Spec 时刻画外部界面。 当 Spec 跨越适配器、契约或数据库等外部界面时,编写一个刻画任务,记录真实边界的行为,而非虚构对象的行为,这样不成立的前提会在编写 Spec 时暴露,而不是等到 QA 阶段才发现。
将其列入
needs,而不只是放在文件前面。 每个前提依赖于刻画结果的任务,都必须在_tasks.md的needs条目中声明该刻画任务。执行批次仅根据needs构建,因此,仅仅在清单中排在后面的任务,可能会与其所依赖的刻画任务处于同一批次,并读取一个尚未刻画的边界。文件顺序不等于依赖关系。刻画任务会触及真实边界,因此必须明确限定范围。 其文件必须按名称注明将访问的目标。它应只读,或在任务自行创建并移除的隔离实例上运行;默认情况下,绝不能针对共享或生产状态进行刻画。它只能使用权限范围不超过该目标所需范围的凭据,遵循取消操作,并在失败时也清理其创建的内容。若刻画必须执行写入,则该写入必须像任何其他不可逆操作一样在任务中获得授权——记录边界的行为并不意味着有权更改边界。 它的 Verification 验证的是记录,而不是边界。 Daemon 会通过 shell 原样运行 Task 声明的
## Verification命令:在 Agent 轮次开始前,针对未更改的代码树运行一次;在结算时再运行一次。此流程不会读取上文的边界:这些边界约束 Agent,而 Daemon 并不是 Agent。因此,任何触及真实外部界面的 Verification 都会不受边界约束地触及它,而且会触及两次,包括在任何工作开始之前。验证 Task 记录的特征——其形态、是否存在,以及下游 Task 将读取的内容——并将边界调用留在 Agent 轮次中,在那里适用 Task 声明的目标、隔离、凭据和写入授权。这就是这些命令本身已遵循的隔离性规则;在最容易让人破例之处明确重申:实时外部界面属于环境状态,依赖此类界面的命令不具备隔离性。 -
规模适合一次全新会话。 Task 应能由 Agent 在一次专注工作中,使用全新上下文完成。子任务或文件超过约 7 个时,应拆分。
-
测试嵌入 Task,绝不单独分离。 每个 Task 的验收标准都必须包含自身测试;如果最后还有一个“编写测试”Task,就说明前面的 Task 实际上都还没完成。
-
可独立实现。 完成
needs中的依赖项后,Task 不应再依赖任何其他未完成工作——这才能在之后通过多个工作树并行执行。 -
Verification 必须具备隔离性、可移植性、证明效果,并由 Daemon 负责。 每个 Task 的
## Verification命令都必须能在全新工作树中仅依靠仓库状态、声明的配置和 Task 自带的设置运行。除非 Task 明确创建了相应状态,否则不得依赖未跟踪的本地文件、之前的 Run、交互式提示、已推送的分支或机器的环境状态。使用可移植的 shell 写法:Task 门禁中优先使用grep,而非rg;避免使用在不同平台上结果不一致的wc管道断言;需要构建时,使用go build -buildvcs=false ./...之类的仓库构建标志。Task 必须通过可执行检查证明自身效果;Run 级门禁不会证明其他方面没有回归。不要在每个 Task 中添加整个包的测试套件命令来覆盖回归。每条 Verification 命令都必须能在没有完成任何工作的情况下失败:如果命令提及的测试不存在,或没有选中任何测试,但命令仍以零状态码退出,那么该命令就没有实际效果。Verification 命令只有以零状态码退出才算通过。Verification 命令中绝不能包含反引号:行内代码片段会在第一个反引号处结束并截断命令,因此应使用.之类的正则表达式字符类进行匹配。对于成功条件是结果为空或字符串不存在的断言,使用能让该条件以零状态码退出的形式:matches="$(find path -name '*.tmp' -print)" || exit 1; test -z "$matches"、test -d path && ! grep -rq 'forbidden' path,或者在失败时必须打印匹配项的情况下使用find path -name '*.tmp' -print > /tmp/matches.txt 2>&1 || { cat /tmp/matches.txt; exit 1; }; test ! -s /tmp/matches.txt || { cat /tmp/matches.txt; exit 1; }。拒绝只由全仓库门禁和工作树洁净度检查组成、且不受实际工作影响的写法;没有完成任何 Task 工作时,这些检查最容易通过。Daemon 会在 Agent 轮次结束后运行这些命令,并可能只针对失败项发送一条 Verification Feedback 提示;不要要求 Agent 自行运行权威门禁。 使用 Shared Contract 的套件是例外;请参阅 Shared Contract 的使用者。 -
受门控的图会使仓库 Verification 保持绿色。 每个包含已编写 QA 门控的图中的 Task,都会在 Task 结束时使仓库 Verification 保持绿色,因为 Daemon 会在每个 Task 结束时运行该命令。
verification.repository_at_settlement是操作者用于此结算检查的开关;它不是编写时可选择的选项。 -
Task 声明必须明确。 当某个 Task 的 Verification 命令相互独立且每条命令都必须在失败后运行时,可以声明
verification: independent;不要根据 shell 文本推断这一点。仓库门控为红色时,只能允许列在冻结的_authorization.mdprecondition_repairs清单中的 Task,且 Task 或 Agent 都不能扩充该清单。creates: docs/adr/NNNN-...声明会认领该 ADR 序号;若树中已有重复项或存在活动 Spec 认领,则会以SC-ORDINAL-CLAIMED拒绝。 -
时间前置条件不会授予权限。 将未来发布、外部观察、生成的序号或其他时间前置条件表示为带有证据负责方的具名前置条件。它绝不会凭空产生发布权限,也不会将预期的未来事实变成已完成的 Task 工作。
-
验收和测试接缝必须体现契约。 编写基于属性的验收标准,说明在有意义的输入和故障边界下,哪些内容仍然成立。指出能够因回归而失败的最窄测试接缝;必要时包括公开用例或持久化行为,并更新受影响的现有契约,而不是添加一个无法因同一缺陷而失败的平行测试。声明需要新增测试类别时,请确认仓库门控确实会运行该测试。
-
保持 Spec 提交范围精简。 Task 的提交只包含已验收的切片及其测试或文档;不要捆绑无关的清理工作或前置工作。按照图和证据分别排序前置修复和后续修复。
-
要求必须能够同时满足。 如果 Task 声明的
MUST和MUST NOT条款要求并禁止同一个具名状态,则拒绝该 Task。不要将无法满足自身书面契约的工作交给 Agent Session。 -
门控演练必须声明其证据。 标题说明要演练或证明门控的 Task,必须包含
## Rehearsal Cases,并为每个必须演练的案例添加一条- Case: <case>; Observation: <observation>条目。若缺少该部分,或任一条目缺少案例或观察结果,则拒绝该 Task。 -
至少一条验收行必须依赖 Spec 未编写的证据。 图中至少一条具名验收行必须依赖源自 Spec 自身产物以外的证据——例如 Spec 未构建的仓库、Spec 未设计的测量结果或已发表文献——并记录该证据的来源。演练能证明代码符合要求;只有外部来源才能证明要求本身正确。若在编写 Task 期间无法获取该来源,则分解过程无需人工介入即可继续,并将该行记录为受阻及其原因。受阻行会带入 QA 门控,在报告中触发
rows_blocked_environment条目,并阻止 PR 准备工作。 -
指定 QA 门控无需联网即可检查的来源:规划变更提交在
docs/references/下的文档,或验收行引用其具体段落的已发表文献。绝不要引用仅存在于操作者机器上的产物、其他仓库的清单,或 Spec 授权所禁止的查询结果;编写该行时,应将需要联网或开放 Pull Request 的判定标准列入 Unreachable Acceptance。 -
声明跨 Spec 前置依赖。 如果某个 Task 的 Verification 或前提依赖于另一个尚未合并的 Spec,请在 manifest 的
requiresfrontmatter 中列出该 Spec,并在 TechSpec 的 Build Order 中说明依赖关系;在每项前置依赖合并之前,Delivery Queue 不会启动该 Spec。 -
提交和推送不属于 Task 标准。 Daemon 负责 Task 提交、Run 集成以及任何已配置的推送。切勿在 Task 的 Requirements、Subtasks、Acceptance Criteria 或 Verification 命令中加入提交、推送、创建 PR 或发布分支的要求。
编写 QA 门禁决策
每个 Spec 遵循同一顺序:实现包含已编写门禁的图,运行已配置的 PR 前审查,在分支上归档,通过仓库门禁,创建 Pull Request,验证当前 HEAD 的检查,然后合并。
ADR-0091 要求在创建任何 Pull Request 之前执行已编写的 QA 门禁,而 ADR-0080 允许环境受阻的条目凭借等效证据通过。Spec 0078 证明了这条路径:十八个条目中有十一个受阻,其中九个是因为没有未关闭的 Pull Request;这九个条目均有记录的 payload、命令运行器和事件流证据支持。
按照 QA Task 合同编写的每个活动 Spec,都必须在分解期间从以下两种形式中恰好选择一种:
- 包含门禁。 在
_tasks.mdfrontmatter 中添加qa: task_NN,指定一个type为qa的task_NN.md。将该节点设为终端节点,并确保其needs列表涵盖所有非 QA 叶节点,这样门禁就不会在图中的任何分支完成之前运行。 - 不启用门禁。 在
_tasks.mdfrontmatter 中添加qa: declined和非空的qa_reason。不启用门禁时,不得生成qaTask。
合同生效后创建的图若未声明任何一种形式、同时声明了两种形式、存在未命名的 qa Task,或门禁不是终端节点,均属缺陷。拒绝生成此类图。只有在确认某个旧版图早于合同时,才允许缺少声明;此类图应保持字节完全一致。
无论图采用哪种形式,其收尾节点还要执行术语表检查——若包含门禁,则由已编写的 qa Task 执行;否则由拓扑顺序中的最后一个 Task 执行。将检查安排在该节点,确保 Spec 新增、修改或弃用的术语能在工作尚未关闭时被发现,而不是等到关闭之后。领域指南(docs/agents/domain.md)规定检查内容,以及何时据此更新领域上下文;图只负责指定检查发生的位置,且其中任何内容都不得等待人工操作。
术语表要求
对于声明中新增或更改的每个术语,docs Task(若 Spec 没有 docs Task,则由专门的术语表 Task)都必须声明术语表文件,包含一项要求,通过领域建模将该术语写入术语表;其 Verification 必须检查空白字符规范化后的文本中,术语表里是否存在加粗术语后跟冒号的内容。
修正 Task 数量上限
修正工作的上限仍为两个 Task。如果 QA 发现的问题需要超过两个修正 Task,不得编写第三个补丁,也不得停下来等待策略决定。门禁状态稳定为 completed 后添加的修正 Task 会成为门禁的依赖项,作者必须先使用 roundfix reopen --spec <slug> 重新打开已稳定的门禁,绝不可通过编辑 QA Task 文件来实现。选择以下一种获准的退出方式:
- 修改 TechSpec,并据此重新生成 Task Graph。
- 将超出上限的修正工作提升为独立 Spec,并明确保留因发现的问题而失败的门禁。
达到上限属于循环执行权限范围内的决策。循环应自行选择退出方式并继续,不得停下来等待人工处理。
Task 类型选择
根据 Task 的主要交付成果选择类型,而不是根据实现者、使用的工具或配置选项:
backend— CLI、守护进程、服务、API、领域或核心应用行为;frontend— 浏览器 UI、TUI、视觉、交互、无障碍或 UX 行为;data— 持久化架构、查询、迁移、导入或数据管道行为;infra— 构建、CI/CD、打包、部署、环境或运维基础设施;docs— 仅涉及文档的行为或持久化知识产物;test— 不改变产品行为的测试框架、测试夹具、评估或覆盖率工作;chore— 不涉及上述产品界面的有限维护工作;qa— 唯一编写的终端关卡,在所有非 QA 叶节点任务完成后执行qa-gate;切勿将其用于实现测试或中间检查点。
当一个垂直切片横跨多个类型时,采用其主要用户可见或运维成果所属的类型。如果两个成果各自具有独立价值,或主要成果仍不明确,则拆分 Task,让每个切片都有一种主要类型;不得编码多个值,也不得延后分类。
验证路径
Task 必须声明其 Verification 涉及的每个仓库路径,除非该路径已存在于已检出树中,或由其依赖的 Task 创建。在 ## Context 中使用 creates:、interface:、deletes: 或 instruction: 声明路径;Daemon 记录的路径也计入。已声明路径的目录前缀,或依赖闭包中某个 Task 创建路径的目录前缀,也视为已提供。
对于处于 Tasks 阶段、尚未完成的非 QA Task,SC-VERIFY-PATH-UNDECLARED 会在没有 horizon 的情况下报告错误。它会读取现有顶层仓库目录下的字面路径,但会排除 grep/rg 模式、printf/echo 操作数、取反的测试操作数、变量、通配符、省略号以及 Spec Root 下的路径。该检查不会执行任何命令。开始 Run 前,请修正命令,或声明计划如何提供缺失路径。
测试选择器及其所在路径
使用选择器运行新测试的 Verification 命令只应指定选择器本身。pytest 9 及更高版本会合并存在重叠的收集参数:如果一次调用同时传入 tests/test_a.py::test_new 这样的节点 ID 和该文件、其上级目录或 .,pytest 会运行整个所在路径,并在不报错的情况下丢弃节点 ID。测试尚不存在时,该命令会在文件已有的测试上通过,且预检查会将其判定为无效,但不会说明原因;单独使用节点 ID 时,pytest 会以 4 退出,命令也会按预期失败。如果 Task 还需要运行所在路径,请将其放在单独的命令中。
对于处于 Tasks 阶段、尚未完成的非 QA Task,SC-VERIFY-SUBSUMED-SELECTOR 会在没有 horizon 的情况下报告错误。它会读取每个 pytest 调用——包括 pytest、py.test 或 python -m pytest,无论它们位于 uv run、poetry run、pdm run、pipenv run 或 hatch run 之后,还是位于 $(...) 替换中——并报告被同一调用中的其他收集参数涵盖的节点 ID:其文件、上级目录、.,或作为其前缀的节点 ID。使用 --keep-duplicates 可豁免该调用。该检查不会执行任何命令。
自有技能版本
非 QA 任务声明对 .agents/skills/<name>/ 下某个自有技能文件的修改时,也声明对其镜像文件 skills/<name>/ 的修改,包括 .agents/skills/<name>/SKILL.md 和 skills/<name>/SKILL.md,以及 skills/testdata/owned-skill-versions.json。自有技能是该版本记录中的 skills 键。删除文件时,双方都使用 deletes:;其他镜像声明、SKILL.md 文件对和版本记录使用 interface: 或 creates:。在某项要求中注明 -record-skill-versions 步骤。其他任务不能覆盖这项工作:对于每个编辑任务缺少自身声明或步骤的自有技能,SC-SKILL-VERSION-UNTASKED 都会报告一个缺口。instruction: 路径为只读,不声明编辑。
任务中的界面转录
实施任务须在其 References 中列出所覆盖的每个界面转录,并在一个命名测试中断言完整转录:标准输出和标准错误的每一行(顺序不变)及其退出代码,均从 TechSpec 复制,且只能包含该转录声明的受控变更;该任务的 Verification 须按名称运行此测试。读者可能会跳过的行仍计入其中:最终摘要或汇总行、Usage 块、缩进,以及程序以非零状态退出时 go run 写入标准错误的 exit status <n> 行。QA 任务须在一项 Requirement 中列出每个转录,以便门禁能通过构建后的产品复现。转录是一个覆盖单元:其名称须能从 TechSpec 追溯到实施测试,再到门禁。
共享契约的使用方
共享契约是任务范围之外的代码会使用的路由、公共签名、持久化格式或报告。每个尚未完成的非 QA 任务都须在 ## Consumers 部分包含一项使用方声明,roundfix spec check 会读取每个此类任务中的声明:
- <contract> — consumers: <suite>, <suite>用反引号标出使用该任务所更改的每个共享契约的套件;套件名称须与其 Verification 命令中的写法完全一致,例如包路径。每个套件都须出现在该任务的一条 Verification 命令中,并与一项只有该任务完成后才能通过的检查写在同一命令里,以确保该命令在工作完成前仍会失败。- checkpoint: task_NN改为命名一个集成检查点:该非 QA 任务依赖此任务,QA 门禁也依赖该任务,并且该任务的 Verification 会运行这些套件。后续任务负责调整使用方时,使用此项。None.后接原因,说明该任务未更改任何共享契约。
SC-CONSUMERS-UNPROVEN 会报告缺少部分、格式错误的条目、Verification 未运行的套件,或不符合该位置要求的检查点。
字节不变量须注明交付基准
QA 要求某文件逐字节相同时,须将其与交付基准比较;交付基准是经审计的头部与默认分支的合并基点,而不是某个指定提交。计划会在队列中等待其他 Spec,且每个先合并的 Spec 都可能更改该文件,因此计划进行度量时所在的提交不再是正确的比较对象。不要在要求中写入该提交;如有必要,将其记录在 TechSpec 中。对于待处理 QA 任务中同时指定字节不变量和类似提交的十六进制标记的要求,roundfix spec check 会报告 SC-QA-BYTES-PINNED。
流程
1. 推导任务拆分
首先阅读 TechSpec 的 Coverage Cross-Read;如果 Coverage Map 缺少
Deviations from the PRD: 行,就退回 write-techspec。
从 TechSpec 的 Build Order 开始(其中的依赖关系陈述会转化为图中的边)。将每个 PRD 用户故事和核心功能映射到至少一个任务;未覆盖的故事就是需要立即修复的漏洞。将每项已声明的 Success Metric 和 API Contract 映射到至少一个任务,并确保它们各自以名称出现在某个任务的 References 中。未覆盖的承诺就是需要立即修复的漏洞。根据已编写的 Spec 一次性决定 QA 门槛,并将其终端节点或有理有据的拒绝说明加入任务拆分。
2. 升级检查——自主决策,仅在例外情况下升级
推导并编写任务拆分。Spec 就是授权依据:通过各自门槛的 PRD 和 TechSpec 已包含产品与架构决策,因此粒度、依赖顺序和 Task Type 分类都应从这些材料中推导,而不是等待确认。报告已完成的任务拆分,之后可以请求修改其中任一部分;不要因等待审批而停滞。
只有当下一项决策会改变授权范围、架构或影响范围时才暂停并询问:
- 缺少授权。 某个任务拆分需要创建、编辑、重命名、移动或删除受保护工具,而 PRD 和当前 TechSpec 未通过精确限定的文件授权此操作。指出所需路径及原因;切勿自行扩大边界。
- 无法在没有人工参与的情况下验证。 某个任务的验收确实需要人员或仓库无法持有的凭证,例如实时外部账户、实体设备或主观判断。验证必须保持隔离,因此无法满足这一要求的任务属于 Spec 问题,而非图的问题。
- Spec 有误,而不只是内容不充分。 只有违背或扩展 TechSpec 的 Build Order、架构或契约,分解方案才能成立。应退回
write-techspec,而不是悄悄重新设计。 - 单个任务拆分内存在不可逆的影响范围。 某个任务会执行数据迁移、破坏性删除、发布或凭证轮换。在创建该任务之前先确认边界。
- 复杂度无法再拆分。 某个任务拆分无法在一个全新的会话中完成,且拆分会破坏纵向切片规则。这表明 Spec 规定不足;说明具体是哪部分,以及原因。
升级时应指出具体阻塞事实并提出解决方案,切勿只问“这样可以吗?”。上述五类之外的事项都应自行推导:粒度偏好、命名、Build Order 已隐含的排序,以及主导结果分类。编写前,每个 type 单元格都必须填写一个且仅一个允许的 Task Type;空白、占位符或组合值都是需要解决的问题,而不是需要提出的问题。
3. 编写文件
根据 references/task-template.md 中的模板,编写 _tasks.md 和所有 task_NN.md(按拓扑顺序从 01 开始编号)。将推导出的 Task Type 复制到每个任务的 type frontmatter 以及 _tasks.md 投影表中。如果纳入 QA 门槛,在清单 frontmatter 中用 qa: 指定 QA 任务,将其放在拓扑顺序末尾,并在 needs 中列出每个非 QA 叶节点;如果拒绝,则写入 qa: declined 和 qa_reason,且不生成 qa 任务。验收标准必须能独立验证——无人能够检查的标准只是愿望,不是标准。添加 ## Verification 部分,提供精确、隔离且可移植的命令,以证明任务在全新工作树中的效果;Daemon 会在 Agent 完成工作后逐字运行这些命令。仅当标准 Spec Context Bundle 无法明确说明任务专属指令或接口路径时,才添加 ## Context。
此处同样适用持久性原则:描述行为和接口,而非仓库文件路径(Spec 文件夹内的相对引用除外,因为该文件夹会整体移动)。
4. 验证图
报告前,请通过机械方式验证——解析,不要凭肉眼判断。
先运行仓库自带的检查器,检查刚刚拆分的 Spec:
roundfix spec check <slug> --run-verification
这种形式会一并读取 PRD、TechSpec、它们引用的 ADR 和图——这是四者首次全部存在的时刻——并在一次性检出目录中的 HEAD 上执行编写的 Verification 命令。运行 roundfix spec check <slug> 时若未加 --run-verification,即使结果干净,也不能覆盖 Vacuous Verification:它不会针对未更改的树执行这些命令,因此原本就会以零退出的命令可能不会被发现。不要为了速度而选择不执行探测的形式;这种速度正是省略命令执行的结果。
将所有报告的错误都视为阻断项:修复产物并重新运行,直到检查通过;只要仍有问题,就不要报告拆分结果。[gap] 也属于阻断项;请处理所指名的 ADR,或记录其不适用的理由。跳过的检查仅供参考。
以下清单不可由此检查器取代,因为它覆盖了检查器不会检查的内容:未列出或未说明的 ADR、不完整的 Project Constraints、未映射的覆盖范围、相互矛盾的要求、未声明的演练、与工作无关的 Verification,以及未记录的 Vocabulary Contract。SC-CITATION-UNSUPPORTED 表示某项声明没有 ADR 文本的支持。
然后通过阅读确认:
- 每个
graph.nodes[].file都存在,并且每个任务文件都有可解析的 frontmatter,且status: pending。 - 每个任务文件恰好有一个
type值,且值为backend、frontend、data、infra、docs、test、chore或qa;该任务在_tasks.md投影中的行包含完全相同的值。 - 每个
needs条目都指向一个现有节点 id;没有环(可以打印拓扑顺序)。 - 每个 contract 之后的图都恰好声明一个 QA 决策。若包含 gate,则该 gate 是唯一的
qaTask,没有依赖它的任务,并且直接或间接依赖每个非 QA 叶节点;若拒绝 gate,则qa_reason非空,且不存在qaTask。 - 每个 PRD 用户故事都出现在某个任务的 References 中。
打印 wave 计划(wave 1 = 无 needs;wave N = 其 needs 已由更早的 wave 满足),作为执行预览。
5. 报告
请回复拆分表(id | title | type | complexity | needs)、编写的 QA 决策,以及在拒绝时给出拒绝理由;还需提供一行切分理由、文件列表和 wave 计划——并说明现在可以请求更改任何切片。指出遇到的任何升级触发条件,以及如何解决。
反模式
- 横向切分(一个模式任务、一个 API 任务、一个 UI 任务)——每项任务都应贯穿整个技术栈。
- “实现该功能”这类超大型任务——如果无法单独验证,就还不能算作一项任务。
- 含糊的标准(“正常工作”“处理错误”)——明确指出可观察到的行为。
- 非自包含的验证:依赖仅本地文件、先前的运行状态、手动提示词或远程分支状态。
- 不可移植的验证,例如使用
wc管道形状检查、在grep可用时使用rg检查依赖,或缺少仓库-buildvcs=false标志的 Go 构建命令。 - 只运行范围宽泛的测试套件,却无法证明该任务具体效果的验证。
- 将提交、推送、PR 或发布分支列为验收标准——这些属于 Daemon 和交付职责,而非任务成功标准。
- 编辑图和任务文件时未保持同步——应根据同一份拆解重新生成两者。
- 对 Spec 已授权的拆解等待批准——调用即代表授权,粒度是推导结果,而非待决定事项。
- 因为循环正在运行,就越过真正的升级触发条件继续执行——缺少工具授权或任务无法进行自包含验证,都意味着必须停止,而非由人酌情判断。
- 缺失、占位、合并或杜撰的任务类型——分类是必需的路由约定,而非描述性自由文本。
- 后契约图中既没有编写好的终端
qa任务,也没有qa: declined及qa_reason——遗漏属于缺陷,而非每次运行时可自行选择的 QA 选项。
参考资料
- references/task-template.md —
_tasks.md和task_NN.md的模板。编写任何文件前请先阅读。