sillyspec 3.26.14 → 3.27.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.
Files changed (70) hide show
  1. package/.claude/skills/sillyspec-archive/SKILL.md +2 -0
  2. package/.claude/skills/sillyspec-brainstorm/SKILL.md +1 -1
  3. package/.claude/skills/sillyspec-commit/SKILL.md +18 -60
  4. package/.claude/skills/sillyspec-continue/SKILL.md +2 -0
  5. package/.claude/skills/sillyspec-execute/SKILL.md +10 -4
  6. package/.claude/skills/sillyspec-explore/SKILL.md +10 -3
  7. package/.claude/skills/sillyspec-plan/SKILL.md +10 -2
  8. package/.claude/skills/sillyspec-quick/SKILL.md +2 -2
  9. package/.claude/skills/sillyspec-resume/SKILL.md +2 -0
  10. package/.claude/skills/sillyspec-verify/SKILL.md +4 -0
  11. package/.claude/skills/sillyspec-workspace/SKILL.md +7 -1
  12. package/README.md +1 -1
  13. package/package.json +1 -1
  14. package/packages/dashboard/server/index.js +22 -6
  15. package/src/change-risk-profile.js +21 -6
  16. package/src/commit-suggest.js +202 -0
  17. package/src/config-cat.js +88 -0
  18. package/src/db.js +14 -3
  19. package/src/docs-check.js +598 -534
  20. package/src/doctor-diagnostics.js +102 -1
  21. package/src/endpoint-extractor.js +21 -2
  22. package/src/fs-atomic.js +4 -2
  23. package/src/git-helper.js +73 -5
  24. package/src/hooks/claude-pre-tool-use.cjs +10 -5
  25. package/src/hooks/worktree-guard.js +42 -4
  26. package/src/index.js +557 -12
  27. package/src/init.js +1 -1
  28. package/src/local-register.js +98 -0
  29. package/src/module-impact.js +166 -0
  30. package/src/module-resolve.js +211 -0
  31. package/src/modules.js +82 -2
  32. package/src/progress/change-registry.js +43 -4
  33. package/src/progress/stage-machine.js +10 -5
  34. package/src/progress/step-store.js +12 -8
  35. package/src/progress.js +19 -3
  36. package/src/quicklog.js +106 -1
  37. package/src/run/command.js +95 -1
  38. package/src/run/complete-handlers.js +73 -5
  39. package/src/run/complete.js +47 -14
  40. package/src/run/gates.js +144 -17
  41. package/src/run/multi-repo-context.js +3 -1
  42. package/src/run/next.js +128 -0
  43. package/src/run/prompt.js +36 -4
  44. package/src/run/quick-audit.js +5 -2
  45. package/src/run/shared.js +48 -20
  46. package/src/run/stage.js +37 -3
  47. package/src/scan-postcheck.js +142 -2
  48. package/src/stage-contract-spec.js +1 -1
  49. package/src/stage-contract.js +14 -1
  50. package/src/stage-review.js +15 -6
  51. package/src/stages/archive.js +4 -2
  52. package/src/stages/brainstorm.js +1 -0
  53. package/src/stages/execute.js +275 -44
  54. package/src/stages/explore.js +11 -2
  55. package/src/stages/knowledge.js +3 -2
  56. package/src/stages/quick.js +18 -9
  57. package/src/stages/scan.js +1 -0
  58. package/src/stages/verify.js +16 -51
  59. package/src/sync.js +44 -3
  60. package/src/task-review.js +273 -11
  61. package/src/taskcard.js +52 -22
  62. package/src/verify-postcheck.js +223 -6
  63. package/src/verify-probes.js +264 -0
  64. package/src/workspace.js +125 -0
  65. package/src/worktree-apply.js +43 -11
  66. package/src/worktree-deps.js +59 -5
  67. package/src/worktree.js +128 -14
  68. package/templates/claude-instruction.md +1 -1
  69. package/templates/prompts/taskcard-rules.md +1 -1
  70. package/templates/prompts/verify-probes.md +13 -47
@@ -9,6 +9,8 @@ description: 用于归档已验证完成的变更。适合用户说"归档、arc
9
9
  - verify 已通过,把变更包归档沉淀
10
10
  - 5 步:任务完成度检查 → 模块影响分析 → 同步模块文档 → 确认归档 → 更新路线图
11
11
 
12
+ > 🔧 模块影响分析步:先跑 `sillyspec module-impact --change <变更名>` 生成 module-impact.md 骨架——文件×模块归属按 `_module-map.yaml` paths 前缀匹配预填 + 未匹配文件清单,你只需逐行填「影响类型」与 review 标记(以 git diff 为准,真实 > 声明);已存在不覆盖。
13
+
12
14
  ## 多变更说明
13
15
 
14
16
  项目有多个活跃变更(`.sillyspec/changes/` 下有多个目录)时,所有 `sillyspec run` 命令需加 `--change <变更名>` 指定操作目标;只有一个变更时可省略(CLI 自动检测)。
@@ -100,7 +100,7 @@ brainstorm 在 `tier=independent` 规模下除 design.md 等四件套外,还
100
100
  }
101
101
  ```
102
102
 
103
- - `docHash` = `sha256(主审查文档内容)`(hex)—— brainstorm 主文档是 `design.md`(即 `reviewedFiles[0]`)。CLI 重算 sha256 比对,不符判伪造(fail-closed)。改 design.md 后须重算 docHash。`tier=self`(≤3 文件)降级为当前 agent 自审,不强制独立子代理。
103
+ - `docHash` = `sha256(主审查文档内容)`(hex)—— brainstorm 主文档是 `design.md`(即 `reviewedFiles[0]`)。CLI 重算 sha256 比对,不符判伪造(fail-closed)。docHash 可先占位(如 "TODO");改 design.md 后勿手算 sha256——跑 `sillyspec register-stage-review --change <变更名> --stage brainstorm --refresh-hash` 一键重算代填(verdict 保留;design 改版多阶段联动加 --all)。`tier=self`(≤3 文件)降级为当前 agent 自审,不强制独立子代理。
104
104
  - 运行时 CLI 会把精确 schema 表 + 完整 JSON 示例 + docHash 算法注入到该步 prompt,以你实际收到的注入版契约为权威逐字模板。
105
105
 
106
106
  ## 铁律
@@ -19,85 +19,43 @@ $ARGUMENTS
19
19
 
20
20
  ## 流程
21
21
 
22
- ### 1. 检查是否有未提交的修改
23
- git diff --quiet 2>/dev/null; UNSTAGED=$?
24
- git diff --cached --quiet 2>/dev/null; STAGED=$?
22
+ ### 1. 收集变更上下文 + 建议 message(一条命令)
25
23
 
26
- 两者都为 0(无修改)→ 提示"没有需要提交的修改",结束。
24
+ ```bash
25
+ sillyspec commit
26
+ ```
27
27
 
28
- ### 2. 暂存所有修改
29
- git add -A
28
+ CLI 已接管全部手工收集(上次 commit 时间过滤 QUICKLOG 条目、活跃变更已勾 task、按路径模式归类阶段产出、diff stat),并按下方 type 表生成建议 message + 可照抄的 `git add -A && git commit -m ...` 命令。**它只建议不提交。**
30
29
 
31
- ### 3. 收集变更语义信息
32
- # 上次 commit 时间
33
- LAST_COMMIT_TIME=$(git log -1 --format=%ci 2>/dev/null)
30
+ - 命令输出「没有需要提交的修改」→ 结束。
31
+ - 无语义来源匹配(输出会明说)→ 展示 diff stat,让用户自己写。
34
32
 
35
- # 修改的文件列表
36
- git diff --cached --stat
33
+ ### 2. 展示确认
37
34
 
38
- 从以下来源收集语义信息(筛选时间戳 > LAST_COMMIT_TIME 的条目):
35
+ 把 `sillyspec commit` 的建议 message + 文件统计原样展示给用户(AskUserQuestion):
39
36
 
40
- 来源 A — QUICKLOG(quick 产生的修改):
41
- USER=$(git config user.name 2>/dev/null || echo "default")
42
- cat .sillyspec/quicklog/QUICKLOG-${USER}.md 2>/dev/null
43
- # 同时扫描活跃变更目录下的归属 quicklog
44
- for dir in .sillyspec/changes/*/quicklog/*.md; do [ -f "$dir" ] && cat "$dir"; done 2>/dev/null
45
- # 注:QUICKLOG 现由 CLI 接管写入(src/quicklog.js),描述取 quick 启动的任务参数、
46
- # 结果取 step3 --output 一句话,粒度可能较粗;条目仍含 标题|时间|描述 + 状态 + 结果 结构,
47
- # 可直接读取。描述过泛时结合 diff stat 与 tasks.md 补充语义。
37
+ 选择:确认提交 / 编辑 message / 取消
38
+
39
+ 用户选择编辑 → 让用户输入新 message → 再次确认。
48
40
 
49
- 来源 B — tasks.md(execute 产生的修改):
50
- LATEST=$(ls -d .sillyspec/changes/*/ 2>/dev/null | grep -v archive | tail -1)
51
- cat "$LATEST/tasks.md" 2>/dev/null
52
- 筛选时间戳 > LAST_COMMIT_TIME 的已勾选 task。
41
+ ### 3. 执行提交
53
42
 
54
- 来源 C — 阶段产出(scan/brainstorm/plan/archive 等):
55
- 检查 .sillyspec/ 下新增或修改的文件,根据路径识别来源阶段:
56
- - .sillyspec/docs/<project>/scan/*.md → scan 产出
57
- - changes/<name>/design.md → brainstorm 产出
58
- - changes/<name>/proposal.md → brainstorm 产出
59
- - changes/<name>/tasks.md → plan 产出
60
- - changes/<name>/plan.md → plan 产出
61
- - changes/archive/ → archive 产出
62
- - knowledge/*.md → 知识库更新
43
+ 用户确认后执行 `git add -A` + 输出里给出的 `git commit` 命令(或用户编辑后的 message)。
63
44
 
64
- ### 4. 自动生成 commit message
45
+ 提交成功后展示 commit hash + 文件数 + 行数统计。
65
46
 
66
- 按 conventional commits 格式,根据来源生成 message:
47
+ ### 参考:message 生成口径(CLI 同源实现,src/commit-suggest.js)
67
48
 
68
49
  | 来源 | type | 示例 |
69
50
  |---|---|---|
70
- | 只有 quick 条目 | fix/refactor | fix: 手机号校验修复(含正则修正) |
71
- | 只有 execute 条目 | feat | feat(user): 用户模块 task 1~3 |
51
+ | 只有 quick 条目 | fix | fix: 手机号校验修复(含正则修正) |
52
+ | 只有 execute 已勾 task | feat | feat: <变更名> 完成 task ×N |
72
53
  | 只有阶段产出 | docs | docs: sillyspec scan 完成 |
73
54
  | 混合来源 | 取最主要的 type | body 里列出所有条目 |
74
55
  | 无匹配来源 | — | 展示 diff stat,让用户自己写 |
75
56
 
76
57
  **如果 $ARGUMENTS 非空**,直接使用用户指定的 message,跳过自动生成,但仍展示 diff stat。
77
58
 
78
- 多条 quick 合并规则:
79
- - 2 条以内 → 逐条列出
80
- - 3 条以上 → 摘要 + body 详情
81
-
82
- ### 5. 展示确认
83
-
84
- 用 AskUserQuestion 展示:
85
- 📝 建议的 commit message:
86
- fix: 手机号校验修复(含正则修正)
87
-
88
- 📁 修改文件(N 个):
89
- src/UserService.java (+15 -3)
90
- src/PhoneValidator.java (+28 -0)
91
-
92
- 选择:确认提交 / 编辑 message / 取消
93
-
94
- 用户选择编辑 → 让用户输入新 message → 再次确认。
95
-
96
- ### 6. 执行提交
97
- git commit -m "{确认后的 message}"
98
-
99
- 提交成功后展示 commit hash + 文件数 + 行数统计。
100
-
101
59
  ## 多项目
102
60
  检查修改的文件分别属于哪个子项目:
103
61
  - 修改集中在一个子项目 → 在该子项目目录中 commit
@@ -9,6 +9,8 @@ description: 自动判断并执行下一步
9
9
 
10
10
  ## 判断逻辑
11
11
 
12
+ > 🔧 **先跑 `sillyspec next`**——CLI 已内置下方探测表(含活跃变更逐个推断 + task 勾选进度),输出「状态 + 下一步命令 + 依据」。直接按输出的建议命令执行;CLI 异常/输出与实际不符时才按下方手工表兜底。
13
+
12
14
  按顺序检查,第一个未完成的就执行:
13
15
 
14
16
  ```
@@ -61,6 +61,7 @@ execute 前缀步「加载上下文」的 `--done` 会硬校验符号影响面
61
61
 
62
62
  - 路径:`{SPEC_ROOT}/changes/<变更名>/symbol-impact.md`(步骤 prompt 中会输出具体路径)。
63
63
  - 要求:plan.md 中**每个 task-XX 都要有一行结论**——涉及签名级变更(构造函数参数/接口/DTO/方法签名增删改)就列变更类型 + 受影响调用点 + 是否在任务范围内;无签名级变更也要显式写「无签名级变更」。
64
+ - 🔧 **骨架生成**:`sillyspec symbol-impact --change <变更名>` 从 tasks.md 生成逐 task `<!--TODO-->` 骨架(撞 gate 时 CLI 也会自动落一份),逐行替换为结论即可;**未替换的 TODO 占位会被 gate 拒绝**(骨架不能直接过门)。
64
65
  - 文件缺失或未覆盖全部 task → `--done` 被阻断(进度不推进),补全后重跑即可。
65
66
 
66
67
  ### Task Review Gate
@@ -88,7 +89,10 @@ execute 完成时,每个 task 必须有 `review.json` 且 verdict 通过,否
88
89
  ```
89
90
 
90
91
  - `base` / `head` 必须是**真实 git commit**(`git rev-parse --verify`),否则判伪造并阻断。`changedFiles` 与实际 `git diff base..head` 完全不相交也判伪造。base..head 空 commit diff 但 working-tree 有未提交改动 → 视为有效改动(warning 不阻断)。
91
- - 后端 router task 另需在 `.sillyspec/.runtime/contract-artifacts/<task-name>/endpoints.json` 写 API 端点清单(扫 `@router.get/post/...`)。
92
+
93
+ > 🔧 **mechanics 字段不要手算**:`schemaVersion`/`task`/`base`/`head`/`changedFiles`(/跨仓 `repo`) 全部可由 CLI 从 git + task 卡推导。子代理/你只需写**语义字段**(`specVerdict`/`qualityVerdict`/`reviewerNotes`/`requiredEvidence`),mechanics 字段可以瞎填占位(如 `"base": "TODO"`),写完跑 `sillyspec backfill-reviews --change <变更名> --adopt` 一键重算代填(verdict 原样保留)。gate 拦下 mechanics 错误时也跑同一条命令修复。
94
+
95
+ - 后端 router task 另需产出 API 端点清单:`sillyspec endpoints extract --change <变更名> --task <task-NN>`(CLI 静态扫描 FastAPI/Express/Spring 路由装饰器生成 endpoints.json,verify 探针 5 消费;扫描面默认取 task 卡 allowed_paths ∪ design 清单,也可 `--dir`/`--files` 显式指定)。勿手扫装饰器手写——易漏 endpoint。
92
96
 
93
97
  ### Stage Review Gate(execute 末尾的 acceptance review.json)
94
98
 
@@ -114,7 +118,7 @@ execute 还有**第二道**独立的 stage 级审查:除逐 task review.json
114
118
  }
115
119
  ```
116
120
 
117
- - `docHash` = `sha256(主审查文档内容)`(hex)—— execute 主审查文档是 `design.md`,即 `reviewedFiles[0]`。CLI 会重算 sha256 比对,不符判伪造(fail-closed);找不到主文档也 fail。**改 design.md 后须重算 docHash 再写**,可用 `sillyspec run execute --done` 触发的 prompt 注入版契约(运行时注入的 schema 表 + JSON 示例 + docHash 算法)逐字改值。
121
+ - `docHash` = `sha256(主审查文档内容)`(hex)—— execute 主审查文档是 `design.md`,即 `reviewedFiles[0]`。CLI 会重算 sha256 比对,不符判伪造(fail-closed);找不到主文档也 fail。**docHash 可先占位(如 "TODO")勿手算**——改 design.md 后跑 `sillyspec register-stage-review --change <变更名> --stage execute --refresh-hash` 一键重算代填(verdict 保留;design 改版多阶段联动加 --all);gate 拦 docHash 失配时也用同一条命令修复。
118
122
  - `tier=independent` 时必须由独立 QA 子代理产出该 review.json(独立上下文,不共享实现者分析);`tier=self`(变更 ≤3 文件)降级为当前 agent 自审。
119
123
  - **审查范围分级**(tier=independent 时省重复消耗):Task Review Gate 已产出 review.json 且 specVerdict/qualityVerdict 双 pass 的 task,QA 子代理只抽查(读 1-2 个核心 diff 文件抽验 reviewerNotes 与实际改动相符);fail/cannot_verify/缺失的 task 全量重审。三项始终必查:跨 task 交界、design.md 整体对照、组装行为(全量测试/构建/启动)——task review 只看单 task diff,覆盖不到这三项。
120
124
  - 该 acceptance review 同时覆盖"代码审查"视角,后续代码审查步骤仅需轻量复审。
@@ -127,6 +131,8 @@ execute 还有**第二道**独立的 stage 级审查:除逐 task review.json
127
131
 
128
132
  可选:`sillyspec dispatch probe` 查看 SillyHub 是否可用。
129
133
 
134
+ > 📍 `local.yaml` 恒在 `.sillyspec/local.yaml`——项目根目录**没有**这个文件,别去那里找或新建(hook 会拦)。worktree 内该文件不随 checkout 出现,读配置直接跑 `sillyspec config cat`(自动定位到主仓真实配置);可用键清单见 `sillyspec config schema`。
135
+
130
136
  ## 跨仓 task(一个 change 改多个仓库)
131
137
 
132
138
  单个 change 的 task 可以分散到主仓 + 多个跨仓仓实现(典型场景:dogfood 自指、monorepo 多包仓、共享库 + 调用方联合改造)。**单仓 change 不需要任何跨仓配置**(所有 task 不写 `repo:` 即走原流程,零回归)。
@@ -134,7 +140,7 @@ execute 还有**第二道**独立的 stage 级审查:除逐 task review.json
134
140
  ### 跨仓 task 配置(plan 阶段产出,execute 阶段消费)
135
141
 
136
142
  - **task 卡片 `repo:` 字段**:跨仓 task 在 `tasks/task-NN.md` frontmatter 写 `repo: <key>`(缺省='main'=主仓 task,不写即主仓)。
137
- - **local.yaml `repos:` 段**:在 `.sillyspec/local.yaml` 注册跨仓仓路径(`main` 不用注册,隐式=当前项目):
143
+ - **local.yaml `repos:` 段**:跨仓仓路径注册(`main` 不用注册,隐式=当前项目)。**用命令注册,勿手编 YAML**:`sillyspec local register-repo <key> <跨仓仓根路径>`(execute 启动报缺注册时报错文案里就带这条命令)。手写格式参考:
138
144
  ```yaml
139
145
  repos:
140
146
  shared-lib: ../shared-lib
@@ -152,7 +158,7 @@ execute 还有**第二道**独立的 stage 级审查:除逐 task review.json
152
158
  ### 跨仓 task 的双锡点(CLI 写入,子代理不改)
153
159
 
154
160
  - `base_commit`:CLI 派发跨仓 task 前实时 `git -C <跨仓仓根> rev-parse HEAD` 落盘到 task 卡 frontmatter(锁 base,防同 Wave 多 task 改同跨仓仓时 HEAD 推进致 diff 漂移)。
155
- - `head_commit`:跨仓 task 子代理 commit 完成后、写 review.json / 勾选 checkbox **之前**,由你(主 agent)运行 `git -C <跨仓仓根> rev-parse HEAD` 把结果写入该 task 卡 frontmatter `head_commit:` 字段。
161
+ - `head_commit`:**同样由 CLI 自动落盘**——execute `--done` 时 CLI 实时 `git -C <跨仓仓根> rev-parse HEAD` 幂等写入 task 卡(已存在不覆盖,你手写的精确锚点优先)。你无需手跑 rev-parse。review.json 的 base/head 无需手算,跑 `sillyspec backfill-reviews --change <变更名> --adopt` 从 task 卡锡点一键代填。
156
162
  - review.json 的 `base`/`head` 取这两个锡点(非瞬时 HEAD)。
157
163
 
158
164
  ### 跨仓 task 的 review.json
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sillyspec:explore
3
- description: 用于自由讨论、代码库调研、方案比较、画 ASCII 图、澄清问题。适合用户说"分析下、讨论下、看看怎么设计、先别写代码、调研一下、画个结构图、帮我再分析下"。只读,不修改文件,不实现功能。
3
+ description: 用于自由讨论、代码库调研、方案比较、画 ASCII 图、澄清问题、生成 HTML 原型。适合用户说"分析下、讨论下、看看怎么设计、先别写代码、调研一下、画个结构图、帮我再分析下、画个原型、出个原型图、做个 demo 页"。默认只读不修改文件(仅用户明确要求时保存结论或生成原型),不实现功能。
4
4
  ---
5
5
 
6
6
  ## 交互规范
@@ -33,7 +33,7 @@ sillyspec run explore --status # 查看阶段状态
33
33
 
34
34
  ## 这是什么模式
35
35
 
36
- **探索模式用于思考,不用于实现。** 你可以读文件、搜代码、调查代码库,但绝对不能写代码或实现功能。如果用户要求实现,提醒他们先退出探索模式。
36
+ **探索模式用于思考,不用于实现。** 你可以读文件、搜代码、调查代码库,但默认不写任何文件(用户明确要求保存结论或生成原型时除外),也绝不写实现代码。如果用户要求实现,提醒他们先退出探索模式。
37
37
 
38
38
  **这不是一个工作流,是一种姿态。** 没有固定步骤、没有必需的输出。你是一个帮助用户思考的伙伴。
39
39
 
@@ -66,6 +66,12 @@ sillyspec run explore --status # 查看阶段状态
66
66
  └─────────────────────────────────┘
67
67
  ```
68
68
 
69
+ **生成 HTML 原型**(仅用户明确要求时):讨论 UI/交互方案时,用户说"画个原型、出个原型图、做个 demo 页"才动手,平时最多提议。生成要求与 brainstorm 阶段原型对齐:
70
+ - 单文件 HTML(内联 CSS + JS),浏览器直接打开
71
+ - 高保真呈现讨论中的布局/组件/交互流程,风格对齐项目现有界面(先读 scan 文档与前端代码)
72
+ - 保存到 `.sillyspec/explore/prototype-<名称>.html`(用户指定其他位置则从其指定)
73
+ - 探索原型是讨论工具、不是交付物,也不是实现代码;后续进入 brainstorm 时可复制到变更目录复用
74
+
69
75
  **暴露风险**:识别可能出错的地方、发现理解空白
70
76
 
71
77
  ## OpenSpec 上下文感知
@@ -90,6 +96,7 @@ cat .sillyspec/ROADMAP.md 2>/dev/null
90
96
 
91
97
  - ❌ 写实现代码
92
98
  - ❌ 安装依赖
93
- - ❌ 修改任何文件(除非用户明确要求保存发现)
99
+ - ❌ 修改任何文件(除非用户明确要求保存发现或生成原型)
100
+ - ❌ 主动生成原型(必须用户明确要求;最多提议)
94
101
  - ❌ 强行下结论
95
102
  - ❌ 强行结构化(让模式自然涌现)
@@ -69,7 +69,7 @@ plan 的步骤是动态的:`generate_plan`(生成分级计划)→ `review_
69
69
  }
70
70
  ```
71
71
 
72
- - `docHash` = `sha256(主审查文档内容)`(hex)—— plan 主文档是 `plan.md`(`reviewedFiles[0]`)。CLI 重算 sha256 比对,不符判伪造(fail-closed)。改 plan.md 后须重算 docHash。`tier=self`(≤3 文件)降级为当前 agent 自审。
72
+ - `docHash` = `sha256(主审查文档内容)`(hex)—— plan 主文档是 `plan.md`(`reviewedFiles[0]`)。CLI 重算 sha256 比对,不符判伪造(fail-closed)。docHash 可先占位(如 "TODO");改 plan.md 后勿手算 sha256——跑 `sillyspec register-stage-review --change <变更名> --stage plan --refresh-hash` 一键重算代填(verdict 保留;多阶段联动加 --all)。`tier=self`(≤3 文件)降级为当前 agent 自审。
73
73
  - 运行时 CLI 会把精确 schema 表 + 完整 JSON 示例 + docHash 算法注入到该步 prompt,以你实际收到的注入版契约为权威逐字模板。
74
74
 
75
75
  ### 契约门控(阻断完成)
@@ -95,7 +95,15 @@ plan 完成校验会检查:design 提到入口文件(cli.ts/main.ts/server.t
95
95
 
96
96
  ### local.yaml `repos:` 段(跨仓注册表)
97
97
 
98
- 跨仓 change 必须在 `.sillyspec/local.yaml` 注册所有跨仓仓路径:
98
+ > 📍 `local.yaml` 恒在 `.sillyspec/local.yaml`——项目根目录**没有**这个文件,别去那里找或新建(hook 会拦)。worktree 内该文件不随 checkout 出现,读配置直接跑 `sillyspec config cat`(自动定位到主仓真实配置);可用键清单见 `sillyspec config schema`。
99
+
100
+ 跨仓 change 的每个 repo key 都要注册(execute 启动 fail-closed 校验)。**用命令注册,勿手编 YAML**:
101
+
102
+ ```
103
+ sillyspec local register-repo <key> <跨仓仓根路径>
104
+ ```
105
+
106
+ (外科手术式写入,只动 `repos:` 段,其余内容保留;execute 启动报缺注册时,报错文案里就带这条命令。)手写格式参考:
99
107
 
100
108
  ```yaml
101
109
  repos:
@@ -43,7 +43,7 @@ sillyspec run quick --done --change quick-<hash> --output "…" # 完成该会
43
43
  ```
44
44
 
45
45
  - 这里的 `--change quick-<hash>` 是「恢复到该 CLI 生成的 session」,与下方 `--linked-changes` 的关联业务变更语义不同:想关联真实业务变更才用 `--linked-changes`。
46
- - 误启动的空壳会话:`sillyspec run quick --reset --change quick-<hash>` 重置其进度;QUICKLOG 里残留的「(quick 任务)」骨架条目需手动删除,不留占位条目。
46
+ - 误启动的空壳会话:`sillyspec run quick --cancel --change quick-<hash>` 一键取消(QUICKLOG 条目翻「已取消」+ tasks.md 挂载行移除 + 会话目录清理 + db 行注销;已完成/已勾选的拒绝取消)。
47
47
 
48
48
  ## 通用参数(所有阶段适用)
49
49
 
@@ -108,7 +108,7 @@ sillyspec run quick --files src/phone.ts,src/phone.test.ts
108
108
  - QUICKLOG 记录的**骨架由 CLI 接管**:启动时 CLI 自动分配 ql-ID 并在 `.sillyspec/quicklog/QUICKLOG-<user>.md` 写「进行中」条目(含关联变更 tasks.md),`--done` 时 CLI 自动翻「已完成」+ 勾选 task + 回填文件路径。ql-ID 分配/状态/task 你无需手写,只需用注入的 `<quicklog-id>` 在模块文档变更索引引用
109
109
  - **QUICKLOG 落盘已结构化(`--done` 后按需核对,多数无需手改)**:CLI 已落盘结构化条目——标题从 `--output` 的「需求:」自动提取、正文四字段自动分行、文件行用 `--file-notes` 时为多行带括注。`--done` 后只需核对:标题弱才改(禁留 `(quick 任务)` 占位);没用 `--file-notes` 时文件行是单行、可事后补括注(参照同文件早期丰富条目);正文 `需求:`/`根因:`/`方案:`/`结果:` 四段按需充实(禁只留一段「结果:」)。一条 quick = 一条独立 ql,不追加到旧条目
110
110
  - **收尾顺序(模块文档在 `--done` 前,QUICKLOG 在 `--done` 后,别记混)**:① 命中模块→改模块文档→`git add`;② `sillyspec run quick --done --change <id> --output "四字段" [--file-notes "..."]`(CLI 自动翻完成 + 勾 task + 落盘 QUICKLOG 标题/文件/正文;若 `--linked-changes` 关联的真实变更其 tasks.md 已全部勾选**且该变更未进入完整流程**(进度库阶段停在 brainstorm 及之前),CLI 会自动将其归档到 `changes/archive/`;已走到 plan/execute/verify/archive 的变更不自动归档(tasks.md 全勾不等于流程收尾),须走原流程收尾);③ 核对 QUICKLOG 标题(CLI 已从「需求:」提取并截断,写成短标题则无需改)→若改了再 `git add`
111
- - **最后一步 `--done --output` 必须按结构化结果模板给全四字段**(逐项一句话):`需求:… 根因:… 方案:… 结果:…`。这是 QUICKLOG「结果:」归档的唯一来源;CLI 校验缺字段会拒绝 `--done`(exit 1),补全后重跑即可。**「需求:」写一句语义化短标题**(写「改了什么」,如「登录限流修复——INCR 计数误清」)——CLI 把它提取为 QUICKLOG 条目标题,截到首个标点、超 80 字截断;写完整需求长句会被截成语义不完整的状语前半段,需求背景放「根因:/方案:」。正文内避免嵌套全角冒号(如「方案:(说明 xxx):」这样标签后紧接嵌套冒号会被拆分判定缺字段),直接让标签接正文。前两个 step 的 `--output` 是中间摘要,不用此模板
111
+ - **最后一步 `--done` 必须给全四字段**(逐项一句话):🔧 **推荐四参数形式**(CLI 自动合成结构化模板,无格式事故面):`--done --change <id> --req "一句语义化短标题" --cause "为什么改" --solution "怎么改的" --result "验证结果"`。兼容旧形式 `--output "需求:… 根因:… 方案:… 结果:…"`(手拼须懂截断规则、禁嵌套全角冒号,缺字段被拒 exit 1)。这是 QUICKLOG「结果:」归档的唯一来源。**`--req` 写一句语义化短标题**(写「改了什么」,如「登录限流修复——INCR 计数误清」)——CLI 把它提取为 QUICKLOG 条目标题,截到首个标点、超 80 字截断;写完整需求长句会被截成语义不完整的状语前半段,需求背景放 `--cause`/`--solution`。前两个 step 的 `--output` 是中间摘要,不用此模板
112
112
  - **禁止**在没有运行 CLI 的情况下自行决定流程
113
113
 
114
114
  ## 用户指令
@@ -32,6 +32,8 @@ sillyspec progress show
32
32
 
33
33
  ### 3. 如果没有活跃变更
34
34
 
35
+ > 🔧 优先跑 `sillyspec next`——CLI 已内置下方探测表,直接输出「状态 + 下一步命令 + 依据」,按输出执行;异常时才按下方手工探测兜底。
36
+
35
37
  自动探测项目状态:
36
38
 
37
39
  ```bash
@@ -51,6 +51,10 @@ verify 是只读阶段(**禁止改代码/改 git 状态**,只检查 + 写报
51
51
 
52
52
  ## verify-result.md 格式
53
53
 
54
+ > 🔧 **机械探针 + 报告骨架一条命令**:`sillyspec verify-probes --change <变更名> --init`——探针 1(TODO 标记)/3(测试覆盖)/5(API 契约对账)/6(删除对账)CLI 跑完并预填进 verify-result.md 骨架(七章节、已存在不覆盖);探针 2/4(关键词/决策追踪)与断言抽查、集成盲区标注是语义判断,替换骨架里的 `<!--TODO-->` 完成。结论必须写明 PASS/FAIL——留「待填」会被 gate 判不过。
55
+ >
56
+ > 🔧 **test/lint 实测对账**:`--done` 时 CLI 亲自执行 local.yaml 的 `commands.test`(实测失败阻断 verify 完成)与 `commands.lint`(advisory 对账,实测失败会明示)——自报告与实测不符时以实测为准,勿谎报跑过。
57
+
54
58
  ```markdown
55
59
  # 验证报告
56
60
  ## 结论
@@ -14,7 +14,13 @@ description: 工作区管理 — 初始化、管理多项目工作区,查看
14
14
 
15
15
  ## CLI 边界(重要)
16
16
 
17
- sillyspec CLI **没有 `workspace` 顶层命令**。本 skill 通过直接读写 `.sillyspec/projects/*.yaml` 管理工作区,配套用 `sillyspec scan` 扫描子项目、`sillyspec init` 安装命令模板。**不要编造 `sillyspec workspace ...` 子命令。**
17
+ `sillyspec workspace` 命令已存在(2026-08-21 落地):
18
+ ```bash
19
+ sillyspec workspace add <名> <相对路径> [--role <角色>] [--repo <仓库地址>] # 登记子项目(外科写入 yaml,已有字段保留)
20
+ sillyspec workspace remove <名> # 删除登记(项目本体不动)
21
+ sillyspec workspace status # 三态探测表(已扫描/已初始化/未初始化)
22
+ ```
23
+ 优先用命令;命令异常时才按下文手工兜底(yaml 字段口径:init 写 name/path/status 三字段,role/repo 由 add 追加)。
18
24
 
19
25
  ## 相关 CLI 命令
20
26
 
package/README.md CHANGED
@@ -109,7 +109,7 @@ SillySpec 进度库使用 SQLite 持久化(基于 Node.js 内置的 `node:sqli
109
109
  |---|---|
110
110
  | `/sillyspec:status` · `/sillyspec:state` | 查看进度 / 当前工作状态 |
111
111
  | `/sillyspec:continue` | 自动判断并执行下一步 |
112
- | `/sillyspec:explore` | 自由思考:画图、讨论、调研 |
112
+ | `/sillyspec:explore` | 自由思考:画图、讨论、调研、HTML 原型 |
113
113
  | `/sillyspec:quick` | 快速模式:跳过完整流程 |
114
114
  | `/sillyspec:resume` | 恢复工作(支持大模块阶段进度) |
115
115
  | `/sillyspec:doctor` | 项目自检与状态修复 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sillyspec",
3
- "version": "3.26.14",
3
+ "version": "3.27.1",
4
4
  "description": "SillySpec CLI — 流程状态机,让 AI 严格按步骤来",
5
5
  "icon": "logo.jpg",
6
6
  "homepage": "https://sillyspec.ppdmq.top/",
@@ -468,10 +468,19 @@ function startServer({ port = 3456, open: openBrowser = true } = {}) {
468
468
  res.end(JSON.stringify({ error: 'Missing project parameter' }))
469
469
  return
470
470
  }
471
- const docs = parseSillyspecDocsTree(projectPath)
472
- res.setHeader('Content-Type', 'application/json')
473
- res.writeHead(200)
474
- res.end(JSON.stringify(docs))
471
+ // SEC-06 对齐:detail/content API 均已限"已发现项目内",此处此前漏校验——
472
+ // 任意绝对路径可列其 .sillyspec/docs 树与根文档文件名
473
+ isKnownProjectPath(projectPath).then(known => {
474
+ if (!known) {
475
+ res.writeHead(403)
476
+ res.end(JSON.stringify({ error: 'Unknown project path' }))
477
+ return
478
+ }
479
+ const docs = parseSillyspecDocsTree(projectPath)
480
+ res.setHeader('Content-Type', 'application/json')
481
+ res.writeHead(200)
482
+ res.end(JSON.stringify(docs))
483
+ })
475
484
  return
476
485
  }
477
486
 
@@ -591,8 +600,15 @@ function startServer({ port = 3456, open: openBrowser = true } = {}) {
591
600
  break
592
601
  case 'docs:get':
593
602
  if (data.data?.projectPath) {
594
- const docs = parseSillyspecDocsTree(data.data.projectPath)
595
- ws.send(JSON.stringify({ type: 'docs:tree', data: docs }))
603
+ // SEC-06 对齐:与 /api/docs 同口径,仅已发现项目可列 docs 树
604
+ isKnownProjectPath(data.data.projectPath).then(known => {
605
+ if (!known) {
606
+ ws.send(JSON.stringify({ type: 'docs:tree', data: { error: 'Unknown project path' } }))
607
+ return
608
+ }
609
+ const docs = parseSillyspecDocsTree(data.data.projectPath)
610
+ ws.send(JSON.stringify({ type: 'docs:tree', data: docs }))
611
+ })
596
612
  }
597
613
  break
598
614
  default:
@@ -90,19 +90,29 @@ export const VERIFICATION_NEEDS = {
90
90
  },
91
91
  real_daemon_backend_integration: {
92
92
  desc: '真实 daemon↔backend 集成验证(非仅 mock 单测)。写「真实集成/端到端」的证据;',
93
- literals: ['端到端', 'integration test', 'e2e test', 'daemon.*backend', '真实集成', 'runtime evidence', '运行时证据'],
93
+ // 同义扩充(坑 verify-literal-evidence-mismatch,2026-08-22 实证:证据第一轮就齐但表述
94
+ // 不含字面词被误拦三轮)——覆盖常见自然表述 + PID 登记句式(verify prompt 要求照写)
95
+ literals: ['端到端', 'integration test', 'e2e test', 'daemon.*backend', '真实集成',
96
+ 'runtime evidence', '运行时证据', '联调', '打通', '实际请求', '真实请求', '跨进程',
97
+ 'PID 已登记', 'verify-services'],
94
98
  },
95
99
  runtime_log_evidence: {
96
100
  desc: 'Runtime Evidence section + 指向真实日志/证据片段。',
97
- literals: ['Runtime Evidence', '运行时证据', 'daemon log', '日志片段'],
101
+ literals: ['Runtime Evidence', '运行时证据', 'daemon log', '日志片段', '日志关键',
102
+ '日志:', '日志摘录', '日志', 'log 摘录', 'log 片段', '进程日志', 'PID 已登记', 'verify-services'],
98
103
  },
99
104
  real_startup_once: {
100
105
  desc: '真实启动一次本变更触及的部署/启动入口(服务入口、CLI 主入口、守护进程等——须是本变更实际改动的那一类入口,不能拿无关进程的启动来凑数)。',
101
- literals: ['启动.*一次', '实际.*启动', 'real startup', 'docker up', 'npm start', 'node server'],
106
+ // 同义扩充(同坑):自然表述 + CLI 回执句式;checkIntegrationEvidence 另拼 CLI 回执文本
107
+ //(verify-services.receipt.json,服务回收器落盘)——结构化信号不依赖 agent 措辞
108
+ literals: ['启动.*一次', '实际.*启动', 'real startup', 'docker up', 'npm start', 'node server',
109
+ '真实启动', '拉起', '已启动', '进程启动', '服务启动', '启动验证',
110
+ 'PID 已登记', 'verify-services'],
102
111
  },
103
112
  terminal_state_assertion: {
104
113
  desc: '终态断言(建议项,不阻断):AgentRun running→completed/failed、session/lease end 状态同步。',
105
- literals: ['terminal state', '终态', 'completed failed', 'session end', 'lease end'],
114
+ literals: ['terminal state', '终态', 'completed failed', 'session end', 'lease end',
115
+ '生命周期终态', '状态同步'],
106
116
  },
107
117
  }
108
118
 
@@ -202,11 +212,16 @@ export function detectChangeRisk({ designContent = '', planContent = '', changed
202
212
 
203
213
  /**
204
214
  * 检查 verify-result.md 是否包含集成验证证据
215
+ *
216
+ * opts.extraEvidenceText(坑 verify-literal-evidence-mismatch,2026-08-22):调用方可注入
217
+ * CLI 结构化回执文本(如 verify-services.receipt.json 的服务回收回执)——它随 verifyContent
218
+ * 一起参与 literals 匹配,agent 真实起过服务且 CLI 回收过(有回执)时不再依赖其自然语言
219
+ * 措辞恰好含字面词,表述差异不再误拦。
205
220
  */
206
- export function checkIntegrationEvidence(verifyContent, requiredVerification) {
221
+ export function checkIntegrationEvidence(verifyContent, requiredVerification, opts = {}) {
207
222
  const errors = []
208
223
  const warnings = []
209
- const lower = verifyContent.toLowerCase()
224
+ const lower = (String(verifyContent || '') + '\n' + String(opts.extraEvidenceText || '')).toLowerCase()
210
225
 
211
226
  // 字面证据正则从 VERIFICATION_NEEDS[k].literals 派生——与报错描述、prompt 事前契约严格同源,
212
227
  // 杜绝历史上"描述说 A、正则查 B"的分叉(checkIntegrationEvidence 正则曾比 VERIFICATION_NEEDS