实现任务
将一个 1-point 的 ticket 作为一个 PR 交付审查,内容严格遵循 ticket 的要求,不多也不少。
输入
$ARGUMENTS
- Ticket,必需:一个追踪器密钥(例如
ENG-123)或本地 ID(例如T-04)。如果缺失,列出就绪的 ticket(状态为open,依赖项已合并),按关键路径排序,并询问选取哪一个。在无人值守模式下,改为报告blocked。 --tasks <file>:本地任务文件。如果未给出,在项目本地的、被 git 忽略的 RFC 文件夹(例如.rfcs/)中查找包含该 ticket 的*.tasks.md文件,然后再查找docs/rfcs/。--base <branch>:起始分支以及 PR 的目标分支。默认为 main。非 main 的 base 意味着该 PR 是 stacked 在其他未合并 ticket 的 PR 之上的。--branch <name>:要使用的分支名称。否则遵循第 1 步中的命名规则。--feedback <pr>:不实现新功能;而是处理现有 PR 上的审查反馈(参见最后一部分)。--unattended:由协调器启动,无人回答问题。永远不要提问;当需要提问时,停止并在报告中解释。在你的自己的工作树中完成工作。
Ticket 和本地文件的位置
- 优先查找追踪器。 如果 ticket 有追踪器密钥(作为参数,或在任务文件的
Tracker:字段中),则通过已连接的追踪器工具(Linear, Jira, GitHub Issues ...)获取它。发布后,追踪器是 ticket 内容的权威来源;如果它在追踪器中已被取消或完成,则停止并报告。 - 否则使用本地任务文件,以及追踪器问题缺少的字段(文件、范围外)。RFC 和任务文件是开发者本地的、未追踪的文档,因此它们仅存在于主项目文件夹中,而不是在工作树中。如果你在工作树中,使用
git worktree list(第一个条目)找到主文件夹,并通过绝对路径读取其中的文件。将主文件夹视为 只读:永远不要在其中编辑、检出或运行 git 命令。 - 永远不要提交 RFC、笔记或任务文件。通过显式路径暂存文件,不要使用
git add -A。
1. 选择 ticket
- 读取 ticket(见上文),包括其验收标准和依赖项。如果其类型是
spike,则停止:spike 产生决策,而非 PR;指向/spike-task(无人值守:报告blocked)。 - 当其 PR 合并到 main 后(使用
gh检查 PR 状态,或依赖项的状态pr-merged/done),或者当基础分支是该依赖项自己的分支时(stacking),依赖项视为已满足。Spike 依赖项仅在其状态为done时才满足,意味着其决策已获批准并且待办事项已完成细化。如果有任何依赖项未满足,则停止并说明是哪一个。 - 确保工作树是干净的,获取最新代码,并从最新的
origin/<base>创建分支。 - 分支名称(除非提供了
--branch):<username>/<project-slug>/<task-branch>。username:如果用户现有分支遵循此模式,则使用其前缀;否则使用其 GitHub 登录名(gh api user --jq .login)。project-slug:来自任务文件的Project slug:头部,或者 RFC 名称的小写连字符形式。task-branch:追踪器密钥加一个简短的 slug,例如eng-123-add-v2-flag(密钥允许追踪器集成链接 PR);如果未发布,则为t-04-add-v2-flag。
- 如果你直接与用户(非无人值守)一起工作,则将任务文件中的 ticket 状态设置为
in progress,如果追踪器的 GitHub 集成不会自动执行此操作,也请在追踪器中设置。
2. 仅加载 ticket 所需的内容
读取 ticket、它依赖的 RFC 部分以及它命名的文件。然后追踪真实流程:调用者、现有的辅助函数以及你将更改的代码旁边的测试。多读一些以充分理解问题,但不要加载整个 RFC 或会话历史;ticket 的设计是独立的。如果不能独立,这是一个需要报告的缺陷,而非自行猜测。
3. 测试先行
将每个验收标准转化为一个测试,使用仓库现有的测试框架、位置和风格。运行它们并确认它们因正确的理由而失败。每个标准一个集中的测试就足够了:不要新建测试工具、固定装置或辅助函数,除非现有模式要求这样做。纯粹机械性的 ticket(例如添加一个标志位)可能不需要新测试,如果该标准已由现有测试或类型检查器检查;在 PR 中说明即可。
4. 实施最小的完整变更
“完整”意味着每个验收标准都通过。“最小”意味着除此之外没有任何内容。这遵循 ponytail 方法;如果安装了 ponytail 技能,立即以其默认级别加载它,并让它控制此步骤。
否则,采用第一个有效的选项:
- 需求是否已满足?如果现有代码已经满足标准,则停止并提议关闭 ticket。
- 重用代码库中已有的内容:辅助函数、类型、模式。
- 使用标准库,然后是原生平台特性(数据库约束、内建 HTML 输入、CSS 先于 JS),然后是已安装的依赖。
- 只有在此之后才编写新代码,越少越好。
在编写代码时:
- 没有推测性结构。 没有只有一个实现的接口,没有为单一产品创建的工厂,没有从不变化的值配置,没有“为了以后”的脚手架。优先编辑现有文件而不是创建新文件。
- 与周围代码匹配:命名、错误处理、结构。差异看起来应该像是代码库自己写的。
- 仅在代码无法表达时才加注释。 不要叙述代码做了什么,不要重述 ticket,也不要留下注释掉的代码或调试输出。唯一值得添加的注释是在一个有意的简化处:说明限制以及何时升级它,以免有人意外地“修复”它。
- 从根本上修复错误。 在更改共享函数之前检查每个调用者。
- 绝不降低安全性。 信任边界处的输入验证、防止数据丢失的错误处理、安全性和可访问性基础始终要正确完成,即使 ticket 没有明确说明。
5. 保护范围
如果 ticket 变得比 1 point 更大(超过一天左右,出现第二个关注点,或者不触及不相关领域就无法满足某个标准),则停止。不要提交任何超出干净代码之外的内容,解释你的发现,并提议拆分为新的 ticket 供批准:在与用户协作时将其写入任务文件,或在无人值守时写入报告。你注意到的无关问题应记入 PR 的 notes 中,而不是 diff 中。永远不要削弱或重新解释验收标准以使其通过。
6. 验证并打开 PR
- 按照仓库的方式运行测试、linter 和类型检查器。如果更改具有运行时行为并且你可以运行
/verify,则执行;否则,使用项目的自有运行或检查命令验证该行为。 - 自己重新阅读整个 diff:每个变更行都应追溯到某个验收标准。移除无关的格式更改、重命名和散落文件,并确保没有本地 RFC 或任务文件混入。
- 遵循仓库的提交风格提交,推送,并打开一个准备就绪以供审查的 PR(非草稿,以便审查自动化运行,除非用户要求草稿),目标为基础分支,使用 templates/pr.md。将追踪器密钥放入标题中,并在描述中链接追踪器问题。如果基础不是 main,请说明它堆叠在哪个 PR 上,并且需要先合并那个 PR。如果你无法从此处打开 PR,则推送分支并将 PR 文本包含在你的回复中。
- 如果你直接与用户一起工作,则将 ticket 的状态设置为
pr-open(或pr-draft),并在任务文件中填写Branch / PR:;如果追踪器的 GitHub 集成不会自动执行此操作,请将追踪器问题移至其审查状态。在无人值守模式下,将状态留给协调器。 - 使用下面的报告结束。如果用户在场,两行或三行的版本就足够了。
处理 PR 反馈 (--feedback)
你收到一个 PR 和一个需要处理的审查项列表(评论链接以及要做什么)。
- 在你的工作树中获取并检出 PR 的分支。读取 ticket 和这些项;读取当前的 diff。
- 用最小的变更解决每一项,遵循与步骤 4 相同的规则。保持在 ticket 的范围内:如果某个项要求超出范围的内容,不要构建它;作为后续事项报告。
- 添加新的提交,而不是修改或强制推送,以便审查者可以看到审查后发生了什么变化。运行测试,然后推送。
- 在每个已处理的评论线程上回复一行,说明更改了什么以及提交的短 SHA。对于被告知无需更改代码即可回答的项,用给定的文本回复。如果你得出结论认为某项不应更改,不要在评论线程中争论;保留它并在你的报告中解释。
- 使用报告结束,如果每个项都已处理,则使用
done;否则使用blocked。
报告
用以下块精确结束你的最终消息,以便协调器可以解析:
RESULT: done | blocked | needs-split | already-met
TICKET: <local id> / <tracker key or "unpublished">
PR: <url or "none">
BRANCH: <branch or "none">
SKIPPED: <deliberate limits or items not addressed, or "none">
NOTES: <one or two lines: why blocked, what to split, follow-ups, unrelated issues found>