close-spec

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Close Spec

Close Spec

A spec is a build plan while you're building and a rationale record once you've shipped. Closing flips it from one to the other. The plan was a ladder of slices and predictions; the record is the layer of meaning the code can't hold — why this exists, what it must never break, what you tried that failed. The code is the single source of truth for how; the closed spec is the source of truth for why, and a map into the code.
Do not summarize the implementation. Anyone can read the code. If a paragraph restates what a function does, cut it and point at the function instead.
在开发阶段,spec是一份构建计划;交付完成后,它就成为一份原理记录。关闭spec的操作会将其从前者转换为后者。计划是由多个阶段和预期组成的阶梯;而记录则承载着代码无法表达的深层含义——为什么存在这个功能、哪些内容绝对不能被破坏、尝试过但失败的方案。代码是实现方式的唯一可信来源;已关闭的spec则是设计原因的可信来源,同时也是通往代码的指引地图。
不要总结实现细节。任何人都可以直接阅读代码。如果某段文字只是复述函数的功能,请删除这段文字,转而指向对应的函数。

Workflow

工作流程

  1. Confirm it shipped. The feature is merged or working in-tree and its tests/screenshot gates are green. If slices remain unverified, it isn't done — finish or review first.
  2. Diff plan against reality. Read the spec's README and slices, then read what actually landed. Note every place the build diverged from the plan: dropped slices, renamed seams, a mechanic that turned out different, an assumption that broke. The divergences are the most valuable thing to record — they're exactly what a future reader would otherwise re-derive.
  3. Move it.
    specs/<feature>/
    specs/done/<feature>/
    (use
    git mv
    ). Single-file specs:
    specs/<feature>.md
    specs/done/<feature>.md
    .
  4. Rewrite the README as a record, not a plan. Keep:
    • Overview & purpose — what shipped and the problem it solves, in present tense ("the economy settles monthly"), not future ("will add").
    • The reason — why it works this way and not the obvious alternatives; the constraints and trade-offs that forced the shape. This is the part the code cannot tell you.
    • Principles & invariants — the rules the implementation must keep honoring. What must stay true; what would silently break if violated.
    • Pointers into the code — greppable module/type/function names, file paths, and the tests that pin the behavior. Send the reader to the code for mechanics; name the entry points so they can find it in one grep.
    • Dead ends — approaches tried and rejected, with the reason, so nobody re-walks them.
    • Visual provenance — any images that were uploaded as a baseline to match, a comparison target, or inspiration for the look. These are the requirement: they say what "done" had to resemble and why the result took the shape it did. Keep them in-tree and reference them from the README, naming where each came from (a real screenshot, a mood board, a reference game) and what it was driving. Without them a reader sees the outcome but not the standard it was held to.
    Cut: slice-by-slice build order, "next we will…", scaffolding instructions, per-slice verification checklists, and any prose that re-narrates code.
  5. Collapse the slices, preserve the imagery. The slices were the build ladder; once shipped they're sediment. Fold anything durable (a divergence, a dead end, an invariant a slice established) into the README, then delete
    slices/
    . But keep the baseline, comparison, and inspiration images — the references the work was measured against — and the
    visualizations/
    or
    assets/
    that still help a reader judge the result. These are provenance, not scaffolding: discard a build instruction, never the picture that defined what the build was aiming at. Wire each one into the README's visual-provenance trail so the story of where the requirement came from survives the close.
  6. Fix references. Update links that pointed at the old path. If
    [[memory]]
    notes or other skills referenced the spec, repoint them.
  7. Audit every statement, unbiased. Spawn sub-agents that did not write the spec and lack the conversation, and have them check the final document claim by claim against the actual code and tests. Fan out — one agent per section, or split the claim list across agents — so no single biased pass waves it through. Each agent returns a verdict per statement:
    • Pointer (a named module/type/function/file/test) — does it exist and say what the spec says? Flag stale names and wrong paths.
    • Invariant / principle — is it actually enforced in the code, or just asserted? Flag claims the code contradicts or doesn't back.
    • Overview / reason — is it consistent with what shipped, present tense, no leftover "will"/"next"/slice numbers?
    • Visual provenance — do the referenced baseline/inspiration images still exist in-tree, and does the README say where each came from and what it drove? Flag a result shown with no standard it was held to.
    Treat unsupported, contradicted, or stale statements as defects: fix the spec (or the pointer) and re-audit the changed claims. The spec is not closed while any statement is unverified.
  1. 确认已交付:功能已合并到代码库或在本地正常运行,且其测试/截图校验环节全部通过。若仍有未验证的阶段,则说明未完成——需先完成验证或执行review流程。
  2. 对比计划与实际情况:阅读spec的README和各阶段内容,再查看实际落地的代码。记录构建过程与计划的所有差异:被取消的阶段、重命名的接口、实际效果不同的机制、被打破的假设。这些差异是最有价值的记录内容——它们正是未来读者可能会重新摸索的点。
  3. 移动文件:将
    specs/<feature>/
    目录通过
    git mv
    命令移动到
    specs/done/<feature>/
    。单文件spec则将
    specs/<feature>.md
    移动到
    specs/done/<feature>.md
  4. 将README重写为记录而非计划:保留以下内容:
    • 概述与目的——已交付的内容及其解决的问题,使用现在时态(如“经济系统每月结算”)而非将来时态(如“将添加”)。
    • 设计原因——为什么采用当前方案而非其他显而易见的替代方案;约束条件和权衡取舍如何塑造了最终形态。这部分是代码无法传达的信息。
    • 原则与不变量——实现过程必须始终遵循的规则。哪些内容必须保持不变;如果被违反会导致哪些隐性问题。
    • 代码指向——可通过grep查找的模块/类型/函数名称、文件路径,以及固定行为的测试用例。让读者通过代码了解具体机制;给出入口点名称,以便他们通过一次grep就能找到对应代码。
    • 失败尝试——尝试过但被否决的方案及其原因,避免他人重复踩坑。
    • 视觉溯源——所有作为基准匹配、对比目标或设计灵感上传的图片。这些图片本身就是需求:它们定义了“完成”的标准以及最终形态的设计依据。将这些图片保留在代码库中,并在README中引用,说明每张图片的来源(真实截图、情绪板、参考游戏等)及其作用。没有这些图片,读者只能看到结果,却无法了解衡量结果的标准。
    删除以下内容:按阶段划分的构建顺序、“接下来我们将……”这类表述、脚手架搭建说明、各阶段的验证清单,以及任何复述代码内容的文字。
  5. 合并阶段内容,保留相关图像:阶段内容是构建的阶梯;交付完成后它们就成为沉淀信息。将所有有留存价值的内容(如差异点、失败尝试、某阶段确立的不变量)合并到README中,然后删除
    slices/
    目录。但务必保留基准图、对比图和灵感图——这些是衡量工作成果的参考依据,同时保留仍能帮助读者理解结果的
    visualizations/
    assets/
    目录。这些属于溯源信息,而非脚手架:可以删除构建指令,但绝不能删除定义构建目标的图片。将每张图片关联到README的视觉溯源部分,确保需求来源的故事在关闭spec后得以留存。
  6. 修复引用链接:更新指向旧路径的链接。如果
    [[memory]]
    笔记或其他技能引用了该spec,需重新指向新路径。
  7. 无偏见审核所有表述:指派未参与该spec编写且不了解相关讨论的子Agent,让他们对照实际代码和测试用例逐条检查最终文档的内容。拆分任务——每个Agent负责一个章节,或把检查项分配给多个Agent——避免单一有偏见的审核直接通过。每个Agent需对每条表述给出以下 verdict:
    • 指向内容(命名的模块/类型/函数/文件/测试用例)——是否存在且与spec描述一致?标记过时的名称和错误的路径。
    • 不变量/原则——代码中是否实际执行了该规则,还是仅作声明?标记代码与之矛盾或未支持的表述。
    • 概述/设计原因——是否与已交付内容一致、使用现在时态、没有残留的“将”/“接下来”/阶段编号?
    • 视觉溯源——引用的基准图/灵感图是否仍存在于代码库中,且README是否说明了每张图片的来源及其作用?标记没有对应衡量标准的结果展示。
    将未被支持、矛盾或过时的表述视为缺陷:修复spec(或指向内容)并重新审核修改后的表述。只要存在未验证的表述,spec就不能被关闭。

Smell Test

检验标准

  • Could a reader reconstruct this paragraph by reading the code? → cut it, leave a pointer.
  • Does it say "will" or "next" or name a slice number? → it's still a plan.
  • Did a real decision diverge from the plan and go unrecorded? → that's the one thing worth keeping; add it.
  • Was there a baseline or inspiration image you were matching against? → keep it and say what it drove; the result is meaningless without the standard.
  • 读者能否通过阅读代码重构这段文字?→ 删除这段文字,留下指向代码的链接。
  • 文中是否出现“将”/“接下来”或阶段编号?→ 说明它仍属于计划而非记录。
  • 是否有实际决策与计划存在差异但未被记录?→ 这是最值得留存的内容,需补充进去。
  • 是否存在作为匹配基准或灵感的图片?→ 保留图片并说明其作用;没有衡量标准,结果就毫无意义。

Done

完成状态

The spec lives under
specs/done/
, reads as why-and-what-must-hold rather than how, names the code that implements it, preserves the baseline and inspiration imagery the work was measured against, and every statement has survived an unbiased audit against the code. A fresh reader gets the intent, the invariants, and the visual standard without the code — the story of why it's done and how the decisions were made — and the mechanics by following the pointers into it.
spec存放在
specs/done/
目录下,内容聚焦于设计原因和必须遵循的规则而非实现方式,指明了实现该功能的代码,保留了衡量工作成果的基准图和灵感图,且所有表述都通过了无偏见的代码审核。新读者无需查看代码就能了解设计意图、不变量和视觉标准——即功能为何如此设计、决策是如何做出的——并可通过指向链接查看具体实现细节。