sillyspec 3.23.9 → 3.24.1
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/.claude/skills/sillyspec-brainstorm/SKILL.md +1 -1
- package/.claude/skills/sillyspec-quick/SKILL.md +1 -0
- package/package.json +1 -1
- package/src/quicklog.js +333 -306
- package/src/run.js +61 -5
- package/src/stage-contract.js +44 -0
- package/src/stages/brainstorm.js +569 -657
- package/src/stages/execute.js +3 -4
- package/src/stages/plan-postcheck.js +5 -1
- package/src/stages/plan.js +3 -3
- package/src/stages/propose.js +1 -1
- package/src/stages/quick.js +29 -18
- package/src/stages/verify.js +4 -82
- package/src/worktree.js +16 -0
- package/templates/prompts/verify-probes.md +53 -0
package/src/stages/execute.js
CHANGED
|
@@ -171,8 +171,7 @@ const fixedPrefix = [
|
|
|
171
171
|
### 输出
|
|
172
172
|
worktree 路径 + 分支名 + 模式
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
sillyspec run execute --done --output "worktree 路径 + 分支名 + 模式"`,
|
|
174
|
+
"`,
|
|
176
175
|
outputHint: 'worktree 路径 + 分支名 + 模式',
|
|
177
176
|
optional: false
|
|
178
177
|
},
|
|
@@ -218,7 +217,7 @@ const acceptanceSteps = [
|
|
|
218
217
|
### 执行方式(CLI 按变更规模判定,占位符由 run.js 注入)
|
|
219
218
|
tier: {REVIEW_TIER}({REVIEW_TIER_REASON})
|
|
220
219
|
- tier=self:当前 agent 汇总执行(对照 design.md 逐项检查 + 偏差说明)
|
|
221
|
-
- tier=independent:必须用 Agent tool 启动一个独立的 QA 子代理(独立上下文,不共享实现者的分析),子代理对照 design.md 逐项检查实现一致性并输出 review.json 到 {SPEC_ROOT}/.runtime/stage-reviews/execute-{STAGE_REVIEW_RUN_ID}/review.json。字段:reviewType=acceptance;reviewedFiles=[changes/<change>/design.md] + git diff 涉及的源码文件;docHash=design.md 的 sha256
|
|
220
|
+
- tier=independent:必须用 Agent tool 启动一个独立的 QA 子代理(独立上下文,不共享实现者的分析),子代理对照 design.md 逐项检查实现一致性并输出 review.json 到 {SPEC_ROOT}/.runtime/stage-reviews/execute-{STAGE_REVIEW_RUN_ID}/review.json。字段:reviewType=acceptance;reviewedFiles=[changes/<change>/design.md] + git diff 涉及的源码文件;docHash=design.md 的 sha256;specVerdict/qualityVerdict=pass|fail|cannot_verify;checklist 按每个设计要点给 pass|gap|fail。该 acceptance review 同时覆盖"代码审查"视角(风格/bug/安全/冗余),后续代码审查步骤仅需轻量复审。
|
|
222
221
|
|
|
223
222
|
### 操作
|
|
224
223
|
1. 读取 design.md(技术方案)
|
|
@@ -644,7 +643,7 @@ task-XX 对应:{SPEC_ROOT}/.runtime/execute-runs/{EXECUTE_RUN_ID}/tasks/task-X
|
|
|
644
643
|
- 在变更文件中搜索所有 router 注册路径(@router.get/post/put/delete)
|
|
645
644
|
- 将端点清单写入 {SPEC_ROOT}/.runtime/contract-artifacts/<task-name>/endpoints.json
|
|
646
645
|
- 格式: { "task": "task-XX", "type": "backend_endpoints", "endpoints": [{ "method": "GET", "path": "/api/ppm/xxx" }] }
|
|
647
|
-
|
|
646
|
+
"`
|
|
648
647
|
}
|
|
649
648
|
|
|
650
649
|
/**
|
|
@@ -9,7 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 这些都是 noAI 步骤,不需要 LLM 参与。
|
|
11
11
|
*/
|
|
12
|
-
import { existsSync, readFileSync, readdirSync } from 'fs'
|
|
12
|
+
import { existsSync, readFileSync as _readFileSync, readdirSync } from 'fs'
|
|
13
|
+
// 归一化行尾为 LF:Windows 下 python/编辑器文本模式写 .md 会产生 CRLF,致本模块多处
|
|
14
|
+
// frontmatter/字段正则(`^---\n`、`allowed_paths:\s*\n…`、`^goal:` 等)失配,报「缺 frontmatter
|
|
15
|
+
// /缺字段」假错误(见缺陷 windows-python-crlf-taskcard)。读取时统一转 LF,一处覆盖全部正则。
|
|
16
|
+
const readFileSync = (filePath, encoding) => _readFileSync(filePath, encoding).replace(/\r\n/g, '\n')
|
|
13
17
|
import { join as pJoin } from 'path'
|
|
14
18
|
import jsYaml from 'js-yaml'
|
|
15
19
|
import { parseFileChangeList, pathMatches } from '../change-list.js'
|
package/src/stages/plan.js
CHANGED
|
@@ -94,7 +94,7 @@ const stepClassify = {
|
|
|
94
94
|
- 如果发现 superseded 决策,只引用最新版本,不引用旧版本
|
|
95
95
|
5. 读取 CONVENTIONS.md、ARCHITECTURE.md、STACK.md
|
|
96
96
|
6. 读取 local.yaml 获取构建/测试命令
|
|
97
|
-
7. 读取
|
|
97
|
+
7. 读取 \`{SPEC_ROOT}/docs/<project>/modules/_module-map.yaml\`(不存在则跳过)
|
|
98
98
|
- 根据 design.md 的文件变更清单匹配模块
|
|
99
99
|
- 读取匹配到的模块文档
|
|
100
100
|
- 利用模块依赖关系辅助分析(depends_on / used_by)
|
|
@@ -314,7 +314,7 @@ full 计划的约束:
|
|
|
314
314
|
2. 读取 design.md 获取文件变更清单
|
|
315
315
|
3. 读取上一步的 plan_level 分类结果
|
|
316
316
|
4. 按对应级别模板生成内容
|
|
317
|
-
5. 保存到变更目录下的 plan.md
|
|
317
|
+
5. 保存到变更目录下的 plan.md(路径格式:\`{SPEC_ROOT}/changes/<change-name>/plan.md\`,其中 <change-name> 是变更目录名,直接使用,不加子目录。正确路径示例:\`{SPEC_ROOT}/changes/2026-05-28-agent-log-streaming/plan.md\`)
|
|
318
318
|
**plan_level 为 none 时生成最小 plan.md(占位),不生成完整蓝图。**
|
|
319
319
|
|
|
320
320
|
---
|
|
@@ -362,7 +362,7 @@ tier: {REVIEW_TIER}({REVIEW_TIER_REASON})
|
|
|
362
362
|
- reviewType: plan ; stage: plan
|
|
363
363
|
- specVerdict / qualityVerdict: pass | fail | cannot_verify
|
|
364
364
|
- reviewedFiles: [changes/<change>/plan.md]
|
|
365
|
-
- docHash: plan.md 内容的 sha256
|
|
365
|
+
- docHash: plan.md 内容的 sha256
|
|
366
366
|
- checklist: 每条 { item, result: pass|gap|fail, note }
|
|
367
367
|
- requiredEvidence: cannot_verify 时必填非空
|
|
368
368
|
- reviewerNotes: 说明
|
package/src/stages/propose.js
CHANGED
|
@@ -143,7 +143,7 @@ export const definition = {
|
|
|
143
143
|
### 当前审查分级(CLI 按变更规模判定,占位符由 run.js 注入)
|
|
144
144
|
tier: {REVIEW_TIER}({REVIEW_TIER_REASON})
|
|
145
145
|
- tier=self:当前 agent 直接执行下方 checklist
|
|
146
|
-
- tier=independent:必须用 Agent tool 启动一个独立的规范审查子代理(独立上下文,不共享你的分析),子代理执行下方 checklist 并输出 review.json 到 {SPEC_ROOT}/.runtime/stage-reviews/propose-{STAGE_REVIEW_RUN_ID}/review.json。字段:reviewType=proposal;reviewedFiles=[proposal.md, design.md, requirements.md, tasks.md](相对 changes/<change>/);docHash=proposal.md 的 sha256
|
|
146
|
+
- tier=independent:必须用 Agent tool 启动一个独立的规范审查子代理(独立上下文,不共享你的分析),子代理执行下方 checklist 并输出 review.json 到 {SPEC_ROOT}/.runtime/stage-reviews/propose-{STAGE_REVIEW_RUN_ID}/review.json。字段:reviewType=proposal;reviewedFiles=[proposal.md, design.md, requirements.md, tasks.md](相对 changes/<change>/);docHash=proposal.md 的 sha256;specVerdict/qualityVerdict=pass|fail|cannot_verify;checklist 每条 pass|gap|fail。
|
|
147
147
|
|
|
148
148
|
### 操作
|
|
149
149
|
检查以下各项:
|
package/src/stages/quick.js
CHANGED
|
@@ -8,11 +8,9 @@ export const definition = {
|
|
|
8
8
|
name: '理解任务',
|
|
9
9
|
prompt: `解析任务参数,加载项目上下文。
|
|
10
10
|
|
|
11
|
-
### 📌 本 quick 会话 sessionId:
|
|
12
|
-
- CLI 是短进程,run 与 done 是独立进程,sessionId 靠
|
|
13
|
-
- **完成每个 step
|
|
14
|
-
- 多会话并发时**必须带 \`--change <quick-session-id>\`**,否则可能命中他者会话的状态
|
|
15
|
-
- 不带 \`--change\` 时 fallback 读 \`current-quick-run-id\`(单会话兼容;多会话不可靠)
|
|
11
|
+
### 📌 本 quick 会话 sessionId: <quick-session-id>
|
|
12
|
+
- CLI 是短进程,run 与 done 是独立进程,sessionId 靠 --change 跨进程传递
|
|
13
|
+
- **完成每个 step 必须带 --change <quick-session-id>**(命令由 CLI 在下方注入);多会话并发时不带会命中他者会话状态(不带时 fallback 读 current-quick-run-id,单会话兼容;多会话不可靠)
|
|
16
14
|
|
|
17
15
|
### 操作
|
|
18
16
|
1. 检查关联变更(\`<linked-changes>\`,逗号分隔的变更名列表;显示「(无)」= 不关联变更),确定记录方式
|
|
@@ -28,13 +26,13 @@ export const definition = {
|
|
|
28
26
|
9. 根据任务描述初步判断可能涉及的模块
|
|
29
27
|
10. 读取匹配到的 \`{SPEC_ROOT}/docs/<project>/modules/<module>.md\`
|
|
30
28
|
|
|
31
|
-
### QUICKLOG 记录(CLI 已接管,无需你手动创建)
|
|
32
|
-
本 quick 会话的 ql-ID 由 CLI 在启动时分配,已注入为 \`<quicklog-id>\`。CLI 同时已自动:
|
|
33
|
-
- 在 \`{SPEC_ROOT}/quicklog/QUICKLOG-<git-user>.md\` 写入「进行中」条目(含关联变更与预估文件)
|
|
34
|
-
- 对每个关联变更 \`<c>\`:在 \`{SPEC_ROOT}/changes/<c>/tasks.md\` 追加未勾选 task \`- [ ] <quicklog-id> <任务描述>\`
|
|
35
|
-
|
|
36
|
-
**你不要创建或修改任何 QUICKLOG / tasks.md 记录**——完成本任务时 CLI 会自动将条目翻为「已完成」并勾选 task(含轮转)。\`<quicklog-id>\` 可用于 design.md / plan.md / archive / 模块变更索引引用。
|
|
37
|
-
|
|
29
|
+
### QUICKLOG 记录(CLI 已接管,无需你手动创建)
|
|
30
|
+
本 quick 会话的 ql-ID 由 CLI 在启动时分配,已注入为 \`<quicklog-id>\`。CLI 同时已自动:
|
|
31
|
+
- 在 \`{SPEC_ROOT}/quicklog/QUICKLOG-<git-user>.md\` 写入「进行中」条目(含关联变更与预估文件)
|
|
32
|
+
- 对每个关联变更 \`<c>\`:在 \`{SPEC_ROOT}/changes/<c>/tasks.md\` 追加未勾选 task \`- [ ] <quicklog-id> <任务描述>\`
|
|
33
|
+
|
|
34
|
+
**你不要创建或修改任何 QUICKLOG / tasks.md 记录**——完成本任务时 CLI 会自动将条目翻为「已完成」并勾选 task(含轮转)。\`<quicklog-id>\` 可用于 design.md / plan.md / archive / 模块变更索引引用。
|
|
35
|
+
|
|
38
36
|
### 输出
|
|
39
37
|
任务理解 + 上下文摘要`,
|
|
40
38
|
outputHint: '任务理解',
|
|
@@ -42,8 +40,11 @@ export const definition = {
|
|
|
42
40
|
},
|
|
43
41
|
{
|
|
44
42
|
name: '实现并验证',
|
|
45
|
-
prompt: `直接在主工作区实现任务。
|
|
46
|
-
|
|
43
|
+
prompt: `直接在主工作区实现任务。
|
|
44
|
+
|
|
45
|
+
### 边界声明(quick 不校验 design.md)
|
|
46
|
+
关联变更的 design.md 仅供理解意图,**不作为验收基准**——quick 不 enforce design 一致性。需要 design 一致性保证 → 走完整流程(plan + verify)。发现 design 本身有错时,可 Reverse Sync 回写(见下方铁律)。
|
|
47
|
+
|
|
47
48
|
### 操作
|
|
48
49
|
1. 先读后写:调用已有方法前 \`cat\` 源文件确认签名,\`grep\` 确认方法存在
|
|
49
50
|
2. 写代码完成任务
|
|
@@ -64,10 +65,20 @@ export const definition = {
|
|
|
64
65
|
name: '暂存和更新记录',
|
|
65
66
|
prompt: `Git 暂存并更新任务记录。
|
|
66
67
|
|
|
67
|
-
### 📌 收尾确认
|
|
68
|
-
- 本步骤是最后一步,完成后 quick
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
### 📌 收尾确认
|
|
69
|
+
- 本步骤是最后一步,完成后 quick 会话即结束(--change 传递见首步 sessionId 说明)
|
|
70
|
+
|
|
71
|
+
### ⚠️ 结果摘要模板(必填,CLI 会校验结构)
|
|
72
|
+
\`--output\` 是 QUICKLOG「结果:」归档的唯一来源,**必须按此结构给全四项**(逐项一句话,不可用「见前述」替代):
|
|
73
|
+
|
|
74
|
+
\`\`\`
|
|
75
|
+
需求:用户/任务要什么
|
|
76
|
+
根因:为什么这样改(若纯新增/配置/样式无根因,写「无,纯新增/纯样式」)
|
|
77
|
+
方案:怎么改的
|
|
78
|
+
结果:验证情况(测试数 / lint / typecheck / 部署状态)
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
缺任一项,\`--done\` 会被拒并提示缺失字段,补全后重跑即可(不丢进度)。
|
|
71
82
|
|
|
72
83
|
### 操作
|
|
73
84
|
1. 查看 \`git status --porcelain\`,确认只包含本次 quick 相关文件
|
package/src/stages/verify.js
CHANGED
|
@@ -100,10 +100,7 @@ export const definition = {
|
|
|
100
100
|
### 输出
|
|
101
101
|
任务完成度列表 + 完成率
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
- **绝对禁止** git checkout/restore/reset 或删除/覆盖任何文件
|
|
105
|
-
- 发现文件缺失只报告,不尝试恢复
|
|
106
|
-
- verify 阶段的唯一职责是「检查 + 报告」,不是「修复」`,
|
|
103
|
+
`,
|
|
107
104
|
outputHint: '任务完成度报告',
|
|
108
105
|
optional: false
|
|
109
106
|
},
|
|
@@ -111,61 +108,7 @@ export const definition = {
|
|
|
111
108
|
name: '对照设计检查',
|
|
112
109
|
prompt: `先运行自动探针,再对照 design.md 检查实现一致性。**design.md 是唯一 truth source,不符合 design.md 的实现 = Bug。**
|
|
113
110
|
|
|
114
|
-
|
|
115
|
-
在检查前,依次运行以下三个探针,将结果作为验证输入:
|
|
116
|
-
|
|
117
|
-
**探针 1:未实现标记扫描(仅变更文件)**
|
|
118
|
-
只扫描本次变更涉及的文件,不要全项目扫描——历史 TODO 与本次变更无关,徒增噪音与 token。变更文件 = design.md「文件变更清单」列出的源码文件(你已在「加载规范」步骤读取 design.md,glob 路径需展开为具体文件):
|
|
119
|
-
\`\`\`bash
|
|
120
|
-
grep -n "尚未实现\|TODO\|FIXME\|HACK\|XXX" <design 清单中的源码文件>
|
|
121
|
-
\`\`\`
|
|
122
|
-
记录每个匹配的文件、行号和内容。
|
|
123
|
-
|
|
124
|
-
**探针 2:设计关键词覆盖探针**
|
|
125
|
-
1. 读取 design.md,从中提取所有能力关键词(如"登录"、"导出"、"批量"、"删除"、"搜索"等动作词)
|
|
126
|
-
2. 对每个关键词,在源码目录中 grep 确认是否有对应的实现代码:
|
|
127
|
-
\`\`\`bash
|
|
128
|
-
grep -rl "<关键词>" <源码目录>/ --include="*.java" --include="*.js" --include="*.ts" --include="*.jsx" --include="*.tsx" --include="*.py"
|
|
129
|
-
\`\`\`
|
|
130
|
-
3. 如果某个关键词在源码中完全没有匹配,标记为 ⚠️ 可能未实现
|
|
131
|
-
|
|
132
|
-
**探针 3:验收标准测试覆盖探针**
|
|
133
|
-
1. 读取变更目录下的 tasks.md,提取所有 checkbox 任务
|
|
134
|
-
2. 对每个 task,检查对应模块目录下是否存在测试文件(*test*、*spec*、*Test*、*Spec*)
|
|
135
|
-
3. 没有测试文件的 task 标记为 ⚠️ 缺少测试
|
|
136
|
-
|
|
137
|
-
**探针 4:决策追踪覆盖探针(如存在 decisions.md)**
|
|
138
|
-
1. 从 decisions.md 提取所有当前版本 D-xxx@vN
|
|
139
|
-
2. 检查 requirements.md 是否引用每个 D-xxx@vN,并映射到 FR-xxx
|
|
140
|
-
3. 检查 plan.md 或 tasks/task-NN.md 是否引用每个 FR-xxx/D-xxx@vN
|
|
141
|
-
4. 检查本步骤收集的实现证据是否能回指到对应 D-xxx@vN/FR-xxx
|
|
142
|
-
5. 任意 D-xxx@vN 无下游覆盖时标记为 ⚠️ 决策未闭环
|
|
143
|
-
6. 任意 P0/P1 unresolved/blocking 决策标记为 FAIL blocker
|
|
144
|
-
|
|
145
|
-
**探针 5:API Contract Parity Check(跨前后端契约对账)**
|
|
146
|
-
此探针仅在以下条件满足时执行:
|
|
147
|
-
- 存在 \.sillyspec/.runtime/contract-artifacts/ 目录(说明 execute 阶段生成了 endpoint artifact)
|
|
148
|
-
- 或者项目同时有 backend/ 和 frontend/ 目录
|
|
149
|
-
|
|
150
|
-
执行步骤:
|
|
151
|
-
1. 收集所有 provider endpoint artifacts:
|
|
152
|
-
- 读取 .sillyspec/.runtime/contract-artifacts/*/endpoints.json
|
|
153
|
-
- 汇总为 backend 端点清单
|
|
154
|
-
2. 扫描前端 API 调用:
|
|
155
|
-
- 在 frontend/ 目录中搜索 apiFetch/request/axios/fetch 调用
|
|
156
|
-
- 提取所有 API 路径(归一化动态参数为 {param})
|
|
157
|
-
3. Diff 对账:
|
|
158
|
-
- 前端调用路径在 backend 端点清单中找不到 → **❌ Missing backend endpoint**(FAIL blocker)
|
|
159
|
-
- backend 端点在前端无调用 → ⚠️ Unused backend endpoint(warning,不阻断)
|
|
160
|
-
4. 输出对账结果表格:
|
|
161
|
-
\
|
|
162
|
-
\
|
|
163
|
-
| 状态 | 前端调用 | 后端端点 | 文件 |
|
|
164
|
-
|---|---|---|---|
|
|
165
|
-
| ❌ missing | GET /api/ppm/project-plan/{param}/plan-nodes | — | frontend/src/lib/ppm/plan.ts |
|
|
166
|
-
\
|
|
167
|
-
\
|
|
168
|
-
如果发现 Missing backend endpoint,必须在验证报告中标记为 ❌ contract gap。
|
|
111
|
+
{{include: verify-probes}}
|
|
169
112
|
|
|
170
113
|
### 探针结果处理
|
|
171
114
|
- 将四个探针的结果汇总为「探针报告」
|
|
@@ -236,29 +179,8 @@ grep -rl "<关键词>" <源码目录>/ --include="*.java" --include="*.js" --inc
|
|
|
236
179
|
|
|
237
180
|
### 操作
|
|
238
181
|
1. 汇总以上所有检查结果
|
|
239
|
-
2.
|
|
240
|
-
|
|
241
|
-
### 变更风险分级规则
|
|
242
|
-
扫描 design.md 和 plan.md 的关键词,自动判定 verify 强度:
|
|
243
|
-
|
|
244
|
-
| 触发条件 | verify 要求 |
|
|
245
|
-
|---|---|
|
|
246
|
-
| 只改文案/文档 | 静态检查即可 |
|
|
247
|
-
| 单模块纯函数 | 单测即可 |
|
|
248
|
-
| API contract / DTO / client | 单测 + contract test |
|
|
249
|
-
| daemon/backend 跨进程 | **必须真实集成** |
|
|
250
|
-
| session/lease/run 状态机 | **必须生命周期端到端验证** |
|
|
251
|
-
| 部署启动路径 | **必须真实启动一次** |
|
|
252
|
-
|
|
253
|
-
触发关键词:daemon, backend, session, lease, agent_run, lifecycle, state_transition, claim, heartbeat, cross-process, cli.ts, main.ts, server.ts, bootstrap, entrypoint
|
|
254
|
-
|
|
255
|
-
### 风险门控规则
|
|
256
|
-
- **integration-critical** 或 **deployment-critical** 变更:
|
|
257
|
-
- 结论为 PASS WITH NOTES → **降级为 FAIL**
|
|
258
|
-
- mock 单测通过但没有真实集成证据 → **FAIL**
|
|
259
|
-
- 必须在 verify-result.md 中包含 **Runtime Evidence** section
|
|
260
|
-
- **contract-required** 变更:需要 contract test 证据
|
|
261
|
-
- **unit-sufficient** 变更:单测即可
|
|
182
|
+
2. **变更风险等级(change_risk_profile)由 CLI 自动判定与门控**:你无需自己扫描关键词。本步骤 --done 时,CLI 会用 detectChangeRisk 扫描 design.md / plan.md 自动判定等级(doc-only / unit-sufficient / contract-required / integration-critical / deployment-critical)并强制门控:integration-critical / deployment-critical 变更若结论为 PASS / PASS WITH NOTES 但缺少真实集成证据,CLI 直接阻断 verify 完成——谎报结论无效。
|
|
183
|
+
你只需:在 verify-result.md 的「变更风险等级」section 如实记录变更性质;若变更涉及 daemon/backend 跨进程、session/lease/lifecycle 状态机、或部署启动路径,在「Runtime Evidence」section 提供真实集成证据(启动命令、daemon↔backend 调用与日志关键片段、终态断言)。
|
|
262
184
|
|
|
263
185
|
3. 生成 verify-result.md 文件,保存到 \`.sillyspec/changes/<change-name>/verify-result.md\`
|
|
264
186
|
4. 给出结论:PASS / PASS WITH NOTES / FAIL(受风险门控约束)
|
package/src/worktree.js
CHANGED
|
@@ -362,6 +362,14 @@ export class WorktreeManager {
|
|
|
362
362
|
mkdirSync(this.worktreeBase, { recursive: true });
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
+
// 4.5 Windows 长路径支持:archive/ 下嵌套的 .runtime/artifacts 超长文件名(>260 字符)
|
|
366
|
+
// 会让 worktree add 的 checkout 报 "Filename too long" 失败 → 降级 in-place 且主工作区
|
|
367
|
+
// 未切分支,直接写代码污染 main(见缺陷 execute-in-place-windows-pitfalls 坑1)。
|
|
368
|
+
// core.longpaths=true 让 git 用 \\?\ 前缀绕过 MAX_PATH,幂等、Windows 推荐、低风险,失败不阻断。
|
|
369
|
+
if (process.platform === 'win32') {
|
|
370
|
+
try { gitQuiet(this.cwd, 'config core.longpaths true'); } catch {}
|
|
371
|
+
}
|
|
372
|
+
|
|
365
373
|
// 5. 创建 worktree(含版本检测 + sandbox fallback)
|
|
366
374
|
try {
|
|
367
375
|
git(this.cwd, `worktree add ${worktreePath} -b ${branch} ${baseHash}`);
|
|
@@ -1085,6 +1093,14 @@ export class WorktreeManager {
|
|
|
1085
1093
|
|
|
1086
1094
|
if (files.length > 0) {
|
|
1087
1095
|
console.log(`📁 baseline overlay: ${files.length} 个未提交文件已同步到 worktree`);
|
|
1096
|
+
// 非阻断 advisory(治「已做完没提交」被裹进 execute 交付):这批未提交改动会单独 commit
|
|
1097
|
+
// 成 baseline checkpoint(git 历史与本阶段新改动分层,可分开验收),但 apply 回 main 时会
|
|
1098
|
+
// 随本阶段交付落地。若它们是独立变更、需要独立验收,先提交到独立分支另行处理——
|
|
1099
|
+
// 注意不能在 main 直接 commit(那等于无验收并入主干、污染 main,正是坑1 形态)。
|
|
1100
|
+
// sillyspec 只做确定性提示(改动是事实),该不该拆分属意图判定,留给 agent/用户。
|
|
1101
|
+
console.log(` ℹ️ 它们将作为独立 baseline checkpoint 提交到 worktree 分支(与本阶段新改动分层、可分开验收),`);
|
|
1102
|
+
console.log(` 但 apply 回 main 会随本阶段交付。若是独立变更、需独立验收:先提交到独立分支另行处理`);
|
|
1103
|
+
console.log(` (不要在 main 直接 commit——那等于无验收并入主干、污染 main),再回到本变更跑 execute。`);
|
|
1088
1104
|
}
|
|
1089
1105
|
} catch (e) {
|
|
1090
1106
|
errors.push(`unexpected: ${e.message}`);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
### 自动探针(必须先执行)
|
|
2
|
+
在检查前,依次运行以下三个探针,将结果作为验证输入:
|
|
3
|
+
|
|
4
|
+
**探针 1:未实现标记扫描(仅变更文件)**
|
|
5
|
+
只扫描本次变更涉及的文件,不要全项目扫描——历史 TODO 与本次变更无关,徒增噪音与 token。变更文件 = design.md「文件变更清单」列出的源码文件(你已在「加载规范」步骤读取 design.md,glob 路径需展开为具体文件):
|
|
6
|
+
```bash
|
|
7
|
+
grep -n "尚未实现\|TODO\|FIXME\|HACK\|XXX" <design 清单中的源码文件>
|
|
8
|
+
```
|
|
9
|
+
记录每个匹配的文件、行号和内容。
|
|
10
|
+
|
|
11
|
+
**探针 2:设计关键词覆盖探针**
|
|
12
|
+
1. 读取 design.md,从中提取所有能力关键词(如"登录"、"导出"、"批量"、"删除"、"搜索"等动作词)
|
|
13
|
+
2. 对每个关键词,在源码目录中 grep 确认是否有对应的实现代码:
|
|
14
|
+
```bash
|
|
15
|
+
grep -rl "<关键词>" <源码目录>/ --include="*.java" --include="*.js" --include="*.ts" --include="*.jsx" --include="*.tsx" --include="*.py"
|
|
16
|
+
```
|
|
17
|
+
3. 如果某个关键词在源码中完全没有匹配,标记为 ⚠️ 可能未实现
|
|
18
|
+
|
|
19
|
+
**探针 3:验收标准测试覆盖探针**
|
|
20
|
+
1. 读取变更目录下的 tasks.md,提取所有 checkbox 任务
|
|
21
|
+
2. 对每个 task,检查对应模块目录下是否存在测试文件(*test*、*spec*、*Test*、*Spec*)
|
|
22
|
+
3. 没有测试文件的 task 标记为 ⚠️ 缺少测试
|
|
23
|
+
|
|
24
|
+
**探针 4:决策追踪覆盖探针(如存在 decisions.md)**
|
|
25
|
+
1. 从 decisions.md 提取所有当前版本 D-xxx@vN
|
|
26
|
+
2. 检查 requirements.md 是否引用每个 D-xxx@vN,并映射到 FR-xxx
|
|
27
|
+
3. 检查 plan.md 或 tasks/task-NN.md 是否引用每个 FR-xxx/D-xxx@vN
|
|
28
|
+
4. 检查本步骤收集的实现证据是否能回指到对应 D-xxx@vN/FR-xxx
|
|
29
|
+
5. 任意 D-xxx@vN 无下游覆盖时标记为 ⚠️ 决策未闭环
|
|
30
|
+
6. 任意 P0/P1 unresolved/blocking 决策标记为 FAIL blocker
|
|
31
|
+
|
|
32
|
+
**探针 5:API Contract Parity Check(跨前后端契约对账)**
|
|
33
|
+
此探针仅在以下条件满足时执行:
|
|
34
|
+
- 存在 \.sillyspec/.runtime/contract-artifacts/ 目录(说明 execute 阶段生成了 endpoint artifact)
|
|
35
|
+
- 或者项目同时有 backend/ 和 frontend/ 目录
|
|
36
|
+
|
|
37
|
+
执行步骤:
|
|
38
|
+
1. 收集所有 provider endpoint artifacts:
|
|
39
|
+
- 读取 .sillyspec/.runtime/contract-artifacts/*/endpoints.json
|
|
40
|
+
- 汇总为 backend 端点清单
|
|
41
|
+
2. 扫描前端 API 调用:
|
|
42
|
+
- 在 frontend/ 目录中搜索 apiFetch/request/axios/fetch 调用
|
|
43
|
+
- 提取所有 API 路径(归一化动态参数为 {param})
|
|
44
|
+
3. Diff 对账:
|
|
45
|
+
- 前端调用路径在 backend 端点清单中找不到 → **❌ Missing backend endpoint**(FAIL blocker)
|
|
46
|
+
- backend 端点在前端无调用 → ⚠️ Unused backend endpoint(warning,不阻断)
|
|
47
|
+
4. 输出对账结果表格:
|
|
48
|
+
|
|
49
|
+
| 状态 | 前端调用 | 后端端点 | 文件 |
|
|
50
|
+
|---|---|---|---|
|
|
51
|
+
| ❌ missing | GET /api/ppm/project-plan/{param}/plan-nodes | — | frontend/src/lib/ppm/plan.ts |
|
|
52
|
+
|
|
53
|
+
如果发现 Missing backend endpoint,必须在验证报告中标记为 ❌ contract gap。
|