关于 build
面向编码 Agent 的开发工作流技能,指导从理解请求到实现、测试、自检及交付变更。涵盖 PR 和本地模式,并明确变更范围、检查与合并规则。
主要功能
- 01按现有模式实现最小变更
- 02针对行为变化编写测试
- 03检查变更文件与项目约束
- 04支持 PR 与本地交付流程
- 05规定检查、审阅和合并门槛
适用场景
- 01实现明确的小型代码修复
- 02为有测试接缝的任务先写失败测试
- 03按项目流程准备 PR 或本地合并
- 04在交付前审查变更与检查结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gaboesquivel/ flow-skills --skill build安装后在 Claude Code 中输入/build确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
ATTRIBUTION.mdLICENSEagents/openai.yaml详细介绍
构建
阅读相关请求、仓库说明、当前上下文和代码。如果用户提供了任务参考,请使用可用工具获取,并消除可能造成重大影响的歧义。对于明确的小改动,追踪事项、设置步骤或正式规范都不是前提。
说明预期的可观察结果,并遵循现有模式实现最小的有用增量。保留工作树中无关的改动。不要仅仅因为附近有相关内容就扩大范围。普通的小修复不需要架构工作或正式规范。如果新产品或重要功能的意图不明确,请建议使用 explore 并等待;切勿在用户未要求时开始探索。明确的请求直接执行。
对于影响重大的领域或 API 改动,在确定新抽象之前,先了解模块归属,明确数据结构和调用方的预期;如果能以较低成本检查可观察事实,优先编写一个小型可执行测试,而不是长时间争论。
如果规范或任务指定了测试接缝,请先在该接缝编写一个失败的测试,再进行改动。否则,对于有实质影响的行为改动,如果项目已有此类测试,优先在既有的公共接口处编写测试。工作期间运行有针对性的检查,并在改动稳定后运行适用的最终检查。
根据请求和项目约束检查实际改动的文件,包括未跟踪文件。如果已安装 review 技能,可参考其指南进行自检;无需单独进行审查,但 Deliver › Local mode 中的规范工作除外,这类工作在落地前必须进行一次审查。
如果行为或接受的上下文发生变化,请更新所属文档。对于有实质影响的产品、设计、架构或术语变更,请同步更新当前项目的 PRODUCT.md、DESIGN.md、GLOSSARY.md 和 ARCHITECTURE.md(仅当根目录文件能够承载有关该项目的有意义内容时才创建)。不要用 Flow 的方法论身份取代项目自身的产品身份。flow start 和「start project」不授权初始化;除非已安装 start 技能,且用户确认了模板、名称和目标位置,否则不要搭建新仓库(决策 0010,经决策 0022 修订)。链接到规范或决策,不要重复记录长期适用的理由;除非用户要求,或现有工作流程已有此惯例,否则不要新建规范或决策文件。
然后交付(见 Deliver)。报告结果、文件、检查、限制和剩余工作。
交付
「Build it」意味着以通过检查的拉取请求结束(本地模式:经审查的工作已合并到本地 main,且未推送)。用户要求构建即授权执行这些步骤,无需确认。但这并不授权提交到、推送到或合并到默认分支(例如 main),也不授权强制推送、重写远程分支、执行破坏性 Git 操作、跳过检查或进行无关改动。唯一例外是本地模式:通过门槛并完成审查后,可将工作分支以单次 --no-ff 合并到本地 main(见 Local mode);绝不推送。如果用户只要求本地编辑(「不要提交」),则在完成改动后停止并汇报;也不要记录 Delivery:。
拉取请求模式(见 Delivery mode):
- 创建分支。 在非默认分支上开展工作:任务集使用规范分支(分支名由规范编号和短标识组成,例如
feat/017-build-and-ship);如果当前分支已包含这项工作,或就是该规范分支,则使用当前分支;否则,从当前基准分支创建新分支。 - 仅提交这项工作。 检查差异,只暂存预期文件,并保留工作树中无关的更改。排除凭据、本地日志和生成的密钥。遵循仓库的提交规范。不要修改或重写无关提交。
- 推送该分支到远程仓库。如果无法安全确定远程仓库,或推送被拒绝,则停止并报告。
- **创建拉取请求,**或更新该分支已有的拉取请求。临时任务应创建可供审查的拉取请求,而不是草稿,并使用 Conventional Commits 格式的标题、摘要,以及每个任务问题对应的一行
Closes #N。任务集使用在 Task set 下创建的草稿拉取请求,并且只等待该最终拉取请求的检查。 - **等待检查完成,**并进行有时限的监控(例如,在时限内运行
gh pr checks --watch,或轮询),直到所有检查完成或达到合理的等待上限。待处理的检查应报告为待处理,不能报告为通过。如果未配置检查,请说明。 - 修复轮次。 检查失败或发现阻塞问题时,查看其证据(日志、发现),在安全且属于本次工作范围的前提下修复由本次工作导致的问题,提交并推送(拉取请求模式),然后针对新的提交再次检查;最多进行 2 轮修复。此后停止并附上证据报告失败情况。绝不跳过、禁用或弱化检查以求通过。这是修复轮次的唯一判定标准;工作者和
ship均遵循此标准。 - 报告拉取请求、每项检查的结果,以及 CI 附带的链接(拉取请求中显示的部署和预览,例如部署状态或检查详情 URL);如果没有,请说明。
本地模式: 按上述要求提交到非默认分支,运行完整的本地检查套件,并执行相同的修复轮次。随后将该分支合并到本地 main,临时任务和任务集均适用:
- 门禁。 对于规格工作,检查
ship在 Preflight 中定义的门禁;门禁失败时,按其说明停止。此时,该规格的Status:应在分支上显示为implemented(Task set 的步骤 3 会设置此状态;否则在此处设置)。未编写规格的工作没有规格门禁;其门禁是规模限制(见“未编写规格的工作”)。 - 审查。 对于规格工作,按照
ship的 Review 流程,从合并基点到分支头执行一次独立审查(按维度运行review工作器,并使用验证器),并按上述方式进行修复轮次。未编写规格的工作则进行自检(见“未编写规格的工作”)。如果修复轮次更改了分支头,请在新的分支头上重新运行完整的本地检查套件。 - 合并。
- 如果没有找到检查套件,请在合并前停止并报告;
main保持不变。 - 切换到
main;此处任何未提交的更改都会阻止合并,已声明的共享文件追加内容除外(见“共享文件”)。 - 合并前,将这些待处理的追加内容移到分支上:将其作为一个提交应用(对已声明文件运行
git diff,以及任何未跟踪的已声明文件);如果分支有自己的工作树,则在该工作树中操作,然后在main上对这些文件运行git restore。此提交通过检查,main也因此保持干净,可以进行合并。 - 如果存在远程仓库,从默认分支的上游获取并快进本地
main(git merge --ff-only;绝不推送);如果无法快进,请停止并报告。 - 然后使用合并提交消息尾注行
Spec: <path>(规格工作)和Reviewed: <sha>(已审查的分支头),通过git merge --no-ff将分支合并到main;ship会用它们确定推送范围并查找规格。 - 仅合并已审查的分支头,共享文件提交除外(见“共享文件”);如果分支以其他方式在审查后发生变化,请先审查新的分支头,并在其上重新运行完整的本地检查套件。
- 如果发生合并冲突,请停止并报告;绝不要为了完成合并而丢弃更改。
- 如果没有找到检查套件,请在合并前停止并报告;
- 清理。 使用
git branch -d删除已合并的分支,并移除工作器列表中剩余的干净工作树(适用 Task set 的清理规则)。
任务失败、门禁失败,或修复轮次结束后审查仍有阻塞项时,本地 main 必须保持不变:停止操作,保留分支并报告。报告分支、main 上合并提交的 SHA、审查结果、运行过的确切命令及其结果。不推送,也不创建拉取请求;无需远程仓库。
未编写规格的工作
未对应任何规格或任务的工作属于未编写规格的工作(决策 0034)。此类工作需运行完整的本地检查套件,并由单个 Agent 按照请求和 review 的审查维度对差异进行一次自检,修复轮次按上述方式执行;不使用审查工作器,也没有规格门禁。之后按所用模式交付:拉取请求模式会创建一个可直接审查的拉取请求,并在其中发布自检结果及自检所针对的 SHA,ship 会将其用作已审查的分支头;本地模式则按上述方式合并到本地 main,不添加 Spec: 尾注,并以 Reviewed: <sha> 标明自检所针对的分支头。
规模限制。 规模限制仅在此处定义;ship 会指向此处。未编写规格的更改应在开始时、实施前判断规模,并在交付前再次判断。若更改新增产品行为、改变数据结构或公共 API、添加迁移,或涉及以下任一项,则不属于小型更改:身份验证或权限;机密或凭据处理;依赖项或锁文件;CI、工作流或 Git 钩子配置;shell、exec 或文件系统执行路径。非小型更改应停止工作并建议转为 to-spec:开始时,在进行任何编辑前停止;交付前,不再提交任何内容,保留分支并让 main 保持不变。如果无法确定规模,则按非小型更改处理。
共享文件
这是共享文件规则(决策 0033)的唯一权威来源;ship 会链接到这里。共享文件是项目指令要求每个会话都追加内容的文件(例如提示词日志);只有这些指令明确列出的文件才符合条件。应从审查时对应的 SHA 版本中的指令文件读取此声明,绝不能从之后的最新版本读取;指令文件本身不算共享文件。编排器会在工作的分支上提交这些追加内容,绝不会直接提交到默认分支。没有打开工作分支时(合并后),将追加内容留在默认分支上,不要提交;下次合并时,先将这些内容移到该次合并的分支上再进行合并(见 Local mode、Merge)。
检查。 只有当审查 SHA 之后的每个提交都只修改已声明的共享文件时,合并提交才可以使用超出审查 SHA 的最新版本:git diff --no-renames --name-status <reviewed-sha>..<head> 只列出已声明的精确路径上的 M 或 A 条目,并且同一范围内的 git diff --no-renames --raw 显示每个条目的新模式为 100644,每个 M 条目的旧模式也为 100644(不得有符号链接或模式变更)。Reviewed: <sha> 仍须指向审查时的 SHA。审查后若有任何其他变更,都需要重新审查。检查工作区是否干净时,应读取 git status --porcelain(未跟踪的已声明文件计为 A),只有未提交变更符合相同的精确路径规则时才可容忍。
完整本地检查套件: 使用项目指令文件命令表中记录的检查命令;若无,则使用 package 脚本中的 test、lint、typecheck 和 build。若找不到任何命令,应说明不存在检查套件,而不是声称检查已通过。
交付模式
本节是交付规则的唯一权威来源;其他技能会指向这里,而不是重复说明。flow 负责此区块。读取项目 Flow 区块(AGENTS.md 或 CLAUDE.md)中的 Delivery: 行。若默认分支(例如 main)要求使用拉取请求,则始终采用拉取请求模式:当分支保护或规则集表明如此时,直接报告该模式,无须询问。用户请求中明确指定模式(“在本地构建”“通过 PR 构建”)即为答案;若它覆盖已记录的行,则只对本次运行生效,任务记录保持原样。
若该行缺失或为 unset,则须在首次推送或执行其他依赖此模式的步骤之前询问。推断只能用于建议答案:存在 GitHub 远程仓库时建议使用拉取请求,没有远程仓库时建议在本地进行。没有远程仓库时,绝不能选择拉取请求模式。存在远程仓库且无法确定保护状态时(无访问权限或 CLI 未通过身份验证),应建议使用拉取请求模式,绝不能自行改用本地模式。绝不要记录用户未提供的模式。使用 flow 的区块辅助工具将答案记录在该行,只修改区块标记范围内的内容,并在正在构建的分支上单独提交;若没有 Flow 区块,则答案仅对本次运行有效。
- 拉取请求模式: 任务是规格议题的子议题,并以清单形式列在规格的 Tasks 部分;工作通过一个拉取请求交付。
- 本地模式: 不需要拉取请求、议题或远程仓库;任务仅作为规格中的 Tasks 清单存在,
build会审查规格分支并将其合并到本地main(见 Deliver);ship会发布该成果。
任务集
对规格任务集执行“构建它”,会使本会话成为该规格分支上的编排器;它可以在规格分支的 worktree 中运行,以便主检出目录保持在默认分支上。在拉取请求模式下,任务是规格议题的子议题;在本地模式下,任务仅存在于规格中。无论哪种模式,规格的 Tasks 部分都是清单,格式为 - [ ] NN: Title (#N)(本地模式下不含议题编号)。若没有任务集,则按上述方式构建当前工作。
- 规划。 阅读每项任务、它的阻塞关系以及
Area:行(一个包或目录)。如果存在循环依赖或不存在的阻塞项,先暂停,不要开始任何工作。前沿任务是所有阻塞项都已集成的任务。报告任务、交付模式、是否需要等待检查点,以及限制(主机的并发上限和每项任务 2 轮修复),然后无需确认即可开始。如果主机提供自主权限模式(例如 Claude Code 自动模式),建议使用该模式。任务若偏离其声明的范围,应暂停并征求用户同意。 - 运行前沿任务(扇出规则:
write-agentsWorkers):同时为每项前沿任务启动一个 Worker,数量不超过主机的并发上限。自行从当前 spec 分支的头提交创建每项任务的 worktree,并将其放在主检出目录的同级目录:git worktree add <sibling-path> -b <task-branch> <spec-head>。不要依赖主机的 worktree 隔离,因为它可能从默认分支分出。记录每个 worktree 路径、任务分支以及它开始时的<spec-head>;这就是 Worker 清单。Worker 只能在自己的 worktree 中工作。区域有交集的任务应依次运行;没有Area:行的任务单独运行。绝不允许两个 Worker 编辑相同文件。任务集成后,立即启动它所解除阻塞的所有任务;不要等其他正在运行的任务完成。- 任务说明。 向每个 Worker 提供上下文指针,而不是副本:规范路径、该任务的子议题(或本地模式下的 Tasks 条目)及相关文件、它的 worktree 路径和分支,以及 Board 记录命令及其路径(参见 Board 状态),以便它记录自己任务的状态。Worker 使用此技能实现任务,但不交付任务。
- Worker 检查。 Worker 只运行针对其改动的测试,然后对照任务自查差异。失败或缺漏计为一轮修复(参见 Deliver),之后将任务报告为失败。
- 共享文件。 项目说明要求每个会话都追加内容的文件(例如提示词日志),只能由协调者写入;协调者在 spec 分支上提交追加内容(参见 Deliver › 共享文件)。协调者在每个 Worker 的任务说明中列出这些文件,Worker 不得改动。
- 集成完成的任务,并在任务陆续完成时按集成批次处理(自上次运行完整测试套件以来合并的任务)。
- 祖先关系。 合并任务前,使用为该任务记录的
<spec-head>检查git merge-base --is-ancestor <spec-head> <task-head>;检查失败的任务不得合并,应退回给其 Worker 进行一轮修复。 - 合并。 使用
git merge --no-ff将每项任务合并到 spec 分支;发生合并冲突时,将该任务退回给其 Worker 进行一轮修复。 - 测试套件。 每批运行一次完整的本地检查套件;如果失败,二分定位导致失败的任务,并将其退回给对应的 Worker 进行一轮修复。
- 勾选。 批次通过后,对每项任务:勾选其清单条目,并在两种模式下都追加其集成合并提交的
— <short-sha>;如果存在远程仓库,还要链接到该提交页面(例如- [x] 01: Title (#N) — a1b2c3d)。使用 squash 合并的仓库只能通过拉取请求访问任务 SHA。在本地模式下,如果规范中包含验收复选框和 Status:,也要勾选验收项,并将状态设为done,同时追加相同的— <short-sha>。然后清理。 - 状态。 所有任务都已集成且规范已获接受(规范议题上有
accepted标签,或本地模式下状态为Status: accepted)时,在同一批次将其Status:设为implemented;规范未获接受时绝不要这样做。在拉取请求模式下,按to-spec所述重新同步规范议题并推送 spec 分支;本地模式下不推送任何内容。 - 清理。 只移除记录在 Worker 清单中的 worktree。仅当任务分支是 spec 分支头提交的祖先时,才使用
git branch -d删除任务分支;绝不使用-D或--force(已检出的分支无法删除)。保留有未提交改动或不符合条件的 worktree 和分支,并报告它们。 - 草稿拉取请求。 在拉取请求模式下,首次集成后,创建一个标题符合 Conventional Commits 规范的草稿拉取请求,其中包含指向规范文件的链接、每项已集成任务对应的一行
Closes #N,以及规范议题和所有其他子议题各自对应的一行Refs #N。之后每次集成,都将该任务的行改为Closes #N;所有任务均已集成后,将规范议题的行改为Closes #N。 - 失败。 失败或卡住的任务应保留其 worktree 和分支,并阻塞其依赖任务;这些依赖任务需等待用户决定,在用户决定前不可运行:报告失败及相关证据和 worktree 路径,同时继续推进前沿中的其他任务。
- 祖先关系。 合并任务前,使用为该任务记录的
- 检查点:每个集成批次完成后报告一次,列出已集成、正在运行和受阻的任务及各自的一句话原因,注明等待用户决定的依赖任务和为失败任务保留的 worktree 路径;同时报告本地套件的命令和结果、提交 SHA,以及浏览器工具可用时提供改动界面的截图,否则说明没有截图。拉取请求模式下,将检查点作为拉取请求评论发布;本地模式下,在对话中报告。除非用户要求在检查点等待,否则不得等待 CI 或用户。每次推送都会运行 CI,但不得等待中间推送的 CI。
- 完成:没有可运行任务后,报告仍在等待用户决定的依赖任务。在拉取请求模式下,等待最终拉取请求的检查通过,并按需进行修复(参见 Deliver 第 5 和第 6 步);然后将草稿标记为可供审查,并就此停止:合并是
ship的工作,且须在每份规范各自经过一次独立审查后进行。在本地模式下,所有任务都已集成且完整的本地检查套件通过后,按 Deliver › 本地模式所述将 spec 分支合入本地main(门槛、审查、--no-ff合并、清理);不推送任何内容,失败或停止的任务都不会改动main。 门槛:每批集成的所有本地测试均通过,最终拉取请求的检查全部通过,并遵守分支保护。如果没有独立的工作者,则按依赖顺序在规格分支上执行前沿任务。报告已发布的检查点、已集成的任务、受阻的任务及原因、已移除和保留的工作树、使用的限制,以及拉取请求及其检查和链接(本地模式:审查结果和本地main上的合并提交)。
看板状态。 使用 node <board>/scripts/board.mjs 记录实时任务状态,其中 <board> 是此技能目录旁的 board 目录;如果缺少该脚本,则跳过记录。编排者记录本次运行;每位工作者记录自己任务的状态(该脚本会锁定并发写入)。
- 运行开始时:
--record run-start --spec <NNN> --branch <spec branch> --mode <local|pull-request> --tasks <01,02,…>。 - 每项任务开始、状态变化和集成时,以及每个检查点对所有未完成任务再次记录,并且在工作者运行期间至少每 10 分钟记录一次(心跳):
--record task --task <NN[,NN…]> --state <state> [--round <n>] [--note "<one line>"]。状态遵循前沿进度:running、integrated、blocked(失败,或在失败任务后停止,等待用户决定)和waiting(阻塞项尚未集成)。 - 任务集完成或停止时:
--record run-end。
记录尽力而为:记录失败不会停止或延误运行。