@namewta/speculo 0.2.10 → 0.2.12

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.
Files changed (23) hide show
  1. package/package.json +1 -1
  2. package/template/canonical/canonical-specdev-tickets.md +19 -19
  3. package/template/skills/archive-and-consolidate/SKILL.md +2 -2
  4. package/template/skills/archive-and-consolidate/assets/archive-plan-template.md +2 -1
  5. package/template/skills/archive-and-consolidate/references/archive-rules.md +4 -4
  6. package/template/workflows/specdev/A-archive-and-consolidate/A-archive-and-consolidate.md +1 -1
  7. package/template/workflows/specdev/A-archive-and-consolidate/archive-rules.md +3 -3
  8. package/template/workflows/specdev/G-grill-with-docs/G-grill-with-docs.md +3 -2
  9. package/template/workflows/specdev/I-init-setup/tracking-convention.md +13 -6
  10. package/template/workflows/specdev/INDEX.md +32 -10
  11. package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +1 -1
  12. package/template/workflows/specdev/P-goal-plan/execution-sections.md +35 -12
  13. package/template/workflows/specdev/P-goal-plan/governance-sections.md +3 -3
  14. package/template/workflows/specdev/P-goal-plan/lead-orchestration-protocol.md +5 -3
  15. package/template/workflows/specdev/T-tickets/T-tickets.md +10 -10
  16. package/template/workflows/specdev/T-tickets/tickets-map-template.md +14 -14
  17. package/template/workflows/specdev/T-triage/T-triage.md +76 -0
  18. package/template/workflows/specdev/T-triage/artifact-templates.md +122 -0
  19. package/template/workflows/specdev/T-triage/intake-rules.md +71 -0
  20. package/template/workflows/specdev/T-triage/routing-rules.md +70 -0
  21. package/template/workflows/specdev/T-triage/understanding-rules.md +102 -0
  22. package/template/workflows/specdev/W-wayfinder/W-wayfinder.md +5 -5
  23. package/template/workflows/specdev/_state/status.json +4 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namewta/speculo",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Workflow-packaged specification-driven development assets with install, update, and migration tooling.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -69,7 +69,7 @@
69
69
 
70
70
  迭代直到用户批准拆分方案。每次修改后重新展示完整列表。
71
71
 
72
- **完成标准**:用户已确认粒度、阻塞边与合并/拆分方案。批准后,tickets 将写入 `ticket/` 目录(一个 ticket 一个独立文件,命名为 `#NN-<name>.md`),并生成 `tickets-map.md` 作为总体地图和执行清单。
72
+ **完成标准**:用户已确认粒度、阻塞边与合并/拆分方案。批准后,tickets 将写入 `ticket/` 目录(一个 ticket 一个独立文件,命名为 `NN-<name>.md`),并生成 `tickets-map.md` 作为总体地图和执行清单。
73
73
 
74
74
  ### 5. 发布
75
75
 
@@ -81,14 +81,14 @@
81
81
 
82
82
  **5b. 写入单个 ticket 文件**
83
83
 
84
- 按依赖顺序(无阻塞者在前,被阻塞者在后),为每个 ticket 创建独立文件 `ticket/#NN-<ticket-name>.md`。`#NN` 为 ticket 编号(`#01`, `#02`, ..., `#10`, ...),代表执行顺序。
84
+ 按依赖顺序(无阻塞者在前,被阻塞者在后),为每个 ticket 创建独立文件 `ticket/NN-<ticket-name>.md`。`NN` 为 ticket 编号(两位零填充阿拉伯数字:`01`, `02`, ..., `10`, ...),代表执行顺序。文件名与编号均不含 `#` 字符,避免 Markdown 链接被编码为 `%23`。
85
85
 
86
86
  每个 ticket 文件按以下模板填写:
87
87
 
88
88
  ```markdown
89
- # Ticket #NN: <标题>
89
+ # Ticket NN: <标题>
90
90
 
91
- - **被阻塞于:** `./ticket/#NN-<name>.md`, `./ticket/#NN-<name>.md`(相对路径,或多个用逗号分隔。无阻塞则写"无 —— 可立即开始"。查看被引用 ticket 文件中的状态字段自行判断是否已就绪)
91
+ - **被阻塞于:** `./ticket/NN-<name>.md`, `./ticket/NN-<name>.md`(相对路径,或多个用逗号分隔。无阻塞则写"无 —— 可立即开始"。查看被引用 ticket 文件中的状态字段自行判断是否已就绪)
92
92
  - **状态:** 未开始
93
93
 
94
94
  <!-- 如需了解整体上下文、所有 ticket 的依赖关系全景或横切关注点,请查看 `../tickets-map.md`。 -->
@@ -146,7 +146,7 @@
146
146
 
147
147
  **模板填写说明:**
148
148
 
149
- - **被阻塞于**使用指向 `./ticket/` 目录的相对路径(如 `./ticket/#01-auth.md`),多个用逗号分隔。执行者应自行打开被引用的 ticket 文件查看其状态字段,判断阻塞是否已解除
149
+ - **被阻塞于**使用指向 `./ticket/` 目录的相对路径(如 `./ticket/01-auth.md`),多个用逗号分隔。执行者应自行打开被引用的 ticket 文件查看其状态字段,判断阻塞是否已解除
150
150
  - **状态**初始固定为"未开始";实现者开始工作时改为"进行中",完成后改为"已完成"
151
151
  - **战略与背景**是必填段——为执行者提供该 ticket 的决策锚点和当前现状。从 spec、ADR、对话中提取,不确定的标记 `[待确认]`
152
152
  - **范围边界**是必填段——明确本 ticket 的 IN/REUSE/OUT 三列,防止范围蔓延。OUT 列吸收"明确不做"的内容
@@ -172,22 +172,22 @@
172
172
 
173
173
  | 编号 | Ticket | 被阻塞于 | 状态 |
174
174
  |------|--------|----------|------|
175
- | #01 | [ticket-name](./ticket/#01-ticket-name.md) | 无 | 未开始 |
176
- | #02 | [ticket-name](./ticket/#02-ticket-name.md) | #01 | 未开始 |
177
- | #10 | [ticket-name](./ticket/#10-ticket-name.md) | #02, #05 | 未开始 |
175
+ | 01 | [ticket-name](./ticket/01-<kebab-title>.md) | 无 | 未开始 |
176
+ | 02 | [ticket-name](./ticket/02-<kebab-title>.md) | 01 | 未开始 |
177
+ | 10 | [ticket-name](./ticket/10-<kebab-title>.md) | 02, 05 | 未开始 |
178
178
 
179
179
  > 状态枚举:未开始 / 进行中 / 已完成。所有 ticket 发布时初始状态为"未开始",随实现进度手动更新。
180
- > **被阻塞于**列填写阻塞本 ticket 的 ticket 编号(如 `#01`、`#02, #05`),执行者需自行打开对应 ticket 文件查看其状态。不可仅凭此表判断——始终以对应 ticket 文件中的状态字段为准。
180
+ > **被阻塞于**列填写阻塞本 ticket 的 ticket 编号(如 `01`、`02, 05`),执行者需自行打开对应 ticket 文件查看其状态。不可仅凭此表判断——始终以对应 ticket 文件中的状态字段为准。
181
181
 
182
182
  ## 依赖关系
183
183
 
184
184
  <!-- 用 ASCII 树形图展示 ticket 之间的阻塞关系。 -->
185
185
 
186
186
  ```
187
- #01-<name> ← 无阻塞,可立即开始
188
- ├── #02-<name> ← 阻塞于 #01
189
- └── #03-<name> ← 阻塞于 #01
190
- └── #04-<name> ← 阻塞于 #03
187
+ 01-<name> ← 无阻塞,可立即开始
188
+ ├── 02-<name> ← 阻塞于 01
189
+ └── 03-<name> ← 阻塞于 01
190
+ └── 04-<name> ← 阻塞于 03
191
191
  ```
192
192
 
193
193
  ## 横切关注点
@@ -202,7 +202,7 @@
202
202
 
203
203
  <!-- 依赖图的文字说明。简单线性链可省略整个小节。对于扩展-收缩模式,解释三阶段。 -->
204
204
 
205
- <描述为何 ticket #B 被 ticket #A 阻塞。扩展-收缩模式:扩展阶段创建新形式 → 迁移批次逐步切换调用点 → 收缩阶段删除旧形式。>
205
+ <描述为何 ticket B 被 ticket A 阻塞。扩展-收缩模式:扩展阶段创建新形式 → 迁移批次逐步切换调用点 → 收缩阶段删除旧形式。>
206
206
 
207
207
  ## 风险与注意事项
208
208
 
@@ -211,22 +211,22 @@
211
211
 
212
212
  **tickets-map.md 填写说明:**
213
213
 
214
- - **执行清单**的 Ticket 列使用指向 `./ticket/` 目录的相对链接(含 `#` 编号前缀),可在 markdown 渲染器中直接点击跳转
215
- - **编号**列使用 `#01`、`#02`、`#10` 格式(`#` + 零填充序号),代表依赖顺序
216
- - **被阻塞于**列填写阻塞者的编号(如 `#01`、`#02, #05`),执行者需自行查看对应 ticket 文件的状态字段确认是否已就绪
214
+ - **执行清单**的 Ticket 列使用指向 `./ticket/` 目录的相对链接(纯数字编号前缀,如 `./ticket/01-auth.md`),可在 markdown 渲染器中直接点击跳转
215
+ - **编号**列使用 `01`、`02`、`10` 格式(两位零填充阿拉伯数字,不含 `#`),代表依赖顺序
216
+ - **被阻塞于**列填写阻塞者的编号(如 `01`、`02, 05`),执行者需自行查看对应 ticket 文件的状态字段确认是否已就绪
217
217
  - **状态**列由 T-tickets 初始化为"未开始",后续由实现者手动更新——始终以对应 ticket 文件中的状态字段为权威来源
218
218
  - **依赖关系**用 ASCII 树形图直观展示阻塞链;纯线性链用缩进列表即可
219
219
  - **横切关注点**只放跨 ticket 的规则——单 ticket 的规则留在该 ticket 文件内
220
220
  - **阻塞关系说明**在依赖图非平凡时补充文字解释,特别是扩展-收缩排序的三阶段
221
221
 
222
- **完成标准**:`ticket/` 目录已创建,所有 ticket 独立文件已按依赖顺序写入(命名为 `#NN-<ticket-name>.md`);`tickets-map.md` 已写入——包含总体摘要、执行清单(编号、ticket 链接、被阻塞于、状态四列,初始均为"未开始")、依赖关系图和横切关注点;每个 ticket 声明阻塞边(使用相对路径)、战略与背景、范围边界、交付物、保留/不动和验收标准。
222
+ **完成标准**:`ticket/` 目录已创建,所有 ticket 独立文件已按依赖顺序写入(命名为 `NN-<ticket-name>.md`);`tickets-map.md` 已写入——包含总体摘要、执行清单(编号、ticket 链接、被阻塞于、状态四列,初始均为"未开始")、依赖关系图和横切关注点;每个 ticket 声明阻塞边(使用相对路径)、战略与背景、范围边界、交付物、保留/不动和验收标准。
223
223
 
224
224
  ## 子文件引用
225
225
 
226
226
  本入口为单文件 work,所有内容均已内联。以下引用供其他 work 读取产物:
227
227
 
228
228
  - ``tickets-map`` —— 总体地图与执行清单(编号 | Ticket | 被阻塞于 | 状态)
229
- - `specdev/changes/{change}/ticket/` —— 独立 ticket 文件目录,每个文件命名为 `#NN-<ticket-name>.md`(`#NN` = `#01`, `#02`, ..., `#10`, ...)
229
+ - `specdev/changes/{change}/ticket/` —— 独立 ticket 文件目录,每个文件命名为 `NN-<ticket-name>.md`(`NN` = `01`, `02`, ..., `10`, ...)
230
230
  - ``spec`` —— 上游 spec(拆分依据)
231
231
  - `specdev/adr/` —— 永久架构决策目录(已确认并提升的 ADR)
232
232
  - `specdev/context/` —— 永久领域词汇表目录(已确认并提升的 CONTEXT)
@@ -127,7 +127,7 @@ description: >
127
127
 
128
128
  1. **重新验证**:路径包含检查、预检重跑(确认计划生成后无新 change 插入)、store 存在性重验。
129
129
  2. **执行顺序**:
130
- a. **归档移动**(原子批处理):创建月目录 → 移动 change 目录 → 更新 `.status.json` → 更新 `status.json#active`
130
+ a. **归档移动**(原子批处理):创建月目录 → 移动 change 目录 → 更新 `.status.json` → `status.json` 的 `active` 移除对应条目,追加到 `completed` 数组
131
131
  b. **知识合并写入**:创建 lazy stores(如 `adr/`、`context/` 不存在则创建)→ 写入新 ADR → 合并术语到 `context/` → 标记 superseded ADR
132
132
  c. **清理**:删除已批准文件 → 合并已批准内容 → 改写已批准条目
133
133
  3. 任一步骤失败:报告已完成/失败清单,停止,不猜测成功。
@@ -136,7 +136,7 @@ description: >
136
136
 
137
137
  1. 重读源路径:归档 change 必须不存在于 `changes_root/`。
138
138
  2. 重读目标路径:归档 change 完整存在于 `archive_root/<YYYY-MM>/`,知识 store 内容正确。
139
- 3. 重读 `status.json`:`active` 数组不包含已归档 change
139
+ 3. 重读 `status.json`:`active` 数组不包含已归档 change 条目,`completed` 数组已追加对应归档记录。
140
140
  4. 重读归档 `.status.json`:`change_status: archived`、`archived: true`、`archive_path` 一致。
141
141
  5. 对照知识 stores:新内容存在,无不期望的修改。
142
142
  6. 任一不一致 → `blocked`,报告具体差异;全部通过 → `verified`。
@@ -26,7 +26,8 @@
26
26
 
27
27
  归档执行后将对 `status.json` 做如下变更:
28
28
 
29
- - `active` 数组移除:`["2026-07-15-add-auth", "2026-07-10-fix-timezone"]`
29
+ - `active` 数组移除对应 change 条目
30
+ - `completed` 数组追加归档记录(`change`、`path`、`archived_at`、`archive_path`)
30
31
  - 每个归档 change 的 `.status.json` 更新:`change_status: archived`, `archived: true`
31
32
 
32
33
  ## 阻塞项详情
@@ -10,7 +10,7 @@
10
10
  - `.status.json` 可解析,`change_status` 字段存在且值为 `completed`。
11
11
  - 源位于 `changes_root/<change>` 且真实存在。
12
12
  - 目标位于 `archive_root/<YYYY-MM>/<change>`(YYYY-MM 从 change 名称提取),目标目录不存在。
13
- - Workflow `status.json` 与 change 状态一致:change 出现在 `active` 数组中。
13
+ - Workflow `status.json` 与 change 状态一致:change 条目出现在 `active` 数组中(通过 `change` 字段匹配),且 `result` 为 `"completed"`。
14
14
  - 若 worktree 模式:已合并回目标分支并清理;未合并则记录 `blocked`。
15
15
  - **任一预检失败阻塞整批操作**(批量原子性)。
16
16
 
@@ -18,7 +18,7 @@
18
18
 
19
19
  1. 创建 `archive_root/<YYYY-MM>/` 月目录(如不存在)。
20
20
  2. 将 `changes_root/<change>/` 整个目录移动到 `archive_root/<YYYY-MM>/<change>/`。使用原子移动(mv/rename),不用复制后删除。
21
- 3. 从 workflow `status.json#active` 数组中移除该 change 条目。
21
+ 3. 从 workflow `status.json` 的 `active` 数组中移除该 change 条目,追加归档记录到 `completed` 数组(`change`、`path`、`archived_at`、`archive_path`)。
22
22
  4. 更新已移动的 `.status.json`:
23
23
  - `change_status: archived`
24
24
  - `archived: true`
@@ -41,8 +41,8 @@
41
41
 
42
42
  1. 源路径不存在(移动成功)。
43
43
  2. 目标路径完整存在,内容与移动前一致。
44
- 3. Workflow `status.json#active` 已移除该 change
44
+ 3. Workflow `status.json` 的 `active` 数组已移除该 change 条目,`completed` 数组已追加对应归档记录。
45
45
  4. 归档目录 `.status.json` 字段一致(`change_status: archived`、`archived: true`、`archive_path` 正确)。
46
46
  5. 验证失败时报告已完成/未完成清单,不猜测成功。
47
47
 
48
- 完成标准:源不存在、目标完整、active 索引已移除、归档状态字段一致。
48
+ 完成标准:源不存在、目标完整、active 索引已移除且 completed 已追加、归档状态字段一致。
@@ -23,7 +23,7 @@ keywords: [归档, 沉淀, 知识持久化, 清理, ADR, 词汇表, 研究]
23
23
 
24
24
  ### 2. 扫描已完成变更
25
25
 
26
- 遍历 `<Path>{roots.state}/specdev/changes/</Path>`,读取每个变更的 `.status.json`,筛选 `change_status: completed`。收集每个已完成变更的 ADR.md、CONTEXT.md、LOG.md 及 research/ 子目录产物。
26
+ 遍历 `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组,筛选 `result: "completed"` 的 change;同时遍历 `<Path>{roots.state}/specdev/changes/</Path>`,读取每个变更的 `.status.json` 作为补充(`change_status: completed`)。收集每个已完成变更的 ADR.md、CONTEXT.md、LOG.md 及 research/ 子目录产物。
27
27
 
28
28
  **完成标准**:每个已完成变更的元数据和知识产物已收集;无可读产物的变更已标注原因。
29
29
 
@@ -10,7 +10,7 @@
10
10
  2. **状态可解析**:`.status.json` 可解析,`change_status` 字段存在且值为 `completed`。
11
11
  3. **源存在**:源目录 `<Path>{roots.state}/specdev/changes/{change}/</Path>` 真实存在。
12
12
  4. **目标不冲突**:目标目录 `<Path>{roots.state}/specdev/archive/<YYYY-MM>/<change>/</Path>` 不存在(YYYY-MM 从 change 名称提取)。
13
- 5. **状态一致**:workflow `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组中包含该 change(或不包含但 change 自身状态为 completed——此时记录警告但不阻塞)。
13
+ 5. **状态一致**:`<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组中存在该 change 的条目(通过 `change` 字段匹配),且 `result` 为 `"completed"`(或不匹配但 change 自身 `.status.json` 状态为 completed——此时记录警告但不阻塞)。
14
14
  6. **worktree 已合并**:若使用了 worktree 隔离模式,确认已合并回目标分支并清理;未合并则记录 `blocked`。
15
15
 
16
16
  ## 归档移动步骤
@@ -19,7 +19,7 @@
19
19
 
20
20
  1. 创建 `<Path>{roots.state}/specdev/archive/<YYYY-MM>/</Path>` 月目录(如不存在)。
21
21
  2. 将 `<Path>{roots.state}/specdev/changes/{change}/</Path>` 整个目录原子移动到 `<Path>{roots.state}/specdev/archive/<YYYY-MM>/<change>/</Path>`。使用 mv/rename,不用复制后删除。
22
- 3. 从 `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组中移除该 change
22
+ 3. 从 `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组中移除该 change 的条目,追加归档记录到 `completed` 数组(`change`、`path`、`archived_at`、`archive_path`)。
23
23
  4. 更新已移动的 `.status.json`:
24
24
  - `change_status: "archived"`
25
25
  - `archived: true`
@@ -42,7 +42,7 @@
42
42
 
43
43
  1. 源路径不存在(移动成功)。
44
44
  2. 目标路径完整存在,内容与移动前一致。
45
- 3. `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组已移除该 change
45
+ 3. `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组已移除该 change 条目,`completed` 数组已追加归档记录。
46
46
  4. 归档目录 `.status.json` 字段一致(`change_status: archived`、`archived: true`、`archive_path` 正确)。
47
47
  5. 验证失败时报告已完成/未完成清单,不猜测成功。
48
48
 
@@ -17,13 +17,14 @@ keywords: [设计, 访谈, 领域建模, ADR, 决策记录, 词汇表, 设计轨
17
17
 
18
18
  ### 1. 启动变更
19
19
 
20
- 创建 `<Path>{roots.state}/specdev/changes/{change}/</Path>` 目录(`{change}` 为 `<YYYY-MM-DD>-<topic>` 格式),初始化三个空文件模板:
20
+ 创建 `<Path>{roots.state}/specdev/changes/{change}/</Path>` 目录(`{change}` 为 `<YYYY-MM-DD>-<topic>` 格式),初始化三个空文件模板及状态文件:
21
21
 
22
+ - `<Path>{roots.state}/specdev/changes/{change}/.status.json</Path>` — 初始状态(`change_status: "active"`、`created_at` 为当前时间、`completed_at: null`、`archived: false`、`archive_path: null`)
22
23
  - `<Path>{roots.state}/specdev/changes/{change}/ADR.md</Path>` — 架构决策记录,仅含 `# 架构决策记录` 标题
23
24
  - `<Path>{roots.state}/specdev/changes/{change}/LOG.md</Path>` — 设计决策日志,含 `# 设计决策日志` 标题及维护规则说明
24
25
  - `<Path>{roots.state}/specdev/changes/{change}/CONTEXT.md</Path>` — 领域词汇表,含 `# {主题} 领域词汇表` 标题及一两句描述
25
26
 
26
- **完成标准**:变更目录 `<YYYY-MM-DD>-<topic>` 已创建,初始 ADR.md/LOG.md/CONTEXT.md 已就位。
27
+ **完成标准**:变更目录 `<YYYY-MM-DD>-<topic>` 已创建,初始 .status.json、ADR.mdLOG.mdCONTEXT.md 已就位。
27
28
 
28
29
  ### 2. 访谈
29
30
 
@@ -6,7 +6,7 @@ specdev workflow 的变更以 markdown 目录形式存储在 `{roots.state}/spec
6
6
 
7
7
  - 每个变更一个目录:`{roots.state}/specdev/changes/<YYYY-MM-DD>-<topic>/`
8
8
  - 例如:`changes/2026-07-21-add-auth-layer/`
9
- - 当前活跃变更通过 `{roots.state}/specdev/status.json` 的 `active` 数组追踪
9
+ - 当前活跃变更通过 `{roots.state}/specdev/status.json` 的 `active` 数组追踪,每个条目为包含 `change`、`current_work`、`works_run`、`result` 等字段的对象
10
10
  - 归档变更移至:`{roots.state}/specdev/archive/YYYY-MM/<change>/`
11
11
  - 例如:`archive/2026-07/2026-07-21-add-auth-layer/`
12
12
  - 变更目录内的工作产物由各 work 定义,典型结构:
@@ -24,17 +24,24 @@ specdev workflow 的变更以 markdown 目录形式存储在 `{roots.state}/spec
24
24
  - `status.json` 结构:
25
25
  ```jsonc
26
26
  {
27
- "schema_version": 1,
27
+ "schema_version": 2,
28
28
  "workflow": "specdev",
29
29
  "active": [
30
- "2026-07-21-add-auth-layer"
31
- ]
30
+ {
31
+ "change": "2026-07-21-add-auth-layer",
32
+ "current_work": "specdev/grill-with-docs",
33
+ "works_run": [],
34
+ "result": null
35
+ }
36
+ ],
37
+ "work_history": [],
38
+ "completed": []
32
39
  }
33
40
  ```
34
41
 
35
42
  ## 当 work 说"发布到变更目录"时
36
43
 
37
- 在 `{roots.state}/specdev/changes/<change>/` 下创建或更新指定文件。如果变更目录尚未加入 `active` 数组,将其追加到 `status.json` 的 `active` 中。
44
+ 在 `{roots.state}/specdev/changes/<change>/` 下创建或更新指定文件。如果变更目录尚未加入 `active` 数组,将其作为新条目(`{ change, current_work: null, works_run: [], result: null }`)追加到 `status.json` 的 `active` 中。
38
45
 
39
46
  例如:`S-spec` 说"将规格发布到变更目录" → 写入 `<Path>{roots.state}/specdev/changes/<change>/spec.md</Path>`。
40
47
 
@@ -44,7 +51,7 @@ specdev workflow 的变更以 markdown 目录形式存储在 `{roots.state}/spec
44
51
 
45
52
  ## 当 work 说"归档变更"时
46
53
 
47
- 将变更目录从 `{roots.state}/specdev/changes/<change>/` 移动到 `{roots.state}/specdev/archive/YYYY-MM/<change>/`(YYYY-MM 取变更日期中的年月),并从 `status.json` 的 `active` 数组中移除。
54
+ 将变更目录从 `{roots.state}/specdev/changes/<change>/` 移动到 `{roots.state}/specdev/archive/YYYY-MM/<change>/`(YYYY-MM 取变更日期中的年月),从 `status.json` 的 `active` 数组中移除对应条目,追加归档记录到 `completed` 数组。
48
55
 
49
56
  ## Wayfinding 操作
50
57
 
@@ -41,25 +41,46 @@ keywords: [specdev, 软件研发, 设计, spec, tickets, 寻路, TDD, 实现,
41
41
 
42
42
  1. **解析运行时** — 解析 workspace 配置和 workflow/state roots。已解析时复用。
43
43
  2. **选择 change** — 读取 `<Path>{roots.state}/specdev/status.json</Path>`:
44
- - 用户指定 → 直接使用
45
- - 唯一活跃 change → 直接使用
46
- - 无活跃 创建 `changes/<YYYY-MM-DD>-<kebab-topic>/`,注册到 `active` 数组
47
- - 多个候选 → 先消歧
44
+ - 用户指定 → 在 `active` 数组中查找匹配 `change` 字段的条目
45
+ - 唯一活跃 change → 直接使用 `active[0]`
46
+ - 无活跃(`active` 为空数组)→ 创建 `changes/<YYYY-MM-DD>-<kebab-topic>/`,追加条目 `{ change, current_work: null, works_run: [], result: null }` 到 `active`
47
+ - 多个候选 → 列出 `active` 中各 change,由用户消歧
48
48
 
49
49
  ## 状态字段
50
50
 
51
51
  `<Path>{roots.state}/specdev/status.json</Path>` 包含以下字段:
52
52
 
53
- - **`schema_version`**(数字)— 状态 schema 版本号,当前为 1
53
+ - **`schema_version`**(数字)— 状态 schema 版本号,当前为 2
54
54
  - **`workflow`**(字符串)— workflow 标识,固定为 `"specdev"`
55
- - **`active`**(字符串数组)— 当前活跃 change 的目录名列表,每个元素为 `"YYYY-MM-DD-<topic>"` 格式。空数组表示无活跃 change
56
- - **`current_work`**(字符串或 null)— 当前正在执行的 work id,如 `"specdev/grill-with-docs"`。无正在执行的 work 时为 null
55
+ - **`active`**(对象数组)— 当前活跃 change 的状态条目,每个条目包含:
56
+ - `change` change 目录名,格式 `"YYYY-MM-DD-<topic>"`
57
+ - `current_work` — 该 change 当前正在执行的 work id,如 `"specdev/grill-with-docs"`。无正在执行的 work 时为 null
58
+ - `works_run` — 该 change 已执行过的 work id 列表
59
+ - `result` — 该 change 的整体结果:null(进行中)或 `"completed"`(全部 work 已完成)
60
+ - `claimed_tickets` —(可选,W-wayfinder 使用)当前被领取的 ticket 名称列表,用于并发会话跳过
57
61
  - **`work_history`**(对象数组)— work 调用记录,每条包含:
62
+ - `change` — 所属 change 目录名
58
63
  - `work_id` — work 标识
59
64
  - `started_at` — 开始时间(ISO 8601)
60
65
  - `completed_at` — 完成时间(ISO 8601),未完成时为 null
61
66
  - `result` — 完成结果,如 `"completed"`、`"aborted"`
62
- - `artifacts` 产物的项目相对路径列表
67
+ - **`completed`**(对象数组)— 已归档 change 记录,每条包含:
68
+ - `change` — change 目录名
69
+ - `path` — 归档前 change 目录的相对路径
70
+ - `archived_at` — 归档时间(ISO 8601)
71
+ - `archive_path` — 归档目标路径的相对路径
72
+
73
+ ### Per-change 状态文件
74
+
75
+ 每个 change 目录内维护 `<Path>{roots.state}/specdev/changes/{change}/.status.json</Path>`,追踪该 change 的个体状态:
76
+
77
+ - **`change_status`**(字符串)— change 生命周期状态:`"active"`(进行中)、`"completed"`(全部 work 完成)、`"archived"`(已归档)
78
+ - **`created_at`**(ISO 8601 字符串)— change 创建时间
79
+ - **`completed_at`**(ISO 8601 字符串或 null)— change 完成时间,进行中时为 null
80
+ - **`archived`**(布尔值)— 是否已归档,默认 false
81
+ - **`archive_path`**(字符串或 null)— 归档目标路径的相对路径,未归档时为 null
82
+
83
+ 创建 change 时由首个 work(如 `T-triage` 步骤 3 或 `G-grill-with-docs` 步骤 1)写入初始 `.status.json`,`change_status` 初始为 `"active"`。change 内所有 work 完成后,由最后一个 work 更新 `change_status` 为 `"completed"`。归档时由 `A-archive-and-consolidate` 更新为 `"archived"`。
63
84
 
64
85
  ## 路径分配
65
86
 
@@ -77,14 +98,15 @@ keywords: [specdev, 软件研发, 设计, spec, tickets, 寻路, TDD, 实现,
77
98
 
78
99
  <!-- AUTO-INDEX-START -->
79
100
 
80
- - **A-archive-and-consolidate** — 归档与沉淀:将已完成变更归档至 archive/,智能评估变更产物与现有 adr/、context/、research/ 知识库的差异,执行创建/更新/合并/废弃,审计清理陈旧内容,确保知识始终最新。
101
+ - **A-archive-and-consolidate** — 归档与沉淀:将已完成变更归档至 archive/,并智能评估、提取持久化知识到 adr/、context/、research/ 知识库——与现有知识逐项比对,执行创建/更新/合并/废弃,确保知识始终最新。
81
102
  - **D-diagnose-bugs** — 诊断:针对疑难 bug 建立诊断循环——构建紧凑反馈回路、复现最小化、可证伪假设排名、插桩定位根因,确认后移交 I-implement 修复。
82
103
  - **G-grill-with-docs** — 设计访谈(带文档):无情访谈打磨设计,同时持续产出 ADR.md、LOG.md 和 CONTEXT.md 三个领域文档。在设计讨论中捕获术语定义、记录架构决策、保存完整设计轨迹。
83
104
  - **I-implement** — 实现:基于 spec 或 tickets 实现工作——以深层模块设计原则指导架构、以 TDD 红绿循环驱动编码、以双轴审查把关质量。
84
105
  - **I-init-setup** — 初始化设置:为 specdev workflow 配置变更追踪、领域文档布局、状态标签和语言偏好。首次使用其他 specdev works 前运行一次。
85
- - **P-goal-plan** — 目标规划:将 spec、tickets 和参考权威综合为一份目标规划文档——编排多 ticket 里程碑的约束、质量门禁和执行协议,桥接"已有 tickets"到"协调执行 20+ tickets"
106
+ - **P-goal-plan** — 目标规划:将 spec、tickets 和参考权威综合为一份目标规划文档——编排多 ticket 里程碑的约束、质量门禁和执行协议,桥接"已有 tickets"到"协调执行 20+ tickets"
86
107
  - **S-spec** — 编写 Spec:将当前对话综合为一份完整的 spec 文档,包含问题陈述、解决方案、用户故事、实现决策和测试决策,持久化到变更目录。
87
108
  - **T-tickets** — 拆分 Tickets:将 spec 或计划拆分为一组曳光弹式垂直切片 tickets,每个声明阻塞边,持久化到变更目录。支持宽重构的扩展-收缩排序。
109
+ - **T-triage** — Issue 分诊:将外部 issue 摄入并分诊为本地 change:深度理解上下文后写入 source-issue.md 与 triage.md,再推荐下一 work(G-grill / S-spec / I-implement / D-diagnose 等)。
88
110
  - **W-wayfinder** — 寻路:为超出单次会话容量的大块工作绘制共享地图,逐个解决调查 tickets 直到通往目标的路径清晰可见。支持研究和决策型 ticket 类型。
89
111
 
90
112
  <!-- AUTO-INDEX-END -->
@@ -59,7 +59,7 @@ keywords: [目标规划, 编排, 里程碑, 门禁, Lead, Subagent, 合同, 参
59
59
 
60
60
  ### 6. 写入产物与停止
61
61
 
62
- 将完整 goal-plan.md 写入 `<Path>{roots.state}/specdev/changes/{change}/goal-plan.md</Path>`。更新 `<Path>{roots.state}/specdev/status.json</Path>` 记录 work 完成状态与产物路径。
62
+ 将完整 goal-plan.md 写入 `<Path>{roots.state}/specdev/changes/{change}/goal-plan.md</Path>`。更新 `<Path>{roots.state}/specdev/status.json</Path>`:在 `work_history` 中追加条目(含 `change`、`work_id`、`started_at`、`completed_at`、`result`),在 `active` 中更新当前 change 条目的 `works_run` 列表。
63
63
 
64
64
  向用户汇报产物摘要(ticket 数量、门禁层级、合同/参考权威引用、关键约束),明确询问进入实现阶段(`<Path>{roots.workflows}/specdev/I-implement/I-implement.md</Path>`)或需要进一步修订。
65
65
 
@@ -32,15 +32,16 @@ P0 门禁先开,阻塞所有 P1/P2 关闭。ticket 可以在其依赖就绪后
32
32
  - 用注释标注门禁边界:`--- P0 gate ---`
33
33
  - 可立即开始的 ticket 标注 `[READY]`
34
34
  - 扇出点标注 `[FAN-OUT: N路并行]`
35
+ - ticket 编号使用两位零填充纯数字(`01`, `02`, …),**不含** `#`
35
36
 
36
37
  示例格式:
37
38
  ```
38
- #4 [READY] → #5 [FAN-OUT: 3路并行]
39
- ├→ #6 [P0]
40
- ├→ #7 [P1]
41
- └→ #8 [P1]
39
+ 04 [READY] → 05 [FAN-OUT: 3路并行]
40
+ ├→ 06 [P0]
41
+ ├→ 07 [P1]
42
+ └→ 08 [P1]
42
43
  --- P0 gate ---
43
- #6#9 [P1] → #10 [P2]
44
+ 0609 [P1] → 10 [P2]
44
45
  ```
45
46
 
46
47
  将丰富后的 DAG 回写到 tickets-map.md 的「依赖关系」节,替换 T-tickets 写入的基础版本。
@@ -55,15 +56,27 @@ tickets-map.md 的「并行规则」节已由模板预设默认值(最大 3
55
56
 
56
57
  ## §5 — Per-Ticket Execution Protocol
57
58
 
59
+ 本协议是对 I-implement 的实例化执行;实现者必须同时遵循 I-implement 四步协议(设计检查→TDD→双轴审查→提交)。权威入口:`<Path>{roots.workflows}/specdev/I-implement/I-implement.md</Path>`。
60
+
58
61
  ### 协议定制
59
62
 
60
63
  根据 input-validation.md 检测到的执行模型选择协议骨架:
61
64
 
62
65
  #### Lead+Subagent 模型(完整八步)
63
66
 
64
- 1. **读取** —— Lead 读取 issue 全文、合同/参考权威对应行、ticket 的验收标准。如果激活参考权威模式,对照参考快照中的对应交互路径。
65
- 2. **派单** —— Lead 输出结构化派单行 `IMPLEMENTER_DISPATCH #<n> issue=<url> gate=<P0|P1|P2> allowlist=<files> contract_ids=<...>`,然后生成实现子代理(model: fable, 唯一 name)。Lead+Subagent 模型下,加载 `<Path>{roots.workflows}/specdev/P-goal-plan/lead-orchestration-protocol.md</Path>` 获取完整的编排协议——包括子代理上下文载荷结构、handoff 交接、合并冲突解决、Worktree 隔离和收尾审查的详细步骤。
66
- 3. **实现** —— 子代理在 file allowlist 内实现变更,按 ticket 指定的测试矩阵运行测试。
67
+ 1. **读取** —— 实现者(Lead 与子代理)在开始前**必须按顺序读取以下文件**建立完整上下文:
68
+
69
+ | # | 文件 | 用途 |
70
+ |---|------|------|
71
+ | 1 | `<Path>{roots.workflows}/specdev/I-implement/I-implement.md</Path>` | specdev 实现流程入口——设计检查、TDD 循环、双轴审查、提交 |
72
+ | 2 | 本 ticket 全文 | 验收标准、范围边界、交付物、保留/不动 |
73
+ | 3 | 合同/参考权威对应行(如激活) | 编号验收条目或对照路径 |
74
+ | 4 | 项目 skills(如有) | 前后端编排、构建规范、路由/菜单、数据库标准等项目级约定——按实际检出的 skill 路径追加,可变 |
75
+
76
+ Lead 读取 issue 全文、合同/参考权威对应行、ticket 的验收标准。如果激活参考权威模式,对照参考快照中的对应交互路径。
77
+
78
+ 2. **派单** —— Lead 输出结构化派单行 `IMPLEMENTER_DISPATCH <n> issue=<url> gate=<P0|P1|P2> allowlist=<files> contract_ids=<...>`(`<n>` 为两位零填充纯数字编号,如 `01`,不含 `#`),然后生成实现子代理(model: fable, 唯一 name)。Lead+Subagent 模型下,加载 `<Path>{roots.workflows}/specdev/P-goal-plan/lead-orchestration-protocol.md</Path>` 获取完整的编排协议——包括子代理上下文载荷结构、handoff 交接、合并冲突解决、Worktree 隔离和收尾审查的详细步骤。
79
+ 3. **实现** —— 子代理在 file allowlist 内实现变更,按 ticket 指定的测试矩阵运行测试;实现过程遵循 I-implement 的设计检查与 TDD 红绿循环。
67
80
  4. **双轴审查** —— 实现完成后,立即启动两个审查子代理并行运行:
68
81
  - `reviewer-standards-<n>`:代码质量、架构、测试覆盖
69
82
  - `reviewer-spec-<n>`:spec 合规、验收标准
@@ -75,9 +88,17 @@ tickets-map.md 的「并行规则」节已由模板预设默认值(最大 3
75
88
 
76
89
  #### 简化模型(精简协议)
77
90
 
78
- 1. **读取** 读 ticket、spec 对应 User Story、验收标准。
79
- 2. **实现** — 在 ticket 声明的范围内实现变更。
80
- 3. **审查** 单审查者检查代码质量和 spec 合规。
91
+ 1. **读取** —— 实现者在开始前**必须按顺序读取以下文件**建立完整上下文:
92
+
93
+ | # | 文件 | 用途 |
94
+ |---|------|------|
95
+ | 1 | `<Path>{roots.workflows}/specdev/I-implement/I-implement.md</Path>` | specdev 实现流程入口——设计检查、TDD 循环、双轴审查、提交 |
96
+ | 2 | 本 ticket 文件 | 验收标准、范围边界、交付物 |
97
+ | 3 | spec 对应 User Story / 验收标准 | 行为与验收锚点 |
98
+ | 4 | 项目 skills(如有) | 项目级约定——按实际检出路径追加,可变 |
99
+
100
+ 2. **实现** — 在 ticket 声明的范围内实现变更;遵循 I-implement 的设计检查与 TDD 红绿循环。
101
+ 3. **审查** — 单审查者检查代码质量和 spec 合规(对齐 I-implement 双轴审查意图)。
81
102
  4. **门禁** — 类型检查、测试通过。
82
103
  5. **关闭** — 提交并关闭 issue。
83
104
 
@@ -87,12 +108,14 @@ tickets-map.md 的「并行规则」节已由模板预设默认值(最大 3
87
108
  - 测试矩阵从 tickets 或 spec 的 Test Decisions 提取
88
109
  - 双轴审查的派单模板写为可复制的文本块
89
110
  - Lead 纪律写为不可协商的约束
111
+ - **§5 步骤 1 表格必须以 I-implement 为第一行**;项目 skills 仅作为后续可变项追加,不得因 skills 列表变化而挤掉或省略 I-implement
112
+ - ticket 编号、派单行、进度行一律使用纯数字(`01`),不使用 `#01`
90
113
 
91
114
  ### 草拟与确认
92
115
 
93
116
  输出 §5 完整协议文本。等待用户确认后进入治理章节。
94
117
 
95
- **完成标准**:§4 DAG 图无循环、门禁标注正确、对照表完整且经用户确认;§5 执行协议八步/精简流程已定制填入具体路径、测试矩阵和双轴审查模板,经用户确认。
118
+ **完成标准**:§4 DAG 图无循环、门禁标注正确、对照表完整且经用户确认;§5 执行协议八步/精简流程已定制填入具体路径、测试矩阵和双轴审查模板,步骤 1 清单以 I-implement 为首项,经用户确认。
96
119
 
97
120
  ## 子文件引用
98
121
 
@@ -70,11 +70,11 @@
70
70
  #### TICKET_DONE 格式(Lead+Subagent 模型)
71
71
 
72
72
  ```
73
- TICKET_DONE #<n> (<k>/<N>) gate=<P0|P1|P2> contract_ids=<P0-01,P1-03> verify=<cmd:result> commit=<sha>
73
+ TICKET_DONE <n> (<k>/<N>) gate=<P0|P1|P2> contract_ids=<P0-01,P1-03> verify=<cmd:result> commit=<sha>
74
74
  ```
75
75
 
76
76
  字段说明:
77
- - `#<n>` —— ticket 编号
77
+ - `<n>` —— ticket 编号(两位零填充纯数字,如 `01`,不含 `#`)
78
78
  - `(<k>/<N>)` —— 进度计数(当前第几个 / 总数)
79
79
  - `gate` —— 门禁层级
80
80
  - `contract_ids` —— 如激活合同模式,列出本 ticket 覆盖的合同条目 ID,逗号分隔;如无合同则使用 `adr_ref=<ADR-NNNN>`
@@ -94,7 +94,7 @@ MILESTONE_DONE issues_closed=<N>/<N> contract_todo=0 verify=GREEN
94
94
  #### 格式变体
95
95
 
96
96
  - **切面跟踪**(ticket 数 > 15 时推荐):在 TICKET_DONE 中增加 `slice=<ADR|DATA|SHELL|WORK|...>` 字段,按切面分组追踪进度
97
- - **简化模型**:使用简化格式 `TICKET_DONE #<n> verify=<cmd:result>`
97
+ - **简化模型**:使用简化格式 `TICKET_DONE <n> verify=<cmd:result>`
98
98
 
99
99
  ### 草拟与确认
100
100
 
@@ -17,14 +17,14 @@
17
17
  | 目标规划文档 | `<Path>{roots.state}/specdev/changes/{change}/goal-plan.md</Path>` | 里程碑级约束、门禁次序、Definition of Done——子代理理解全局上下文和自身 ticket 在整体中的位置 |
18
18
  | ticket 文件 | `<Path>{roots.state}/specdev/changes/{change}/</Path>` 下对应 ticket | 验收标准、file allowlist、合同引用、阻塞关系——子代理的直接任务定义,包含「要构建什么」「范围边界」「保留/不动」 |
19
19
  | 合同验收条目 | 合同文档中本 ticket 覆盖的条目(如激活合同模式) | 编号验收条目及当前状态——子代理必须逐个满足的可检查条件 |
20
- | 实现方法参考 | `<Path>{roots.workflows}/specdev/I-implement/I-implement.md</Path>` | 深层模块设计原则、TDD 红绿循环、双轴审查流程——子代理的实现方法论,确保所有子代理采用一致的工程质量标准 |
20
+ | 实现方法参考 | `<Path>{roots.workflows}/specdev/I-implement/I-implement.md</Path>` | 深层模块设计原则、TDD 红绿循环、双轴审查流程——子代理的实现方法论;子代理开始实现前**必须先读**,与 goal-plan §5 步骤 1 第一项一致 |
21
21
 
22
22
  ### 1.2 派单模板
23
23
 
24
24
  Lead 向子代理发送的内容应包含以下结构化信息块,而非仅一行元数据:
25
25
 
26
26
  ```
27
- IMPLEMENTER_DISPATCH #<n>
27
+ IMPLEMENTER_DISPATCH <n>
28
28
  issue: <url>
29
29
  gate: <P0|P1|P2>
30
30
  allowlist: <files>
@@ -36,10 +36,12 @@ IMPLEMENTER_DISPATCH #<n>
36
36
  context: <{roots.state}/specdev/changes/{change}/CONTEXT.md>
37
37
  permanent_context: <{roots.state}/specdev/context/>
38
38
  goal_plan: <{roots.state}/specdev/changes/{change}/goal-plan.md>
39
- ticket_file: <{roots.state}/specdev/changes/{change}/<ticket-file>>
39
+ ticket_file: <{roots.state}/specdev/changes/{change}/ticket/<nn>-<slug>.md>
40
40
  implement_ref: <{roots.workflows}/specdev/I-implement/I-implement.md>
41
41
  ```
42
42
 
43
+ 其中 `<n>` / `<nn>` 为两位零填充纯数字 ticket 编号(如 `01`),不含 `#`。
44
+
43
45
  Lead 在生成子代理时将以上文件作为上下文传入,确保子代理在开始实现前已读取全部载荷。永久 ADR 和永久 CONTEXT 目录可能为空——静默继续。
44
46
 
45
47
  **完成标准**:每个子代理在启动时收到完整的上下文载荷(ADR、CONTEXT、goal-plan、ticket 文件、合同条目、I-implement 参考),所有路径指向真实存在的文件;IMPLEMENTER_DISPATCH 行和附加上下文已一并传递给子代理。
@@ -80,7 +80,7 @@ keywords: [tickets, 拆分, 任务, 垂直切片, 阻塞, 曳光弹]
80
80
 
81
81
  迭代直到用户批准拆分方案。每次修改后重新展示完整列表。
82
82
 
83
- **完成标准**:用户已确认粒度、阻塞边与合并/拆分方案。批准后,tickets 将写入 `ticket/` 目录(一个 ticket 一个独立文件,命名为 `#NN-<name>.md`),并生成 `tickets-map.md` 作为总体地图和执行清单。
83
+ **完成标准**:用户已确认粒度、阻塞边与合并/拆分方案。批准后,tickets 将写入 `ticket/` 目录(一个 ticket 一个独立文件,命名为 `NN-<name>.md`),并生成 `tickets-map.md` 作为总体地图和执行清单。
84
84
 
85
85
  ### 5. 发布
86
86
 
@@ -92,14 +92,14 @@ keywords: [tickets, 拆分, 任务, 垂直切片, 阻塞, 曳光弹]
92
92
 
93
93
  **5b. 写入单个 ticket 文件**
94
94
 
95
- 按依赖顺序(无阻塞者在前,被阻塞者在后),为每个 ticket 创建独立文件 `<Path>{roots.state}/specdev/changes/{change}/ticket/#NN-<ticket-name>.md</Path>`。`#NN` 为 ticket 编号(`#01`, `#02`, ..., `#10`, ...),代表执行顺序。
95
+ 按依赖顺序(无阻塞者在前,被阻塞者在后),为每个 ticket 创建独立文件 `<Path>{roots.state}/specdev/changes/{change}/ticket/NN-<ticket-name>.md</Path>`。`NN` 为 ticket 编号(两位零填充阿拉伯数字:`01`, `02`, ..., `10`, ...),代表执行顺序。文件名与编号均不含 `#` 字符,避免 Markdown 链接被编码为 `%23`。
96
96
 
97
97
  每个 ticket 文件按以下模板填写:
98
98
 
99
99
  ```markdown
100
- # Ticket #NN: <标题>
100
+ # Ticket NN: <标题>
101
101
 
102
- - **被阻塞于:** `./ticket/#NN-<name>.md`, `./ticket/#NN-<name>.md`(相对路径,或多个用逗号分隔。无阻塞则写"无 —— 可立即开始"。查看被引用 ticket 文件中的状态字段自行判断是否已就绪)
102
+ - **被阻塞于:** `./ticket/NN-<name>.md`, `./ticket/NN-<name>.md`(相对路径,或多个用逗号分隔。无阻塞则写"无 —— 可立即开始"。查看被引用 ticket 文件中的状态字段自行判断是否已就绪)
103
103
  - **状态:** 未开始
104
104
 
105
105
  <!-- 如需了解整体上下文、所有 ticket 的依赖关系全景或横切关注点,请查看 `../tickets-map.md`。 -->
@@ -157,7 +157,7 @@ keywords: [tickets, 拆分, 任务, 垂直切片, 阻塞, 曳光弹]
157
157
 
158
158
  **模板填写说明:**
159
159
 
160
- - **被阻塞于**使用指向 `./ticket/` 目录的相对路径(如 `./ticket/#01-auth.md`),多个用逗号分隔。执行者应自行打开被引用的 ticket 文件查看其状态字段,判断阻塞是否已解除
160
+ - **被阻塞于**使用指向 `./ticket/` 目录的相对路径(如 `./ticket/01-auth.md`),多个用逗号分隔。执行者应自行打开被引用的 ticket 文件查看其状态字段,判断阻塞是否已解除
161
161
  - **状态**初始固定为"未开始";实现者开始工作时改为"进行中",完成后改为"已完成"
162
162
  - **战略与背景**是必填段——为执行者提供该 ticket 的决策锚点和当前现状。从 spec、ADR、对话中提取,不确定的标记 `[待确认]`
163
163
  - **范围边界**是必填段——明确本 ticket 的 IN/REUSE/OUT 三列,防止范围蔓延。OUT 列吸收"明确不做"的内容
@@ -178,16 +178,16 @@ T-tickets 阶段填写的列:**编号**、**Ticket**、**被阻塞于**、**
178
178
 
179
179
  **tickets-map.md 填写说明:**
180
180
 
181
- - **执行清单**的 Ticket 列使用指向 `./ticket/` 目录的相对链接(含 `#` 编号前缀)
182
- - **编号**列使用 `#01`、`#02`、`#10` 格式(`#` + 零填充序号),代表依赖顺序
183
- - **被阻塞于**列填写阻塞者的编号(如 `#01`、`#02, #05`)
181
+ - **执行清单**的 Ticket 列使用指向 `./ticket/` 目录的相对链接(纯数字编号前缀,如 `./ticket/01-auth.md`)
182
+ - **编号**列使用 `01`、`02`、`10` 格式(两位零填充阿拉伯数字,不含 `#`),代表依赖顺序
183
+ - **被阻塞于**列填写阻塞者的编号(如 `01`、`02, 05`)
184
184
  - **状态**列由 T-tickets 初始化为"未开始",后续由实现者手动更新——始终以对应 ticket 文件中的状态字段为权威来源
185
185
  - **Gate** 列(P0/P1/P2)和 **Contract ID** 列由 P-goal-plan 填充;T-tickets 阶段留空或标 `[待标注]`
186
186
  - **依赖关系**用 ASCII 树形图展示阻塞链——T-tickets 写入基础结构,P-goal-plan 叠加门禁标注
187
187
  - **横切关注点**只放跨 ticket 的规则——单 ticket 的规则留在该 ticket 文件内
188
188
  - **阻塞关系说明**在依赖图非平凡时补充文字解释
189
189
 
190
- **完成标准**:`ticket/` 目录已创建,所有 ticket 独立文件已按依赖顺序写入(命名为 `#NN-<ticket-name>.md`);`tickets-map.md` 已按 `<Path>{roots.workflows}/specdev/T-tickets/tickets-map-template.md</Path>` 格式写入——包含总体摘要、六列执行清单(Gate 和 Contract ID 列为 `[待标注]`)、基础依赖关系 ASCII 树形图、并行规则和横切关注点;每个 ticket 声明阻塞边、战略与背景、范围边界、交付物、保留/不动和验收标准。
190
+ **完成标准**:`ticket/` 目录已创建,所有 ticket 独立文件已按依赖顺序写入(命名为 `NN-<ticket-name>.md`);`tickets-map.md` 已按 `<Path>{roots.workflows}/specdev/T-tickets/tickets-map-template.md</Path>` 格式写入——包含总体摘要、六列执行清单(Gate 和 Contract ID 列为 `[待标注]`)、基础依赖关系 ASCII 树形图、并行规则和横切关注点;每个 ticket 声明阻塞边、战略与背景、范围边界、交付物、保留/不动和验收标准。
191
191
 
192
192
  ## 子文件引用
193
193
 
@@ -198,7 +198,7 @@ T-tickets 阶段填写的列:**编号**、**Ticket**、**被阻塞于**、**
198
198
  本入口为单文件 work,所有 ticket 拆分流程内容均已内联。以下引用供其他 work 读取产物:
199
199
 
200
200
  - `<Path>{roots.state}/specdev/changes/{change}/tickets-map.md</Path>` —— 总体地图与执行清单(编号 | Ticket | 被阻塞于 | Gate | Contract ID | 状态),格式遵循 `<Path>{roots.workflows}/specdev/T-tickets/tickets-map-template.md</Path>`
201
- - `<Path>{roots.state}/specdev/changes/{change}/ticket/</Path>` —— 独立 ticket 文件目录,每个文件命名为 `#NN-<ticket-name>.md`(`#NN` = `#01`, `#02`, ..., `#10`, ...)
201
+ - `<Path>{roots.state}/specdev/changes/{change}/ticket/</Path>` —— 独立 ticket 文件目录,每个文件命名为 `NN-<ticket-name>.md`(`NN` = `01`, `02`, ..., `10`, ...)
202
202
  - `<Path>{roots.state}/specdev/changes/{change}/spec.md</Path>` —— 上游 spec(拆分依据)
203
203
  - `<Path>{roots.state}/specdev/adr/</Path>` —— 永久架构决策目录(已确认并提升的 ADR)
204
204
  - `<Path>{roots.state}/specdev/context/</Path>` —— 永久领域词汇表目录(已确认并提升的 CONTEXT)
@@ -6,12 +6,12 @@
6
6
 
7
7
  | 编号 | Ticket | 被阻塞于 | Gate | Contract ID | 状态 |
8
8
  |------|--------|----------|------|-------------|------|
9
- | #01 | [ticket-name](./ticket/#01-ticket-name.md) | 无 | P0 | — | 未开始 |
10
- | #02 | [ticket-name](./ticket/#02-ticket-name.md) | #01 | P1 | P1-03 | 未开始 |
11
- | #10 | [ticket-name](./ticket/#10-ticket-name.md) | #02, #05 | P2 | — | 未开始 |
9
+ | 01 | [ticket-name](./ticket/01-<kebab-title>.md) | 无 | P0 | — | 未开始 |
10
+ | 02 | [ticket-name](./ticket/02-<kebab-title>.md) | 01 | P1 | P1-03 | 未开始 |
11
+ | 10 | [ticket-name](./ticket/10-<kebab-title>.md) | 02, 05 | P2 | — | 未开始 |
12
12
 
13
13
  > **状态枚举**:未开始 / 进行中 / 已完成。所有 ticket 初始均为"未开始"。
14
- > **被阻塞于**列填写阻塞本 ticket 的 ticket 编号(如 `#01`、`#02, #05`),执行者需自行打开对应 ticket 文件查看其状态。不可仅凭此表判断——始终以对应 ticket 文件中的状态字段为准。
14
+ > **被阻塞于**列填写阻塞本 ticket 的 ticket 编号(如 `01`、`02, 05`),执行者需自行打开对应 ticket 文件查看其状态。不可仅凭此表判断——始终以对应 ticket 文件中的状态字段为准。
15
15
  > **Gate 列**:P0 = 核心基础设施(阻塞所有后续工作)/ P1 = 主要功能切片 / P2 = 增强和边界情况。由 P-goal-plan 填充,T-tickets 阶段留空或标注 `[待标注]`。
16
16
  > **Contract ID 列**:如有冻结合同/验收文档,填写本 ticket 覆盖的验收条目 ID(如 `P0-01, P1-03`);无合同则填 `—`。由 P-goal-plan 填充。
17
17
 
@@ -29,19 +29,19 @@
29
29
  - 扇出点标注 [FAN-OUT: N路并行]
30
30
 
31
31
  示例格式:
32
- #01 [READY] → #02 [FAN-OUT: 3路并行]
33
- ├→ #03 [P0]
34
- ├→ #04 [P1]
35
- └→ #05 [P1]
32
+ 01 [READY] → 02 [FAN-OUT: 3路并行]
33
+ ├→ 03 [P0]
34
+ ├→ 04 [P1]
35
+ └→ 05 [P1]
36
36
  --- P0 gate ---
37
- #03 → #06 [P1] → #07 [P2]
37
+ 03 → 06 [P1] → 07 [P2]
38
38
  -->
39
39
 
40
40
  ```
41
- #01-<name> ← 无阻塞,可立即开始
42
- ├── #02-<name> ← 阻塞于 #01
43
- └── #03-<name> ← 阻塞于 #01
44
- └── #04-<name> ← 阻塞于 #03
41
+ 01-<name> ← 无阻塞,可立即开始
42
+ ├── 02-<name> ← 阻塞于 01
43
+ └── 03-<name> ← 阻塞于 01
44
+ └── 04-<name> ← 阻塞于 03
45
45
  ```
46
46
 
47
47
  ## 并行规则
@@ -63,7 +63,7 @@
63
63
 
64
64
  <!-- 依赖图的文字说明。简单线性链可省略整个小节。对于扩展-收缩模式,解释三阶段。 -->
65
65
 
66
- <描述为何 ticket #B 被 ticket #A 阻塞。扩展-收缩模式:扩展阶段创建新形式 → 迁移批次逐步切换调用点 → 收缩阶段删除旧形式。>
66
+ <描述为何 ticket B 被 ticket A 阻塞。扩展-收缩模式:扩展阶段创建新形式 → 迁移批次逐步切换调用点 → 收缩阶段删除旧形式。>
67
67
 
68
68
  ## 风险与注意事项
69
69
 
@@ -0,0 +1,76 @@
1
+ ---
2
+ id: specdev/triage
3
+ type: workflow-entry
4
+ workflow: specdev
5
+ name: Issue 分诊
6
+ description: 将外部 issue 摄入并分诊为本地 change:深度理解上下文后写入 source-issue.md 与 triage.md,再推荐下一 work(G-grill / S-spec / I-implement / D-diagnose 等)。
7
+ keywords: [分诊, triage, issue, 摄入, 变更引导, needs-triage]
8
+ ---
9
+
10
+ # Issue 分诊
11
+
12
+ 将外部 issue **分诊**为本地 change 引导:摄入 → 深度理解 → 写入 `source-issue.md` 与 `triage.md` → 推荐下一 work 后停止。本 work 只落本地产物;ADR / LOG / CONTEXT / spec / ticket 与 tracker 写回由其他 work 或 `common/triage` skill 负责。
13
+
14
+ 产物路径:`<Path>{roots.state}/specdev/changes/{change}/</Path>`(`{change}` = `<YYYY-MM-DD>-<topic>`)。
15
+
16
+ ## 流程
17
+
18
+ ### 1. 摄入 Issue
19
+
20
+ 加载 `<Path>{roots.workflows}/specdev/T-triage/intake-rules.md</Path>`。将 `#N`、URL、粘贴正文或口头描述规范化为统一结构(source、title、body、comments、来源标识)。`gh` 可用则拉取;否则请用户粘贴或补齐最小字段。
21
+
22
+ **完成标准**:标题、正文、评论与来源标识齐全,或已标注 paste/manual 且最小字段已齐。
23
+
24
+ ### 2. 深度理解
25
+
26
+ 加载 `<Path>{roots.workflows}/specdev/T-triage/understanding-rules.md</Path>`。行为契约对齐 `<Path>{roots.workflows}/specdev/common/triage/AGENT-BRIEF.md</Path>`;范围外只读去重遵循 `<Path>{roots.workflows}/specdev/common/triage/OUT-OF-SCOPE.md</Path>`。
27
+
28
+ 读取永久 `<Path>{roots.state}/specdev/adr/</Path>`、`<Path>{roots.state}/specdev/context/</Path>`(若有);按领域概念探查代码库;扫描 `.out-of-scope/`;对 bug 做轻量可复现判定;归类 `bug` | `enhancement` 并列出具体信息缺口。
29
+
30
+ **完成标准**:类别已判定;冗余与范围外结果已报告;验证结果或缺口已明确;足以起草行为摘要或已穷尽缺失问题。
31
+
32
+ ### 3. 选择 / 创建 Change
33
+
34
+ 读 `<Path>{roots.state}/specdev/status.json</Path>`(INDEX 启动协议):新 issue 默认创建 `changes/<YYYY-MM-DD>-<kebab-topic>/`;仅用户声明续作时复用 active;多候选先消歧。在 `active` 数组中追加条目 `{ change, current_work: "specdev/triage", works_run: [], result: null }`;`work_history` 追加进行中记录(含 `change` 字段,缺字段时按 INDEX 补齐)。创建 change 目录后写入初始 `<Path>{roots.state}/specdev/changes/{change}/.status.json</Path>`(`change_status: "active"`、`created_at` 为当前时间)。
35
+
36
+ **完成标准**:`{change}` 目录存在;`active` 含该 change;`current_work` 为 `"specdev/triage"`。
37
+
38
+ ### 4. 写入分诊产物
39
+
40
+ 加载 `<Path>{roots.workflows}/specdev/T-triage/artifact-templates.md</Path>`,仅写入:
41
+
42
+ 1. `<Path>{roots.state}/specdev/changes/{change}/source-issue.md</Path>` — 原文快照
43
+ 2. `<Path>{roots.state}/specdev/changes/{change}/triage.md</Path>` — 分诊结论、行为契约草案、推荐 status 与 next work
44
+
45
+ 推荐 status 只记在 `triage.md`。标签字符串可读 `<Path>{roots.state}/specdev/.config/status-labels.md</Path>`(若有),否则用角色名。
46
+
47
+ **完成标准**:两文件已落盘;含类别、推荐 status、行为契约草案与 next work;无残留 `[TODO:]`(`needs-info` 的信息缺口列表除外)。
48
+
49
+ ### 5. 路由推荐
50
+
51
+ 加载 `<Path>{roots.workflows}/specdev/T-triage/routing-rules.md</Path>`。首匹配恰好一条主推荐(可附一条备选),写入 `triage.md` 并展示 Path 与理由。
52
+
53
+ **完成标准**:主推荐已展示;下游尚未启动。
54
+
55
+ ### 6. 停止并交接
56
+
57
+ 更新 `<Path>{roots.state}/specdev/status.json</Path>`:`active` 中对应条目的 `current_work = null`;`work_history` 对应条目补 `completed_at`、`result`(无 `artifacts` 字段)。汇报 change、类别、status、next work、产物路径;明确询问是否进入推荐 work。用户确认前保持代码与下游不动。
58
+
59
+ **完成标准**:status 已更新;用户已收到摘要与确认问题;本 work 结束。
60
+
61
+ ## 子文件引用
62
+
63
+ | 文件 | 内容 | 触发条件 |
64
+ |------|------|----------|
65
+ | `<Path>{roots.workflows}/specdev/T-triage/intake-rules.md</Path>` | gh / 粘贴摄入、字段规范化 | 步骤 1 |
66
+ | `<Path>{roots.workflows}/specdev/T-triage/understanding-rules.md</Path>` | 理解清单、冗余与范围外 | 步骤 2 |
67
+ | `<Path>{roots.workflows}/specdev/T-triage/artifact-templates.md</Path>` | 两产物模板 | 步骤 4 |
68
+ | `<Path>{roots.workflows}/specdev/T-triage/routing-rules.md</Path>` | 首匹配路由与话术 | 步骤 5 |
69
+ | `<Path>{roots.workflows}/specdev/common/triage/AGENT-BRIEF.md</Path>` | 行为契约原则 | 步骤 2/4 起草摘要 |
70
+ | `<Path>{roots.workflows}/specdev/common/triage/OUT-OF-SCOPE.md</Path>` | 范围外只读去重 | 步骤 2 扫描时 |
71
+
72
+ ## 依赖关系
73
+
74
+ - **上游**:外部 issue(`gh` 或用户);可选永久 adr/context;可选 `.out-of-scope/`
75
+ - **下游**(确认后):`<Path>{roots.workflows}/specdev/G-grill-with-docs/G-grill-with-docs.md</Path>`、`<Path>{roots.workflows}/specdev/S-spec/S-spec.md</Path>`、`<Path>{roots.workflows}/specdev/I-implement/I-implement.md</Path>`、`<Path>{roots.workflows}/specdev/D-diagnose-bugs/D-diagnose-bugs.md</Path>`、`<Path>{roots.workflows}/specdev/W-wayfinder/W-wayfinder.md</Path>`
76
+ - **并列**:`<Path>{roots.workflows}/specdev/common/triage/SKILL.md</Path>` 仍可独立做 tracker 状态机;本 work 只引用其 AGENT-BRIEF / OUT-OF-SCOPE
@@ -0,0 +1,122 @@
1
+ # 分诊产物模板
2
+
3
+ 本 work 在 change 目录**仅**写入以下两个文件。路径:
4
+
5
+ - `<Path>{roots.state}/specdev/changes/{change}/source-issue.md</Path>`
6
+ - `<Path>{roots.state}/specdev/changes/{change}/triage.md</Path>`
7
+
8
+ 行为契约章节对齐 `<Path>{roots.workflows}/specdev/common/triage/AGENT-BRIEF.md</Path>`,但落在本地文件,而非 tracker 评论。
9
+
10
+ 推荐 status 角色字符串:若存在 `<Path>{roots.state}/specdev/.config/status-labels.md</Path>`,使用其「标签」列;否则使用角色名本身(`needs-triage` / `needs-info` / `ready-for-agent` / `ready-for-human` / `wontfix`)。
11
+
12
+ ---
13
+
14
+ ## source-issue.md
15
+
16
+ ```markdown
17
+ # Source Issue
18
+
19
+ - **Source:** gh | paste | manual
20
+ - **Kind:** issue | pr | manual
21
+ - **ID:** #N 或 n/a
22
+ - **URL:** <url 或空>
23
+ - **Fetched at:** <ISO-8601>
24
+ - **Author:** <作者>
25
+ - **Labels:** <逗号分隔,或无>
26
+ - **State:** <open/closed 或空>
27
+
28
+ ## Title
29
+
30
+ <标题>
31
+
32
+ ## Body
33
+
34
+ <正文原文>
35
+
36
+ ## Comments
37
+
38
+ ### @<author> (<date>)
39
+
40
+ <body>
41
+
42
+ <!-- 无评论时写:_无评论_ -->
43
+ ```
44
+
45
+ 填写规则:
46
+
47
+ - 保留摄入时快照;远端后续编辑不自动同步
48
+ - 评论按时间顺序;过长可摘要并注明「已截断,完整内容见远端 #N」
49
+ - `manual` 来源:Body 由问题描述 + 期望行为组成,并在顶部注明「非远端快照」
50
+
51
+ ---
52
+
53
+ ## triage.md
54
+
55
+ ```markdown
56
+ # Triage: <一句话主题>
57
+
58
+ - **Change:** <YYYY-MM-DD-kebab-topic>
59
+ - **Category:** bug | enhancement
60
+ - **Recommended status:** needs-triage | needs-info | ready-for-agent | ready-for-human | wontfix
61
+ - **Recommended next work:** <显示名> | none
62
+ - **Source:** [./source-issue.md](./source-issue.md)
63
+ - **Verification:** confirmed | not-reproduced | needs-info | n/a
64
+
65
+ ## 问题摘要
66
+
67
+ <用户可理解的一两句>
68
+
69
+ ## 理解结论
70
+
71
+ - **代码库现状:** <相关模块/接口与现状行为>
72
+ - **验证结果:** <同上 Verification,可附命令/证据>
73
+ - **冗余 / 范围外:** none | 已实现于… | 匹配 `.out-of-scope/<concept>.md`(用户选择:确认/重新考虑/不相关)
74
+
75
+ ## 行为契约草案
76
+
77
+ **Current behavior:**
78
+ <当前发生什么>
79
+
80
+ **Desired behavior:**
81
+ <完成后应发生什么;含边界与错误条件>
82
+
83
+ **Key interfaces:**
84
+ - `<TypeOrFn>` — 需要改变什么以及为什么
85
+ - …
86
+
87
+ **Acceptance criteria:**
88
+ - [ ] <可独立验证的标准 1>
89
+ - [ ] <可独立验证的标准 2>
90
+
91
+ **Out of scope:**
92
+ - <本 change 明确不做的事项>
93
+
94
+ ## 信息缺口
95
+
96
+ <!-- needs-info 或仍有开放问题时填写;否则写「无」 -->
97
+
98
+ - <具体可回答的问题 1>
99
+ - <具体可回答的问题 2>
100
+
101
+ ## 推荐下一 Work
102
+
103
+ - **主推荐:** <Path>{roots.workflows}/specdev/<Work>/<Work>.md</Path> 或 `none`
104
+ - **理由:** <对应 routing-rules 首匹配条件的一句话>
105
+ - **备选:** <可选一条 Path 或 none>
106
+ - **停止说明:** 用户确认前不启动下游 work
107
+ ```
108
+
109
+ 填写规则:
110
+
111
+ - 一句话主题来自 issue 标题的 kebab 压缩语义,与 change 目录名一致或为其可读版
112
+ - `Recommended next work` 显示名与路由表一致(如「设计访谈」「编写 Spec」「实现」「诊断」「寻路」「none」)
113
+ - 行为契约不足时:status 倾向 `needs-info`,next 为 `none`,缺口章节穷尽
114
+ - 已实现或用户确认拒绝:status `wontfix`,next `none`;范围外文件仅提示,默认不自动创建
115
+ - 无残留 `[TODO:]` 占位符
116
+
117
+ ## 完成检查
118
+
119
+ - 两文件均已存在于 `{change}` 目录
120
+ - `triage.md` 元数据五行齐全(Change / Category / Recommended status / Recommended next work / Source)
121
+ - 行为契约五块齐全(Current / Desired / Key interfaces / AC / Out of scope)——`needs-info` 时 AC 可较少,但缺口必须穷尽
122
+ - 主推荐 Path 使用 `{roots.workflows}` 别名,或为字面 `none`
@@ -0,0 +1,71 @@
1
+ # 摄入规则
2
+
3
+ 将外部 issue 或 PR 规范化为会话内统一结构,供后续理解与落盘使用。本步骤只读取远端或用户输入,不写回 tracker。
4
+
5
+ ## 远程可用性
6
+
7
+ 按顺序探测:
8
+
9
+ 1. 当前目录处于 git 仓库内
10
+ 2. `gh` 可执行
11
+ 3. `gh auth status` 成功
12
+
13
+ 三者皆满足 → **远程可用**。任一项失败 → 按粘贴 / 口头路径处理,向用户说明原因。
14
+
15
+ ## 远程拉取
16
+
17
+ 用户给出 `#N`、纯数字编号、issue URL 或 PR URL 时:
18
+
19
+ **Issue(优先)**
20
+
21
+ ```bash
22
+ gh issue view <n> --json number,title,body,author,labels,url,createdAt,state,comments
23
+ ```
24
+
25
+ 人类可读备选:`gh issue view <n> --comments`。
26
+
27
+ **PR(用户明确给了 PR,或 issue view 失败且 `gh pr view <n>` 成功)**
28
+
29
+ ```bash
30
+ gh pr view <n> --json number,title,body,author,labels,url,createdAt,state,comments,files
31
+ ```
32
+
33
+ PR 按「附带代码的 issue」处理:正文 + 评论 + 变更文件列表进入内部结构;diff 摘要可记入 `body` 附录或 comments 旁注。仍只写本地产物。
34
+
35
+ **解析 `#N`**:先尝试 `gh pr view N`,再 `gh issue view N`(或按用户声明的类型二选一)。
36
+
37
+ **失败回退**:网络错误、无权限、编号不存在 → 向用户说明,并请粘贴标题 + 正文 + 关键评论。不中止分诊。
38
+
39
+ ## 粘贴与口头
40
+
41
+ | 来源 | 条件 | 处理 |
42
+ |------|------|------|
43
+ | `paste` | 用户粘贴全文(可含评论) | 拆出标题、正文、评论块;缺评论则 `comments: []` |
44
+ | `manual` | 仅口头 / 碎片描述 | 索取最小字段:标题、问题描述、期望行为;可选复现步骤 |
45
+
46
+ ## 规范化内部结构
47
+
48
+ 无论来源,统一为:
49
+
50
+ | 字段 | 说明 |
51
+ |------|------|
52
+ | `source` | `gh` \| `paste` \| `manual` |
53
+ | `kind` | `issue` \| `pr` \| `manual` |
54
+ | `number` | 编号,无则 `n/a` |
55
+ | `title` | 标题 |
56
+ | `body` | 正文(markdown 原文) |
57
+ | `url` | 远端 URL,无则空 |
58
+ | `author` | 作者登录名或「用户」 |
59
+ | `labels` | 标签字符串数组 |
60
+ | `state` | open/closed 等,未知则空 |
61
+ | `comments` | `{ author, created_at, body }[]` |
62
+ | `fetched_at` | ISO-8601 摄入时间 |
63
+
64
+ 后续步骤只消费此结构;写入 `source-issue.md` 时按 `<Path>{roots.workflows}/specdev/T-triage/artifact-templates.md</Path>` 展开。
65
+
66
+ ## 完成检查
67
+
68
+ - 标题非空
69
+ - 正文非空(`manual` 时问题描述 + 期望行为可拼成 body)
70
+ - `source` 与 `fetched_at` 已设
71
+ - 远程路径下 `number` 与 `url` 尽量齐全;失败回退已标注
@@ -0,0 +1,70 @@
1
+ # 路由规则
2
+
3
+ 在 `triage.md` 已具备类别、验证结果、信息缺口与行为契约草案后,按**首匹配**(从上到下)选定恰好一条主推荐。可附一条备选。推荐后**停止**,等用户确认再加载对应 work 入口。
4
+
5
+ ## 首匹配表
6
+
7
+ | # | 条件 | Recommended status | 主推荐 |
8
+ |---|------|--------------------|--------|
9
+ | 1 | 已实现,或用户确认拒绝 / wontfix | `wontfix` | `none` |
10
+ | 2 | 关键信息不足(无法写出可测 AC 或无法判断类别/复现) | `needs-info` | `none` |
11
+ | 3 | `bug`,可复现(confirmed),根因未知 | `ready-for-agent` 或 `needs-triage` | **诊断** |
12
+ | 4 | `bug`,AC 清晰,范围小,修复点/模块清楚 | `ready-for-agent` | **实现** |
13
+ | 5 | `enhancement`,设计未定或接口仍开放 | `needs-triage` 或 `ready-for-human` | **设计访谈** |
14
+ | 6 | `enhancement`,设计已定,足以写 PRD | `ready-for-agent` | **编写 Spec** |
15
+ | 7 | 工作超单会话、通往目标的路径仍在迷雾中 | `needs-triage` | **寻路** |
16
+ | 8 | 以上皆非(默认) | `needs-triage` | **设计访谈** |
17
+
18
+ 规则 1 的补充:用户确认拒绝 enhancement 时,可**提示**写入项目根 `.out-of-scope/<concept>.md`(格式见 `<Path>{roots.workflows}/specdev/common/triage/OUT-OF-SCOPE.md</Path>`);默认不自动写。已实现关闭不写 `.out-of-scope/`。
19
+
20
+ 规则 3 vs 4:「根因未知」= 知道坏在哪一类症状,但不知哪个模块/不变量失败;「修复点清楚」= 已能指出接口或模块级落点。
21
+
22
+ 规则 7 可选:仅当用户或理解结论明确「多会话 / 战争迷雾」时命中;否则落入默认规则 8。
23
+
24
+ ## 入口 Path
25
+
26
+ | 显示名 | Path |
27
+ |--------|------|
28
+ | 设计访谈 | `<Path>{roots.workflows}/specdev/G-grill-with-docs/G-grill-with-docs.md</Path>` |
29
+ | 编写 Spec | `<Path>{roots.workflows}/specdev/S-spec/S-spec.md</Path>` |
30
+ | 实现 | `<Path>{roots.workflows}/specdev/I-implement/I-implement.md</Path>` |
31
+ | 诊断 | `<Path>{roots.workflows}/specdev/D-diagnose-bugs/D-diagnose-bugs.md</Path>` |
32
+ | 寻路 | `<Path>{roots.workflows}/specdev/W-wayfinder/W-wayfinder.md</Path>` |
33
+ | none | 字面 `none`(向用户提问或结束分诊) |
34
+
35
+ ## 推荐话术
36
+
37
+ 向用户展示时使用固定骨架:
38
+
39
+ ```markdown
40
+ ## 分诊结论
41
+
42
+ - **Change:** `{change}`
43
+ - **类别:** bug | enhancement
44
+ - **推荐 status:** …
45
+ - **主推荐:** <显示名> → <Path>…
46
+ - **理由:** <对应上表条件的一句话>
47
+ - **备选:** <可选>
48
+
49
+ 产物:
50
+ - `<Path>{roots.state}/specdev/changes/{change}/source-issue.md</Path>`
51
+ - `<Path>{roots.state}/specdev/changes/{change}/triage.md</Path>`
52
+
53
+ 是否进入主推荐 work?确认前我不会启动下游或修改项目代码。
54
+ ```
55
+
56
+ `needs-info` 时:话术改为列出「信息缺口」中的具体问题,主推荐写 `none`,并说明补齐后可再次运行本 work 或直接指定下游。
57
+
58
+ `none` + `wontfix` 时:说明已实现位置或拒绝理由;询问是否需要记录到 `.out-of-scope/`(仅 enhancement 拒绝)。
59
+
60
+ ## 停止规则
61
+
62
+ - 本步只推荐与展示;用户确认「进入 X」后再加载对应 Path,并移交 change 名、`triage.md` 路径与行为契约要点
63
+ - 用户选择备选或否决时,先更新 `triage.md` 推荐字段,再结束或按新选择移交
64
+
65
+ ## 完成检查
66
+
67
+ - 从上到下只命中一条主推荐
68
+ - Path 使用上表别名格式(或 `none`)
69
+ - 用户已看到理由与确认问题
70
+ - 下游仍处于未启动状态
@@ -0,0 +1,102 @@
1
+ # 深度理解规则
2
+
3
+ 在写入分诊产物之前,对摄入的 issue 完成可检查的理解。行为契约对齐 `<Path>{roots.workflows}/specdev/common/triage/AGENT-BRIEF.md</Path>`:
4
+
5
+ - **持久优于精确**——描述接口、类型与行为契约;少绑易变文件路径与行号
6
+ - **行为而非过程**——写系统应做什么,不写如何实现
7
+ - **完整验收标准**——每条可独立验证
8
+ - **明确范围外**——写清本 change 不做什么
9
+
10
+ 范围外只读去重遵循 `<Path>{roots.workflows}/specdev/common/triage/OUT-OF-SCOPE.md</Path>`。
11
+
12
+ ## 检查清单(逐项完成)
13
+
14
+ ### 1. 问题一句话
15
+
16
+ 用一句用户可理解的话概括「出了什么问题 / 要什么能力」。
17
+
18
+ ### 2. 类别
19
+
20
+ 判定恰好一个:
21
+
22
+ - `bug`——现有行为不符合预期
23
+ - `enhancement`——新功能或对现有能力的改进
24
+
25
+ 依据不足时倾向 `enhancement` 并在信息缺口中写清「请确认是回归还是新需求」。
26
+
27
+ ### 3. 当前行为 vs 期望行为
28
+
29
+ - **当前**:代码库与 issue 共同描述的现状(bug 为故障表现;enhancement 为建立其上的基线)
30
+ - **期望**:完成后应发生什么;含已知边界与错误条件
31
+
32
+ 未知部分列入信息缺口,不编造。
33
+
34
+ ### 4. 代码库探查
35
+
36
+ - 先读 `<Path>{roots.state}/specdev/adr/</Path>` 与 `<Path>{roots.state}/specdev/context/</Path>`(若存在),使用既有术语与决策
37
+ - 按**领域概念**搜索(不仅是 issue 措辞)
38
+ - 记录相关模块、类型、函数签名或配置形态——行为级命名优先
39
+ - 报告查找范围,便于用户质疑遗漏
40
+
41
+ ### 5. 冗余(已实现)
42
+
43
+ 若请求行为已在代码库中存在:
44
+
45
+ - 指向存在位置(模块/接口名 + 简要证据)
46
+ - 倾向推荐 status `wontfix`、next work `none`
47
+ - 已实现路径只指向代码位置;`.out-of-scope/` 仅用于被拒绝的 enhancement
48
+
49
+ ### 6. 范围外匹配(只读)
50
+
51
+ 读取项目根 `.out-of-scope/*.md`(目录不存在则跳过):
52
+
53
+ - 按**概念相似**匹配(如「night theme」≈ `dark-mode`)
54
+ - 有匹配则呈现文件路径与拒绝理由,请用户选择:
55
+ - **确认**——仍拒绝 → next `none`;可提示用户自行追加 prior request(本 work **默认不自动写** `.out-of-scope/`)
56
+ - **重新考虑**——进入正常分诊
57
+ - **不相关**——继续正常分诊
58
+
59
+ ### 7. 信息缺口
60
+
61
+ 列出具体、可回答的问题。每条应能独立关闭一个决策或验证点。
62
+
63
+ - 好:「在 Node 20 + macOS 上执行 `speculo init` 后的完整终端输出是什么?」
64
+ - 坏:「请提供更多信息。」
65
+
66
+ 无缺口则写「无」。
67
+
68
+ ### 8. Bug 验证(轻量)
69
+
70
+ 仅 `bug` 类别:
71
+
72
+ | 结果 | 含义 |
73
+ |------|------|
74
+ | `confirmed` | 按报告步骤复现成功,或代码路径明确支撑该故障 |
75
+ | `not-reproduced` | 按步骤未能复现;记录尝试环境与命令 |
76
+ | `needs-info` | 步骤不足,无法尝试复现 |
77
+ | `n/a` | 非 bug |
78
+
79
+ 完整反馈回路、插桩与假设排名由 `<Path>{roots.workflows}/specdev/D-diagnose-bugs/D-diagnose-bugs.md</Path>` 负责。本步只需确认「是否像真 bug」及可复现性档位。
80
+
81
+ ## 输出给后续步骤的结论包
82
+
83
+ 步骤 4 写入 `triage.md` 前,会话中应具备:
84
+
85
+ | 字段 | 来源 |
86
+ |------|------|
87
+ | 类别 | 清单 §2 |
88
+ | 问题摘要 | 清单 §1 |
89
+ | 当前 / 期望行为 | 清单 §3 |
90
+ | 关键接口(草案) | 清单 §4 |
91
+ | 验收标准(草案) | 自期望行为拆出;不足则进缺口 |
92
+ | 范围外 | 清单 §6 + 显式不做项 |
93
+ | 验证结果 | 清单 §8 |
94
+ | 冗余 / 范围外结论 | 清单 §5–6 |
95
+ | 信息缺口 | 清单 §7 |
96
+ | 完备性 | 足以写契约 → 可路由下游;否则 `needs-info` |
97
+
98
+ ## 完成检查
99
+
100
+ - 八项均有结论或明确「不适用」
101
+ - 用户已看到已实现 / 范围外匹配(若有)并给出方向(或已 AFK 默认继续)
102
+ - 信息缺口每条可操作
@@ -33,7 +33,7 @@ Wayfinder 默认进行**规划**:每个 ticket 解决一个决策,当地图
33
33
 
34
34
  **前沿查询:** 前沿上的 tickets 是指:checkbox 未勾选(开放)、其"被阻塞于"中列出的所有 tickets 均已勾选(无阻塞)、且尚未被领取的 tickets。Agent 通过阅读地图文件本身即可识别前沿。
35
35
 
36
- **领取机制:** 当一个 agent 会话开始处理某个 ticket 时,它应在 `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组中记录当前处理的 ticket 名称,以便并发会话跳过它。处理完成后从 `active` 中移除。`active` 中存在记录即为领取标记。
36
+ **领取机制:** 当一个 agent 会话开始处理某个 ticket 时,它应在 `<Path>{roots.state}/specdev/status.json</Path>` 的当前 change 的 `active` 条目中,将 ticket 名称追加到 `claimed_tickets` 数组,以便并发会话跳过它。处理完成后从 `claimed_tickets` 中移除。`claimed_tickets` 中存在记录即为领取标记。
37
37
 
38
38
  ### 地图正文
39
39
 
@@ -93,7 +93,7 @@ Wayfinder 默认进行**规划**:每个 ticket 解决一个决策,当地图
93
93
 
94
94
  每个 ticket 携带一个类型标签 —— 以下之一:`research`、`prototype`、`grilling`、`task`(参见下方 [Ticket 类型](#ticket-类型))。
95
95
 
96
- **领取机制:** 一个会话通过将其名称写入 `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组来**领取**一个 ticket,在开始任何工作**之前**领取,以便并发会话跳过它。该记录*就是*领取标记:一个开放、未被领取的 ticket 是未被领取的。
96
+ **领取机制:** 一个会话通过将其名称追加到 `<Path>{roots.state}/specdev/status.json</Path>` 的当前 change 的 `active` 条目中的 `claimed_tickets` 数组来**领取**一个 ticket,在开始任何工作**之前**领取,以便并发会话跳过它。该记录*就是*领取标记:一个开放、未被领取的 ticket 是未被领取的。
97
97
 
98
98
  **阻塞关系:** 使用 ticket 标题在"被阻塞于"字段中声明依赖。这很关键,因为它使前沿在地图文件中*可视化*呈现 —— 人类无需额外工具就能看到哪些可以开始。当一个 ticket 的所有阻塞 tickets 都已勾选(已解决)时,该 ticket 是**未被阻塞的**;**前沿**是开放(未勾选)、未被阻塞、未被领取的 tickets —— 即已知的边界。
99
99
 
@@ -163,7 +163,7 @@ Wayfinder 默认进行**规划**:每个 ticket 解决一个决策,当地图
163
163
 
164
164
  **完成标准**:地图的低分辨率视图已加载,当前状态已理解。
165
165
 
166
- 2. **选择 ticket。** 如果用户指定了一个,使用它。否则按顺序选择第一个前沿 ticket(开放、未被阻塞、未被领取)。**领取它**:在任何工作之前将 ticket 名称写入 `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组。
166
+ 2. **选择 ticket。** 如果用户指定了一个,使用它。否则按顺序选择第一个前沿 ticket(开放、未被阻塞、未被领取)。**领取它**:在任何工作之前将 ticket 名称追加到 `<Path>{roots.state}/specdev/status.json</Path>` 的当前 change 的 `active` 条目中的 `claimed_tickets` 数组。
167
167
 
168
168
  **完成标准**:一个前沿 ticket 已被选中并领取。
169
169
 
@@ -171,7 +171,7 @@ Wayfinder 默认进行**规划**:每个 ticket 解决一个决策,当地图
171
171
 
172
172
  **完成标准**:ticket 的问题已解决,答案已记录。
173
173
 
174
- 4. **记录解决方案:** 在 ticket 的"答案"小节中填写答案,将 checkbox 从 `- [ ]` 改为 `- [x]`,在地图的 Decisions-so-far 中**追加一条上下文指针**:`- [ticket 标题] —— 答案的一句话概括`。从 `<Path>{roots.state}/specdev/status.json</Path>` 的 `active` 数组中移除该 ticket。
174
+ 4. **记录解决方案:** 在 ticket 的"答案"小节中填写答案,将 checkbox 从 `- [ ]` 改为 `- [x]`,在地图的 Decisions-so-far 中**追加一条上下文指针**:`- [ticket 标题] —— 答案的一句话概括`。从 `<Path>{roots.state}/specdev/status.json</Path>` 的当前 change 的 `active` 条目中的 `claimed_tickets` 数组中移除该 ticket。
175
175
 
176
176
  **完成标准**:ticket checkbox 已勾选,Decisions-so-far 已更新,active 数组已清理。
177
177
 
@@ -206,4 +206,4 @@ Wayfinder 默认进行**规划**:每个 ticket 解决一个决策,当地图
206
206
  | `<Path>{roots.state}/specdev/changes/{change}/map.md</Path>` | 地图持久化文件 |
207
207
 
208
208
  状态追踪:
209
- - `<Path>{roots.state}/specdev/status.json</Path>` —— `active` 数组记录当前领取的 ticket
209
+ - `<Path>{roots.state}/specdev/status.json</Path>` —— `active` 条目中的 `claimed_tickets` 数组记录当前领取的 ticket
@@ -1,5 +1,7 @@
1
1
  {
2
- "schema_version": 1,
2
+ "schema_version": 2,
3
3
  "workflow": "specdev",
4
- "active": []
4
+ "active": [],
5
+ "work_history": [],
6
+ "completed": []
5
7
  }