create-specfuse 0.10.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -19,33 +19,34 @@ npm install -g @fission-ai/openspec # 流程引擎;装好后自动注册 /o
19
19
  /plugins add obra/superpowers # 行为约束插件(在 Claude Code 内执行)
20
20
  ```
21
21
 
22
- ## 生成物
22
+ 装完即可在项目里启动 `claude`,用 `/opsx:propose` 开始第一个变更。
23
23
 
24
- 装完得到四样东西:
24
+ ## 生成物
25
25
 
26
26
  ```
27
27
  my-app/
28
- ├── CLAUDE.md # 流水线调度协议(五拍规则全文)
29
- ├── .gitignore # 共享忽略规则
28
+ ├── CLAUDE.md # 流水线调度协议(五拍规则全文)
29
+ ├── .gitignore # 共享忽略规则
30
30
  ├── .claude/
31
- │ ├── settings.local.json # 权限白名单
31
+ │ ├── settings.local.json # 权限白名单
32
+ │ ├── commands/
33
+ │ │ ├── opsx/ # OpenSpec 提供:/opsx:* 命令面
34
+ │ │ └── specfuse.md # SpecFuse 提供:全自动入口
32
35
  │ └── skills/
33
- │ ├── design-md/ # 设计令牌生成技能
34
- │ ├── fusereview/ # 实施后代码评审技能
35
- │ └── fuseqa/ # 实施后端到端验收技能(含 4 份模板)
36
+ │ ├── design-md/ # 设计令牌生成技能(含 16 个原型模板)
37
+ │ ├── fusedoc/ # 文档标准技能(含 3 份参考文件)
38
+ │ ├── fusereview/ # 实施后代码评审技能
39
+ │ ├── fuseqa/ # 实施后端到端验收技能(含 4 份模板)
40
+ │ └── openspec-*/ # OpenSpec 提供:随其 init 生成
36
41
  └── openspec/
37
- ├── config.yaml # spec 规则(流程约束)
38
- ├── specs/ # 主规格
39
- └── changes/archive/ # 变更档案
42
+ ├── config.yaml # spec 规则(流程约束)
43
+ ├── specs/ # 主规格
44
+ └── changes/archive/ # 变更档案
40
45
  ```
41
46
 
42
- 项目目录会自动加入 Claude Code 信任列表。
43
-
44
- ### Design Tokens(前端项目)
47
+ 项目目录会自动加入 Claude Code 信任列表。`commands/opsx/` 与 `openspec-*` 由 OpenSpec 自己的 `init` 产生,随其版本更新;`commands/specfuse.md` 与四个技能由 SpecFuse 写入,已存在则不覆盖;`CLAUDE.md` 按 FUSION 标记合并(见下文)。
45
48
 
46
- 涉 UI/前端的项目,Think 阶段会触发 `/design-md` 技能生成 `DESIGN-TOKENS.md`,定义色彩、字体、间距、圆角等设计变量。也可手动 `/design-md` 为已有项目生成。
47
-
48
- ## 五拍流水线
49
+ ## 五个阶段
49
50
 
50
51
  在项目中启动 Claude Code,按这套节奏开发:
51
52
 
@@ -57,6 +58,16 @@ FuseQA apply 收尾检查点 —— 真实入口端到端验
57
58
  Verify /opsx:verify → /opsx:archive —— 全量验收与归档
58
59
  ```
59
60
 
61
+ ### 无人值守:`/specfuse`
62
+
63
+ 需求已经明确、不想逐拍确认时,用一条命令跑完整条流水线:
64
+
65
+ ```bash
66
+ /specfuse <需求描述>
67
+ ```
68
+
69
+ brainstorm、`/design-md` 问卷、模型切换与两个收尾检查点都由模型按推荐答案自答,并记录在最终报告中:模型切换默认不切换,FuseReview 自动进入,FuseQA 记录为跳过,verify 全部通过后 archive,全程不 commit、不 push。verify 仍失败时不 archive,保留变更目录并把失败写进报告。默认的 `/opsx:*` 交互行为不受影响。
70
+
60
71
  ### Think
61
72
 
62
73
  - `/opsx:propose`(Path A)一次生成全部制品;`/opsx:new` + `/opsx:continue`(Path B)一次一个制品、逐步确认。
@@ -68,20 +79,20 @@ Verify /opsx:verify → /opsx:archive —— 全量验收与归档
68
79
  - 逐任务红绿循环,严格遵守 TDD。
69
80
  - **铁律:`NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE`** —— 每个任务完成前必须粘贴终端原始输出作为证据。
70
81
 
71
- ### FuseReview
82
+ ### FuseReview(第三拍)
72
83
 
73
84
  - apply 完成后必须询问是否评审(禁止静默跳过);呈报任务数、涉及模块等事实,由你决定是否执行。
74
- - 评审以冷读方式审查 `基线..HEAD` 的累积 diff(评审者不参与实现)。
85
+ - 评审者不参与实现,以冷读方式审查 `基线..HEAD` 的累积 diff,按十一项检查逐条走(测试强度、缺失检测、范围契合、真实入口、接口两侧、生命周期与并发、强制路径、配置选择、能力与消费者契合、借用状态、边界值)。
75
86
  - Blocking 发现走 TDD 修复;修复后只复审修复 diff,不进行第二轮全量评审。
76
87
  - 跳过评审必须记录在收尾报告中留痕。
77
88
 
78
- ### FuseQA
89
+ ### FuseQA(第四拍)
79
90
 
80
- - apply 完成后必须询问是否验收(与 FuseReview 是**两问**,前一问答什么都不影响这一问必问,禁止合并成一问)。
91
+ - apply 完成后必须询问是否验收。**与 FuseReview 是两问**:前一问答什么都不影响这一问必问,禁止合并成一问。
81
92
  - 单测覆盖源码,冷读评审不运行系统,全量测试跑的还是单测——**没人以用户身份运行过制品**。这一拍补的就是这个缺口。
82
93
  - 用例从 specs 的 Scenario 派生,重建为真实入口(子进程 / HTTP 请求 / 浏览器),被测物是构建产物而非 `src/`;禁止 `import ../src/`(机械可查)。
83
94
  - 用例落 `tests/e2e/<capability>/`,与 `openspec/specs/<capability>/` 同名对齐,因此**回归零成本成立**——它已是全量测试的一部分。
84
- - 发现按**归因**分级而非按红:实现缺陷 Blocking,spec 漏洞默认 Suggestion,假红记为用例债并须写明代码为何正确。
95
+ - 发现按**归因**分级而非按红:实现缺陷 Blocking,spec 漏洞默认 Suggestion,假红记为用例债并须写明代码为何正确。
85
96
  - 用例是项目资产,新增/修正/剔除都要留理由——剔除尤其,否则「删掉红用例」和「掩盖缺陷」在台账上无从区分。
86
97
  - **收尾报告必须同时记录 FuseReview 与 FuseQA 两条决定**,缺一条即 apply 未完成。
87
98
 
@@ -90,6 +101,20 @@ Verify /opsx:verify → /opsx:archive —— 全量验收与归档
90
101
  - `/opsx:verify` 逐条对照 specs 验证实现;`/opsx:archive` 前运行全量测试 + lint 零警告,粘贴原始输出。
91
102
  - 全量测试**即 E2E 回归门禁**(包含 `tests/e2e/` 下所有用例),不得跳过。
92
103
 
104
+ ## 文档标准:FuseDoc
105
+
106
+ `/fusedoc` 是贯穿全链路的文档标准,**不属于五拍中的任何一拍**:无检查点、无强制提问、不进 apply 收尾序列,由产出散文的各阶段按需调用。
107
+
108
+ 它管三件事——一段话必须说什么、读起来是从仓库出发还是从写作会话出发、一个事实该放在哪一层。派上用场的典型场合:写 README 和注释、审计一份文档、判断某个事实该落在决策记录还是使用指南。
109
+
110
+ ```bash
111
+ /fusedoc <scope> # scope 必填;不填则报缺输入并停止,不推断全仓库范围
112
+ ```
113
+
114
+ ## 设计令牌(前端项目)
115
+
116
+ 涉 UI/前端的项目,Think 阶段会触发 `/design-md` 生成 `DESIGN-TOKENS.md`,定义色彩、字体、间距、圆角等设计变量。内置 16 个原型模板(SaaS 面板、营销页、后台管理、移动端……),按项目形态匹配。也可手动 `/design-md` 为已有项目生成。
117
+
93
118
  ## 已有项目:能不动就不动
94
119
 
95
120
  `npm create specfuse@latest .` 的合并策略逐文件保守:
@@ -97,15 +122,17 @@ Verify /opsx:verify → /opsx:archive —— 全量验收与归档
97
122
  | 文件 | 行为 |
98
123
  |------|------|
99
124
  | `CLAUDE.md` | 有 `<!-- FUSION:START/END -->` 标记 → 只替换标记内段落;无标记 → 追加 |
100
- | `.gitignore` | 追加缺失模式,不重复 |
101
- | `.claude/settings.local.json` | 合并权限列表 |
125
+ | `.gitignore` | 追加缺失模式(带 `# Added by specfuse` 分节),不重复 |
126
+ | `.claude/settings.local.json` | 合并 `permissions.allow`,其余键原样透传 |
102
127
  | `openspec/config.yaml` | 已存在 → 跳过 |
128
+ | `.claude/skills/*` | 已存在 → 不覆盖 |
129
+ | `.claude/commands/specfuse.md` | 已存在 → 不覆盖 |
103
130
 
104
131
  删除 `CLAUDE.md` 里的 FUSION 块,项目即回到无调度状态——整套编排零侵入、可逆。
105
132
 
106
- ## 不问技术栈
133
+ ## 与技术栈无关
107
134
 
108
- SpecFuse 是流程,不是栈选择器。Think → Do → FuseReview → FuseQA → Verify 对 Rust、React 或一个裸脚本完全一致,所以初始化时不会问你用什么栈,也不生成栈特化内容:
135
+ SpecFuse 是流程,不是栈选择器。五拍对 Rust、React 或一个裸脚本完全一致,所以初始化时不会问你用什么栈,也不生成栈特化内容:
109
136
 
110
137
  - `CLAUDE.md` 不含 Tech Stack 段落,验证指令写作「项目的测试命令」「项目的 linter」——由项目自己的工具链定义。
111
138
  - `.gitignore` 只给 IDE / OS / env / 日志这些共享模式,构建产物模式留给首次提交时判断。
@@ -119,27 +146,38 @@ SpecFuse 是流程,不是栈选择器。Think → Do → FuseReview → FuseQA
119
146
  ```
120
147
  Usage: create-specfuse [options] [project-name]
121
148
 
122
- project-name 目标目录(省略或 "." 表示当前目录)
123
- -y, --yes 非交互模式
124
- -V, --version 版本号
125
- -h, --help 帮助
149
+ Arguments:
150
+ project-name 目标目录(省略或 "." 表示当前目录就地初始化)
151
+
152
+ Options:
153
+ -y, --yes 非交互模式(全取默认值,CI 友好)
154
+ -V, --version 版本号
155
+ -h, --help 帮助
126
156
  ```
127
157
 
158
+ 交互模式只问两个问题:是否初始化 git(仅新目录)、是否初始化 OpenSpec。项目名由参数给出,不提问。
159
+
160
+ **失败行为**:OpenSpec 装不上或初始化失败时,脚手架仍以退出码 0 结束,并打印一条指向手动命令的提示——报告失败不等于让脚手架失败。Superpowers 插件缺失时打印安装提示,不中断。
161
+
128
162
  ## 开发
129
163
 
130
164
  ```bash
131
165
  npm install
132
- npm run build
133
- npm test
166
+ npm run build # tsc + 拷贝模板资产到 dist/
167
+ npm test # vitest run,含 tests/e2e/ 下的端到端用例
168
+ npm run lint # eslint,零告警
169
+ npx tsc --noEmit # 类型检查
134
170
  ```
135
171
 
136
- 生成设计模版预览页面(输出到 `docs/samples/`):
172
+ 生成设计模板预览页面(输出到 `docs/samples/`):
137
173
 
138
174
  ```bash
139
175
  npm run samples
140
176
  ```
141
177
 
142
- 16 个内置模版各生成一个自包含 HTML 页面,展示色彩系统、字体阶梯、间距、圆角和组件预览。打开 `docs/samples/index.html` 查看全部模版。
178
+ 16 个内置模板各生成一个自包含 HTML 页面,展示色彩系统、字体阶梯、间距、圆角和组件预览。打开 `docs/samples/index.html` 查看全部模板。
179
+
180
+ 方法论的权威定义在 `openspec/specs/`——每个 capability 一份 spec,描述可观察的行为契约。分发到目标项目的技能模板在 `src/templates/`,静态资产在 `src/<skill>/templates/`。
143
181
 
144
182
  ## License
145
183
 
@@ -0,0 +1,423 @@
1
+ # Calibration examples
2
+
3
+ Use these to identify the governing principle, not as text templates. **Balanced** preserves every load-bearing proposition with the least explanation needed at that location.
4
+
5
+ This file quotes flawed prose deliberately, so search patterns exclude this skill's own directory.
6
+
7
+ ## Part 1 — Proposition judgment
8
+
9
+ ### Preserve every factual clause
10
+
11
+ **Original:** "The coordinator carefully serializes writes per session, flushes buffered events before disposal resolves, and reports backend failures to the caller."
12
+
13
+ **Over-trimmed:** "The coordinator serializes persistence."
14
+
15
+ **Balanced:** "The coordinator serializes writes per session, flushes buffered events before disposal resolves, and reports backend failures to the caller."
16
+
17
+ Remove decoration and repetition, not propositions. Actor, per-session scope, disposal ordering, and failure visibility are separate facts.
18
+
19
+ ### Explicit scope limitation is functional
20
+
21
+ **Over-trimmed:** "Read the sources and use judgment."
22
+
23
+ **Balanced:** "This is guidance, not a complete checklist. Use judgment beyond the named checks; documented requirements still apply."
24
+
25
+ **Over-detailed:** Several paragraphs defending why lists cannot replace independent reasoning.
26
+
27
+ Keep the explicit limitation because it changes how an agent applies the workflow. Trim repeated persuasion, not the guardrail.
28
+
29
+ ### A how-to guide keeps action and verification
30
+
31
+ **Over-trimmed:** "Add tests for the new command."
32
+
33
+ **Balanced:** "Test registration and teardown at unit level, exercise the command through the real entry path, and add a recorded-output test when its rendering changes. Verify the assertion observes the external result rather than the tool's own report."
34
+
35
+ **Over-detailed:** A walkthrough of every fixture file and assertion already visible in the example code.
36
+
37
+ Keep the test tiers, required action, real entry path, and observable verification. Remove fixture narration.
38
+
39
+ ### Preserve ownership and timing
40
+
41
+ **Over-trimmed:** "Provider work is cancelled during teardown."
42
+
43
+ **Balanced:** "The runtime requests provider cancellation before releasing the child scope; the provider remains responsible for joining its workers before disposal resolves."
44
+
45
+ **Over-detailed:** A chronological account of every promise and callback used to implement teardown.
46
+
47
+ The actor, ordering, point where ownership changes, and completion guarantee are separate factual clauses.
48
+
49
+ ### Event documentation preserves ordering consequences
50
+
51
+ **Over-trimmed:** "Composes and caches the request prefix."
52
+
53
+ **Balanced:** "Composes the request prefix once before the first request. Listener appends join the current request, and size accounting receives the composed prefix."
54
+
55
+ **Over-detailed:** A walkthrough of the helpers, cache fields, and callbacks that implement the ordering.
56
+
57
+ Event order and its current-request consequence are caller-visible behavior, not implementation narration.
58
+
59
+ ### Orient complicated code without narrating it
60
+
61
+ **Over-trimmed:** "Worker sandbox support."
62
+
63
+ **Balanced:** "Owns the worker sandbox and its host bridge. Initialization is single-shot; disposal terminates the worker and rejects later calls. See the isolation design doc for the protocol rationale."
64
+
65
+ **Over-detailed:** A paragraph-by-paragraph preview of the classes and helper functions below.
66
+
67
+ Keep the module's role, dependencies, responsibilities, and non-obvious lifecycle behavior. Link architecture rationale and let the code show local control flow.
68
+
69
+ ### Public API documentation includes failures
70
+
71
+ **Over-trimmed:** "Returns the sandbox handle."
72
+
73
+ **Balanced:** "Returns the initialized sandbox handle. Throws if initialization has not completed or the sandbox has already been disposed."
74
+
75
+ **Over-detailed:** The internal state-machine branches and exact helper calls that lead to each throw.
76
+
77
+ Throws and state preconditions are caller-visible contract facts.
78
+
79
+ ### Keep a concise implementation mapping
80
+
81
+ **Over-trimmed:** "Search provider backed by an external API."
82
+
83
+ **Balanced:** "Maps each provider result to the shared search-result fields, preserving the title, URL, and text while omitting provider-only ranking metadata."
84
+
85
+ **Over-detailed:** A field-by-field restatement of the mapping code, including fields with identical names and obvious assignments.
86
+
87
+ Keep mapping details that explain where an adapter drops or changes information.
88
+
89
+ ### Link rationale while keeping the local contract
90
+
91
+ **Over-trimmed:** "Disposal is documented in the lifecycle design doc."
92
+
93
+ **Balanced:** "Disposal aborts the run and waits for provider quiescence. See the lifecycle design doc for ownership and race handling."
94
+
95
+ **Over-detailed:** Repeating the design doc's promise choreography and rejected ownership models beside every disposer.
96
+
97
+ Keep the behavior and completion guarantee where callers need them. Link aggressively for the algorithm and rationale; a link cannot replace the local contract.
98
+
99
+ ### Shipped decision records retain verification contracts
100
+
101
+ **Over-trimmed:** Deleting the entire verification section because the decision has already shipped.
102
+
103
+ **Balanced:** "Unit tests cover cancellation before and after publication, disposal quiescence, and provider reload. A built-artifact smoke covers the real entry path; recorded-output coverage is deferred because the transport is process-specific."
104
+
105
+ **Over-detailed:** A file-by-file walkthrough of fixtures and assertions with no additional behavioral distinction.
106
+
107
+ Remove migration tasks and test narration. Keep the tiers, the behaviors they pin, the real entry path, and named coverage gaps.
108
+
109
+ ### A security boundary may need one concrete example
110
+
111
+ **Over-trimmed:** "Mounted plugins share the host's authority."
112
+
113
+ **Balanced:** "Mounted plugins share the host's authority; for example, access to a shell service permits commands with the host executor's privileges."
114
+
115
+ **Over-detailed:** A list of every service a plugin could misuse and every hypothetical exploit.
116
+
117
+ Keep one example when it makes an otherwise abstract security limit operationally clear.
118
+
119
+ ### Delete reasoning transcripts entirely
120
+
121
+ **Over-detailed:** "First the loop checks whether the value is absent. If it is absent, the next branch returns early. Otherwise it continues, which is why the final assertion is safe."
122
+
123
+ **Balanced:** No comment when the code already expresses those branches. If the early return protects a non-obvious invariant, state only that invariant.
124
+
125
+ Do not compress a reasoning transcript into shorter narration; remove it.
126
+
127
+ ### Configuration comments explain what the tree cannot
128
+
129
+ **Over-detailed:** "This entry loads the storage provider, followed by the policy component, followed by the read, write, and edit commands," when the adjacent entries already show that order.
130
+
131
+ **Balanced:** "Load policy before the user-facing commands so their write and edit calls pass through the read-before-mutation check."
132
+
133
+ Keep the consequence of order, a surprising scope rule, or a security boundary. Let the configuration show its own inventory.
134
+
135
+ ### Do not trim for word count alone
136
+
137
+ **Current:** "The adapter converts provider errors into the shared error type so callers can handle authentication, rate-limit, and transient failures uniformly."
138
+
139
+ **Shorter but worse:** "The adapter normalizes provider errors."
140
+
141
+ **Balanced decision:** Keep the current sentence unless a link or surrounding contract already lists the failure categories. The shorter version loses the consequence and distinctions without improving structure.
142
+
143
+ ### Model-visible text follows ownership
144
+
145
+ **Over-trimmed:** "The tool returns errors when a call fails."
146
+
147
+ **Over-detailed:** Copying another component's schema and renderer strings into this backend's README.
148
+
149
+ **Balanced:** Quote stable prompt, result, and error text this component owns. Link the generated tool reference for schemas and the consumer README for text another component owns; state only this component's conditions or deltas locally.
150
+
151
+ Wording that reaches a model is behavior, but duplication still drifts. Exactness belongs at the owner.
152
+
153
+ ### Generated summaries must stand alone
154
+
155
+ **Over-trimmed:** "Approval request and policy service." The owner explains policy order and audit logging later, but the generated reference exports only its first sentence.
156
+
157
+ **Over-detailed:** Moving the service's full lifecycle and notification behavior into the extracted sentence.
158
+
159
+ **Balanced:** "Approval service that applies policy before answerers and logs every ask/outcome pair to the requesting session." Keep non-extracted detail in later sentences.
160
+
161
+ Know what the generator extracts. That fragment must preserve the contract needed on its generated surface.
162
+
163
+ ### Limitations are contracts, not debt inventories
164
+
165
+ **Over-trimmed:** Omitting a process-lifetime cache that makes configuration changes require a restart.
166
+
167
+ **Over-detailed:** Listing private helper cleanup and unused test-only accessors with no caller or maintainer consequence.
168
+
169
+ **Balanced:** "Provider selection is cached for the process lifetime; installing or repairing a provider requires a restart." Keep ordinary cleanup in its tracking marker or decision record.
170
+
171
+ Retain gaps and non-obvious constraints that affect use or safe maintenance. A README is not a backlog dump.
172
+
173
+ ## Part 2 — Vantage correction
174
+
175
+ ### Dead citations
176
+
177
+ #### Decision ordinal with a committed owner
178
+
179
+ **Leaked:** "Command input resolves against the visible list (decision 21)."
180
+
181
+ **Fixed:** "Command input resolves against the visible list — the plain-text-reference decision, owned by `docs/decisions/palette-resolution.md`."
182
+
183
+ The ordinal resolves nowhere at the current commit; the decision's name and owning path do. Name the owning path at least once per file — as a link where the surface supports one — and later mentions may use the searchable name alone.
184
+
185
+ #### Decision ordinal without an owner
186
+
187
+ **Leaked:** "The registry rejects duplicate names (decision 7: names are flat, no namespacing)."
188
+
189
+ **Fixed:** "The registry rejects duplicate names; names are flat, with no namespacing."
190
+
191
+ No committed artifact owns "decision 7", so the citation is deleted — but its factual clause (flat names) is restated to stand alone, not deleted with it.
192
+
193
+ #### Audit item codes
194
+
195
+ **Leaked:** "Rendering is pure: same input, same string (audit R3)."
196
+
197
+ **Fixed:** "Rendering is pure: same input, same string."
198
+
199
+ No audit document exists in the repository; the code is session shorthand carrying zero propositions.
200
+
201
+ #### Section numbers of uncommitted drafts
202
+
203
+ **Leaked:** "Layering follows the design (v2 §3.2): `src/core/` is the pure core."
204
+
205
+ **Fixed:** "Layering: `src/core/` is the pure core."
206
+
207
+ A section number of a draft nobody committed is unresolvable. Contrast: "escapes per RFC 9110 §10.1.5" stays — an external standard resolves outside the repository by design, and a committed document that owns its numbering may be cited by section.
208
+
209
+ #### Plan-phase labels
210
+
211
+ **Leaked:** "`src/ui/` is the shell (T4); the P-I migration owns the adapters."
212
+
213
+ **Fixed:** "`src/ui/` is the shell; the adapters live in `src/ui/adapters/`."
214
+
215
+ Phase labels index a plan that never landed. Replace the label with what the phase produced.
216
+
217
+ ### Series and review-thread vantage
218
+
219
+ #### Series position in durable prose
220
+
221
+ **Leaked:** "A future remote backend implements this interface (the sandbox backend is a later change in this series)."
222
+
223
+ **Fixed:** "A remote backend can implement this interface without changing the render layer."
224
+
225
+ Durable prose cannot see the series. Keep the extension-point contract; the pending work's home is the change itself, a tracking marker, or an issue.
226
+
227
+ #### "This change" in a README
228
+
229
+ **Leaked:** "This change adds cursor-based pagination to the item list."
230
+
231
+ **Fixed:** "The item list paginates by cursor."
232
+
233
+ A README outlives every change; state the mechanism as current fact.
234
+
235
+ ### Change narration and version stamps
236
+
237
+ #### War story with a change reference
238
+
239
+ **Leaked:** "Colors used to come from `--surface-*` tokens, which nothing defined, so it always rendered the fallbacks; the alias tokens fixed that (change #88)."
240
+
241
+ **Fixed:** "Colors come from the alias tokens; an undefined token renders the fallbacks."
242
+
243
+ Both live facts survive — the current mechanism and the standing failure behavior — restated in the present. The defect's biography belongs to the change and its decision record.
244
+
245
+ #### Removal narration
246
+
247
+ **Leaked:** "The `legacy` flag is gone with the cleanup; requests ride the single code path now."
248
+
249
+ **Fixed:** "Requests use a single code path."
250
+
251
+ Readers who never saw the flag learn nothing from its absence. "Now" contrasting with a deleted past is a version stamp.
252
+
253
+ #### Fixed regression → counterfactual present
254
+
255
+ **Leaked:** "This used to double-encode multibyte labels."
256
+
257
+ **Fixed:** "Without the byte-length guard, multibyte labels double-encode."
258
+
259
+ The regression pin survives as a present-tense counterfactual that names the guard; "used to" pins it to repository archaeology instead.
260
+
261
+ #### Indexical version stamps
262
+
263
+ **Leaked:** "Batch rendering is synchronous this release; the async path is roadmap work."
264
+
265
+ **Fixed:** "Batch rendering is synchronous." (The deferral lives in `TODO(batch-render):` at the call site.)
266
+
267
+ "This release" / "v1" / "today" go stale the moment they merge. A historical stage name inside a decision record's change-story section is current-state-safe; the indexical form never is.
268
+
269
+ ### Review choreography
270
+
271
+ #### Review verdicts as prose
272
+
273
+ **Leaked:** "Rejected in review: caching the resolved path. We keep resolution per-call."
274
+
275
+ **Fixed (in a decision record's alternatives-considered section):** "**Caching the resolved path.** Rejected: the path depends on the caller's working directory, so a cache keyed by request would serve stale roots."
276
+
277
+ The alternatives-considered genre is the sanctioned home; the reviewer and the round are not part of the rationale.
278
+
279
+ #### Draft ordinals
280
+
281
+ **Leaked:** "As of the fifth revision of this record, the parser also validates manifests."
282
+
283
+ **Fixed:** "The parser validates the manifest."
284
+
285
+ A shipped record states shipped reality; its own revision history lives in version control.
286
+
287
+ ### Reviewer-addressed justification
288
+
289
+ #### Arguing a cast
290
+
291
+ **Leaked:** "The cast is safe — the client constructed the object, it simply doesn't declare the optionals strictly enough."
292
+
293
+ **Fixed:** "The client constructs this object with every optional populated; the declared type is looser than the runtime guarantee."
294
+
295
+ State the invariant a maintainer must not break. "It simply…" answers an objection nobody at the current commit raised. If the invariant is visible in the code, delete the comment instead.
296
+
297
+ #### Appeal to review authority
298
+
299
+ **Leaked:** "This is correct because the reviewer confirmed the wrapping order."
300
+
301
+ **Fixed:** (deleted; the wrapping order is stated in the function's return documentation.)
302
+
303
+ Correctness claims cite invariants or tests, never people.
304
+
305
+ ### Restatement and derivation
306
+
307
+ #### Control-flow narration
308
+
309
+ **Leaked:** "First we normalize the label, then we truncate it, then we wrap it."
310
+
311
+ **Fixed:** (deleted.)
312
+
313
+ The three lines below the comment say the same thing in code.
314
+
315
+ #### Test walkthrough
316
+
317
+ **Leaked:** "This test creates a client, sends two requests, waits for the second reply, and then asserts the log has four entries."
318
+
319
+ **Fixed:** "Two round-trips must produce exactly four log entries — the projection dedupes the shared prefix."
320
+
321
+ Keep only the non-obvious assertion rationale; the walkthrough restates the test body.
322
+
323
+ ### Hedges and planning residue
324
+
325
+ #### Unmarked deferral
326
+
327
+ **Leaked:** "Probably fine to render eagerly for now."
328
+
329
+ **Fixed:** (deleted; the deferral already has its `TODO(batch-render):` marker.)
330
+
331
+ A hedge without an owner is planning residue. If no marker exists, write one (`TODO(batch-render): coalesce per animation frame`) instead of keeping the hedge.
332
+
333
+ #### Vague sizing
334
+
335
+ **Leaked:** "A 64 KiB buffer should be enough for most cases."
336
+
337
+ **Fixed:** "64 KiB holds the largest observed frame (48 KiB) with headroom; a larger frame fails loudly in the decoder."
338
+
339
+ Replace the hedge with the actual bound and the failure behavior when it is exceeded.
340
+
341
+ ### Authoring-language slips
342
+
343
+ **Leaked:** "The renderer runs on the client 端; see the 设计稿 for spacing. ---- 私有 ----"
344
+
345
+ **Fixed:** "The renderer runs on the client side; spacing follows the design-tool frame `item-badges`."
346
+
347
+ Working-language fragments and session separators are transcription residue. The design-tool frame name stays: external provenance that resolves outside the repository by design.
348
+
349
+ ### Keeps
350
+
351
+ #### Issue references are durable on every surface
352
+
353
+ **Keep:** "The cap applies to the complete rendered value, wrappers included (issue #1470 owns the follow-up)."
354
+
355
+ An unaided pass deleted this, reasoning that issue citations belong in decision records. Wrong direction: issues resolve at the current commit from any surface, and "#N owns the follow-up" is the sanctioned home for deferred work in a README. What decision records and incident reports additionally sanction is citing *merged changes* as evidence.
356
+
357
+ #### Dead name-drops are not "naming the owner"
358
+
359
+ **Delete:** "Badge renderer over the widget interface (see the rendering design doc)."
360
+
361
+ An unaided pass kept this as "naming the owning document by topic". The test is resolvability, not form: if no committed file answers to "the rendering design doc", the pointer is dead. Retarget it to the committed owner if one exists; otherwise delete it.
362
+
363
+ #### Suppression justifications
364
+
365
+ **Keep (after fixing):** a linter suppression comment whose trailing reason reads "the one-element literal guarantees index 0."
366
+
367
+ The justification clause is required prose. When the stated reason is false — the original claimed "the loop guard above proves a frame exists" with no loop in sight — fix the reason; never delete it.
368
+
369
+ #### Measured bounds
370
+
371
+ **Keep:** "Depth cap (measured: 512 nests ≈ 0.15s synchronous; 4096 blocks the loop)."
372
+
373
+ The measurement pins the constant against uninformed retuning, and "measured" is the provenance that distinguishes data from a guess.
374
+
375
+ #### Runtime old/new is not change history
376
+
377
+ **Keep:** "The old connection drains before the new one accepts."
378
+
379
+ "Old" and "new" here name two live runtime objects during handover, not repository states. The change-narration ban is about repository history, not lifecycle vocabulary.
380
+
381
+ ## Part 3 — Overcorrection traps
382
+
383
+ Enumerate a passage's propositions before trimming it.
384
+
385
+ ### Flipping an obligation into an endorsement
386
+
387
+ **Original:** "These direct registrations are exceptions pending migration to the registry API."
388
+
389
+ **Overcorrected:** "These direct registrations are sanctioned exceptions."
390
+
391
+ **Right:** "These direct registrations are exceptions pending migration to the registry API."
392
+
393
+ "Pending migration" is an obligation; "sanctioned" blesses the status quo. The trim inverted the sentence's modality while shortening it.
394
+
395
+ ### Promoting a hypothetical to a shipped feature
396
+
397
+ **Original:** "A future IPC transport subclasses the executor and overrides `send`."
398
+
399
+ **Overcorrected:** "An IPC transport subclasses the executor and overrides `send`."
400
+
401
+ **Right:** "A hypothetical IPC transport — no such transport exists — would subclass the executor and override `send`."
402
+
403
+ Deleting the future-marker alone turns a design illustration into a claim that the class ships. Mark the hypothetical explicitly instead of just unmarking the future.
404
+
405
+ ### Deleting a true fact with the transcript around it
406
+
407
+ **Original:** "The check notice narrates the validation order; the notice text is also what the documentation type check compiles against."
408
+
409
+ **Overcorrected:** (whole sentence deleted as narration.)
410
+
411
+ **Right:** "The notice text is what the documentation type check compiles against."
412
+
413
+ Half the sentence was narration; the other half was a load-bearing coupling. Delete clauses, not sentences, when propositions share a line.
414
+
415
+ ### Dropping provenance while keeping the number
416
+
417
+ **Original:** "The 4 MiB ceiling is measured: the largest generated type module is 3.1 MiB."
418
+
419
+ **Overcorrected:** "The ceiling is 4 MiB; the largest generated type module is 3.1 MiB."
420
+
421
+ **Right:** keep "measured".
422
+
423
+ Without "measured" the 3.1 MiB reads as a definition rather than an observation, and nobody re-measures before raising the ceiling.