specline 1.0.0 → 1.1.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 +48 -12
- package/cli.mjs +403 -10
- package/package.json +5 -1
- package/templates/.cursor/agents/specline-backend-dev.md +1 -1
- package/templates/.cursor/agents/specline-code-reviewer.md +1 -1
- package/templates/.cursor/agents/specline-config-dev.md +52 -0
- package/templates/.cursor/agents/specline-config-reviewer.md +79 -0
- package/templates/.cursor/agents/specline-frontend-dev.md +1 -1
- package/templates/.cursor/agents/specline-test-writer.md +1 -1
- package/templates/.cursor/hooks/specline-agent-guard.sh +113 -5
- package/templates/.cursor/hooks/specline-phase-guard.sh +202 -0
- package/templates/.cursor/hooks/specline-pipeline-gate.sh +5 -2
- package/templates/.cursor/hooks/specline-reminder.sh +139 -0
- package/templates/.cursor/hooks/specline-session-start.sh +134 -0
- package/templates/.cursor/hooks.json +22 -1
- package/templates/.cursor/skills/specline-apply-change/SKILL.md +35 -8
- package/templates/.cursor/skills/specline-archive-change/SKILL.md +39 -4
- package/templates/.cursor/skills/specline-explore/SKILL.md +21 -18
- package/templates/.cursor/skills/specline-pipeline/SKILL.md +311 -184
- package/templates/.cursor/skills/specline-propose/SKILL.md +101 -42
|
@@ -7,109 +7,67 @@ description: >-
|
|
|
7
7
|
|
|
8
8
|
# /specline-pipeline 开发流水线编排 Skill
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Layer 1: 速览与定位
|
|
11
13
|
|
|
12
14
|
你是**流水线编排者**,不是执行者。
|
|
13
15
|
|
|
14
16
|
**你做:**
|
|
15
17
|
- 读取 `.pipeline-state.json` 确定当前阶段和恢复点
|
|
16
|
-
- 启动子 Agent
|
|
17
|
-
- 解析 `tasks.md` 构建任务依赖 DAG,按批次并发派发 coding Agent
|
|
18
|
+
- 启动子 Agent,按批次并发派发 coding Agent
|
|
18
19
|
- 显式调用 `specline-pipeline-gate.sh` 进行门禁校验
|
|
19
20
|
- 根据 exit code 决策:前进 / 回退修复 / 暂停等人工确认
|
|
20
|
-
- 写入状态文件(子 Agent 完成后写入 `completed_at`)
|
|
21
21
|
|
|
22
22
|
**你不做:**
|
|
23
|
-
-
|
|
24
|
-
- 代码审查(由 specline-code-reviewer 负责)
|
|
25
|
-
- 门禁判断(由 specline-pipeline-gate.sh 负责,零 LLM 参与)
|
|
26
|
-
- 代码编写(由 coding agents 负责)
|
|
27
|
-
- 测试编写(由 specline-test-writer 负责)
|
|
28
|
-
|
|
29
|
-
## 入口模式
|
|
30
|
-
|
|
31
|
-
1. **新建流水线**: `/specline-pipeline <自然语言需求>`
|
|
32
|
-
2. **恢复流水线**: `/specline-pipeline --change <change-name>`
|
|
33
|
-
3. **自动发现**: `/specline-pipeline`(无参数,列出所有未完成流水线)
|
|
34
|
-
|
|
35
|
-
## 用户交互规范(省 request)
|
|
23
|
+
- 需求判断/Spec 编写、代码编写、代码审查、测试编写、门禁判断——这些都交给子 Agent 和 Gate 脚本
|
|
36
24
|
|
|
37
|
-
|
|
25
|
+
### Phase 流程图
|
|
38
26
|
|
|
39
|
-
使用模式:
|
|
40
|
-
```javascript
|
|
41
|
-
AskUserQuestion({
|
|
42
|
-
title: "简洁标题",
|
|
43
|
-
questions: [{
|
|
44
|
-
id: "unique_id",
|
|
45
|
-
prompt: "问题描述",
|
|
46
|
-
options: [
|
|
47
|
-
{ id: "option_a", label: "选项 A 的描述" },
|
|
48
|
-
{ id: "option_b", label: "选项 B 的描述" }
|
|
49
|
-
],
|
|
50
|
-
allow_multiple: false // 单选;需要多选时设为 true
|
|
51
|
-
}]
|
|
52
|
-
})
|
|
53
27
|
```
|
|
28
|
+
SPEC ──→ CODING ──→ CODE REVIEW ──→ TEST ──→ ARCHIVE
|
|
29
|
+
│G │G │G │G │G
|
|
30
|
+
🟡HG (并行) │G (串行) 🟡HG
|
|
31
|
+
🟡HG
|
|
54
32
|
|
|
55
|
-
|
|
33
|
+
G = Gate(确定性门禁脚本,零 LLM 参与)
|
|
34
|
+
🟡 = Human Gate(人工确认检查点)
|
|
35
|
+
```
|
|
56
36
|
|
|
57
|
-
|
|
37
|
+
### 入口模式
|
|
58
38
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
→ GATE: specline-pipeline-gate.sh spec
|
|
63
|
-
→ 🟡 HUMAN GATE: 人工确认 Spec & 任务规划
|
|
39
|
+
1. **新建流水线**: `/specline-pipeline <自然语言需求>`
|
|
40
|
+
2. **恢复流水线**: `/specline-pipeline --change <change-name>`
|
|
41
|
+
3. **自动发现**: `/specline-pipeline`(无参数,列出所有未完成流水线)
|
|
64
42
|
|
|
65
|
-
|
|
66
|
-
解析 tasks.md → 按依赖层级分批并发派发 coding agents
|
|
67
|
-
→ GATE: specline-pipeline-gate.sh build
|
|
43
|
+
### 最终产出
|
|
68
44
|
|
|
69
|
-
|
|
70
|
-
specline-code-reviewer → code-review.json
|
|
71
|
-
→ GATE: specline-pipeline-gate.sh lint
|
|
72
|
-
→ 🟡 HUMAN GATE: warnings 可选复核
|
|
45
|
+
归档到 `specline/changes/archive/YYYY-MM-DD-<name>/`
|
|
73
46
|
|
|
74
|
-
|
|
75
|
-
单元测试 → GATE → 集成测试 → GATE → E2E → GATE
|
|
76
|
-
(specline-test-writer 为黑盒,不能看实现代码)
|
|
47
|
+
---
|
|
77
48
|
|
|
78
|
-
|
|
79
|
-
→ 🟡 HUMAN GATE: 归档确认
|
|
80
|
-
→ specline-pipeline-gate.sh archive --execute --change <change>
|
|
81
|
-
→ GATE: specline-pipeline-gate.sh archive
|
|
82
|
-
```
|
|
49
|
+
## Layer 2: Happy Path — 新建流水线
|
|
83
50
|
|
|
84
|
-
|
|
51
|
+
### Phase 1: SPEC
|
|
85
52
|
|
|
86
|
-
|
|
53
|
+
#### Step 1: 创建 Change
|
|
87
54
|
|
|
88
55
|
```bash
|
|
89
56
|
specline-pipeline-gate.sh new --change "<kebab-case-name>"
|
|
90
57
|
```
|
|
91
58
|
|
|
92
|
-
初始化 `.pipeline-state.json
|
|
59
|
+
初始化 `.pipeline-state.json`,关键字段:
|
|
93
60
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"current_phase": "spec",
|
|
101
|
-
"current_step": "specline-spec-creator",
|
|
102
|
-
"phases": {
|
|
103
|
-
"spec": { "status": "in_progress", "retry_count": 0, "sub_phases": {}, "gates": { "spec_gate": { "passed": null }, "human_gate_1": { "passed": null } } },
|
|
104
|
-
"coding": { "status": "pending", "tasks": [], "sub_phases": {}, "gates": { "build_gate": { "passed": null } } },
|
|
105
|
-
"code_review": { "status": "pending", "retry_count": 0, "gates": { "lint_gate": { "passed": null }, "human_gate_2": { "passed": null } } },
|
|
106
|
-
"test": { "status": "pending", "framework": null, "sub_phases": { "unit": { "status": "pending", "gates": { "test_unit_gate": { "passed": null } } }, "integration": { "status": "pending", "gates": { "test_integration_gate": { "passed": null } } }, "e2e": { "status": "pending", "gates": { "test_e2e_gate": { "passed": null } } } } },
|
|
107
|
-
"archive": { "status": "pending", "gates": { "human_gate_3": { "passed": null }, "archive_gate": { "passed": null } } }
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
```
|
|
61
|
+
| 字段 | 说明 |
|
|
62
|
+
|------|------|
|
|
63
|
+
| `current_phase` | 当前阶段(spec / coding / code_review / test / archive) |
|
|
64
|
+
| `phases.<phase>.status` | 阶段状态(pending / in_progress / completed) |
|
|
65
|
+
| `phases.<phase>.gates.<gate_name>.passed` | 门禁通过状态(null / true / false) |
|
|
66
|
+
| `phases.coding.tasks[]` | 编码任务列表(含 id / type / deps / batch / status / files) |
|
|
111
67
|
|
|
112
|
-
|
|
68
|
+
> 📋 完整 JSON Schema 见 [附录 A](#附录-a-pipeline-statejson-完整-schema)
|
|
69
|
+
|
|
70
|
+
#### Step 2: 启动 specline-spec-creator
|
|
113
71
|
|
|
114
72
|
specline-spec-creator 子 Agent 的职责是根据内联模板直接生成全部规划文件:
|
|
115
73
|
- `proposal.md` — 需求提案(What/Why/Scope)
|
|
@@ -128,29 +86,30 @@ specline-spec-creator 子 Agent 的职责是根据内联模板直接生成全部
|
|
|
128
86
|
> **注意**:specline-spec-creator 直接按内联模板生成 4 个 Artifact 并自检输出完整性(含并行度 ≥ 60% 和 Files 无冲突自检)。
|
|
129
87
|
|
|
130
88
|
完成后写入状态:
|
|
89
|
+
|
|
131
90
|
```bash
|
|
132
91
|
NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
133
92
|
jq --arg time "$NOW" '.updated_at = $time | .phases.spec.sub_phases["specline-spec-creator"] = {"status": "completed", "completed_at": $time}' "$STATE_FILE" > tmp && mv tmp "$STATE_FILE"
|
|
134
93
|
```
|
|
135
94
|
|
|
136
|
-
|
|
95
|
+
#### Step 3: 审核全部规划文件(specline-spec-reviewer)
|
|
137
96
|
|
|
138
97
|
specline-spec-reviewer 审核三份文件:
|
|
139
98
|
1. `specs/` 下所有 spec.md 的完整性和一致性
|
|
140
|
-
2. `design.md`
|
|
141
|
-
3. `tasks.md`
|
|
99
|
+
2. `design.md` 的技术决策合理性和覆盖完整性
|
|
100
|
+
3. `tasks.md` 的格式、独立性、覆盖度、文件冲突
|
|
142
101
|
|
|
143
102
|
产出 spec-review.json (`{ "status": "approved"|"rejected", "feedback": [...], "coverage": {...}, "task_stats": {...} }`)。
|
|
144
103
|
|
|
145
104
|
若 rejected:将 feedback 反馈给用户修改,或手动编辑相应文件后重新审核(最多 3 次循环)。
|
|
146
105
|
|
|
147
|
-
|
|
106
|
+
#### Step 4: Spec Gate
|
|
148
107
|
|
|
149
108
|
```bash
|
|
150
109
|
.cursor/hooks/specline-pipeline-gate.sh spec --change "<name>"
|
|
151
110
|
```
|
|
152
111
|
|
|
153
|
-
|
|
112
|
+
校验内容:
|
|
154
113
|
- ✓ `proposal.md` 存在
|
|
155
114
|
- ✓ `design.md` 存在
|
|
156
115
|
- ✓ `tasks.md` 存在,且每个任务含 `Type:`、`Depends:`、`Covers:`、`Files:` 标注
|
|
@@ -160,10 +119,31 @@ specline-spec-reviewer 审核三份文件:
|
|
|
160
119
|
|
|
161
120
|
exit code 0 = 通过,写入 passed。exit code != 0 = 失败,读取 stderr 展示给用户。
|
|
162
121
|
|
|
163
|
-
|
|
122
|
+
#### Step 5: 人工确认 (Human Gate 1) 🟡
|
|
164
123
|
|
|
165
124
|
Spec Gate 通过后,使用 `AskUserQuestion` 工具请求确认。展示内容包括:需求提案摘要、功能需求列表、任务拆解概览(含并行组)。
|
|
166
125
|
|
|
126
|
+
> **用户交互规范**:所有需要用户做选择的交互,必须使用 `AskUserQuestion` 工具而非自由文本询问。结构化问题能让 Cursor 在单次请求中完成交互,避免额外轮次。
|
|
127
|
+
|
|
128
|
+
AskUserQuestion 使用模式:
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
AskUserQuestion({
|
|
132
|
+
title: "简洁标题",
|
|
133
|
+
questions: [{
|
|
134
|
+
id: "unique_id",
|
|
135
|
+
prompt: "问题描述",
|
|
136
|
+
options: [
|
|
137
|
+
{ id: "option_a", label: "选项 A 的描述" },
|
|
138
|
+
{ id: "option_b", label: "选项 B 的描述" }
|
|
139
|
+
],
|
|
140
|
+
allow_multiple: false // 单选;需要多选时设为 true
|
|
141
|
+
}]
|
|
142
|
+
})
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Human Gate 1 具体交互:
|
|
146
|
+
|
|
167
147
|
```javascript
|
|
168
148
|
AskUserQuestion({
|
|
169
149
|
title: "确认 Spec 和任务规划",
|
|
@@ -184,11 +164,27 @@ AskUserQuestion({
|
|
|
184
164
|
- `approve` → 写入 `human_gate_1.passed = true`,进入 Phase 2
|
|
185
165
|
- `reject` → 等待用户修改 spec/tasks 文件后,回到 Step 3 重新审核
|
|
186
166
|
|
|
187
|
-
|
|
167
|
+
### Phase 2: CODING
|
|
188
168
|
|
|
189
169
|
> **并行加速**:Human Gate 1 通过后,**同时**启动 coding 和 specline-test-writer。specline-test-writer 是黑盒的——只需要 Spec 文档,不需要实现代码。两者并行可节省 specline-test-writer 的编写时间。
|
|
190
170
|
|
|
191
|
-
|
|
171
|
+
#### Step 6: 并行启动(test-writer + DAG 构建)
|
|
172
|
+
|
|
173
|
+
时序图:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
时间 ────────────────────────────────────────────────────────────────────→
|
|
177
|
+
|
|
178
|
+
Track A (test-writer):
|
|
179
|
+
6a 启动 ───── specline-test-writer(黑盒,与 Coding 并行运行) ──────→ 等待 Step 12
|
|
180
|
+
|
|
181
|
+
Track B (coding):
|
|
182
|
+
6b 解析 tasks.md ──→ 6c 冲突检测 ──→ 7a 派发批次1 ──→ 7b 更新状态 ──→ 7c 派发批次2...
|
|
183
|
+
↓
|
|
184
|
+
Step 8: Build Gate
|
|
185
|
+
|
|
186
|
+
Track A 和 Track B 同时启动,互不阻塞。test-writer 在 Coding 全部完成后、TEST 阶段前被检查(Step 12)。
|
|
187
|
+
```
|
|
192
188
|
|
|
193
189
|
**6a. 启动 specline-test-writer(与 Coding 阶段 Agent 同时启动)**:
|
|
194
190
|
|
|
@@ -211,13 +207,11 @@ Task({
|
|
|
211
207
|
4. 基于 Covers 追溯链,确保每个 Scenario 都有测试
|
|
212
208
|
|
|
213
209
|
## 产出报告
|
|
214
|
-
完成后在
|
|
210
|
+
完成后在 specline/changes/${changeName}/.tmp/test-code-result.json 写入状态(含 test_framework / language / test_dir / scenarios_covered 等字段)
|
|
215
211
|
`
|
|
216
212
|
})
|
|
217
213
|
```
|
|
218
214
|
|
|
219
|
-
specline-test-writer 在 Coding 阶段并行执行,不阻塞 coding agent 的派发。只有当 Coding 全部完成进入 TEST 阶段时,才需要等待 specline-test-writer 完成。
|
|
220
|
-
|
|
221
215
|
**6b. 解析 tasks.md,构建任务 DAG**:
|
|
222
216
|
|
|
223
217
|
读取 `specline/changes/<name>/tasks.md`,解析每个任务的 `Type`、`Depends`、`Covers`、`Files` 标注,构建依赖关系图,划分为多个**并行批次**。
|
|
@@ -247,7 +241,7 @@ jq --argjson tasks '[
|
|
|
247
241
|
- 批次 1:所有 `Depends: (none)` 的任务
|
|
248
242
|
- 批次 N:所有依赖仅限于 1..N-1 批次内已完成任务的任务
|
|
249
243
|
|
|
250
|
-
|
|
244
|
+
**6c. 文件冲突检测(每批次派发前)**:
|
|
251
245
|
|
|
252
246
|
在派发每批任务之前,检查该批次中所有任务的 `Files` 集合是否有交集:
|
|
253
247
|
|
|
@@ -257,12 +251,7 @@ jq --argjson tasks '[
|
|
|
257
251
|
# 如果有任意两个任务的 files 有交集 → 标记冲突任务对,暂停并报告用户
|
|
258
252
|
```
|
|
259
253
|
|
|
260
|
-
|
|
261
|
-
1. 标记冲突的任务为 `status: "conflict"`
|
|
262
|
-
2. 暂停流水线,告知用户哪两个任务的文件范围重叠
|
|
263
|
-
3. 用户可以手动调整 tasks.md 后恢复
|
|
264
|
-
|
|
265
|
-
### Step 7: 按批次并发派发 Coding Agent
|
|
254
|
+
#### Step 7: 按批次并发派发 Coding Agent
|
|
266
255
|
|
|
267
256
|
对每个批次依次处理:
|
|
268
257
|
|
|
@@ -273,22 +262,25 @@ Type: frontend → subagent_type: "specline-frontend-dev"
|
|
|
273
262
|
Type: backend → subagent_type: "specline-backend-dev"
|
|
274
263
|
Type: infra → subagent_type: "specline-backend-dev"(基础设施类,用后端 agent 处理)
|
|
275
264
|
Type: db → subagent_type: "specline-backend-dev"(数据库迁移,用后端 agent 处理)
|
|
276
|
-
Type: config →
|
|
277
|
-
Type: docs →
|
|
265
|
+
Type: config → subagent_type: "specline-config-dev"(shell 脚本、配置文件、JSON/YAML)
|
|
266
|
+
Type: docs → subagent_type: "specline-config-dev"(Markdown 文档、Skill 定义)
|
|
278
267
|
```
|
|
279
268
|
|
|
280
269
|
每个任务启动一个独立的子 Agent:
|
|
281
270
|
|
|
282
271
|
```javascript
|
|
283
272
|
for (const task of currentBatchTasks) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
273
|
+
// 根据 Type 选择对应的 agent 类型
|
|
274
|
+
let agentType;
|
|
275
|
+
switch (task.type) {
|
|
276
|
+
case "frontend": agentType = "specline-frontend-dev"; break;
|
|
277
|
+
case "backend": case "infra": case "db": agentType = "specline-backend-dev"; break;
|
|
278
|
+
case "config": case "docs": agentType = "specline-config-dev"; break;
|
|
279
|
+
default: agentType = "specline-backend-dev";
|
|
288
280
|
}
|
|
289
281
|
|
|
290
282
|
Task({
|
|
291
|
-
subagent_type:
|
|
283
|
+
subagent_type: agentType,
|
|
292
284
|
description: `实现任务 ${task.id}: ${task.title} [${task.type}]`,
|
|
293
285
|
prompt: `
|
|
294
286
|
你收到一个编码任务(Type: ${task.type}),请只实现本任务范围内的代码。
|
|
@@ -313,10 +305,10 @@ ${task.content}
|
|
|
313
305
|
2. 不修改其他任务负责的文件
|
|
314
306
|
3. 与已完成任务的接口约定必须遵守(参考已生成的接口/类型定义文件)
|
|
315
307
|
4. 确认过 design.md 中的技术决策后再动手
|
|
316
|
-
5. **完成后必须将 tasks.md 中本任务的
|
|
308
|
+
5. **完成后必须将 tasks.md 中本任务的 \`[ ]\` 改为 \`[x]\`**(方便断点续跑识别进度)
|
|
317
309
|
|
|
318
310
|
## 产出报告
|
|
319
|
-
完成后在
|
|
311
|
+
完成后在 specline/changes/${changeName}/.tmp/task-${task.id}-result.json 写入:
|
|
320
312
|
{
|
|
321
313
|
"task_id": "${task.id}",
|
|
322
314
|
"type": "${task.type}",
|
|
@@ -331,7 +323,7 @@ ${task.content}
|
|
|
331
323
|
```
|
|
332
324
|
|
|
333
325
|
**7b. 等待当前批次所有 Agent 完成后**:
|
|
334
|
-
1. 验证每个 Agent
|
|
326
|
+
1. 验证每个 Agent 的产出报告(`specline/changes/<name>/.tmp/task-<id>-result.json`)
|
|
335
327
|
2. 更新状态文件中对应 task 的 `status` 和 `completed_at`
|
|
336
328
|
3. **验证 tasks.md 中对应任务的 checkbox 已从 `[ ]` 变为 `[x]`**(如果未标记,自动补标)
|
|
337
329
|
|
|
@@ -350,7 +342,7 @@ sed -i '' "s/^## ${task_id}\. \[ \]/## ${task_id}. [x]/" specline/changes/<name>
|
|
|
350
342
|
|
|
351
343
|
**7c. 检查是否有下一批次**。如有,回到 6c(冲突检测)→ 7a 继续派发。
|
|
352
344
|
|
|
353
|
-
|
|
345
|
+
#### Step 8: Build Gate
|
|
354
346
|
|
|
355
347
|
全部批次完成后,运行 Build Gate:
|
|
356
348
|
|
|
@@ -358,50 +350,25 @@ sed -i '' "s/^## ${task_id}\. \[ \]/## ${task_id}. [x]/" specline/changes/<name>
|
|
|
358
350
|
.cursor/hooks/specline-pipeline-gate.sh build --change "<name>"
|
|
359
351
|
```
|
|
360
352
|
|
|
361
|
-
|
|
353
|
+
exit code 0 = 通过,进入 Phase 3。失败处理见 [Layer 3: Build Gate 失败处理](#build-gate-失败处理)。
|
|
362
354
|
|
|
363
|
-
|
|
355
|
+
### Phase 3: CODE REVIEW
|
|
364
356
|
|
|
365
|
-
|
|
357
|
+
#### Step 9: 启动审查 Agent
|
|
366
358
|
|
|
367
|
-
|
|
368
|
-
# 影响范围分析:基于 tasks.md 的 Depends 关系,计算受影响的下游任务
|
|
369
|
-
# 例如:Task 1 的 API 签名改了 → Task 3 (Depends: 1)、Task 5 (Depends: 1,3) 需要重跑
|
|
370
|
-
# Task 2 无依赖关系 → 不受影响,保持 completed
|
|
359
|
+
根据 tasks.md 中任务类型决定审查方式:
|
|
371
360
|
|
|
372
|
-
|
|
361
|
+
**9a. specline-code-reviewer**(有 frontend/backend/infra/db 类型任务时):
|
|
373
362
|
|
|
374
|
-
|
|
375
|
-
jq --arg tid "$tid" '
|
|
376
|
-
.phases.coding.tasks |= map(
|
|
377
|
-
if .id == $tid then .status = "pending" | .completed_at = null else . end
|
|
378
|
-
)
|
|
379
|
-
' "$STATE_FILE" > tmp && mv tmp "$STATE_FILE"
|
|
380
|
-
done
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
影响范围算法:
|
|
384
|
-
1. 找到被修改的任务 ID 集合 M
|
|
385
|
-
2. 遍历所有任务,如果某任务的 Depends 列表中包含 M 中任一 ID,则加入受影响集合
|
|
386
|
-
3. 递归执行第 2 步直到不再扩展
|
|
387
|
-
|
|
388
|
-
**8c. Build Gate 重置**:
|
|
389
|
-
|
|
390
|
-
```bash
|
|
391
|
-
jq '.phases.coding.gates.build_gate.passed = null' "$STATE_FILE" > tmp && mv tmp "$STATE_FILE"
|
|
392
|
-
```
|
|
363
|
+
审查前端/后端代码变更。审查时利用 tasks.md 的 `Covers` 追溯链:每个 finding 应标注涉及的文件和对应的 Requirement/Scenario。
|
|
393
364
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
## Phase 3: CODE REVIEW 阶段
|
|
365
|
+
**9b. specline-config-reviewer**(有 config/docs 类型任务时):
|
|
397
366
|
|
|
398
|
-
|
|
367
|
+
审查 config/docs 变更——shell 脚本安全性、配置文件语法和一致性、Markdown 文档结构完整性。
|
|
399
368
|
|
|
400
|
-
specline
|
|
369
|
+
> 两种审查 Agent 可并发启动。产出均为 `specline/changes/<name>/.tmp/code-review.json`(`{ "findings": [{ "severity": "error"|"warning", "file": "...", "covers": "Requirement: xxx", "message": "..." }] }`)。
|
|
401
370
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
### Step 10: Lint Gate
|
|
371
|
+
#### Step 10: Lint Gate
|
|
405
372
|
|
|
406
373
|
```bash
|
|
407
374
|
.cursor/hooks/specline-pipeline-gate.sh lint --change "<name>"
|
|
@@ -411,7 +378,7 @@ specline-code-reviewer 审查代码变更。审查时利用 tasks.md 的 `Covers
|
|
|
411
378
|
|
|
412
379
|
失败 → 根据 findings 的 `file` 和 `covers` 字段定位到具体任务,只回对应 coding agent 修复(最多 2 次)。
|
|
413
380
|
|
|
414
|
-
|
|
381
|
+
#### Step 11: 可选人工复核 (Human Gate 2) 🟡
|
|
415
382
|
|
|
416
383
|
仅当 code-review.json 中 warnings > 0 且 errors = 0 时,使用 `AskUserQuestion`:
|
|
417
384
|
|
|
@@ -432,15 +399,17 @@ AskUserQuestion({
|
|
|
432
399
|
- `skip`(默认)→ 自动继续
|
|
433
400
|
- `review` → 展示警告详情,等待人工处理
|
|
434
401
|
|
|
435
|
-
|
|
402
|
+
### Phase 4: TEST
|
|
403
|
+
|
|
404
|
+
> **config/docs 跳过测试**:如果 tasks.md 中所有任务均为 `Type: config` 或 `Type: docs`(无应用代码变更),TEST 阶段自动跳过——test-unit/integration/e2e Gate 在无测试目录时自动放行。流水线直接从 CODE REVIEW 进入 ARCHIVE。
|
|
436
405
|
|
|
437
|
-
|
|
406
|
+
#### Step 12: 确认 specline-test-writer 完成
|
|
438
407
|
|
|
439
408
|
specline-test-writer 已在 Phase 2(Step 6a)与 Coding 并行启动。进入 TEST 阶段时,检查 specline-test-writer 是否已完成:
|
|
440
409
|
|
|
441
|
-
- 已完成 → 读取
|
|
410
|
+
- 已完成 → 读取 `specline/changes/<name>/.tmp/test-code-result.json` 获取 `test_framework`,写入 `.pipeline-state.json`:
|
|
442
411
|
```bash
|
|
443
|
-
FRAMEWORK=$(jq -r '.test_framework'
|
|
412
|
+
FRAMEWORK=$(jq -r '.test_framework' specline/changes/<name>/.tmp/test-code-result.json)
|
|
444
413
|
jq --arg fw "$FRAMEWORK" '.phases.test.framework = $fw' "$STATE_FILE" > tmp && mv tmp "$STATE_FILE"
|
|
445
414
|
```
|
|
446
415
|
然后直接进入测试执行
|
|
@@ -450,7 +419,7 @@ specline-test-writer 已在 Phase 2(Step 6a)与 Coding 并行启动。进入
|
|
|
450
419
|
|
|
451
420
|
> **黑盒约束回顾**:specline-test-writer 只能基于 Spec 文档编写测试,不能读取任何实现源代码。specline-test-writer 会自动检测项目测试框架(Jest/pytest/go test 等),按项目实际语言编写测试。
|
|
452
421
|
|
|
453
|
-
|
|
422
|
+
#### Step 13: 测试门禁链(串行)
|
|
454
423
|
|
|
455
424
|
```bash
|
|
456
425
|
# 单元测试
|
|
@@ -461,24 +430,11 @@ specline-test-writer 已在 Phase 2(Step 6a)与 Coding 并行启动。进入
|
|
|
461
430
|
.cursor/hooks/specline-pipeline-gate.sh test-e2e --change "<name>"
|
|
462
431
|
```
|
|
463
432
|
|
|
464
|
-
|
|
465
|
-
- 测试代码问题 → specline-test-writer 自修(最多 2 次)
|
|
466
|
-
- 实现代码问题 → 利用 `Covers` 追溯链定位到具体任务,只回对应 coding agent 修复 → **使用影响范围算法精确重置受影响任务的 Gate**
|
|
467
|
-
- `spec_ambiguity`(Spec 模糊)→ **不自动循环修复**,暂停流水线并展示模糊点给用户,等待用户澄清 Spec 后继续
|
|
468
|
-
- 循环最多 2 次
|
|
469
|
-
|
|
470
|
-
代码修复后 Gate 重置:
|
|
471
|
-
```bash
|
|
472
|
-
jq '
|
|
473
|
-
.phases.test.sub_phases.unit.gates.test_unit_gate.passed = null |
|
|
474
|
-
.phases.test.sub_phases.integration.gates.test_integration_gate.passed = null |
|
|
475
|
-
.phases.test.sub_phases.e2e.gates.test_e2e_gate.passed = null
|
|
476
|
-
' "$STATE_FILE" > tmp && mv tmp "$STATE_FILE"
|
|
477
|
-
```
|
|
433
|
+
exit code 全 0 = 通过,进入 Phase 5。失败处理见 [Layer 3: 测试失败处理](#测试失败处理)。
|
|
478
434
|
|
|
479
|
-
|
|
435
|
+
### Phase 5: ARCHIVE
|
|
480
436
|
|
|
481
|
-
|
|
437
|
+
#### Step 14: 归档确认 (Human Gate 3) 🟡
|
|
482
438
|
|
|
483
439
|
全部测试通过后,使用 `AskUserQuestion` 请求归档确认:
|
|
484
440
|
|
|
@@ -496,21 +452,128 @@ AskUserQuestion({
|
|
|
496
452
|
})
|
|
497
453
|
```
|
|
498
454
|
|
|
499
|
-
- `archive` →
|
|
455
|
+
- `archive` → 执行归档
|
|
500
456
|
- `cancel` → 暂停流水线,保留状态文件待后续继续
|
|
501
457
|
|
|
502
|
-
|
|
458
|
+
#### Step 15: 归档
|
|
503
459
|
|
|
504
460
|
```bash
|
|
505
461
|
specline-pipeline-gate.sh archive --execute --change "<name>"
|
|
506
462
|
.cursor/hooks/specline-pipeline-gate.sh archive --change "<name>"
|
|
507
463
|
```
|
|
508
464
|
|
|
465
|
+
> 归档的详细逻辑(Delta spec sync 决策、目录移动、摘要展示)由 **specline-archive-change** Skill 负责。编排者只需确认 Human Gate 3 通过后调用上述归档命令。
|
|
466
|
+
|
|
509
467
|
---
|
|
510
468
|
|
|
511
|
-
##
|
|
469
|
+
## Layer 3: 异常与恢复
|
|
470
|
+
|
|
471
|
+
### Build Gate 失败处理
|
|
472
|
+
|
|
473
|
+
⚠️ Build Gate 失败时,分析失败原因并定位到具体任务:
|
|
474
|
+
|
|
475
|
+
**8a. 单个任务构建失败** → 回对应 coding agent 修复(最多 2 次循环)
|
|
476
|
+
|
|
477
|
+
**8b. 接口不兼容** → 计算影响范围,只重置受影响的下游任务:
|
|
512
478
|
|
|
513
|
-
|
|
479
|
+
```bash
|
|
480
|
+
# 影响范围分析:基于 tasks.md 的 Depends 关系,计算受影响的下游任务
|
|
481
|
+
# 例如:Task 1 的 API 签名改了 → Task 3 (Depends: 1)、Task 5 (Depends: 1,3) 需要重跑
|
|
482
|
+
# Task 2 无依赖关系 → 不受影响,保持 completed
|
|
483
|
+
|
|
484
|
+
AFFECTED_TASK_IDS=("3" "5") # 从 DAG 计算得出
|
|
485
|
+
|
|
486
|
+
for tid in "${AFFECTED_TASK_IDS[@]}"; do
|
|
487
|
+
jq --arg tid "$tid" '
|
|
488
|
+
.phases.coding.tasks |= map(
|
|
489
|
+
if .id == $tid then .status = "pending" | .completed_at = null else . end
|
|
490
|
+
)
|
|
491
|
+
' "$STATE_FILE" > tmp && mv tmp "$STATE_FILE"
|
|
492
|
+
done
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
影响范围算法:
|
|
496
|
+
1. 找到被修改的任务 ID 集合 M
|
|
497
|
+
2. 遍历所有任务,如果某任务的 Depends 列表中包含 M 中任一 ID,则加入受影响集合
|
|
498
|
+
3. 递归执行第 2 步直到不再扩展
|
|
499
|
+
|
|
500
|
+
**8c. Build Gate 重置**:
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
jq '.phases.coding.gates.build_gate.passed = null' "$STATE_FILE" > tmp && mv tmp "$STATE_FILE"
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
修复后**只重跑受影响的任务**(按原批次顺序),未受影响的任务保持 completed 状态。
|
|
507
|
+
|
|
508
|
+
### 测试失败处理
|
|
509
|
+
|
|
510
|
+
⚠️ 任何测试失败 → specline-test-runner 分析原因:
|
|
511
|
+
- **测试代码问题** → specline-test-writer 自修(最多 2 次)
|
|
512
|
+
- **实现代码问题** → 利用 `Covers` 追溯链定位到具体任务,只回对应 coding agent 修复 → **使用影响范围算法精确重置受影响任务的 Gate**
|
|
513
|
+
- **`spec_ambiguity`**(Spec 模糊)→ **不自动循环修复**,暂停流水线并展示模糊点给用户,等待用户澄清 Spec 后继续
|
|
514
|
+
- 循环最多 2 次
|
|
515
|
+
|
|
516
|
+
代码修复后 Gate 重置:
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
jq '
|
|
520
|
+
.phases.test.sub_phases.unit.gates.test_unit_gate.passed = null |
|
|
521
|
+
.phases.test.sub_phases.integration.gates.test_integration_gate.passed = null |
|
|
522
|
+
.phases.test.sub_phases.e2e.gates.test_e2e_gate.passed = null
|
|
523
|
+
' "$STATE_FILE" > tmp && mv tmp "$STATE_FILE"
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Hook 阻断处理规范
|
|
527
|
+
|
|
528
|
+
⚠️ 当任何子 Agent 被 `subagentStart` hook 阻止时,**编排者绝对不允许静默降级为自己直接执行**。必须按以下流程处理:
|
|
529
|
+
|
|
530
|
+
**Step 1: 识别阻断原因**
|
|
531
|
+
|
|
532
|
+
根据阻断信息判断原因类型,按优先级诊断:
|
|
533
|
+
|
|
534
|
+
| 原因类型 | 典型症状 | 诊断命令 |
|
|
535
|
+
|---------|---------|---------|
|
|
536
|
+
| 脚本缺少执行权限 | "Permission denied" 或脚本执行失败 | `ls -la .cursor/hooks/specline-agent-guard.sh` |
|
|
537
|
+
| `jq` 未安装 | jq 相关错误 | `which jq` |
|
|
538
|
+
| Agent 名称不在白名单 | "子Agent类型 'xxx' 不在允许列表中" | 检查 `specline-agent-guard.sh` 中 `ALLOWED_AGENTS` 变量 |
|
|
539
|
+
| hooks.json 缺失或不完整 | hook 未触发或配置错误 | 检查 `.cursor/hooks.json` 文件是否存在且内容完整 |
|
|
540
|
+
|
|
541
|
+
**Step 2: 与用户沟通**
|
|
542
|
+
|
|
543
|
+
```javascript
|
|
544
|
+
AskUserQuestion({
|
|
545
|
+
title: "Hook 阻断 - 子 Agent 启动失败",
|
|
546
|
+
questions: [{
|
|
547
|
+
id: "hook_fix",
|
|
548
|
+
prompt: `子 Agent **${agentName}** 被 hook 阻止,诊断结果:
|
|
549
|
+
|
|
550
|
+
**阻断原因**:${diagnosis}
|
|
551
|
+
**影响**:${impact_description}
|
|
552
|
+
|
|
553
|
+
**建议修复操作**:${fix_commands}
|
|
554
|
+
|
|
555
|
+
请选择处理方式:`,
|
|
556
|
+
options: [
|
|
557
|
+
{ id: "auto_fix", label: "自动修复(执行上述修复命令)" },
|
|
558
|
+
{ id: "manual_fix", label: "我手动修复后通知你重试" },
|
|
559
|
+
{ id: "skip_agent", label: "跳过此 Agent,由编排者直接执行(不推荐)" }
|
|
560
|
+
]
|
|
561
|
+
}]
|
|
562
|
+
})
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
**Step 3: 执行修复并重试**
|
|
566
|
+
- `auto_fix` → 执行修复命令(如 `chmod +x .cursor/hooks/*.sh`、安装 `jq` 等),修复完成后立即重试启动子 Agent
|
|
567
|
+
- `manual_fix` → 等待用户确认修复完成,然后重试启动子 Agent
|
|
568
|
+
- `skip_agent` → **仅当用户明确选择时才降级为编排者直接执行**,并必须在事件日志中记录降级原因
|
|
569
|
+
|
|
570
|
+
**Step 4: 验证修复结果** — 修复后重新启动子 Agent,如果仍然被阻止:重新诊断 → 再次沟通(最多循环 2 次)→ 暂停流水线并报告用户,不得自行降级
|
|
571
|
+
|
|
572
|
+
此规范适用于**所有 hook 阻断场景**(`subagentStart`、`beforeShellExecution` 等)。
|
|
573
|
+
|
|
574
|
+
### 断点续跑流程
|
|
575
|
+
|
|
576
|
+
#### 发现未完成流水线
|
|
514
577
|
|
|
515
578
|
扫描 `specline/changes/*/.pipeline-state.json`:
|
|
516
579
|
|
|
@@ -545,13 +608,9 @@ AskUserQuestion({
|
|
|
545
608
|
})
|
|
546
609
|
```
|
|
547
610
|
|
|
548
|
-
|
|
549
|
-
- 指定 change → 加载状态文件,计算恢复点
|
|
550
|
-
- 无需再询问"是否继续",直接展示恢复摘要并自动开始恢复
|
|
611
|
+
#### 恢复算法
|
|
551
612
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
从后往前扫描 `phases` 中每个阶段的 `gates`,找到最后一个 `passed: true` 且 `run_at` 有值的门禁:
|
|
613
|
+
从后往前扫描 `phases` 中每个阶段的 `gates`,找到最后一个 `passed: true` 的门禁:
|
|
555
614
|
|
|
556
615
|
```bash
|
|
557
616
|
RESTORE_POINT="spec" # 默认从 spec 开始
|
|
@@ -573,7 +632,7 @@ for phase in archive test code_review coding spec; do
|
|
|
573
632
|
done
|
|
574
633
|
```
|
|
575
634
|
|
|
576
|
-
|
|
635
|
+
#### 重置不可信子阶段
|
|
577
636
|
|
|
578
637
|
```bash
|
|
579
638
|
# 将恢复阶段中 completed_at 为空的子阶段重置为 pending
|
|
@@ -588,7 +647,7 @@ jq --arg phase "$RESTORE_POINT" '
|
|
|
588
647
|
' "$STATE_FILE" > tmp && mv tmp "$STATE_FILE"
|
|
589
648
|
```
|
|
590
649
|
|
|
591
|
-
|
|
650
|
+
#### 从 tasks.md 恢复已完成任务状态
|
|
592
651
|
|
|
593
652
|
恢复到 CODING 阶段时,必须先读取 tasks.md 的 checkbox 状态,与 `.pipeline-state.json` 交叉校验:
|
|
594
653
|
|
|
@@ -609,7 +668,7 @@ done
|
|
|
609
668
|
|
|
610
669
|
这个交叉校验确保:即使 `.pipeline-state.json` 丢失或损坏,tasks.md 的 `[x]`/`[ ]` 标记仍可作为任务进度的可靠来源。
|
|
611
670
|
|
|
612
|
-
|
|
671
|
+
#### 展示恢复摘要
|
|
613
672
|
|
|
614
673
|
计算恢复点后,**直接开始恢复,不需要再次人工确认**(用户选择 pipeline 时已确认意图)。
|
|
615
674
|
|
|
@@ -629,7 +688,35 @@ AskUserQuestion({
|
|
|
629
688
|
})
|
|
630
689
|
```
|
|
631
690
|
|
|
632
|
-
|
|
691
|
+
---
|
|
692
|
+
|
|
693
|
+
## Layer 4: 附录
|
|
694
|
+
|
|
695
|
+
> ℹ️ 初次阅读可跳过 — 以下为完整参考信息,首次阅读可略过
|
|
696
|
+
|
|
697
|
+
### 附录 A: .pipeline-state.json 完整 Schema
|
|
698
|
+
|
|
699
|
+
```json
|
|
700
|
+
{
|
|
701
|
+
"version": 1,
|
|
702
|
+
"change_name": "<name>",
|
|
703
|
+
"created_at": "<ISO8601>",
|
|
704
|
+
"updated_at": "<ISO8601>",
|
|
705
|
+
"current_phase": "spec",
|
|
706
|
+
"current_step": "specline-spec-creator",
|
|
707
|
+
"phases": {
|
|
708
|
+
"spec": { "status": "in_progress", "retry_count": 0, "sub_phases": {}, "gates": { "spec_gate": { "passed": null }, "human_gate_1": { "passed": null } } },
|
|
709
|
+
"coding": { "status": "pending", "tasks": [], "sub_phases": {}, "gates": { "build_gate": { "passed": null } } },
|
|
710
|
+
"code_review": { "status": "pending", "retry_count": 0, "gates": { "lint_gate": { "passed": null }, "human_gate_2": { "passed": null } } },
|
|
711
|
+
"test": { "status": "pending", "framework": null, "sub_phases": { "unit": { "status": "pending", "gates": { "test_unit_gate": { "passed": null } } }, "integration": { "status": "pending", "gates": { "test_integration_gate": { "passed": null } } }, "e2e": { "status": "pending", "gates": { "test_e2e_gate": { "passed": null } } } } },
|
|
712
|
+
"archive": { "status": "pending", "gates": { "human_gate_3": { "passed": null }, "archive_gate": { "passed": null } } }
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### 附录 B: 状态写入规则
|
|
718
|
+
|
|
719
|
+
> ℹ️ 初次阅读可跳过
|
|
633
720
|
|
|
634
721
|
所有状态写入由 Gate 脚本或 Skill 编排逻辑完成,**不使用 LLM 写入状态**:
|
|
635
722
|
|
|
@@ -637,11 +724,11 @@ AskUserQuestion({
|
|
|
637
724
|
- 子 Agent 完成后 Skill 写入 `completed_at`
|
|
638
725
|
- 代码修复后 Skill 重置相关 gates 为 null
|
|
639
726
|
|
|
640
|
-
|
|
727
|
+
### 附录 C: 结构化事件日志
|
|
641
728
|
|
|
642
|
-
|
|
729
|
+
> ℹ️ 初次阅读可跳过
|
|
643
730
|
|
|
644
|
-
|
|
731
|
+
每个关键事件追加写入 `specline/changes/<name>/pipeline-events.jsonl`(JSON Lines 格式,每行一个事件):
|
|
645
732
|
|
|
646
733
|
```json
|
|
647
734
|
{"ts":"...","event":"pipeline_start","change":"<name>"}
|
|
@@ -665,10 +752,50 @@ AskUserQuestion({
|
|
|
665
752
|
- Gate 脚本不写事件日志(Gate 是无状态的),仅编排层写入
|
|
666
753
|
- 事件日志用于人工排查问题和统计分析,不影响流水线决策
|
|
667
754
|
|
|
668
|
-
|
|
755
|
+
### 附录 D: Hook 约束体系
|
|
756
|
+
|
|
757
|
+
> ℹ️ 初次阅读可跳过
|
|
758
|
+
|
|
759
|
+
Specline 通过 Cursor Hooks 提供了三层自动约束,确保在长对话中 Agent 不偏离流水线逻辑:
|
|
760
|
+
|
|
761
|
+
```
|
|
762
|
+
sessionStart → specline-session-start.sh
|
|
763
|
+
新会话启动时检测活跃 pipeline,自动注入阶段上下文到 Agent 系统提示
|
|
764
|
+
|
|
765
|
+
preToolUse → specline-phase-guard.sh
|
|
766
|
+
操作前检查:SPEC 阶段拦截代码编辑、阶段不匹配的子Agent 启动
|
|
767
|
+
|
|
768
|
+
postToolUse → specline-reminder.sh
|
|
769
|
+
关键操作后注入提醒:更新 tasks.md checkbox、运行 Gate 脚本
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
#### 对你(编排者)的影响
|
|
773
|
+
|
|
774
|
+
1. **总是先检查** - preToolUse 会阻止不匹配当前阶段的操作,所以你在行动前自然会考虑阶段
|
|
775
|
+
2. **被提醒下一步** - postToolUse 在子Agent完成后提醒你更新 checkbox 和运行 Gate
|
|
776
|
+
3. **非流水线会话无影响** - 所有 Hook 的第一步检查「是否有活跃 pipeline」,无则透明放行
|
|
777
|
+
|
|
778
|
+
#### 约束策略
|
|
779
|
+
|
|
780
|
+
| 场景 | 策略 | 原因 |
|
|
781
|
+
|------|------|------|
|
|
782
|
+
| SPEC 阶段编辑代码文件 | **硬拦截 (deny)** | 明确违规 |
|
|
783
|
+
| SPEC 阶段启动编码 Agent | **硬拦截 (deny)** | 阶段不匹配 |
|
|
784
|
+
| CODING 阶段直接编辑代码 | **软提醒 (postToolUse)** | Hook 无法区分编排者和子Agent的 Write |
|
|
785
|
+
| 子Agent完成后忘记 Gate | **软提醒 (postToolUse)** | 操作后注入下一步提醒 |
|
|
786
|
+
|
|
787
|
+
> 注意:CODING 阶段 Orchestrator 直接编辑代码文件不会被 Hook 硬拦截(因为子Agent 也需要 Write 权限),但 SKILL 指令和 sessionStart 注入的上下文会持续提醒你「编码应通过子 Agent」。如果你发现自己想直接编辑代码,停一下,改用 Task 工具。
|
|
788
|
+
|
|
789
|
+
### 附录 E: 关键约束速查表
|
|
790
|
+
|
|
791
|
+
> ℹ️ 初次阅读可跳过
|
|
669
792
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
793
|
+
| # | 约束 | 说明 |
|
|
794
|
+
|---|------|------|
|
|
795
|
+
| 1 | **不做判断,只做编排** | 不评估代码质量、需求好坏、测试覆盖——这些由子 Agent 和 Gate 脚本负责 |
|
|
796
|
+
| 2 | **所有门禁通过 Gate 脚本** | 调用 `specline-pipeline-gate.sh`,不要自己写 grep/检查逻辑 |
|
|
797
|
+
| 3 | **状态文件是唯一真相源** | 所有决策基于 `.pipeline-state.json` 的当前值 |
|
|
798
|
+
| 4 | **人工确认点必须暂停** | 不要自动跳过 human_gate |
|
|
799
|
+
| 5 | **测试 Agent 必须黑盒** | 不给 specline-test-writer 传递源代码文件路径 |
|
|
800
|
+
| 6 | **Hook 阻断绝不静默降级** | 子 Agent 被 hook 阻止时,必须先诊断、沟通、修复后重试 |
|
|
801
|
+
| 7 | **接受 Hook 约束** | preToolUse/postToolUse/sessionStart Hook 会自动校验和提醒,不要试图绕过 |
|