@cyning/harness 2.6.0 → 2.8.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/CHANGELOG.md CHANGED
@@ -4,6 +4,36 @@
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2.8.0] - 2026-07-25
8
+
9
+ ### Added
10
+
11
+ - **SPEC 审查文留档闸(N3 · G2 姊妹)**:`verify --spec FILE` 检查 `docs/harness/reviews/` 下 SPEC 审查文存在性(推荐 `spec_<slug>_audit_R*` · 兼容 `*_ACCEPT_*` / `task_*_spec_ACCEPT_*`)。缺失 → `VERIFY: BLOCKED · missing SPEC R<n> review` exit 2。
12
+ - 豁免:`--allow-no-spec-review`;元信息 `track: bugfix` / `skip_spec_audit: true`。
13
+ - `findSpecReview`(支持 `--workspace-root` 分仓);handoff:`may_start_00` · `spec_review_found` · `spec_review_latest`。
14
+ - `lifecycle.yaml` 转移 `to_00` + guard `spec_reviews_retention`(只登记)。
15
+
16
+ ### Notes
17
+
18
+ - 与 `--task` 互斥;**不**改 task 侧 verify/close。
19
+ - SPEC:`docs/spec/SPEC-spec-reviews-retention-gate_v1.md`
20
+ - minor · 行为新增(新模式)
21
+
22
+ ## [2.7.0] - 2026-07-24
23
+
24
+ ### Added
25
+
26
+ - **`harness/lifecycle.yaml`(方向二 · 文档先行)**:登记 task 状态 / 转移 / 守卫(`to_30` · `close`);`task_lint` severity=`warn`。Schema:`schema/lifecycle.v1.schema.json`。
27
+ - **`harness lifecycle show [--json]`**:只读渲染包内 yaml(**不做**转移引擎、不写盘)。
28
+ - **`verify --task` ↔ task lint(N2)**:E 级仅 `WARN: task lint FAIL`(不改 exit / 不改 `may_start_30`);`--allow-lint-fail` 抑制 WARN;handoff JSON 增加 `lint: { ok, errors, warnings, suppressed? }`;无 `--task` 全量模式不跑 lint。
29
+
30
+ ### Notes
31
+
32
+ - 背景:Post-G4 方案 N1+N2 · rethink 方向二骨架;dogfood active lint FAIL 率高故本波不做 block。
33
+ - SPEC:`docs/spec/SPEC-lifecycle-and-verify-lint_v1.md`
34
+ - minor · `npm test` 含 lifecycle + verify-lint-warn
35
+ - **已发布**:`@cyning/harness@2.7.0`(npm `latest` · 2026-07-24)· tag `v2.7.0`
36
+
7
37
  ## [2.6.0] - 2026-07-24
8
38
 
9
39
  ### Added
@@ -21,7 +51,7 @@
21
51
 
22
52
  - 背景:机械化率审计 G4(rethink 矩阵 P1 · 第三波);与 G1 同命令、分开交付。
23
53
  - minor · 无 verify 行为变更 · `npm test` 含既有回归全绿
24
- - **待发布**:`@cyning/harness@2.6.0`(维护者 CLOSE npm publish + tag)
54
+ - **已发布**:`@cyning/harness@2.6.0`(npm `latest` · 2026-07-24)· tag `v2.6.0` 已推送
25
55
 
26
56
  ## [2.5.0] - 2026-07-24
27
57
 
@@ -45,10 +45,21 @@ cd your-project
45
45
  `npx @cyning/harness verify` 在 30 执行前聚合扫描人工闸与测试声明,确保 ICVO 公理可机械检查:
46
46
 
47
47
  ```bash
48
- # 30 前聚合验证(gate-check + audit D5 + S5 warn + 可选 --graph)
48
+ # 30 前聚合验证(gate-check + audit D5 + reviews + S5 warn + 可选 --graph)
49
49
  npx @cyning/harness verify --target /path/to/your-repo
50
50
  npx @cyning/harness verify --target /path/to/your-repo \
51
51
  --task docs/tasks/active/task_xxx.md
52
+ # --task 另跑 task lint(v2.7+ · E 级仅 WARN,不挡 may_start_30)
53
+ # 抑制 lint WARN:加 --allow-lint-fail
54
+
55
+ # SPEC→00 前:审查文存在性(v2.8+ · 与 --task 互斥)
56
+ npx @cyning/harness verify --spec docs/spec/SPEC-xxx_v1.md \
57
+ --workspace-root /path/to/Projects
58
+ # 豁免:--allow-no-spec-review · 或 SPEC track=bugfix / skip_spec_audit
59
+
60
+ # 只读生命周期登记(方向二 · 非引擎)
61
+ npx @cyning/harness lifecycle show
62
+ npx @cyning/harness lifecycle show --json
52
63
 
53
64
  # 仅人工闸
54
65
  npx @cyning/harness gate-check --target /path/to/your-repo
@@ -67,6 +78,9 @@ npx @cyning/harness sync index --target /path/to/your-repo
67
78
  | **D3** | 30 前置人闸 | 复用 `gate-check.sh`,HG-AUDIT-R1 非 approved 时 verify 非 0 |
68
79
  | **D5** | 改码任务测试声明 | `test_strategy=required` 但无测试/CI 引用时 verify 非 0 |
69
80
  | **S5** | Git 工作区干净 | dirty 时 warn(不直接 fail verify,但 apply 须 `--force`) |
81
+ | **lint** | task 结构(仅 `--task`) | v2.7+ E 级 → `WARN: task lint`(不改 exit / `may_start_30`) |
82
+
83
+ 生命周期真值:[`harness/lifecycle.yaml`](../harness/lifecycle.yaml)(`lifecycle show` 只读)。
70
84
 
71
85
  Audit **不替代** 维护者最终判断;Agent 首输出仍须人工复核。
72
86
 
@@ -111,8 +111,14 @@ npx @cyning/harness@1.0.1 init --preset harness-only --ide cursor,agents --yes
111
111
  **原则**:Agent 可以写 task 和 review,**人工闸只有维护者能签**。
112
112
 
113
113
  ```bash
114
- # 30 前聚合验证(gate-check + audit D5 + S5 warn + 可选 --graph)
114
+ # 30 前聚合验证(gate-check + audit D5 + reviews + task lint WARN + S5 · 可选 --graph)
115
115
  npx @cyning/harness verify --target . --task docs/tasks/active/task_xxx.md
116
+ # lint FAIL 仅 WARN(v2.7+ · 不挡 30);抑制:--allow-lint-fail
117
+
118
+ # SPEC→00:审查文存在性(v2.8+ · 与 --task 互斥)
119
+ npx @cyning/harness verify --spec docs/spec/SPEC-xxx_v1.md \
120
+ --workspace-root /path/to/Projects
121
+ # 豁免:--allow-no-spec-review
116
122
 
117
123
  # Agent handoff(v2.0.2+):JSON 路由 + 下一帽提示
118
124
  npx @cyning/harness verify --target . \
@@ -120,6 +126,9 @@ npx @cyning/harness verify --target . \
120
126
  [--json] [--agent-hint] \
121
127
  [--workspace-root /path/to/Projects]
122
128
 
129
+ # 只读生命周期登记(方向二 · harness/lifecycle.yaml · 非引擎)
130
+ npx @cyning/harness lifecycle show [--json]
131
+
123
132
  # 仅人工闸
124
133
  npx @cyning/harness gate-check --target . --task docs/tasks/active/task_xxx.md
125
134
  npx @cyning/harness gate-check --graph --target . # Inform 图谱闸
@@ -136,6 +145,7 @@ npx @cyning/harness gate-check --graph --target . # Inform 图谱闸
136
145
  | `HG-TASK-DRAFT` | task 初稿维护者签 | pending 且 blocks 含 30 → 拒 30 |
137
146
  | `HG-GRAPH-MODULES` | 架构模块表人签 | pending → 拒改码 30 |
138
147
  | `HG-RELEASE` | 发版闸(产品仓) | 一般业务仓不涉及 |
148
+ | `task_lint`(v2.7+) | `verify --task` 结构检查 | **仅 WARN** · 不改 `may_start_30` |
139
149
 
140
150
  ### 5.1 Agent handoff(v2.0.2+)
141
151
 
@@ -150,6 +160,7 @@ npx @cyning/harness gate-check --graph --target . # Inform 图谱闸
150
160
  | `entry_invoke_30_resolved` | 绝对路径(`Projects/` 前缀须 `--workspace-root`) |
151
161
  | `next_hat` | `"30"` 或 `null` |
152
162
  | `agent_preamble` | 短句提醒首输出 GATE_VERIFY |
163
+ | `lint`(v2.7+ · 仅 `--task`) | `{ ok, errors, warnings, suppressed? }` · 不参与 `may_start_30` |
153
164
 
154
165
  Schema:[`schema/verify_result.v1.schema.json`](../schema/verify_result.v1.schema.json)
155
166
 
@@ -166,7 +177,8 @@ Schema:[`schema/verify_result.v1.schema.json`](../schema/verify_result.v1.sche
166
177
  | `npx @cyning/harness init` | 首次安装模板与 manifest(可选 `--with-scripts`) |
167
178
  | `npx @cyning/harness upgrade` | 同步产品包更新(可加 `--gate-check` 先 audit) |
168
179
  | `npx @cyning/harness check` | 检查是否有新版本 |
169
- | `npx @cyning/harness verify` | 30 前聚合:gate-check + audit D5 + S5 warn + 可选 `--graph` · v2.0.2+ `--json` / `--agent-hint` / `--workspace-root` |
180
+ | `npx @cyning/harness verify` | `--task`:30 前聚合;`--spec`:SPEC→00 审查文闸(v2.8+ · 互斥)· `--allow-no-spec-review` |
181
+ | `npx @cyning/harness lifecycle show` | 只读展示 `harness/lifecycle.yaml`(状态/转移/守卫 · v2.7+ · 非引擎) |
170
182
  | `npx @cyning/harness gate-check` | 仅人工闸(`--graph` / `--json`) |
171
183
  | `npx @cyning/harness audit` | ICVO 机械审计(D3/D5/S5) |
172
184
  | `npx @cyning/harness sync index` | 生成 `.cyning-harness/invoke_index.json` |
@@ -28,6 +28,7 @@ v2.2 的故事(invoke 留档连续 4 任务失守 → `task close` 补闸)
28
28
 
29
29
  CLI 今天是一袋动词,背后实际是**一个** task 生命周期:`draft → R1 → approved → 30 → 40 → done → archived`。`verify` 是 30 转移的前置检查,`close` 是 done→archived 转移——状态机是隐式的。
30
30
  显式化后(如 `lifecycle.yaml`:状态/转移/前置条件),方向一产出的每个新闸都有**天然挂点**;「这个 task 现在能做什么」一条命令可答(`verify --json` 的 handoff 是胚胎)。
31
+ **落地(v2.7.0 · 文档先行)**:产品包真值 [`harness/lifecycle.yaml`](../../../harness/lifecycle.yaml) + `npx @cyning/harness lifecycle show [--json]`(只读 · **不做**转移引擎);`verify --task` 已挂 `task_lint`(severity=warn)。
31
32
  **原则**:闸只挡实质、宽容形式(slug 事件教训:现实有两种命名惯例,闸太死就误伤)。
32
33
 
33
34
  ### 方向三 · Agent 一等公民接口(分发放大器)
@@ -0,0 +1,174 @@
1
+ # SPEC:lifecycle.yaml 最小版 + verify↔lint 挂点(N1+N2)(v1)
2
+
3
+ > **状态**:`signed`(维护者签收 2026-07-24 · 对话「签收」)
4
+ > **track**:`epic`
5
+ > **关联图谱**:无(纯 Harness 工具链 / 过程轨)
6
+ > **上游**:工作区 [`PLAN_post_g4_next_mechanization_v1_zh.md`](../../../docs/harness/guides/PLAN_post_g4_next_mechanization_v1_zh.md) · rethink [`01_big_directions`](../rethink/2026-07-mechanization-rate/01_big_directions.md) 方向二
7
+ > **前置**:G1–G4 文档闸 ✅ · `@cyning/harness@2.6.0`
8
+ > **下游**:00 已起草 task → 20-task-audit → HG-AUDIT-R1 → 30
9
+
10
+ ---
11
+
12
+ ## Harness 元信息
13
+
14
+ | 字段 | 值 |
15
+ |------|-----|
16
+ | **spec_slug** | `lifecycle-and-verify-lint` |
17
+ | **test_strategy** | `required` |
18
+ | **test_strategy_note** | N1:schema 校验夹具 + fixture yaml;N2:verify 三态(无 lint 错 / warn / 豁免)+ 既有 verify 回归 |
19
+ | **entry_invoke_10_spec** | `Projects/docs/harness/invokes/by-task/cyning-harness-lifecycle-and-verify-lint/invoke_20260724_10_spec_lifecycle_and_verify_lint.md` |
20
+ | **entry_invoke_00_draft** | 工作区 `docs/harness/prompts/PROMPT_00_draft_spec_or_task_v1_zh.md` |
21
+
22
+ ---
23
+
24
+ ## 1. 背景与目标
25
+
26
+ G1–G4 把「文档存在性/结构」闸补齐后,CLI 仍是一袋动词:新闸的挂点靠临场设计(verify?close?独立命令?)。rethink 方向二主张用 **`lifecycle.yaml`** 显式登记状态/转移/守卫,让补闸变便宜。
27
+
28
+ 同时 G1 遗留决策未闭合:`task lint` 是否接入 `verify`。2026-07-24 dogfood:**active 16 · PASS 1 · FAIL 15**——全量 block 会立即误伤工作区。
29
+
30
+ **本 Epic 双目标**:
31
+
32
+ 1. **N1**:产品仓落地 `lifecycle.yaml` 最小真值(文档 + schema;可选只读 CLI),**不**实现状态机引擎。
33
+ 2. **N2**:在 lifecycle 上裁定并实现 **verify↔lint** 挂点语义——本波 **warn-only**(见 R2),为将来升 block 留泄压阀与登记位。
34
+
35
+ ---
36
+
37
+ ## 2. 范围
38
+
39
+ ### N1 · lifecycle.yaml 最小版
40
+
41
+ - **D1 · 真值文件**:`harness/lifecycle.yaml`(随包分发)描述:
42
+ - `states[]`:至少覆盖 `draft` · `in_progress` · `done` · `archived`(与 task 状态词表 / close 对齐;允许注释映射 `pending` 等别名)
43
+ - `transitions[]`:至少 `→30`(开工)与 `done→archived`(close);每条含 `id` · `from` · `to` · `guards[]`
44
+ - `guards[]` 元素:`{ id, command_or_check, severity: block|warn, allow_flag? }`
45
+ - 本波须把 **既有** 守卫登记进去:`HG-AUDIT-R1` / reviews 留档 / audit D5 / `task close` 五~六检(描述级 · 不要求引擎执行)
46
+ - **D2 · Schema**:`schema/lifecycle.v1.schema.json`(或等价 YAML schema)+ 非法 fixture 校验测试
47
+ - **D3 · 只读 CLI(最小)**:`harness lifecycle show [--json]` —— 读包内 yaml · 打印状态/转移/守卫表;**不做**转移执行、不做持久化状态
48
+ - **D4 · 文档**:USER_GUIDE 或 ONBOARDING 一小节 + CHANGELOG;rethink 01 方向二链到本文件
49
+
50
+ ### N2 · verify 接入 task lint(本波语义)
51
+
52
+ - **D5 · 裁定落地(R2)**:**severity = warn**(非 block)
53
+ - `verify --task`:在 gate-check + audit + reviews 之后调用 `lintTaskFile`;有 E 级 → `WARN: task lint FAIL · …` 拼入 stdout,**不**改 exit / **不**改 `may_start_30`
54
+ - `--json` handoff 增字段:`lint_ok` · `lint_errors[]`(或 `lint: { ok, errors, warnings }`)
55
+ - 豁免:`--allow-lint-fail`(即使未来升 block 也复用此旗;本波 warn 模式下作用为「抑制 WARN 行」或留痕 `lint_suppressed`)
56
+ - **D6 · lifecycle 登记**:`to_30` 守卫含 `task_lint` · `severity: warn` · `allow_flag: --allow-lint-fail`;注释写明升 `block` 的前置条件(见 §非范围 / residual)
57
+ - **D7 · 测试**:verify fixture 三态(lint pass 无 warn / lint fail 有 warn 且 exit 0 / `--allow-lint-fail`);既有 verify 用例不回归
58
+ - **D8 · 版本**:**v2.7.0**(N1 文档+只读 CLI + N2 warn 行为;无硬 block)
59
+
60
+ ---
61
+
62
+ ## 3. 非范围
63
+
64
+ - **状态机引擎**(按转移执行、写回 status、事件溯源)—— 方向二下一波
65
+ - **N2 选项 C(verify block lint)**—— 本波不做;待 active lint FAIL 率下降或另立「仅新流转」策略后再开
66
+ - `harness run` / G7 执行证据
67
+ - G6 git 行为层 · HGM G2 查询
68
+ - SPEC 审查文闸(N3)· verify 无 `--task` 全量模式纳入 reviews
69
+ - 强制修复工作区存量 15 个 FAIL task(可另开 hygiene task)
70
+ - 改变既有 E1–E10 规则集语义
71
+
72
+ ---
73
+
74
+ ## 4. 验收标准
75
+
76
+ ### N1
77
+
78
+ - [ ] `harness/lifecycle.yaml` 可被 schema 校验通过;含 `to_30` 与 `close` 两条主转移及既有守卫登记
79
+ - [ ] 非法 yaml(缺 states / 非法 severity)→ schema 或 `lifecycle show` 可失败可定位
80
+ - [ ] `harness lifecycle show` 退出 0 · 人读表含状态与守卫;`--json` 输出稳定字段
81
+ - [ ] 文档章节可从 README/ONBOARDING/USER_GUIDE 链到
82
+
83
+ ### N2
84
+
85
+ - [ ] `verify --task` 对 lint FAIL 的 task:exit **0**(在其余闸通过时)且 stdout 含 `WARN: task lint`
86
+ - [ ] lint PASS:无该 WARN
87
+ - [ ] `--json` 含 lint 结果字段;`may_start_30` **不**因 lint FAIL 变 false(本波)
88
+ - [ ] `--allow-lint-fail` 可抑制 WARN(或显式 `lint_suppressed: true`)
89
+ - [ ] `npm test` 全绿(含既有 verify 回归)
90
+
91
+ ### 发布
92
+
93
+ - [ ] CHANGELOG v2.7.0;PLAN / rethink 回链本 SPEC
94
+
95
+ ---
96
+
97
+ ## 5. failure_paths
98
+
99
+ | 触发条件 | 系统行为 | 可重试 |
100
+ |----------|----------|--------|
101
+ | lifecycle.yaml 损坏 / 不符 schema | `lifecycle show` exit ≠0 · 信息可定位 | 修 yaml |
102
+ | verify 时 task 文件不可读 | 既有 verify 行为不变 | 修正路径 |
103
+ | lint FAIL(本波) | WARN · exit 仍由其余闸决定 | 修 task 或 `--allow-lint-fail` |
104
+ | 业务仓未升级 2.7.0 | 无 lifecycle 子命令 · verify 无 lint WARN | upgrade |
105
+ | 误以为 lint FAIL 会挡 30 | 文档 + lifecycle 表 severity=warn 明示 | — |
106
+
107
+ ---
108
+
109
+ ## 6. 依赖与引用
110
+
111
+ - rethink 01 方向二;PLAN_post_g4 N1/N2
112
+ - `lib/task-lint.js` · `lib/verify.js` · `lib/task-meta.js`(handoff)
113
+ - G1 SPEC:刻意不接入 verify 的历史裁定 → 本 SPEC **修订**为 warn 挂点(非沉默独立)
114
+ - dogfood 证据:2026-07-24 active `PASS=1 FAIL=15`
115
+
116
+ ---
117
+
118
+ ## 7. 思考轮(10-spec 回填 · R0–R5)
119
+
120
+ ### R0 · 读入与约束
121
+
122
+ 读入:PLAN_post_g4(点菜 N1+N2)· rethink 01 方向二原文 · G1/G4 SPEC 非范围(verify 不接入)· verify.js 当前插点顺序(gate → audit D5 → reviews → S5 warn)· dogfood active 15/16 lint FAIL。约束:本波 **不**做引擎;闸三问(挂点/误报/泄压)必须过;不误伤存量。
123
+
124
+ ### R1 · 范围 / 非范围 / 场景
125
+
126
+ **场景**:① 维护者/Agent 查「to_30 有哪些守卫」→ lifecycle show;② 30 前 verify 看到结构问题但不被存量堵死 → lint WARN;③ 未来升 block 时有登记位与 `--allow-lint-fail`。
127
+ **同 Epic 理由**:N2 的挂点必须写进 N1 的转移表,拆开会再临场一次。
128
+ **非范围**:引擎、C 硬挡、N3/N4/G6/G7——避免 Epic 膨胀。
129
+
130
+ ### R2 · 方案对比
131
+
132
+ | 决策点 | 选项 | 裁定 | 理由 |
133
+ |---|---|---|---|
134
+ | N1 形态 | 仅 md 文档 / yaml+schema / yaml+引擎 | **yaml+schema+只读 show** | 真值可校验;引擎无消费者则违反「消费者先行」 |
135
+ | N1 CLI | 无 / show / doctor+建议 | **show** | doctor 暗示修复策略,本波无库存治理承诺 |
136
+ | N2 A 维持独立 | 永不进 verify | **否** | 丢掉机械化挂点;与方向二冲突 |
137
+ | N2 B warn-only | verify 提示不挡 | **是 · 本波** | FAIL 率 15/16,block=治理负担 |
138
+ | N2 C block+allow | 硬挡 + 豁免 | **推迟** | 须 hygiene 或「仅新流转」另 SPEC;本波在 yaml 预留 severity 升级路径 |
139
+ | 版本 | 拆 2.7 docs + 2.8 lint | **同发 2.7.0** | 同 Epic 同挂点叙事;warn 非 breaking |
140
+
141
+ ### R3 · 边界 / 失败语义 / 安全
142
+
143
+ - **挂点**:lint 检查时刻 = verify `--task`(产物 task md 已存在)✓;全量无 `--task` 模式本波 **不**跑 lint(与 G2 全量策略一致,避免扫库爆炸)。
144
+ - **误报**:沿用 lint 形式宽容;WARN 须带 rule 列表便于修。
145
+ - **泄压**:`--allow-lint-fail`;升 block 后同旗变豁免。
146
+ - **安全**:只读 lint;不改 task 文件;lifecycle show 不写盘。
147
+ - **兼容**:未升级仓行为不变。
148
+
149
+ ### R4 · 验收 / 可测性 / test_strategy
150
+
151
+ `test_strategy: required`。N1:schema 正反例 + show JSON 快照字段。N2:verify 夹具三态 + 全量模式「不出现 lint WARN」断言。回归:既有 verify/close/lint 套件。
152
+
153
+ ### R5 · SPEC 签收就绪 · 是否可交 00 出 task
154
+
155
+ SPEC 自足:双 D 包边界清晰,N2 裁定写死为 warn,C 升级条件在 residual。**可交 00**:建议单 task `cyning-harness-lifecycle-and-verify-lint`(D1–D8 同 PR),或拆 `…-lifecycle` + `…-verify-lint` 两 task 串行(lifecycle 先 merge)。图谱无需 bootstrap。版本 **v2.7.0**。
156
+
157
+ ### 思考轮控制
158
+
159
+ | 字段 | 值 |
160
+ |------|-----|
161
+ | `actual_last_round` | `R5` |
162
+ | `early_stop` | `no` |
163
+ | `early_stop_reason` | — |
164
+ | `residual_risks` | ① 升 C(block)时机依赖存量 FAIL 率或「新流转」定义未在本 SPEC 冻结;② lifecycle 描述级守卫与代码路径可能漂移——须 30 实现时对照 verify/close 源码回填 yaml;③ `lifecycle show` 若被误解为引擎,需文档醒目标「只读」 |
165
+ | `round_extension_note` | — |
166
+
167
+ ---
168
+
169
+ ## 修订记录
170
+
171
+ | 日期 | 摘要 |
172
+ |------|------|
173
+ | 2026-07-24 | 10-spec R0–R5(维护者点菜「开 N1+N2」)· 分支清理后同会话落盘 |
174
+ | 2026-07-24 | 维护者签收(对话「签收」)· 下游 00 起草 task |
@@ -0,0 +1,192 @@
1
+ # SPEC:SPEC 审查文留档闸(20-spec-audit / HG-SPEC-SIGNOFF 存在性检查)(v1)
2
+
3
+ > **状态**:`signed`(维护者签收 2026-07-25 · 对话「签收」)
4
+ > **track**:`feature`
5
+ > **关联图谱**:无(纯 Harness 工具链)
6
+ > **上游**:[`PLAN_post_g4_next_mechanization_v1_zh.md`](../../../docs/harness/guides/PLAN_post_g4_next_mechanization_v1_zh.md) · N3 · G2 姊妹
7
+ > **前置**:G2 `@cyning/harness@2.5.0`(`findReview`)· N1 `@2.7.0`(`lifecycle.yaml`)
8
+ > **下游**:00 已起草 task → 20-task-audit → HG-AUDIT-R1 → 30(目标版本 **v2.8.0**)
9
+
10
+ ---
11
+
12
+ ## Harness 元信息
13
+
14
+ | 字段 | 值 |
15
+ |------|-----|
16
+ | **spec_slug** | `spec-reviews-retention-gate` |
17
+ | **test_strategy** | `required` |
18
+ | **test_strategy_note** | `findSpecReview` 命名变体 + `verify --spec` 三态(pass/block/豁免)+ bugfix 豁免;既有 `verify --task` 回归不改 |
19
+ | **entry_invoke_10_spec** | `Projects/docs/harness/invokes/by-task/cyning-harness-spec-reviews-retention-gate/invoke_20260725_10_spec_spec_reviews_retention_gate.md` |
20
+ | **entry_invoke_00_draft** | 工作区 `docs/harness/prompts/PROMPT_00_draft_spec_or_task_v1_zh.md` |
21
+
22
+ ---
23
+
24
+ ## 1. 背景与目标
25
+
26
+ G2(v2.5.0)已把 **task** 侧「R&lt;n&gt; 审查文存在」机械化为 `verify --task` / `task close` 检查 6。功能轨上游对称缺口仍在:
27
+
28
+ - [`20-spec-audit.md`](../../harness/prompts/20-spec-audit.md) 要求落盘 `reviews/spec_<slug>_audit_R<n>_*.md`(或既有 `*_spec_ACCEPT_R*` 惯例);
29
+ - **`HG-SPEC-SIGNOFF` 可由对话「签收」完成,签署依据(SPEC 审查文)存在性零机械**——与 G2 补闸前的 task 侧同构。
30
+
31
+ **dogfood(2026-07-25)**:产品仓 `docs/spec/SPEC-*.md` **5** 份近期 SPEC(含 G1–G4 / N1+N2)**均无**对应 `spec_*_audit_R*` / `*_spec_ACCEPT_R*` 文;工作区仅有少量历史 `spec_*_ACCEPT_*` / `*_spec_ACCEPT_*`。说明当前主流是「对话签收 + 跳过 20-spec-audit 落盘」。
32
+
33
+ **目标**:补上 SPEC→task 纸链的对称闸——机器只查**审查文存在性**;审查结论仍由人签 `HG-SPEC-SIGNOFF` 覆盖。
34
+
35
+ **职责切分(同 G2)**:机器 = 形式(文件在);人 = 实质(通过/条件通过)。
36
+
37
+ ---
38
+
39
+ ## 2. 范围
40
+
41
+ ### D1 · `findSpecReview`(`lib/task-meta.js` 或邻近模块)
42
+
43
+ - 输入:`specFile` + `target`(reviews 根所在仓)+ 可选 `workspaceRoot`(SPEC 在产品仓、reviews 在工作区时)
44
+ - 匹配(任一命中即 `found`;取最新轮):
45
+ 1. **推荐**:`spec_<slug>_audit_R<n>_*.md`
46
+ 2. **兼容**:`spec_<slug>_ACCEPT_R<n>_*.md`
47
+ 3. **兼容**:`task_<slug>_spec_ACCEPT_R<n>_*.md`(工作区历史惯例)
48
+ - slug 来源:优先 SPEC 表 `spec_slug`;否则自文件名剥离 `SPEC-` / `_v\d+` / 扩展名后 `normalizeSlug`
49
+ - 文件名与 slug:**两侧**下划线/连字符等价;版本后缀 `_v\d+` 双侧剥离(复用 G2 R1-B1 思路)
50
+ - 返回:`{ found, latest, rounds[], matched_pattern? }`
51
+
52
+ ### D2 · CLI 挂点:`verify --spec FILE`
53
+
54
+ - **新模式**(与 `--task` 互斥):`npx @cyning/harness verify --spec PATH [--target PATH] [--workspace-root PATH] [--json] [--allow-no-spec-review]`
55
+ - 行为:
56
+ - 审查文存在 → `VERIFY: PASS`(或等价摘要)· exit 0
57
+ - 缺失 → `VERIFY: BLOCKED · missing SPEC R<n> review` · exit 2
58
+ - `--allow-no-spec-review` → warn 放行 · 留痕
59
+ - `--json`:`may_start_00`(或 `spec_review_ok`)· `spec_review_found` · `spec_review_latest` · `blocked_reason`
60
+ - **不**改动既有 `verify --task` / 无参全量模式语义(N4 仍另议)
61
+ - **不**把本闸挂进 `verify --task`(挂点错误:30 查的是 task 审查文,不是 SPEC)
62
+
63
+ ### D3 · bugfix / 跳过 10-spec 豁免
64
+
65
+ 满足任一则 **不**要求 SPEC 审查文(exit 0 + 可选 info 行):
66
+
67
+ - SPEC / 元信息显式:`track: bugfix` 或 `skip_spec_audit: true`(字段名以实现为准 · 文档冻结)
68
+ - CLI:`--allow-no-spec-review`(通用泄压,含历史对话签收存量)
69
+
70
+ ### D4 · lifecycle 登记
71
+
72
+ - `harness/lifecycle.yaml` 新增转移(建议 id:`to_00` 或 `spec_signoff`):
73
+ - from:spec draft / signed 相关状态(可用注释说明别名;本波允许最小 states 扩展或仅在 transitions 注释)
74
+ - to:可起草 task
75
+ - guard:`spec_reviews_retention` · severity=`block` · `allow_flag: --allow-no-spec-review`
76
+ - **只登记 · 不实现引擎**(同 N1)
77
+
78
+ ### D5 · 文档 / 版本
79
+
80
+ - `20-spec-audit.md` / ONBOARDING 或 USER_GUIDE:注明 v2.8+ `verify --spec` 机械强制存在性
81
+ - CHANGELOG **v2.8.0**(行为新增 · minor;醒目说明 + 豁免指引)
82
+ - PLAN / rethink 矩阵回链本 SPEC
83
+
84
+ ### D6 · 测试
85
+
86
+ - 命名三变体命中;slug 连字符/下划线;版本后缀
87
+ - verify `--spec` 三态 + bugfix 豁免 + 与 `--task` 互斥用法
88
+ - 既有 verify/close/lifecycle 回归绿
89
+
90
+ ---
91
+
92
+ ## 3. 非范围
93
+
94
+ - 审查文**内容**判定(pass / conditional_pass / fail)——人/20-spec-audit 职责
95
+ - 强制给**存量** 5 份已对话签收的产品 SPEC 补审(可用豁免;另开 hygiene 可选)
96
+ - 把 SPEC 审查闸挂进 `verify --task` 或 `task close`
97
+ - N4:verify 无 `--task` 全量模式纳入 task reviews
98
+ - 自动代签 `HG-SPEC-SIGNOFF`;状态机引擎执行 `to_00`
99
+ - 统一历史所有命名为单一范式(本波只兼容读取)
100
+
101
+ ---
102
+
103
+ ## 4. 验收标准
104
+
105
+ - [ ] `findSpecReview`:推荐名 / `ACCEPT` / `task_*_spec_ACCEPT_*` 均可 `found`;多轮取最新
106
+ - [ ] `verify --spec`:有文 → PASS;无文 → BLOCKED exit 2;`--allow-no-spec-review` → warn 放行
107
+ - [ ] bugfix / `skip_spec_audit` → 不要求审查文
108
+ - [ ] `--json` 含 `spec_review_found`(或等价)且 **不**破坏 `--task` handoff 字段
109
+ - [ ] lifecycle.yaml 已登记 `to_00`(或等价)+ `spec_reviews_retention` guard
110
+ - [ ] `npm test` 全绿;CHANGELOG v2.8.0;文档可链到
111
+ - [ ] dogfood:对本 SPEC 走通「20-spec-audit 落盘 → `verify --spec` PASS」(实现波自检)
112
+
113
+ ---
114
+
115
+ ## 5. failure_paths
116
+
117
+ | 触发条件 | 系统行为 | 可重试 |
118
+ |----------|----------|--------|
119
+ | 00 前无 SPEC 审查文 | `VERIFY: BLOCKED · missing SPEC R<n> review` | 跑 20-spec-audit 落盘;或 `--allow-no-spec-review` |
120
+ | SPEC 在产品仓、reviews 在工作区 | 未传 `--workspace-root` / 错 `--target` → 误报缺失 | 按文档传参后重跑 |
121
+ | 命名不在兼容列表 | 视为缺失 | 按推荐名重命名或补一份推荐名 |
122
+ | bugfix 轨被误挡 | 应走 D3 豁免;若未标 track → 用 allow 旗 | 补元信息 |
123
+ | 业务仓未升级 2.8.0 | 无 `--spec` 模式 · 行为不变 | upgrade |
124
+
125
+ ---
126
+
127
+ ## 6. 依赖与引用
128
+
129
+ - G2:`findReview` / `--allow-no-review` 模式;本波 **独立** flag `--allow-no-spec-review`(审计痕迹不混)
130
+ - N1:`lifecycle.yaml` 挂点登记
131
+ - 纪律:`harness/prompts/20-spec-audit.md` · `10-spec-requirements.md`(bugfix 跳过)
132
+ - PLAN N3;G2 SPEC 非范围「SPEC 审查文——下一轮」本 SPEC 关闭该句
133
+
134
+ ---
135
+
136
+ ## 7. 思考轮(10-spec 回填 · R0–R5)
137
+
138
+ ### R0 · 读入与约束
139
+
140
+ 读入:PLAN N3;G2 SPEC(非范围点名本缺口);`20-spec-audit` 命名双惯例;`findReview` 实现;lifecycle.yaml 仅有 task 转移;dogfood:5/5 产品 SPEC 无 spec 审查文。约束:挂点时刻须晚于审查文应存在时刻;不误伤 bugfix;不把闸错挂到 `--task`。
141
+
142
+ ### R1 · 范围 / 非范围 / 场景
143
+
144
+ **场景**:① 维护者/Agent 在 00 起草 task 前跑 `verify --spec`,挡「对话签了但无审查文」;② 20-spec-audit 多轮 R1→R2 取最新;③ 历史 `*_ACCEPT_*` 命名仍认;④ bugfix 无 10-spec 不挡。
145
+ **同构 G2、异挂点**:共享「存在性闸」模式,但消费者是 **SPEC→00**,不是 **task→30**。
146
+ **非范围**:内容判定、存量强制补审、挂进 task verify/close——避免双重计费与挂点错位。
147
+
148
+ ### R2 · 方案对比
149
+
150
+ | 决策点 | 选项 | 裁定 | 理由 |
151
+ |---|---|---|---|
152
+ | 严格度 | warn 起步 / block+allow | **block + `--allow-no-spec-review`** | 与 G2 同构;warn 等于再留自觉层。dogfood 存量用豁免,不降级整闸 |
153
+ | CLI 形态 | 独立 `spec check` / 并入 `verify --spec` | **`verify --spec`** | 与 G2 叙事一致(「verify = 下一转移前置」);少一个动词 |
154
+ | 挂点 | `--task` 附带查 SPEC / 仅 `--spec` / close | **仅 `--spec`** | `--task` 时 SPEC 链路可能已结束;close 查 SPEC 无审计价值 |
155
+ | 命名 | 只认推荐 / 兼容 ACCEPT | **推荐 + 两兼容** | 20-spec-audit 已写双惯例;工作区有 ACCEPT 实档 |
156
+ | reviews 根 | 仅 SPEC 所在仓 / 可 workspace-root | **支持 `--workspace-root`(或 `--target` 指 reviews 仓)** | 产品 SPEC × 工作区 reviews 是本仓常态 |
157
+ | 豁免旗 | 复用 `--allow-no-review` / 独立 | **独立 `--allow-no-spec-review`** | 与 task 审查豁免分迹 |
158
+ | 版本 | 2.7.x patch / 2.8.0 | **2.8.0** | 新 blocking 模式 · minor |
159
+
160
+ ### R3 · 边界 / 失败语义 / 安全
161
+
162
+ - **存量**:5 份已对话签收 SPEC 不自动被扫;仅在有人执行 `verify --spec` 时暴露 → 豁免或补 20-spec-audit。
163
+ - **误报**:形式宽容止于「slug 匹配 + 兼容模式名」;不接受任意含 spec 字样的文件。
164
+ - **安全**:只读检查;不写盘、不代签人闸。
165
+ - **兼容**:无 `--spec` 的旧调用链行为不变。
166
+
167
+ ### R4 · 验收 / 可测性 / test_strategy
168
+
169
+ `test_strategy: required`。fixture:三命名 · 互斥参数 · block/pass/allow · bugfix 跳过;回归 verify-task / lifecycle show。实现波 dogfood:本 SPEC 的 20-spec-audit 文 + `verify --spec` PASS。
170
+
171
+ ### R5 · SPEC 签收就绪 · 是否可交 00 出 task
172
+
173
+ 自足:挂点、命名、豁免、lifecycle 登记、版本均已裁定。**可交 00**:建议单 task `cyning-harness-spec-reviews-retention-gate`。图谱无需 bootstrap。
174
+
175
+ ### 思考轮控制
176
+
177
+ | 字段 | 值 |
178
+ |------|-----|
179
+ | `actual_last_round` | `R5` |
180
+ | `early_stop` | `no` |
181
+ | `early_stop_reason` | — |
182
+ | `residual_risks` | ① 对话签收文化可能继续依赖豁免旗——须文档把「00 前 verify --spec」写成默认;② SPEC 路径与 reviews 仓分裂时 Agent 漏传 workspace-root → 误 BLOCKED;③ 是否在 00 帽 Prompt 增加「开工前 GATE_VERIFY_SPEC」句,属文档同步,实现时对照 10-spec/00 模板 |
183
+ | `round_extension_note` | — |
184
+
185
+ ---
186
+
187
+ ## 修订记录
188
+
189
+ | 日期 | 摘要 |
190
+ |------|------|
191
+ | 2026-07-25 | 10-spec R0–R5(维护者点菜「继续 N3」)· dogfood 5/5 无 spec 审查文 |
192
+ | 2026-07-25 | 维护者签收(对话「签收」)· → 00 起草 task |
@@ -0,0 +1,83 @@
1
+ # Task lifecycle · 最小真值(方向二文档先行 · v1)
2
+ #
3
+ # 只读登记:状态 / 转移 / 守卫。不由引擎执行。
4
+ # CLI:npx @cyning/harness lifecycle show [--json]
5
+ # Schema:schema/lifecycle.v1.schema.json
6
+
7
+ version: "1"
8
+
9
+ states:
10
+ - id: draft
11
+ note: "含 pending / active 等词表别名 · 见 KNOWN_STATUS_TOKENS;SPEC 侧亦用 draft"
12
+ - id: signed
13
+ note: "SPEC 人签 HG-SPEC-SIGNOFF 后 · 可起草 task"
14
+ - id: in_progress
15
+ - id: done
16
+ note: "close 可接受 completed 别名"
17
+ - id: archived
18
+ note: "task close 归档后 · 物理上在 done/ 目录"
19
+
20
+ transitions:
21
+ - id: to_00
22
+ from: ["draft", "signed"]
23
+ to: signed
24
+ hat: "00"
25
+ description: "SPEC 签收后起草 task(verify --spec 聚合 · v2.8+)"
26
+ guards:
27
+ - id: spec_reviews_retention
28
+ command_or_check: "verify --spec · findSpecReview(v2.8+)"
29
+ severity: block
30
+ allow_flag: "--allow-no-spec-review"
31
+ note: "bugfix / skip_spec_audit 元信息豁免 · 不挂 verify --task"
32
+
33
+ - id: to_30
34
+ from: ["draft", "in_progress"]
35
+ to: in_progress
36
+ hat: "30"
37
+ description: "执行帽开工(verify --task 聚合)"
38
+ guards:
39
+ - id: HG-AUDIT-R1
40
+ command_or_check: "gate-check · human_gate HG-AUDIT-R1=approved"
41
+ severity: block
42
+ - id: HG-TASK-DRAFT
43
+ command_or_check: "gate-check · HG-TASK-DRAFT=approved(blocks 22,30)"
44
+ severity: block
45
+ - id: audit_D5
46
+ command_or_check: "verify/audit · test_strategy vs 测试文件存在"
47
+ severity: block
48
+ - id: reviews_retention
49
+ command_or_check: "verify · findReview R<n> 存在性(v2.5+)"
50
+ severity: block
51
+ allow_flag: "--allow-no-review"
52
+ - id: task_lint
53
+ command_or_check: "verify --task · lintTaskFile(v2.7+)"
54
+ severity: warn
55
+ allow_flag: "--allow-lint-fail"
56
+ note: "升 block 前置:active lint FAIL 率下降或另立「仅新流转」SPEC(N2-C)"
57
+
58
+ - id: close
59
+ from: ["done"]
60
+ to: archived
61
+ hat: "close"
62
+ description: "task close · active→done 归档"
63
+ guards:
64
+ - id: close_invoke
65
+ command_or_check: "task close 检查1 · invoke 快照存在"
66
+ severity: block
67
+ - id: close_self_check
68
+ command_or_check: "task close 检查2 · 自检结论已回填"
69
+ severity: block
70
+ - id: close_acceptance
71
+ command_or_check: "task close 检查3 · 验收勾选"
72
+ severity: block
73
+ allow_flag: "--allow-unchecked"
74
+ - id: close_slug
75
+ command_or_check: "task close 检查4 · slug 一致"
76
+ severity: block
77
+ - id: close_status
78
+ command_or_check: "task close 检查5 · 状态 done/completed"
79
+ severity: block
80
+ - id: close_review
81
+ command_or_check: "task close 检查6 · R<n> 审查文(v2.5+)"
82
+ severity: block
83
+ allow_flag: "--allow-no-review"
@@ -17,6 +17,7 @@
17
17
  - 判定:`pass` | `conditional_pass` | `fail` · 建议 **HG-SPEC-SIGNOFF**(**不**代签)
18
18
  - **轻量路径**:10-spec 思考轮已充分时,单轮 R1 即可
19
19
  - 通过 → 建议 00 起草 task;**不**附 30 Prompt
20
+ - **v2.8+ 机械闸**:00 前跑 `npx @cyning/harness verify --spec <SPEC路径> [--workspace-root <Projects>]`——机器只查审查文**存在性**;缺失 exit 2。豁免:`--allow-no-spec-review` · bugfix / `skip_spec_audit`
20
21
 
21
22
  ## 禁止什么
22
23