sillyspec 3.25.9 → 3.26.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/.claude/skills/sillyspec-auto/SKILL.md +8 -13
- package/.claude/skills/sillyspec-brainstorm/SKILL.md +8 -6
- package/.claude/skills/sillyspec-continue/SKILL.md +3 -3
- package/.claude/skills/sillyspec-doctor/SKILL.md +1 -1
- package/.claude/skills/sillyspec-execute/SKILL.md +10 -4
- package/.claude/skills/sillyspec-plan/SKILL.md +1 -1
- package/.claude/skills/sillyspec-quick/SKILL.md +3 -1
- package/.claude/skills/sillyspec-verify/SKILL.md +1 -1
- package/.sillyspec-platform-cleaned +1 -0
- package/.sillyspec-platform.json +7 -0
- package/README.md +9 -0
- package/package.json +2 -2
- package/src/change-list.js +11 -8
- package/src/change-risk-profile.js +22 -0
- package/src/db.js +170 -161
- package/src/dispatch/backends/local-agent.js +152 -0
- package/src/dispatch/backends/sillyhub-mcp.js +242 -0
- package/src/dispatch/probe.js +210 -0
- package/src/dispatch/strategy.js +121 -0
- package/src/doctor-diagnostics.js +19 -25
- package/src/fs-atomic.js +69 -69
- package/src/git-helper.js +66 -0
- package/src/hooks/worktree-guard.js +64 -55
- package/src/index.js +326 -36
- package/src/init.js +7 -14
- package/src/local-detect.js +120 -110
- package/src/machine-interface.js +54 -19
- package/src/migrate.js +14 -4
- package/src/modules.js +16 -5
- package/src/progress/change-registry.js +85 -70
- package/src/progress/consistency-doctor.js +71 -14
- package/src/progress/shared.js +8 -5
- package/src/progress/stage-machine.js +67 -65
- package/src/progress/step-store.js +72 -67
- package/src/progress.js +448 -236
- package/src/quicklog.js +59 -12
- package/src/run/command.js +78 -39
- package/src/run/complete-handlers.js +1028 -889
- package/src/run/complete.js +132 -212
- package/src/run/concurrent-detect.js +132 -0
- package/src/run/gates.js +302 -19
- package/src/run/prompt.js +22 -68
- package/src/run/quick-audit.js +10 -9
- package/src/run/shared.js +722 -600
- package/src/run/stage.js +43 -24
- package/src/scan-postcheck.js +9 -31
- package/src/sillyhub-mcp/client.js +394 -0
- package/src/sillyhub-mcp/config.js +62 -0
- package/src/spec-dir-typo.js +71 -0
- package/src/stage-contract-engine.js +22 -1
- package/src/stage-contract-spec.js +11 -4
- package/src/stage-contract.js +26 -3
- package/src/stage-review.js +118 -10
- package/src/stages/archive.js +4 -6
- package/src/stages/brainstorm-auto.js +26 -20
- package/src/stages/brainstorm.js +29 -5
- package/src/stages/cmd-existence.js +145 -0
- package/src/stages/doctor.js +10 -7
- package/src/stages/execute.js +64 -22
- package/src/stages/plan-postcheck.js +152 -0
- package/src/stages/plan.js +16 -31
- package/src/stages/quick.js +25 -9
- package/src/stages/scan.js +53 -8
- package/src/stages/status.js +0 -1
- package/src/stages/verify.js +14 -9
- package/src/sync.js +433 -16
- package/src/task-review.js +59 -1
- package/src/verify-postcheck.js +938 -862
- package/src/version.js +19 -0
- package/src/worktree-apply.js +218 -93
- package/src/worktree-deps.js +89 -5
- package/src/worktree.js +213 -111
- package/templates/prompts/taskcard-rules.md +27 -0
- package/templates/prompts/verify-probes.md +3 -3
- package/.claude/skills/sillyspec-propose/SKILL.md +0 -87
- package/src/stages/propose.js +0 -181
package/src/stages/plan.js
CHANGED
|
@@ -198,7 +198,7 @@ light 计划的约束:
|
|
|
198
198
|
- **禁止**泛泛风险分析(如"需要充分测试")
|
|
199
199
|
- **禁止**放实现细节(函数签名、代码示例)
|
|
200
200
|
- 来源/目标直接引用已有文档,不重新生成
|
|
201
|
-
- 如果存在 decisions.md,所有当前版本 D-xxx@vN 必须在 Tasks
|
|
201
|
+
- 如果存在 decisions.md,所有当前版本 D-xxx@vN 必须在 Tasks 或覆盖矩阵中出现(CLI 只校验 D-xxx@vN ID 字面出现在 plan.md,warning 不阻断;矩阵结构供人类追溯,CLI 不校验 D→FR→task 映射完整性)
|
|
202
202
|
- 如果存在 P0/P1 unresolved blocker,不生成 plan.md
|
|
203
203
|
- 任务列表控制在 10 条以内
|
|
204
204
|
- **任务必须使用 checkbox 格式**(\`- [ ] task-XX:\`),不要用纯编号列表(\`1. 2.\`),execute 阶段依赖此格式解析任务
|
|
@@ -256,7 +256,7 @@ full 计划的约束:
|
|
|
256
256
|
- Mermaid 依赖关系图**仅当依赖关系非平凡时生成**(线性依赖或全并行时不生成)
|
|
257
257
|
- **Wave 下的 checkbox 行必须保留**(execute 阶段解析依赖 \`- [ ] task-XX:\` 格式)
|
|
258
258
|
- plan.md 包含 Wave 分组 + 任务总表 + 关键路径 + 全局验收标准,**不放实现细节**
|
|
259
|
-
- 如果存在 decisions.md,plan.md
|
|
259
|
+
- 如果存在 decisions.md,plan.md 建议包含当前版本 D-xxx@vN/FR-xxx 覆盖矩阵(CLI 只校验 D-xxx@vN/FR-xxx ID 字面出现在 plan.md,warning 不阻断;矩阵的 D→FR→task 映射完整性供人类追溯,CLI 不校验——勿以为画了矩阵就被结构校验)
|
|
260
260
|
- 如果存在 P0/P1 unresolved blocker,不生成 plan.md,输出阻塞清单
|
|
261
261
|
- 实现细节写到后续的 tasks/task-NN.md 中
|
|
262
262
|
- 每个任务编号格式:task-01、task-02 ...
|
|
@@ -308,8 +308,17 @@ plan_level + 计划内容(审查在下一步独立进行)`,
|
|
|
308
308
|
const stepReviewPlan = {
|
|
309
309
|
id: 'review_plan',
|
|
310
310
|
name: '审查计划',
|
|
311
|
+
conditionalWait: true,
|
|
312
|
+
waitReason: '等待用户确认计划后进入执行',
|
|
313
|
+
waitOptions: ['确认,进入执行', '需要调整'],
|
|
311
314
|
prompt: `对上一步生成的 plan.md 做审查。生成与审查分离——不在生成 plan 的同一上下文里自审,避免确认偏差。
|
|
312
315
|
|
|
316
|
+
### 执行前确认门(plan_level=full 时)
|
|
317
|
+
plan.md 审查通过后、进入 execute 前,若 plan_level=full(跨模块/大变更),必须先向用户展示计划摘要并等待确认,不要让 AI 默认共识擅自开工:
|
|
318
|
+
- 展示:Wave 分组 + task 总数 + 关键 allowed_paths 边界 + 依赖说明(一两屏内,不贴全文)
|
|
319
|
+
- 调用:\`sillyspec run plan --wait --reason "等待用户确认计划" --options "确认,进入执行,需要调整" --output "计划摘要"\`
|
|
320
|
+
- 用户确认后再 --done;plan_level=none/light(小变更)无需等待,正常完成即可
|
|
321
|
+
|
|
313
322
|
### 当前审查分级(CLI 按变更规模判定,占位符由 run.js 注入)
|
|
314
323
|
tier: {REVIEW_TIER}({REVIEW_TIER_REASON})
|
|
315
324
|
- tier=self:当前 agent 直接执行下方审查清单(小变更,独立审查仪式成本 > 收益)
|
|
@@ -323,7 +332,8 @@ tier: {REVIEW_TIER}({REVIEW_TIER_REASON})
|
|
|
323
332
|
- [ ] 不存在 P0/P1 unresolved blocker 残留
|
|
324
333
|
- [ ] 没有实现细节泄漏到 plan.md(接口签名/代码示例应在 tasks/task-NN.md)
|
|
325
334
|
- [ ] 关键路径与 Wave 依赖合理(无循环依赖、无遗漏前置)
|
|
326
|
-
- [ ]
|
|
335
|
+
- [ ] 连带测试归属:本批改动是否会导致既有测试断言失效(改共享/被多 task 依赖源文件、改被测试精确匹配的值如 UI 文案/按钮文本/错误信息/常量/枚举字面量、改函数签名或返回结构等单文件场景)?此类 task 是否在 related_tests 声明了失效测试、且路径在 allowed_paths 内(或由独立测试 task 覆盖)?(漏声明 = execute 阶段测试债、主代理事后兜底)
|
|
336
|
+
- [ ] acceptance 字段对照实际 schema/类型源文件核验存在性与形态,不凭 design.md 文字臆断(plan-postcheck best-effort grep 会给 allowed_paths 源文件未命中的 snake_case/camelCase 标识符提 warning,此处是语义层复查;臆断 = execute 阶段返工)
|
|
327
337
|
|
|
328
338
|
### tier=independent 时:启动 plan-review 子代理
|
|
329
339
|
用 Agent tool 启动子代理(subagent_type: general),prompt 要点:
|
|
@@ -403,37 +413,12 @@ verify:
|
|
|
403
413
|
constraints:
|
|
404
414
|
- 边界约束 1(如:不加测试)
|
|
405
415
|
- 边界约束 2(如:不修改传入参数)
|
|
406
|
-
related_tests: #
|
|
416
|
+
related_tests: # 可选。当本 task 改动会导致既有测试断言失效时填(共享源文件/UI文案/常量/签名变更等,判据=测试是否失败非文件是否共享)
|
|
407
417
|
- path: frontend/src/lib/errors.test.ts # 因本次改动断言失效的既有测试文件
|
|
408
418
|
reason: 旧断言假设单例,改归属键后需同步
|
|
409
419
|
---
|
|
410
420
|
|
|
411
|
-
|
|
412
|
-
- 总长度 20~40 行,不要写成长文档
|
|
413
|
-
- frontmatter 只含必要字段,不加 estimated_hours
|
|
414
|
-
- goal: 一句话,用 > 多行字符串
|
|
415
|
-
- implementation: 列表,每条一个具体步骤
|
|
416
|
-
- acceptance: 列表,每条可独立验证(不是表格)
|
|
417
|
-
- verify: 列表,实际可执行的命令
|
|
418
|
-
- constraints: 列表,明确边界(含 brownfield 兼容、异常处理)
|
|
419
|
-
- 不需要:修改文件章节、覆盖来源章节、接口定义章节、TDD 步骤章节、参考章节
|
|
420
|
-
- frontmatter 必须以三减号结尾闭合(开头和结尾各一行 ---)。缺结尾会让 postcheck 提取不到 frontmatter,误报「字段缺失 / allowed_paths 为空」
|
|
421
|
-
- allowed_paths 用块式写法(键名换行后每项一行「 - 路径」),不要用流式方括号 [path]——块式与所有校验器一致最稳
|
|
422
|
-
- implementation / acceptance / constraints / verify 的每条列表项是 YAML plain scalar,避免以下特殊字符触发 ScannerError:
|
|
423
|
-
- 冒号+空格(如代码签名 provider_id:str、queryUsage(id:string))会被当映射键报 mapping values are not allowed here——去掉冒号后空格或改成中文描述
|
|
424
|
-
- 花括号且内部含冒号或引号(如 JS 对象、JS 模板字面量)会报 expected block end——改用不含这些字符的中文描述
|
|
425
|
-
- 引号不成对会报扫描错误
|
|
426
|
-
- 注:goal 用 > 折叠标量可容忍花括号,goal 里写占位符不炸;只有上述 plain scalar 列表项需注意
|
|
427
|
-
- provides / expects_from 是可选字段:仅当跨 task 契约(一个 task 的接口/DTO/响应被另一个 task 消费)时才填,单 task 或无对外接口场景留空即可
|
|
428
|
-
- 填写后 plan-postcheck 会做硬对账:consumer 的每个 expects_from[provider].needs 字段必须在对应 provider 的 provides.fields 里,否则 plan 阶段阻断(不进入 execute)
|
|
429
|
-
- 不要把内部实现字段塞进 provides;只暴露给其他 task 的对外契约形状
|
|
430
|
-
- related_tests 是可选字段:仅当本 task 改共享源文件(被既有测试引用、或被多 task 依赖)时填,列出会因本次改动断言失效的既有测试文件 + 为何失效。关键:这些测试路径必须同时写进本 task 的 allowed_paths(否则子代理被 allowed_paths 铁律锁死、改不了测试 → 退化成主代理事后兜底);若测试由独立的测试 task 负责,则在该测试 task 的 allowed_paths 覆盖、本字段留空
|
|
431
|
-
- 如果存在 decisions.md,无法覆盖的 D-xxx@vN 在 constraints 中标注
|
|
432
|
-
- **保存前格式自检**(plan-postcheck 会硬校验,不通过到 Step 4 会批量报错,先在这里逐条自查):
|
|
433
|
-
- frontmatter 字段齐全:id、title、title_zh、author、created_at、priority、depends_on、blocks、allowed_paths、goal、implementation、acceptance、verify、constraints
|
|
434
|
-
- allowed_paths 非空(至少一个真实源文件路径;回归类 task 无源码改动时填被验证的关键入口文件)
|
|
435
|
-
- acceptance 与 verify 都在 frontmatter 内(漏写会被 plan-postcheck 报「缺少验收标准」/「缺少验证步骤」)
|
|
436
|
-
- 写完后用 Write tool 保存到文件
|
|
421
|
+
{{include: taskcard-rules}}
|
|
437
422
|
\`\`\``
|
|
438
423
|
}).join('\n\n')
|
|
439
424
|
|
|
@@ -470,7 +455,7 @@ ${subagentPrompts}
|
|
|
470
455
|
- allowed_paths 有无冲突
|
|
471
456
|
- depends_on 与 plan.md Wave 分组是否一致
|
|
472
457
|
- provides/expects_from 契约自洽:每个 expects_from[provider].needs 字段都在该 provider task 的 provides.fields 里(plan-postcheck 会硬校验,这里提前自查)
|
|
473
|
-
- related_tests
|
|
458
|
+
- related_tests 判据 = 是否有既有测试因本次改动而失败(非「源文件是否共享」;UI 文案/常量/签名变更等单文件场景也算);若填,测试路径必须都在本 task 或某 task 的 allowed_paths 内(否则子代理无权改 → execute 测试债、主代理事后兜底)
|
|
474
459
|
- 如发现矛盾,列出问题清单,不要自动修复`
|
|
475
460
|
|
|
476
461
|
return {
|
package/src/stages/quick.js
CHANGED
|
@@ -10,7 +10,7 @@ export const definition = {
|
|
|
10
10
|
|
|
11
11
|
### 📌 本 quick 会话 sessionId: <quick-session-id>
|
|
12
12
|
- CLI 是短进程,run 与 done 是独立进程,sessionId 靠 --change 跨进程传递
|
|
13
|
-
- **完成每个 step 必须带 --change <quick-session-id>**(命令由 CLI
|
|
13
|
+
- **完成每个 step 必须带 --change <quick-session-id>**(命令由 CLI 在下方注入);多会话并发时不带会命中他者会话状态
|
|
14
14
|
|
|
15
15
|
### 操作
|
|
16
16
|
1. 检查关联变更(\`<linked-changes>\`,逗号分隔的变更名列表;显示「(无)」= 不关联变更),确定记录方式
|
|
@@ -33,7 +33,7 @@ export const definition = {
|
|
|
33
33
|
|
|
34
34
|
**你不要创建或修改任何 QUICKLOG 的条目骨架 / tasks.md 记录**——ql-ID 分配、「进行中」条目、状态翻转、task 勾选、轮转全由 CLI 接管,你无需手写。<quicklog-id> 可用于 design.md / plan.md / archive / 模块变更索引引用。
|
|
35
35
|
|
|
36
|
-
>
|
|
36
|
+
> ℹ️ step 3 --done 时,CLI 已落盘结构化 QUICKLOG 条目(标题从「需求:」提取、正文四字段分行、文件行可用 --file-notes 写多行括注)。事后只需按需核对,详见 step 3「QUICKLOG 正文核对」。
|
|
37
37
|
|
|
38
38
|
### 输出
|
|
39
39
|
任务理解 + 上下文摘要`,
|
|
@@ -82,12 +82,26 @@ export const definition = {
|
|
|
82
82
|
|
|
83
83
|
缺任一项,\`--done\` 会被拒并提示缺失字段,补全后重跑即可(不丢进度)。
|
|
84
84
|
|
|
85
|
+
### 📎 文件括注 --file-notes(可选,省事后手改文件行)
|
|
86
|
+
若希望 QUICKLOG「文件:」行直接落盘为多行带括注(而非单行逗号路径),\`--done\` 时加 \`--file-notes\`,CLI 落盘为多行 \`- path(括注)\`,免去事后手改:
|
|
87
|
+
|
|
88
|
+
\`\`\`
|
|
89
|
+
sillyspec run quick --done --change <id> --output "需求:… 根因:… 方案:… 结果:…" --file-notes "src/a.js::登录端点串限流 || src/b.js::新建 INCR 计数"
|
|
90
|
+
\`\`\`
|
|
91
|
+
|
|
92
|
+
格式:\`path::括注\` 一条,\`||\` 分隔多条(括注可省略只留 \`path\`)。不传则「文件:」行回填审计到的实际改动文件单行(仍可事后手改)。
|
|
93
|
+
|
|
94
|
+
### 收尾推荐顺序(模块文档在 --done 前,QUICKLOG 在 --done 后,别记混)
|
|
95
|
+
1. 【--done 前】命中模块 → 改模块文档 → \`git add -- <模块文档>\`(见下方「模块文档同步」)
|
|
96
|
+
2. 【--done】\`sillyspec run quick --done --change <id> --output "四字段" [--file-notes "..."]\`(CLI 自动翻完成 + 勾 task + 落盘 QUICKLOG 标题/文件/正文)
|
|
97
|
+
3. 【--done 后】核对 QUICKLOG 标题(CLI 已从「需求:」自动提取,仅弱标题才手改)→ 若改了再 \`git add\`
|
|
98
|
+
|
|
85
99
|
### 操作
|
|
86
100
|
1. 查看 \`git status --porcelain\`,确认只包含本次 quick 相关文件
|
|
87
101
|
2. 使用 \`git add -- <file...>\` 暂存本次 quick 实际修改的文件(不要 commit,由用户通过统一提交工具处理)
|
|
88
102
|
- 禁止使用 \`git add -A\`
|
|
89
103
|
- 不要暂存 quick 开始前就已存在的无关改动
|
|
90
|
-
3. QUICKLOG / tasks.md 记录由 CLI 在本 step 完成时自动收尾(翻「已完成」+ 勾选 task +
|
|
104
|
+
3. QUICKLOG / tasks.md 记录由 CLI 在本 step 完成时自动收尾(翻「已完成」+ 勾选 task + 轮转),你无需手动建/翻骨架——**QUICKLOG 核对按需**(见下方「QUICKLOG 正文核对」;文件行可用 --file-notes 免手改)
|
|
91
105
|
4. 如果发现项目特有的坑,追加到 \`{SPEC_ROOT}/knowledge/uncategorized.md\`
|
|
92
106
|
5. 任务比预期复杂 → 建议用完整流程
|
|
93
107
|
|
|
@@ -105,17 +119,19 @@ export const definition = {
|
|
|
105
119
|
### 输出
|
|
106
120
|
暂存确认 + 记录路径 + 模块文档同步结果(如有)
|
|
107
121
|
|
|
108
|
-
### 📝 QUICKLOG
|
|
109
|
-
|
|
122
|
+
### 📝 QUICKLOG 正文核对(--done 之后,按需;多数无需手改)
|
|
123
|
+
CLI 落盘的条目已是结构化产物(非简版骨架):标题从「需求:」自动提取、正文四字段自动分行、文件行用 --file-notes 时为多行括注。--done 后只需核对,多数情况无需手改:
|
|
124
|
+
|
|
125
|
+
1. 标题:CLI 已从「需求:」提取摘要刷新标题;仅当需求写得太弱(占位/笼统)才手改为真实需求摘要。
|
|
126
|
+
2. 文件:用了 --file-notes 已是多行括注;没传则回填审计到的实际文件单行,可事后补括注(示例见下)。
|
|
127
|
+
3. 正文:四字段已分行落盘,按需扩写充实(不允许只留一段「结果:」)。
|
|
110
128
|
|
|
111
|
-
|
|
112
|
-
2. 文件:把 CLI 写的单行「文件:a.js, b.js」改写为多行 bullet,每个文件带关键改动括注;禁止「(见实际改动)」或无括注纯路径单行。示例:
|
|
129
|
+
补括注示例(仅当没用 --file-notes、想事后补时):
|
|
113
130
|
文件:
|
|
114
131
|
- backend/app/modules/auth/router.py(登录端点串 check_rate_limit→assert_captcha_if_needed)
|
|
115
132
|
- backend/app/modules/auth/captcha_service.py(新建:限流 INCR + 失败计数 + Pillow 滑块生成/校验)
|
|
116
|
-
3. 正文:核对 需求: 根因: 方案: 结果: 四段逐项充实(--output 已写、CLI 原样插入,按需扩写),不允许只留一段「结果:」。
|
|
117
133
|
|
|
118
|
-
一条 quick = 一条独立 ql
|
|
134
|
+
一条 quick = 一条独立 ql 条目;核对只动本次 <quicklog-id> 条目,不追加到旧条目。QUICKLOG 在 .sillyspec/(gitignore),核对不影响 --done 已通过的边界审计。`,
|
|
119
135
|
outputHint: '暂存和记录确认',
|
|
120
136
|
optional: false
|
|
121
137
|
}
|
package/src/stages/scan.js
CHANGED
|
@@ -38,6 +38,9 @@ export const definition = {
|
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
name: '构建扫描项目列表',
|
|
41
|
+
conditionalWait: true,
|
|
42
|
+
waitReason: '等待用户确认扫描项目列表',
|
|
43
|
+
waitOptions: ['全部重新扫描', '只补缺失', '跳过'],
|
|
41
44
|
prompt: `确定本次要扫描的项目列表。
|
|
42
45
|
|
|
43
46
|
### 操作
|
|
@@ -139,7 +142,7 @@ export const definition = {
|
|
|
139
142
|
对每个项目分别执行(将 \`<project>\` 替换为实际项目名)
|
|
140
143
|
4. 如果检查报告有失败项,按报告中的角色和文件重试失败的部分
|
|
141
144
|
|
|
142
|
-
### 覆盖保护
|
|
145
|
+
### 覆盖保护
|
|
143
146
|
- **scan_depth: quick 的浅层文档允许覆盖升级**:读取旧 frontmatter 时,若旧文档含 scan_depth: quick(由 --quick 快速接入生成的浅层版本),即使其 source_commit 与当前 HEAD 一致、updated_at 未变,也允许覆盖重写——深度扫描的目的就是把它升级为完整文档。
|
|
144
147
|
- 生成每份 scan 文档时,frontmatter 必须包含:
|
|
145
148
|
\`\`\`yaml
|
|
@@ -188,24 +191,63 @@ export const definition = {
|
|
|
188
191
|
2. 调用 \`sillyspec local detect\` 命令生成 local.yaml(该命令封装了纯 fs 项目类型嗅探:package.json→nodejs / pom.xml→maven / build.gradle→gradle / Makefile→make / 否则 generic,对应默认 commands)。**不要自行嗅探 package.json/pom.xml/build.gradle 等文件**——探测逻辑唯一归属 local-detect.js,本步骤只负责调用命令并报告结果。
|
|
189
192
|
3. 该命令内部已处理:确保目录存在(mkdir -p)、已存在则跳过、原子写入(先写 tmp 再 rename)。
|
|
190
193
|
4. 报告生成的 project.type 与 local.yaml 路径。
|
|
191
|
-
|
|
192
|
-
|
|
194
|
+
5. **detect 只生成 \`project.type\` / \`commands.{build,test,lint}\`(存在性核验驱动)/ \`test_strategy\` 骨架**,以下策略字段由你(agent)按项目实际情况补充——能在 package.json / lockfile / 构建文件 / CI 配置 / README 中找到依据就填,不确定留空或注释:
|
|
195
|
+
- \`commands.install\`:依赖安装命令(如 \`npm install\` / \`pnpm install\` / \`yarn\`)
|
|
196
|
+
- \`env\`:构建/测试所需环境变量键值(仅从 README / CI 配置 / .env.example 能确证的)
|
|
197
|
+
- \`test_strategy\`:detect 未注入时按项目实际补(full=全量 / module=只测变更模块 / skip=跳过测试)
|
|
198
|
+
- \`modules\`:模块路径根(module_paths,如 \`src/\` / \`packages/\`)
|
|
199
|
+
- \`known_failures\`:已知失败/不稳定测试清单(仅从 CI 历史 / 测试注释能确证的)
|
|
200
|
+
|
|
201
|
+
### platform / dispatch / mcp 段检查(FR-08,可选补充)
|
|
202
|
+
detect 不写这三段,由你按项目是否接入 sillyhub 平台决定是否补:
|
|
203
|
+
- **platform 段缺失**(要接入 sillyhub 平台)→ 运行 \`sillyspec platform connect <url> <token>\` 自动写入(推荐)
|
|
204
|
+
- **dispatch 段调参缺失**(启用 sillyhub 派发且需调优)→ 手填示例 \`probe_ttl_ms\` / \`poll_interval_ms\` / \`worker_timeout_ms\`(仅在你确知调优值时填,否则留默认)
|
|
205
|
+
- **mcp 段缺失**(dispatch worker 走 MCP 协议连 sillyhub)→ 优先 \`sillyspec platform connect\`(同源假设,platform+mcp 同写);不同源则手填 \`mcp.url\` / \`mcp.token\`,或设环境变量 \`SILLYHUB_MCP_URL\` / \`SILLYHUB_MCP_TOKEN\`(不入盘)
|
|
206
|
+
|
|
207
|
+
### ⛔ 铁律(R-04,防编造)
|
|
208
|
+
只写能从 package.json / lockfile / 构建文件 / CI 配置 / README 中确证的事实。不确定的字段一律留空或写注释占位,**绝不编造命令、路径或凭据**。commands 键的存在性已由 detect 核验,不要重复核验。
|
|
209
|
+
|
|
210
|
+
### 输出格式参考(detect 自动产出骨架 + agent 补充策略字段)
|
|
193
211
|
\`\`\`yaml
|
|
194
212
|
# SillySpec 本地配置(自动生成,可手动修改)
|
|
195
213
|
project:
|
|
196
214
|
type: nodejs # nodejs/maven/gradle/make/generic
|
|
197
215
|
|
|
216
|
+
# commands 键存在性由 detect 核验 package.json scripts 驱动:
|
|
217
|
+
# 有 scripts.build 才写 build,有 scripts.test 才写 test,有 scripts.lint 才写 lint
|
|
218
|
+
# (仅 test/lint 无 build 的项目,build 键不写)
|
|
198
219
|
commands:
|
|
199
|
-
build: "npm run build"
|
|
220
|
+
build: "npm run build" # 仅 scripts.build 存在时由 detect 写入
|
|
200
221
|
test: "npm test"
|
|
201
222
|
lint: "npm run lint"
|
|
223
|
+
# install: "npm install" # ← agent 补:依赖安装命令
|
|
202
224
|
|
|
203
225
|
# 测试策略:full=全量测试, module=只测变更模块, skip=跳过测试
|
|
204
226
|
test_strategy: module
|
|
227
|
+
|
|
228
|
+
# ↓ 以下为 agent 按项目实际补充的策略字段(不确定留空或注释)
|
|
229
|
+
# env: # ← agent 补:构建/测试所需环境变量
|
|
230
|
+
# NODE_ENV: test
|
|
231
|
+
# modules: # ← agent 补:模块路径根(module_paths)
|
|
232
|
+
# - src/
|
|
233
|
+
# known_failures: # ← agent 补:已知失败/不稳定测试
|
|
234
|
+
# - "test/flaky.test.mjs"
|
|
235
|
+
|
|
236
|
+
# ↓ 外部连接段(接入 sillyhub 平台时补,detect 不写)
|
|
237
|
+
# platform: # ← sillyspec platform connect <url> <token> 写入
|
|
238
|
+
# url: ...
|
|
239
|
+
# token: ...
|
|
240
|
+
# mcp: # ← platform connect 同源写入 或 手填 或 env(SILLYHUB_MCP_URL/TOKEN)
|
|
241
|
+
# url: ...
|
|
242
|
+
# token: ...
|
|
243
|
+
# dispatch: # ← agent 按需调参(确知调优值才填)
|
|
244
|
+
# probe_ttl_ms: 30000
|
|
245
|
+
# poll_interval_ms: 2000
|
|
246
|
+
# worker_timeout_ms: 60000
|
|
205
247
|
\`\`\`
|
|
206
248
|
|
|
207
249
|
### 输出
|
|
208
|
-
local.yaml 生成结果(已存在/已生成 + project.type
|
|
250
|
+
local.yaml 生成结果(已存在/已生成 + project.type + agent 补充的策略字段摘要)`,
|
|
209
251
|
outputHint: 'local.yaml 生成状态',
|
|
210
252
|
optional: false
|
|
211
253
|
},
|
|
@@ -330,6 +372,9 @@ _module-map.yaml 生成结果(已存在/已生成/模块列表)`,
|
|
|
330
372
|
{
|
|
331
373
|
name: '生成模块卡片文档',
|
|
332
374
|
perProject: true,
|
|
375
|
+
conditionalWait: true,
|
|
376
|
+
waitReason: '检测到已有模块文档覆盖风险',
|
|
377
|
+
waitOptions: ['只生成缺失', '全部重新生成', '跳过'],
|
|
333
378
|
prompt: `根据当前项目的 \`_module-map.yaml\` 生成模块卡片文档。
|
|
334
379
|
|
|
335
380
|
### ⚠️ 重要:模块卡片只负责人类语义说明
|
|
@@ -350,7 +395,7 @@ _module-map.yaml 生成结果(已存在/已生成/模块列表)`,
|
|
|
350
395
|
### 生成方法(子代理并行,只针对用户选中的模块)
|
|
351
396
|
**你必须为每个模块启动独立子代理执行,不要自己写文档。**
|
|
352
397
|
|
|
353
|
-
每个子代理的 prompt(**主 agent
|
|
398
|
+
每个子代理的 prompt(**主 agent 启动前必须拼入**):
|
|
354
399
|
- 模块名和路径(从 _module-map.yaml 读取)
|
|
355
400
|
- 环境探测结果摘要(构建工具、语言框架)
|
|
356
401
|
- scan 文档关键信息摘要(ARCHITECTURE.md 的技术栈、CONVENTIONS.md 的代码风格要点,如已生成)
|
|
@@ -526,13 +571,13 @@ INDEX.md 维护索引,格式(每行:关键词1|关键词2 → [条目名](
|
|
|
526
571
|
3. 自检门控:ARCHITECTURE(技术栈+Schema摘要)、CONVENTIONS(隐形规则+代码风格)、STRUCTURE(目录结构)、INTEGRATIONS(外部依赖)、TESTING(测试现状)、CONCERNS(技术债务)、PROJECT(项目概览)
|
|
527
572
|
4. 检查 flows/ 和 glossary.md 是否已生成(如有)
|
|
528
573
|
5. 清理:\`rm -f {DOCS_ROOT}/scan/_env-detect.md\`
|
|
529
|
-
6. 如果非平台模式:\`git add
|
|
574
|
+
6. 如果非平台模式:\`git add {DOCS_ROOT}/ {KNOWLEDGE_ROOT}/\` — 暂存本次扫描产物(scan 文档 / 模块文档 / flows / glossary / knowledge;勿用 .sillyspec/ 整目录——会裹挟 changes/ 下其他活跃变更;不要 commit,由用户通过统一提交工具处理)。如果平台模式:跳过 git add(specRoot 不在 sourceRoot 的 git repo 内)。
|
|
530
575
|
|
|
531
576
|
### ⛔ 路径合规检查(平台模式下必须执行)
|
|
532
577
|
7. 确认所有文档都写入 \`{DOCS_ROOT}/\`(spec-root 下),**而非源码目录下的 .sillyspec/**
|
|
533
578
|
8. 检查是否出现 tool_use_error 或 API Error 未恢复
|
|
534
579
|
9. 检查 7 份文档 header 是否包含 author 和 created_at
|
|
535
|
-
10.
|
|
580
|
+
10. 复查 detect 核验结果——commands 键已由 detect 核验 scripts 存在性,agent 无需重复核验或标 unavailable,仅确认 local.yaml 与 detect 产出一致
|
|
536
581
|
|
|
537
582
|
### ⛔ API 错误处理
|
|
538
583
|
- 遇到 API Error 529(服务过载)或 rate_limit 时,**停止当前操作并报告**,不要自动重试
|
package/src/stages/status.js
CHANGED
|
@@ -28,7 +28,6 @@ export const definition = {
|
|
|
28
28
|
1. \`ls .sillyspec/changes/ 2>/dev/null | grep -v archive\`
|
|
29
29
|
2. 对每个进行中的变更:检查 proposal.md ✅/❌、design.md ✅/❌、requirements.md ✅/❌、tasks.md — X/Y 完成
|
|
30
30
|
3. \`ls .sillyspec/changes/archive/ 2>/dev/null | wc -l\`
|
|
31
|
-
4. \`cat .sillyspec/HANDOFF.json 2>/dev/null\`
|
|
32
31
|
|
|
33
32
|
### 输出
|
|
34
33
|
变更状态列表`,
|
package/src/stages/verify.js
CHANGED
|
@@ -31,6 +31,9 @@ export const definition = {
|
|
|
31
31
|
- 运行测试命令(不修改源码)
|
|
32
32
|
- 运行 lint 命令(不自动修复)
|
|
33
33
|
|
|
34
|
+
### 长测试/构建执行铁律
|
|
35
|
+
- 长测试/构建/lint 命令必须**前台同步执行**,禁止 run_in_background:true / & / nohup / disown——后台任务易被会话生命周期回收导致中断无果
|
|
36
|
+
|
|
34
37
|
如果发现文件缺失或异常,**只报告问题,不尝试修复**。
|
|
35
38
|
`,
|
|
36
39
|
|
|
@@ -63,7 +66,7 @@ export const definition = {
|
|
|
63
66
|
- 如果存在 P0/P1 unresolved/blocking 决策,验证结论不能为 PASS
|
|
64
67
|
- 如果发现 superseded 决策被下游引用,标记为 ⚠️ stale decision reference
|
|
65
68
|
3. 加载项目信息:\`cat .sillyspec/projects/*.yaml 2>/dev/null\`
|
|
66
|
-
4. 加载本地配置:\`cat .sillyspec/local.yaml 2>/dev/null\`(构建命令、测试命令、lint
|
|
69
|
+
4. 加载本地配置:\`cat .sillyspec/local.yaml 2>/dev/null\`(构建命令、测试命令、lint 命令等)若 local.yaml 不存在,先 \`sillyspec local detect\` 生成骨架再读取
|
|
67
70
|
5. 加载代码规范:\`cat .sillyspec/docs/<project>/scan/CONVENTIONS.md 2>/dev/null\`
|
|
68
71
|
- 测试现状:\`cat .sillyspec/docs/<project>/scan/TESTING.md 2>/dev/null\`(了解既有测试约定与覆盖范围,验收时对照)
|
|
69
72
|
- 技术债清单:\`cat .sillyspec/docs/<project>/scan/CONCERNS.md 2>/dev/null\`(🔴/🟡 区域;本次变更若触碰须在 verify-result.md 标注)
|
|
@@ -72,16 +75,18 @@ export const definition = {
|
|
|
72
75
|
### Execute Evidence 传递检查
|
|
73
76
|
7. 检查 verify-required-evidence.json 是否存在(由 execute 阶段 Task Review Gate 写入)
|
|
74
77
|
- 路径:变更目录下的 verify-required-evidence.json
|
|
75
|
-
-
|
|
78
|
+
- 文件 schema:\`{ items: [{ task, verdict, evidence: string[] }] }\`——顶层是 \`items\`,每项的 \`evidence\` 是字符串数组(**不是** \`requiredEvidence\` 键;旧 prompt 写 requiredEvidence 是字段名错配,照读必落空)
|
|
79
|
+
- 如果存在 → 逐项读取 \`items\`,对每个 cannot_verify 任务逐条核对其 \`evidence\` 数组是否已满足
|
|
76
80
|
- 每条 evidence 必须在 verify-result.md 中给出明确结论(satisfied / missing / partial)
|
|
77
81
|
- 如果有任何 evidence 为 missing → verify 结论不能为 PASS
|
|
78
82
|
- 如果文件不存在 → 表示 execute 阶段无 cannot_verify 任务,正常继续
|
|
83
|
+
- CLI 会 advisory 复核每个 cannot_verify 任务是否在 verify-result.md 体现(未体现仅 warn 不阻断归档;evidence 是否真满足由你诚实判定,CLI 不替你语义判定)
|
|
79
84
|
|
|
80
85
|
### 模块文档加载
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
8. 读取 \`.sillyspec/docs/<project>/modules/_module-map.yaml\`(不存在则跳过以下步骤)
|
|
87
|
+
9. 根据 design.md 的文件变更清单匹配 _module-map.yaml 中的模块
|
|
88
|
+
10. 读取匹配到的 \`.sillyspec/docs/<project>/modules/<module>.md\`
|
|
89
|
+
11. **检查模块索引可信度**:如果相关模块的 needs_review 为 true,提示"该模块索引可能不可信,需要回看模块卡片或源码"
|
|
85
90
|
|
|
86
91
|
### 输出
|
|
87
92
|
文件加载确认清单(含 decisions.md 当前版本/未决项状态、模块文档 + 索引可信度)`,
|
|
@@ -130,7 +135,7 @@ export const definition = {
|
|
|
130
135
|
4. API 设计是否符合
|
|
131
136
|
5. **Reverse Sync 检查**:如果发现实现合理但 design.md 未覆盖,先更新 design.md 补充遗漏
|
|
132
137
|
6. **模块文档一致性检查**:如果在"加载规范并锚定"步骤中加载了模块文档,检查实现是否符合模块文档描述的当前设计(特别关注接口签名、数据流、依赖关系)。不符合时标记 ⚠️(不阻断,模块文档可能未及时更新)
|
|
133
|
-
7. **决策链路检查**:如果存在 decisions.md,输出 D-xxx@vN → FR-xxx → task-xx → evidence
|
|
138
|
+
7. **决策链路检查**:如果存在 decisions.md,输出 D-xxx@vN → FR-xxx → task-xx → evidence 的追踪矩阵;缺失项必须列为风险(CLI 只校验每个 D-xxx@vN ID 字面出现在 verify-result.md,warning 不阻断;矩阵的 D→FR→task→evidence 映射完整性供人类追溯,CLI 不校验——是否真覆盖由你诚实判定)
|
|
134
139
|
|
|
135
140
|
### 输出
|
|
136
141
|
探针报告 + 设计一致性检查结果 + 模块文档一致性检查结果 + 决策追踪矩阵(如有)`,
|
|
@@ -159,7 +164,7 @@ export const definition = {
|
|
|
159
164
|
prompt: `运行代码质量扫描(测试实测统一由 CLI 对账执行,本步不重复手动跑全量)。
|
|
160
165
|
|
|
161
166
|
### 操作
|
|
162
|
-
1. 读取 \`.sillyspec/local.yaml\` 获取构建、测试和 lint
|
|
167
|
+
1. 读取 \`.sillyspec/local.yaml\` 获取构建、测试和 lint 命令若 local.yaml 不存在,先 \`sillyspec local detect\` 生成骨架再读取
|
|
163
168
|
2. **不要手动重复跑 commands.test**——CLI 会在最终 --done 时统一执行一次(按变更命中模块子集),本步再跑 = 与 CLI 对账重复耗时(实测 198s×2)。如为提前发现实现问题,可对变更模块做**针对性快速冒烟**(可选,非必需):
|
|
164
169
|
- Maven:\`mvn test -pl <变更模块> -am\`(仅编译变更模块及其依赖)
|
|
165
170
|
- Gradle:\`./gradlew :<模块>:test\`
|
|
@@ -212,7 +217,7 @@ PASS / PASS WITH NOTES / FAIL
|
|
|
212
217
|
- 测试覆盖:...
|
|
213
218
|
- 决策追踪覆盖:...
|
|
214
219
|
- API 契约对账:...
|
|
215
|
-
- 代码删除对账:声明修改/新增却被整文件删除 = 高风险;清单未列出的删除 = 未声明(CLI 会用 git diff --name-status HEAD
|
|
220
|
+
- 代码删除对账:声明修改/新增却被整文件删除 = 高风险;清单未列出的删除 = 未声明(CLI 会用 git diff --name-status HEAD advisory 复核,仅 warn 不阻断——是否 FAIL blocker 由你诚实判定)
|
|
216
221
|
|
|
217
222
|
## 决策追踪矩阵(如存在 decisions.md)
|
|
218
223
|
| 决策 ID | FR | Task | Evidence | 状态 |
|