安装此技能
npx skills@latest add mattpocock/skills --skill=to-tickets然后输入 /to-tickets 来调用它。
本页内容
它的作用
to-tickets 取一个计划、 spec,或你当前所在的对话,并把它们拆成一组 tickets 在你的 issue 追踪器上。每个任务声明它的 阻塞边界 ——必须在它开始前完成的其他任务。
每个任务都是一个 曳光弹:一条穿越改动每个层次(schema、API、UI、测试)的狭窄但完整的路径,落地即可单独演示。正是这个约束让它区别于显而易见的拆分方式——一次切一层、最后再集成。它还把每个任务控制在单个全新 上下文窗口,因为接手任务的东西是 会话 从未见过你的规格说明。
何时使用
你通过输入 /to-tickets ——这个 agent 不会自动调用它。
| 你现在在哪 | 运行什么 |
|---|---|
| 你有一个规格 issue,构建跨越多个会话 | /to-tickets,或 /to-tickets #<spec_issue> |
| 计划只在对话里,从未被写下来 | /to-tickets 直接读取线索——无需规格说明 |
| 整个改动装得进一个上下文窗口 | implement ——跳过任务 |
| 还没有决定任何事 | grill-with-docs,然后 to-spec |
| A wayfinder 地图已清空 | to-spec 先,以折叠地图,然后 /to-tickets |
那些 to-tickets 产出的天生为智能体就绪。不要运行 triage 处理它们——triage 是给来自他人的工作的。
前置条件
to-tickets 发布到追踪器,所以 setup-matt-pocock-skills 必须为这个仓库配置一个,连同分流标签词汇。两种都可以:GitHub 或 Linear 这样的真实追踪器,或 .scratch/,开箱即可支持。
曳光弹,不是分层
A horizontal 切片只发布改动的一层。在所有层都落地之前什么都不工作,而且每个任务的验收标准必须伸进另一个任务拥有的工作。 vertical 切片——曳光弹——一次穿过所有层发布一条细路径,所以它可以单独验证,并拥有它评价的一切。
这是人们违反最多的规则,后果有充分记录。一个团队运行了一个按层切片的 26 任务堆栈——语料、生产者、聚合器、选择器——每个关闭的任务大约花了二十次智能体运行,其中约四分之三是返工。他们自己的事后复盘把每一类失败都追溯到横向切片,而不是实现。
在发布任何内容之前有两件事发生。 to-tickets 寻找预重构——「让改动变容易,再做出容易的改动」——并把这些工作排在最前。然后它以编号列表呈现拆分方案并就它考你:粒度合适吗、阻塞边界真实吗、有什么该合并或拆分。在你批准之前,什么都不会到达追踪器,而那个测验正是你顶回去的地方。
阻塞边界
边界正是产物的重点。它们按追踪器有两种读法:
| 追踪器 | 边界住在哪里 | 你如何操作它们 |
|---|---|---|
| 本地 Markdown | 每个任务一个文件,位于 .scratch/<feature>/issues/<NN>-<slug>.md,按阻塞顺序编号 | 从上到下,手动 |
| 一个真实的追踪器(GitHub、Linear) | 原生阻塞链接,或追踪器支持时的子 issue | 任何阻塞项已完成的票都在 frontier 并且可以抓取 |
无论如何,边界都住在任务里。媒介只决定是否有东西能并行地作用于它们。 to-tickets 产出产物;运行它——一次一个会话,或一群——是你的工作,不是技能的。
宽重构例外
有一种形态破坏了曳光弹规则。 宽重构 是一个单一的机械性改动——重命名一列、重新输入一个共享符号——其 爆炸半径 扇到整个代码库,所以一次编辑破坏数千个调用点,没有任何垂直切片能全绿落地。
to-tickets 把那个排序为 扩展-收缩 改为:
- 展开 ——在旧形态旁边添加新形态,这样什么都不破坏。
- 迁移 ——按爆炸半径分批迁移调用点(按包、按目录),每批一个任务,每个都被扩展阻塞。因为旧形态仍然存在,CI 保持全绿。
- 契约 ——在没有调用者剩余后删除旧形态,放在被每个迁移批次阻塞的任务里。
即使批次单独无法保持全绿,它们共享一个集成分支,全部阻塞一个最终的集成验证任务。只有那里承诺全绿。
常见问题
它为三行的改动产出了十二个任务。 过度拆分是该技能被报告最多的摩擦点,而且实践者之间高度一致: model 默认拆成原子单位,丢失了本可让它们有意义的分组。测验步骤正是为此存在——让它合并,它就会合并。更深的答案是任务有一个下限:如果整个改动装得进一个 上下文窗口,你根本不需要这个技能。直接使用 implement.
任务按层拆分——全部 schema 在一个里,全部 API 在另一个里。 这正是垂直切片规则所对抗的失败,而技能有时仍会产出它。在测验步骤抓住它:每个任务问一个问题——完成后我能演示什么?没有答案的任务就是横向切片。有人为此在每个任务加一行「演示路径」,并报告这推动模型走向垂直拆分。
在 GitHub 上,任务没有被创建为规格 issue 的子 issue。
已知且未修复。它已在十几次运行和多个模型上被报告, 在 issue #554 中阐述得最充分,而且在 Codex 上比在 Claude 上更糟。 gh 自 v2.94 起就原生支持这一点: gh issue create --parent <n>,以及 gh issue edit <parent> --add-sub-issue <n> 事后。在追踪器模板优先支持这些之前,运行后自己手动接上父链接是可靠的做法。
「Blocked by」被写进了 issue 正文,而不是真正的阻塞链接。
同类问题, 在 issue #513 中被报告,智能体甚至断言 GitHub 根本没有原生的阻塞关系。它其实是有的—— gh issue create --blocked-by 12,15。因为阻塞项会先发布,所以它们的编号在创建时总是可用的。正文文本是给没有原生边(edge)的追踪器用的后备方案,而不是默认方案。
本地任务去哪了?v1.1 的说明提到一个根级 tickets.md.
它们确实会,而那是个 bug——单个共享文件在并行智能体写入时也会竞争。本地模式现在每个任务一个文件,位于 .scratch/<feature-slug>/issues/<NN>-<slug>.md,按依赖顺序,与本地追踪器模板已描述的布局一致。这个 NN 前缀是真实的任务 ID,所以 /implement 03 能用的方案,而不是重新输入长标题。
它读我的规格说明时一直截断。
非常大的规格说明可能超出追踪器 issue 能干净回读的范围,而且没有本地副本可以兜底——智能体随后会烧掉 次工具调用 重新抓取块,永远到不了头。不要 clear or compact between /to-spec and /to-tickets。在同一个上下文窗口中运行它们,规格说明就完全不需要再被取回。
验收标准什么都没评判——有些在任何工作开始前就已经通过了。 模板要求标准,却对它们能否失败只字未提,所以会发生这种事。三种形态反复出现:在基准提交就已成立的标准、只能由另一个任务拥有的工作满足的标准,以及重述请求而非从产物推导的标准。垂直切片能阻止大部分——一个交付此前不存在行为的切片,在基准提交上按构造就是红的——但这个检查值得手动做。对每个标准,点名能证明它为假的观察,并确认它在实现者开始的提交上失败。
任务已发布。我到底怎么运行它们? 技能在产物处停下,没有自动派发模式。派发是手动的:看板、数没有开放阻塞项的任务、开那么多智能体会话。每个全新上下文一个任务,之间清空。注意 implement 在完成时不能可靠地关闭或勾掉任务,无论在 GitHub 还是本地 markdown 上都是如此,所以任务状态要由你来更新。
做到以下就算成功
- 每个任务都有「完成后能演示什么?」的答案——而且答案是行为,不是某一层。
- 列表编号返回给你,每项带「Blocked by」行,在任何内容发布之前。
- 最上面的任务没有阻塞项,可以立即开始。
- 任务正文里没有文件路径或行号,除了原型产出的片段。
- 每个任务读起来都像全新会话能在你不在场时完成的东西。
- 预重构(如果发现任何)排在顺序最前,而不是混进功能任务里。
在流程中的位置
to-tickets 是主构建链上的一步:
grill-with-docs → to-spec → to-tickets → implement → code-review
上游是 to-spec,它把已定稿的规格交给它来切片——让两者保持在同一个完整上下文窗口中。下游是 implement,它每个全新会话构建一个任务,驱动 tdd 用于测试,并以 code-review。当你不确定哪个技能或流程合适时, ask-matt 为你指路。
技能操作
npx skills@latest add mattpocock/skills安装整套技能,然后在智能体中输入 /to-tickets 来调用它。