sillyspec 3.28.13 → 3.29.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 (47) hide show
  1. package/package.json +1 -1
  2. package/src/blast-surface.js +168 -0
  3. package/src/ceremony-tier.js +359 -0
  4. package/src/change-risk-profile.js +72 -199
  5. package/src/config-schema.js +22 -1
  6. package/src/decisions-io.js +32 -0
  7. package/src/design-facts.js +1 -0
  8. package/src/doctor-diagnostics.js +119 -1
  9. package/src/index.js +92 -5
  10. package/src/knowledge-stats.js +25 -0
  11. package/src/modules.js +28 -0
  12. package/src/prefill.js +491 -0
  13. package/src/probe7-anchor-check.js +8 -6
  14. package/src/quick-gate-profile.js +8 -4
  15. package/src/quick-session-owner.js +63 -0
  16. package/src/redlines.js +195 -0
  17. package/src/review-dispatch.js +473 -1
  18. package/src/review-material-pack.js +265 -0
  19. package/src/review-tier.js +185 -41
  20. package/src/run/archive-distill.js +6 -0
  21. package/src/run/command.js +158 -87
  22. package/src/run/complete-handlers.js +82 -1
  23. package/src/run/complete.js +90 -3
  24. package/src/run/gate-snapshot.js +30 -1
  25. package/src/run/gates.js +301 -19
  26. package/src/run/prompt.js +423 -21
  27. package/src/run/quick-audit.js +12 -2
  28. package/src/run/shared.js +36 -0
  29. package/src/run/verify-quality-scan.js +15 -7
  30. package/src/scope-audit.js +8 -1
  31. package/src/span-risk-surface.js +127 -0
  32. package/src/stage-contract-spec.js +2 -2
  33. package/src/stage-contract.js +102 -81
  34. package/src/stage-review.js +26 -2
  35. package/src/stages/brainstorm-auto.js +1 -1
  36. package/src/stages/brainstorm.js +35 -19
  37. package/src/stages/execute.js +11 -3
  38. package/src/stages/plan.js +45 -24
  39. package/src/stages/scan.js +1 -1
  40. package/src/stages/verify.js +7 -7
  41. package/src/taskcard.js +3 -0
  42. package/src/verify-postcheck.js +375 -20
  43. package/src/verify-probes.js +194 -10
  44. package/src/worktree-apply.js +1 -1
  45. package/src/worktree.js +1 -1
  46. package/templates/prompts/taskcard-rules.md +1 -0
  47. package/templates/prompts/verify-probes.md +1 -1
@@ -440,8 +440,9 @@ ${REVIEW_CHECKLISTS.execute.map((item, index) => ' ' + (index + 1) + '. ' + ite
440
440
  **执行纪律(坑 review-subagent-stall,2026-09-15 wp EHS 会话实证)**:brainstorm/plan 阶段已实证的结论(既往 stage-review checklist pass 项、file:line 锚点)直接引用勿重验;必读材料读完即逐条出结论落盘,仅结论存疑时定向补证,禁止循环扩大核验面(连续读文件 10+ 次仍零结论 = 基于已读材料立即收敛)。QA 子代理写操作持续被平台拒绝(session not in running turn 类)→ 重试 ≤3 次即停,完整结论(含 review.json 全文)回传主代理代落盘,reviewerNotes 首行留痕「代落盘:子代理写通道故障」;禁止长时间空转重试。
441
441
  **gate 重试修复**:review.json 落盘后若 design.md 又有改版,gate 会**自动机械重算 docHash 放行**(verdict/checklist 保留,结论是否仍适用于新文档需人工确认)——**不要重做审查**(重做=同一材料第三遍);主文档路径错/缺失不会被自动修复,按 gate 报错修正 reviewedFiles[0],或跑 \`sillyspec register-stage-review --change <变更名> --stage execute --refresh-hash\`。
442
442
 
443
- ### 操作
444
- 1. 读取 design.md(技术方案)——按章节精准读(design-check 对照表可借 tasks 卡 §锚点定位),避免反复整读全文
443
+ ### 操作(材料包口径——2026-09-19-review-material-cli-wiring)
444
+ 1. **评审材料包(基准面)**:CLI 已机械组装注入下方(src/review-material-pack.js assembleStageReviewMaterials('execute-qa'):diff 摘要+design 热区+验收清单)——checklist 逐条只对包作答;包外文件可定向查证但须列明(禁全量扫读);包不足以作答→cannot_verify+requiredEvidence 列缺件。task review 双 pass 抽查、未双 pass 全量重审的分级照旧(上方「审查范围分级」);tier=independent 时把整包贴进 QA 子代理派发 prompt:
445
+ {REVIEW_MATERIALS}
445
446
  2. 逐一对照 design.md 中的设计要点与实际代码实现
446
447
  3. 检查接口签名、数据结构、模块划分是否一致
447
448
  4. 记录偏差项(偏差 ≠ 错误,可能是合理的实现调整)
@@ -885,7 +886,7 @@ export function buildWavePrompt(wave, waveIndex, changeDir, worktreePath, option
885
886
  if (relevantContracts.length > 0) {
886
887
  contractInjection = `
887
888
  ### API Contract Matrix
888
- 本 Wave 存在前端/后端跨 task 契约:
889
+ 本 Wave 存在跨 task 契约(provider → consumer):
889
890
  ${relevantContracts.map(c => `- **${c.consumer}** 消费 **${c.provider}** 产出的 API`).join('\n')}
890
891
  `
891
892
  for (const taskName of waveTasks) {
@@ -1234,6 +1235,8 @@ ${workdirLines}
1234
1235
  蓝图文件(tasks.md / design.md / proposal.md / requirements.md)在主工作区 {SPEC_ROOT}/changes/<change>/ 下(CLI 已替换为主仓绝对路径),它们可能不在 worktree 中。读取蓝图时使用主工作区路径,不要拼接到 worktree 路径下。
1235
1236
 
1236
1237
  ⚠️ **铁律:spec 流程产物只写主仓 {SPEC_ROOT},绝不写进 worktree 副本**——包括 module-impact.md / knowledge 条目 / 模块卡与 \`<module>.changelog.md\` sidecar。在 worktree 内发现 \`.sillyspec/\` 目录是 checkout 副本,写进去的任何内容都会随 worktree cleanup 整目录蒸发(2026-09-10 实证:模块文档写副本、归档被迫 checkout 补救)。子代理 prompt 中涉及此类产物时,必须原样带上主仓绝对路径。
1238
+
1239
+ ⚠️ **Python 导入链陷阱(venv editable install,2026-09-18 实证)**:worktree 内跑任何 \`import <项目包>\` / dump_openapi / 代码生成类命令时,若用的是主仓 venv(junction 链接或裸调主仓 python),其 editable install(\`_editable_impl_*.pth\`)指向**主仓**绝对路径——项目包 import 会静默解析到主仓旧代码,产出旧 schema/旧行为且零报错(看似「改动没生效」)。**跑生成链前设 \`PYTHONPATH=<worktree>/<项目源码根>\`**(PYTHONPATH 优先于 .pth),或用 worktree 自建 venv;\`sillyspec worktree doctor\` 的 editable-install-escape 检查可提前暴露。
1237
1240
  `
1238
1241
  : ''
1239
1242
  }
@@ -1316,6 +1319,7 @@ ${taskSummary}
1316
1319
  4. ${moduleDocPoint}
1317
1320
  5. 任务含测试代码时,把下方「测试用例设计」整段复制进子代理 prompt,要求子代理按此设计测试用例
1318
1321
  6. **增量落盘与中断接手指引**:每完成一个可见产出(代码/测试/文档),立即写盘并执行一次最小验证(如语法检查、单跑相关测试)。工作过程中如被 429/API 配额/会话中断,应在最终回复里输出「已完成清单」(含文件路径、测试命令、当前卡点),不要只输出结论——主代理会依据磁盘产物和该清单判断哪些部分已完成,哪些需接手补做,避免重做已落盘的工作
1322
+ **中间验证定向优先:node --test <本任务测试文件>;全量 npm test 留 task 收口与 verify --done**(测选路引导,2026-09-18-preflight-slimming task-04:中间验证只跑本任务相关测试文件,全量套件留给 task 收口与 verify --done,防每步全量测试拖慢执行;与 taskcard-rules.md verify 段同款文案)
1319
1323
  7. **任务边界铁律**:严格只实现本 task 的 \`allowed_paths\` 内文件;若 design.md/plan.md 明确指定了接口/回调/钩子接入位置,必须逐字遵守;不允许顺手实现其他 task 的内容(如 task-01 不要把 task-02 的接入也做了)。如发现必须改其他 task 文件才能继续,先回到主代理由主代理决定是否重分 Wave 或调整 plan,禁止子代理私自越界
1320
1324
  8. **batch 子代理协议**(仅当按「执行方式」节条件合并 batch 时附加进该子代理 prompt):按 batch 内 task 顺序逐个完成实现闭环——读取 tasks/task-N.md → 实现 → 跑该 task 的 verify 命令 → 记录该 task 报告(改动文件清单 / verify 结果 / 卡点)→ 才开始下一个 task;最终回复输出逐 task 报告清单。禁止写 review.json、禁止勾选 tasks.md checkbox——task 审查与勾选归主 agent,在子代理返回后逐 task 进行。越权即停:发现必须改 batch 内其他 task 或任何 batch 外 task 的 allowed_paths 文件 → 立即停止本 task 及后续,报告冲突文件与卡点,回主 agent 裁决(重分 Wave / 调整 plan / 回退独立子代理)。第 7 条任务边界铁律在 batch 语境下的「本 task」= 当前正在实现的 task
1321
1325
  ${globalConstraintsBlock}
@@ -1463,6 +1467,10 @@ export function buildExecuteSteps(planFilePath = null, options = {}) {
1463
1467
  const waveSteps = waves.map((wave, i) => ({
1464
1468
  name: `Wave ${i + 1} 执行`,
1465
1469
  mode: 'implementation',
1470
+ // 前置失败清单声明(2026-09-18-preflight-slimming task-04,D-001@v1):任务步预留键位——
1471
+ // allowed_paths 越界速查(allowed-paths-scan)留 v2 扩展点(run/prompt.js PREFLIGHT_VALIDATORS
1472
+ // 未收录键安全跳过),本期显式空声明锚定 shape,渲染行为与未声明同态(恒空清单零注入)。
1473
+ preflightValidators: [],
1466
1474
  prompt: buildWavePrompt(wave, i + 1, changeDir, worktreePath, { dispatchMode: options.dispatchMode, branch: options.branch, ctx, _execCache: execCache }),
1467
1475
  outputHint: `Wave ${i + 1} 执行结果`,
1468
1476
  optional: false
@@ -92,13 +92,17 @@ const stepClassify = {
92
92
  判定为 full(满足任一即升为 full):
93
93
  - 预计 8 个以上 task
94
94
  - 跨 3 个以上模块
95
- - 涉及 CLI + 平台 + DB 联动
95
+ - 跨技术层联动(同一变更需多层协同改造,如前端 + 服务端 + 数据库)
96
96
  - 涉及 agent 调度 / worktree / isolation 逻辑
97
97
  - 涉及复杂状态恢复(checkpoint / resume)
98
98
  - 需要并行 sub-agent 执行
99
99
  - 需要人工审查设计方向
100
100
  - 涉及 worktree / baseline / sandbox 等基础设施
101
101
 
102
+ ### plan_level 语义(编排标签,不定价评审仪式)
103
+ plan_level 只决定**工作量轴**:wave 拆分、并行子代理调度、plan 模板厚度(none 占位 / light 四段 / full 全蓝图)。
104
+ 评审仪式档位(ceremony_tier,S0~S3)由 CLI 按 blast/span/friction 三轴风险**客观定价**(风险轴),与 plan_level 无关——「计划写得完整」不会、也不应触发更重的评审仪式;反之,agent 报 full 但档位为 S0/S1 时,CLI 强制轻仪执行并在审查步注入文案留审计痕。plan_level 按编排需要如实判定即可,勿用它博取或回避评审强度。
105
+
102
106
  ### 输出格式
103
107
  在输出开头,以如下格式输出分类结果:
104
108
 
@@ -130,7 +134,12 @@ needs_human_review: true | false
130
134
  const stepGeneratePlan = {
131
135
  id: 'generate_plan',
132
136
  name: '生成分级计划',
133
- prompt: `根据 plan.md frontmatter 的 plan_level 结果,按对应级别生成计划。
137
+ // 前置失败清单声明(2026-09-18-preflight-slimming task-04,D-001@v1):产出 plan.md 前置快查
138
+ // brainstorm 四件套规则轻子集(与生成分级计划 --done 消费的门禁同源;postcheck 轻子集
139
+ // postcheck-lite 为 v2 扩展点——PREFLIGHT_VALIDATORS 未收录,勿用)。声明键位随步骤定义
140
+ // 分发(键名消费见 run/prompt.js renderPreflightFailures)。
141
+ preflightValidators: ['four-piece-rules'],
142
+ prompt: `根据 plan.md frontmatter 的 plan_level 结果,按对应级别生成计划。plan_level 只决定编排(wave 拆分 / 并行子代理 / 模板厚度——工作量轴);评审仪式档位一律由 ceremony_tier 按 risk 客观定价(风险轴),与本步所选级别无关。
134
143
 
135
144
  ### 操作
136
145
  1. 读取 plan.md frontmatter 的 \`plan_level:\` 字段(上一步已落盘为持久锚点;文件不存在或无该字段时回退读上一步输出的分类结果)
@@ -148,7 +157,7 @@ const stepGeneratePlan = {
148
157
  ---
149
158
 
150
159
  #### plan_level = none
151
- 生成最小 plan.md(占位文件,保持流程兼容),不生成完整蓝图。格式:
160
+ 生成最小 plan.md(占位文件,保持流程兼容),不生成完整蓝图(plan_level=none 只收缩编排与模板厚度,不减免评审仪式——仪式档位由 ceremony_tier 定价)。格式:
152
161
  \`\`\`markdown
153
162
  ---
154
163
  plan_level: none
@@ -173,7 +182,7 @@ plan_level: none
173
182
  ---
174
183
 
175
184
  #### plan_level = light
176
- 生成轻量 plan.md,保存到变更目录。只包含以下四部分:
185
+ 生成轻量 plan.md,保存到变更目录(plan_level=light 只决定轻量模板与简化编排,不升降评审仪式——仪式档位由 ceremony_tier 定价)。只包含以下四部分:
177
186
 
178
187
  \`\`\`markdown
179
188
  ---
@@ -212,7 +221,7 @@ light 计划的约束:
212
221
  ---
213
222
 
214
223
  #### plan_level = full
215
- 生成完整 plan.md,保存到变更目录。格式如下:
224
+ 生成完整 plan.md,保存到变更目录(plan_level=full 只展开完整蓝图与 wave/并行编排,不加重评审仪式——仪式档位由 ceremony_tier 定价;agent 报 full 而档位 S0/S1 时 CLI 强制轻仪并留审计痕)。格式如下:
216
225
 
217
226
  \`\`\`markdown
218
227
  ---
@@ -315,13 +324,18 @@ plan_level + 计划内容(审查在下一步独立进行)`,
315
324
 
316
325
  /**
317
326
  * 审查计划 step —— 把"审查"从生成 step 拆出(原 stepGeneratePlan 生成+自检同次输出是最严重的 self-review)。
318
- * 按规模分级:tier=self 当前 agent 自审;tier=independent 强制独立子代理 + review.json。
319
- * 占位符 {REVIEW_TIER} / {REVIEW_TIER_REASON} / {STAGE_REVIEW_RUN_ID} 由 run.js 注入。
327
+ * 按档分级(2026-09-18-ceremony-risk-pricing task-05):tier 由 ceremony_tier 风险定价映射——
328
+ * S0/S1→self(CLI 清单核验[+定向探针])、S2/S3→independent(单轮/两轮);plan_level 降级为编排标签,
329
+ * 不再驱动评审仪式档。占位符 {REVIEW_TIER} / {REVIEW_TIER_REASON} / {STAGE_REVIEW_RUN_ID} 由 run.js 注入
330
+ * ({REVIEW_TIER} 注入值随附 ceremony 档位菜单,见 run/prompt.js renderCeremonyTierInjection)。
320
331
  */
321
332
  const stepReviewPlan = {
322
333
  id: 'review_plan',
323
334
  name: '审查计划',
324
335
  conditionalWait: true,
336
+ // 前置失败清单声明(2026-09-18-preflight-slimming task-04):审查步不产出规范文件、无
337
+ // --done 门禁面要前置快查——显式空声明锚定键位(renderPreflightFailures 空/未声明同态返 '')。
338
+ preflightValidators: [],
325
339
  waitReason: '等待用户确认计划后进入执行',
326
340
  waitOptions: ['确认,进入执行', '需要调整'],
327
341
  prompt: `对上一步生成的 plan.md 做审查。生成与审查分离——不在生成 plan 的同一上下文里自审,避免确认偏差。
@@ -332,19 +346,22 @@ plan.md 审查通过后、进入 execute 前,若 plan_level=full(跨模块/
332
346
  - 调用:\`sillyspec run plan --wait --reason "等待用户确认计划" --options "确认,进入执行,需要调整" --output "计划摘要"\`
333
347
  - 用户确认后再 --done;plan_level=none/light(小变更)无需等待,正常完成即可
334
348
 
335
- ### 当前审查分级(CLI 按变更规模判定,占位符由 run.js 注入)
349
+ ### 当前审查分级(CLI 按 ceremony_tier 风险定价,占位符由 run.js 注入)
336
350
  tier: {REVIEW_TIER}({REVIEW_TIER_REASON})
337
- - tier=self:当前 agent 直接执行下方审查清单(小变更,独立审查仪式成本 > 收益)
338
- - tier=independent:必须用 Agent tool 启动一个独立的计划审查子代理(独立上下文,不共享你生成 plan 时的分析与倾向),由子代理执行下方审查清单并输出 review.json
339
- 宿主环境无 Agent tool 可用(调用报 Unknown agent / Available agents: none)→ 不卡死:主代理切换为审查者角色自审替代,reviewerNotes 首行记录「降级:环境无子代理可用」,逐条结论附源码锚点(file:line 或 grep/read 证据)补偿独立性。
351
+ - tier=self(ceremony 档 S0/S1):当前 agent 直接执行下方审查清单——S0=CLI 清单核验;S1=CLI 清单核验+定向探针抽查(对最高风险条目定向读源码验证)。轻仪是风险定价的正常形态而非偷懒豁免,清单机械项一条不省
352
+ - tier=independent(ceremony 档 S2/S3):必须用 Agent tool 启动独立的计划审查子代理(独立上下文,不共享你生成 plan 时的分析与倾向),由子代理执行下方审查清单并输出 review.json——S2=单轮;S3=两轮独立评审(视角互补,第二轮聚焦首轮未决项)
353
+ 宿主环境无 Agent tool 可用(调用报 Unknown agent / Available agents: none)→ 不卡死(降级兜底,仅评审通道全不可用时):主代理切换为审查者角色自审替代,reviewerNotes 首行记录「降级:环境无子代理可用」,逐条结论附源码锚点(file:line 或 grep/read 证据)补偿独立性。
354
+ - 仪式按 risk 计价,plan_level 仅编排:agent 自报 plan_level=full 而 CLI 判档 S0/S1 时,CLI 强制轻仪执行并在注入文案留审计痕(强制轻仪说明行随 tier 注入)——不因「计划写得完整」进入 independent×2,勿自行升仪对抗定价
340
355
 
341
356
  ### 审查清单(读取 plan.md 的 plan_level,逐条核对)
342
357
  ${REVIEW_CHECKLISTS.plan.map((item) => '- [ ] ' + item).join('\n')}
343
358
 
344
359
  ### tier=independent 时:启动 plan-review 子代理
345
360
  {PRIOR_REVIEW_FACTS}
346
- 用 Agent tool 启动子代理(subagent_type: general),prompt 要点:
347
- 1. 独立读取 {SPEC_ROOT}/changes/<change>/plan.md + design.md + tasks/*.md(不要让生成者喂结论给你,自己读原始文件)
361
+ 用 Agent tool 启动子代理(subagent_type: general),**材料包口径(2026-09-19-review-material-cli-wiring)**——CLI 已机械组装注入下方(src/review-material-pack.js assembleStageReviewMaterials('plan-review'):design 硬约束,缺「全局硬约束」节时 decisions.md P0/P1 accepted 决策兜底);「plan 差量」节留位——派发前由你逐约束判定补齐(一致/偏离/未覆盖+注),留空则评审者按 cannot_verify 列缺件。把补完的整包贴进派发 prompt:
362
+ {REVIEW_MATERIALS}
363
+ prompt 要点:
364
+ 1. **材料包是评审基准面**:checklist 逐条只对包作答;包外文件可定向查证但须列明(禁全量扫读);包不足以作答→cannot_verify+requiredEvidence 列缺件。plan.md 本体可读(审查对象),design.md 只读包内 digest+点名锚(不是全文)。
348
365
  2. 执行上方审查清单,每条给 pass/gap/fail + 证据
349
366
  3. 输出 review.json(CLI Stage Review Gate 将硬校验,契约如下 —— schema + 完整示例 + docHash 算法,照抄改值):
350
367
  {REVIEW_JSON_CONTRACT}
@@ -370,7 +387,7 @@ execute/verify 阶段会按实际代码变更更新此文档;archive 阶段会
370
387
  // ═══════════════════════════════════════════════════════════════
371
388
 
372
389
  /**
373
- * 构建紧凑 TaskCard 协调器步骤(单步,子代理按 batch 并行写卡片)
390
+ * 构建紧凑 TaskCard 协调器步骤(默认主 agent 直填;>8 任务且跨模块/上下文紧张时按 batch 派子代理)
374
391
  * 每个 task 生成 20~40 行紧凑可执行卡片
375
392
  * 允许把多个相关 task 合并为一个 batch,由单个子代理一次生成多张卡片,
376
393
  * 在保留 plan 任务拆分完整性的同时减少子代理调用数量。
@@ -399,7 +416,7 @@ allowed_paths: # ⚠️ 路径相对 repo 声明的
399
416
  target_files: # 可选。本 task 计划要改动的文件清单(文件级意图,供对账;与 allowed_paths 语义不同——那是权限范围)。骨架已预置 [] 占位行,无明确意图保留 [] 不动
400
417
  - src/foo.js # ✅ 精确仓根相对路径(口径同 allowed_paths);计划新建文件加 NEW: 前缀(NEW:src/bar.js)。❌ 禁 glob(src/**)/目录前缀(src/dir/)/绝对路径
401
418
  provides: # 可选。仅当本 task 给其他 task 提供接口/DTO/响应时填
402
- - contract: <DTO或响应类型名> # 如 DaemonRuntimeRead
419
+ - contract: <DTO或响应类型名> # 如 UserDTO
403
420
  fields: [field_a, field_b]
404
421
  expects_from: # 可选。仅当本 task 消费其他 task 的契约时填
405
422
  <provider-task-id>: # 如 task-05(占位符,不要照抄)
@@ -422,7 +439,7 @@ constraints:
422
439
  - 边界约束 2(如:不修改传入参数)
423
440
  related_tests: # 可选。当本 task 改动会导致既有测试断言失效时填(共享源文件/UI文案/常量/签名变更等,判据=测试是否失败非文件是否共享)
424
441
  - path: frontend/src/lib/errors.test.ts # 因本次改动断言失效的既有测试文件
425
- reason: 旧断言假设单例,改归属键后需同步
442
+ reason: 旧断言依赖本次要重构掉的实现细节,需同步
426
443
  ---
427
444
 
428
445
  {{include: taskcard-rules}}`
@@ -455,17 +472,21 @@ ${taskList}
455
472
  \`\`\`
456
473
  幂等,已存在的卡跳过不覆盖;骨架带 LF 行尾 + 闭合 frontmatter + 硬校验 9 字段 + depends_on 反填。**只有主 agent 跑这一次,子代理一律不再运行 taskcard CLI。**
457
474
  1. 确认 \`${changeDir}/tasks/\` 目录存在(上一步预生成会自动创建)
458
- 2. **按 batch 分派子代理(减少总子代理数量,而不是一个 task 一个子代理):**
475
+ 2. **默认主 agent 自己填卡(P0-2,2026-09-20 对撞实验驱动——6 个填卡子代理 6.7M token 做的是主 agent 可自完成的誊写,独立性价值为零):**
476
+ - task 总数 ≤8 或变更单仓单模块 → 主 agent 逐卡 Edit 填充(骨架已预生成,誊写近乎免费),**不派子代理**
477
+ - 仅当 task 总数 >8 **且**跨多模块/跨仓、或主会话上下文已明显吃紧时,才按 batch 分派子代理(此时并行省墙钟有真实收益)
478
+ 3. **(分派形态时)按 batch 分派子代理(减少总子代理数量,而不是一个 task 一个子代理):**
459
479
  - 把任务按「同一 Wave + 同一模块/相近能力 + 无跨 batch 强依赖」原则分组
460
480
  - **每个 batch 包含 2~4 个 task**;Wave 内任务数 ≤4 时整个 Wave 可作为一个 batch
461
481
  - 有提供/消费契约的 task 尽量放到同一 batch(子代理能同时看到 consumer 与 provider,避免契约字段漏配)
462
482
  - 跨 Wave 依赖的 task 不要放在同一 batch(子代理只需读 plan.md,但 batch 内 task 的 allowed_paths 不应互相阻塞)
463
- 3. 为每个 batch 启动一个独立子代理(Agent tool),可并行启动多个 batch
464
- 4. 每个子代理使用下方「批量 TaskCard 子代理 prompt」,一次生成该 batch 的全部 task-N.md
465
- 5. 等待所有 batch 子代理完成
466
- 6. 验证每个 task-N.md 文件已生成且非空
483
+ - batch 数量封顶 ≤3(13 任务≈3 batch 已足;再多是协调税)
484
+ 4. 为每个 batch 启动一个独立子代理(Agent tool),可并行启动多个 batch
485
+ 5. 每个子代理使用下方「批量 TaskCard 子代理 prompt」,一次生成该 batch 的全部 task-N.md
486
+ 6. 等待所有 batch 子代理完成
487
+ 7. 验证每个 task-N.md 文件已生成且非空
467
488
 
468
- > 设计意图:plan.md 里 task 数可以较多(能力拆分完整),但 TaskCard 生成阶段要合理合并,避免子代理数量随 task 数线性爆炸。一个子代理生成 2~4 张卡片与生成 1 张卡片的 token/时间成本接近,却能显著减少协调开销。
489
+ > 设计意图:plan.md 里 task 数可以较多(能力拆分完整),但 TaskCard 生成阶段的**默认形态是主 agent 直填**——卡是 design/plan 的誊写不是创作,主 agent 刚写完 plan 上下文最热;子代理只在规模/上下文压力真实存在时才有净收益(每个子代理都要重读 design+plan+源码,6 个子代理 6.7M token 的实证教训)。分派时合并 batch,避免子代理数量随 task 数线性爆炸。
469
490
 
470
491
  ### 批量 TaskCard 子代理 prompt
471
492
  \`\`\`
@@ -493,7 +514,7 @@ ${taskcardTemplate}
493
514
  ## 约束
494
515
  - 每个 task 20~40 行;禁止在 TaskCard 里写实现细节之外的冗长设计
495
516
  - 同 batch 内 task 的 allowed_paths 不要互相冲突
496
- - **跨仓 task 路径口径(涉及 local.yaml repos: 注册仓的变更必读)**:跨仓 task frontmatter 必须填 \`repo: <repo-key>\`(local.yaml repos: 注册键,缺省=main 省略不填);allowed_paths 相对**该仓根**写(\`src/routes/x.js\`),从 design.md「\`## <repo-key> 仓变更\`」段内路径原样搬。❌ 禁止带仓库名前缀(\`sub-grid-security/src/...\`)、❌ 禁止绝对路径/盘符(\`C:/repo/src/...\`)——review 对账按 \`git -C <仓根> diff\` 的仓根相对路径匹配 allowed_paths,带前缀/绝对路径永不命中 → task 改完却判「无归属」对账不上
517
+ - **跨仓 task 路径口径(涉及 local.yaml repos: 注册仓的变更必读)**:跨仓 task frontmatter 必须填 \`repo: <repo-key>\`(local.yaml repos: 注册键,缺省=main 省略不填);allowed_paths 相对**该仓根**写(\`src/routes/x.js\`),从 design.md「\`## <repo-key> 仓变更\`」段内路径原样搬。❌ 禁止带仓库名前缀(\`<repo-key>/src/...\`)、❌ 禁止绝对路径/盘符(\`C:/repo/src/...\`)——review 对账按 \`git -C <仓根> diff\` 的仓根相对路径匹配 allowed_paths,带前缀/绝对路径永不命中 → task 改完却判「无归属」对账不上
497
518
  - 若 task 之间有 provides/expects_from 契约,同 batch 生成时必须字段对齐
498
519
  - 只生成本 batch 声明的任务,不要多写或少写
499
520
  - 不要在 TaskCard 里泄露 plan.md 中未出现的实现假设
@@ -521,7 +542,7 @@ ${taskcardTemplate}
521
542
 
522
543
  return {
523
544
  id: 'generate_blueprints',
524
- name: '生成 TaskCard(子代理按 batch 并行)',
545
+ name: '生成 TaskCard(默认主代理直填,大规模才派 batch)',
525
546
  prompt,
526
547
  outputHint: 'TaskCard 生成结果',
527
548
  optional: false
@@ -289,7 +289,7 @@ modules:
289
289
  ### 示例
290
290
  \`\`\`yaml
291
291
  schema_version: 2
292
- project: multi-agent-platform
292
+ project: demo-platform
293
293
  source_commit: abc1234
294
294
  generated_at: 2026-06-02 22:00:00
295
295
  generator: sillyspec-scan
@@ -162,7 +162,7 @@ export const definition = {
162
162
  2. 如果存在:
163
163
  - 逐个读取 tasks/task-NN.md,对照 frontmatter 的 \`acceptance:\` 列表逐条核验(TaskCard 协议的验收标准在 frontmatter YAML,正文无 checkbox)
164
164
  - 每条 acceptance 对照实际实现/测试结果判定满足与否,未满足的项列为不通过
165
- - 覆盖对账走探针 7 矩阵:verify-result.md「探针 7:验收×测试覆盖矩阵」段已由 CLI 预填归属测试文件与关键词提示(骨架未生成时先跑 \`sillyspec verify-probes --change <change-name> --init\`,幂等不覆盖已有正文);逐行填判定(covered/partial/uncovered/non-testable 四选一)与证据——covered/partial 附测试锚点(file:line / \`.test.\` 测试文件名 / 反引号包裹的路径或测试名,行号可省),non-testable 写一句理由;判定/证据未填会被 verify \`--done\` 门禁阻断(fail-closed)
165
+ - 覆盖对账走探针 7 矩阵:verify-result.md「探针 7:验收×测试覆盖矩阵」段已由 CLI 预填归属测试文件与关键词提示(骨架未生成时先跑 \`sillyspec verify-probes --change <change-name> --init\`,幂等不覆盖已有正文);逐行填判定(covered/covered-service/partial/uncovered/non-testable 五选一——covered-service 适用:端点行为由 service 层等非端点层测试锁定,证据附测试锚点)与证据——covered/covered-service/partial 附测试锚点(file:line / \`.test.\` 测试文件名 / 反引号包裹的路径或测试名,行号可省),non-testable 写一句理由;判定/证据未填会被 verify \`--done\` 门禁阻断(fail-closed)
166
166
  3. 如果不存在:跳过此步骤
167
167
 
168
168
  ### 输出
@@ -191,11 +191,11 @@ export const definition = {
191
191
 
192
192
  ### 操作
193
193
  1. 汇总以上所有检查结果
194
- 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 完成——谎报结论无效。
195
- - **判级是机械字面匹配 + 同句否定抑制**:关键词命中位置前方同句有否定提示(不/未/无/避免…,如「本次不新增 daemon 协议」)时该次命中被抑制、不参与判级;「daemon 不稳定」「不同模块的 daemon」这类否定词不在关键词前方的仍正常命中。
196
- - **误判时的诚实出路(豁免级)**:在 design.md 顶部 frontmatter 加一行 \`risk_level: <真实等级>\`(doc-only / unit-sufficient / contract-required / integration-critical / deployment-critical),CLI 会以声明为准覆盖关键词判级。声明后若是 unit-sufficient 等豁免级,PASS WITH NOTES 不再被强制拦;但结论为 PASS 仍需对应证据。
197
- - **留痕要求(防逃逸)**:用了显式声明,必须在本报告「变更风险等级」section 写明「risk_level 由 design frontmatter 显式声明 = <等级>(覆盖关键词判级)」+ 一句话理由,让豁免可审计;若有命中被否定语境抑制,同样写明被抑制关键词与理由(抑制可审计,不许用来静默降级)。
198
- 你只需:在 verify-result.md 的「变更风险等级」section 如实记录变更性质;若变更涉及 daemon/backend 跨进程、session/lease/lifecycle 状态机、或部署启动路径,在「Runtime Evidence」section 提供真实集成证据(启动命令、daemon↔backend 调用与日志关键片段、终态断言)。
194
+ 2. **变更风险等级(change_risk_profile)由 CLI 自动判定与门控**:你无需自己扫描。本步骤 --done 时,CLI 按项目声明危险面(\`_module-map.yaml\` 顶层 blast 段的路径前缀声明)× 变更文件面自动判定(2026-09-19-ceremony-pricing-five-cuts 起的声明面口径——文档措辞与文件内容不参与判级),并强制门控:命中 evidence:true 声明路径的变更若结论为 PASS / PASS WITH NOTES 但缺少真实集成证据,CLI 直接阻断 verify 完成——谎报结论无效。
195
+ - **判级输入=文件路径 × 项目声明**(不是关键词):变更文件(design 文件变更清单 / 实际 diff)命中声明前缀即取该声明档位;未配置项目/未命中路径一律 S1 起步。「撞词」时代结束:文档里写 daemon/session 等措辞不再影响判级。
196
+ - **frontmatter risk_level 的作用边界**:在 design.md 顶部 frontmatter 加 \`risk_level: <等级>\`(doc-only / unit-sufficient / contract-required / integration-critical / deployment-critical)可**压低/抬高仪式档**(评审轮次定价),但**不豁免 evidence:true 命中的集成证据要求**——证据豁免的唯一出路是改 \`_module-map.yaml\` blast 段的 evidence 声明(进 git、评审可见),不得靠声明措辞绕证据门。
197
+ - **留痕要求(防逃逸)**:用了显式声明,必须在「变更风险等级」section 写明「risk_level 由 design frontmatter 显式声明 = <等级>(压仪式档;evidence 要求不受豁免)」+ 一句话理由,让声明可审计。
198
+ 你只需:在 verify-result.md 的「变更风险等级」section 如实记录变更性质;若变更文件命中 evidence:true 声明路径(CLI 会在 design/verify 门禁 warnings 点名命中前缀),在「Runtime Evidence」section 提供真实集成证据(启动命令、跨进程调用与日志关键片段、终态断言)。
199
199
  - **集成回执须真实执行——commands.smoke 配置后由 CLI 亲跑并机器落盘(source: cli-noai-smoke 标记,亲跑段谎报无效)**,其余形态仍须 agent 实跑后据实填写:CLI 对其余形态只校验**字面存在**(是否含关键词),**不会替你启动 daemon、打真实请求或跑迁移**——它是否名副其实取决于你是否实跑过,不得凭堆关键词通过门控。(测试套件对账另算:commands.test 由 CLI 真实执行,那块谎报无效。)
200
200
 
201
201
  3. **生成 verify-result.md 骨架(勿从零手写)**:先跑 \`sillyspec verify-probes --change <change-name> --init\`——一条命令生成十章节骨架(已存在不覆盖),其中**探针结果章节已机械预填**(探针 1 的 TODO/FIXME 命中清单、探针 3 的测试覆盖、探针 5 的 API 契约对账表、探针 6 的删除对账三态判定),文件落 \`{SPEC_ROOT}/changes/<change-name>/verify-result.md\`(CLI 替换出的**主仓绝对路径**;若当前 cwd 在 worktree 内也绝不落 worktree 副本——CLI 校验读主仓,副本随 worktree 清理蒸发)。你只需把各 \`<!--TODO-->\` 占位替换为语义结论;半语义探针(2 关键词覆盖 / 4 决策追踪)与断言抽查、集成盲区标注由你补在对应 TODO 处
@@ -204,7 +204,7 @@ export const definition = {
204
204
  6. 给出结论:PASS / PASS WITH NOTES / FAIL(受风险门控约束)——**结论只认骨架「结论枚举:」槽行(行首锚定,把 <待填:三选一> 整体替换为枚举值);槽留待填会被 gate 判不过,正文其他位置的 PASS/FAIL 字样不参与判定**
205
205
  - **结论想写 PASS 前自查四事实条件(PASS 封顶语义,--done 门禁按 verify-facts.json 实拦)**:①集成实测未跑 ②「## 移交项(结构化)」含 blocking 级行 ③db/**/*.sql 未声明执行(verify-result.md 无「已对目标库执行」声明、回执 command 亦不含该文件)④验收×测试覆盖矩阵含 partial/uncovered 行且移交项零有效行——任一成立即不得写 PASS:改写 PASS WITH NOTES 并在「## 移交项(结构化)」表格如实分行(类型枚举 env-blocked/manual-acceptance/db-script/other)。severity 口径:db-script/env-blocked 恒 blocking;manual-acceptance/other 默认 advisory、须显式标 blocking 才计入封顶;确需把 blocking 降为 advisory 必须附「(降级:<理由>,依据 <file:line 或 D-xxx>)」
206
206
  7. **核对 module-impact.md**(若 \`{SPEC_ROOT}/changes/<change>/module-impact.md\` 存在):对照本次实际代码变更(git diff)与 module-impact.md 的模块影响矩阵,发现不一致(漏标受影响模块 / 影响类型错误 / 实际未触碰的模块被误标)则在 verify-result.md 标注。module-impact 由 plan 首版生成、execute 各 Wave 更新,verify 是最后一次核对机会(archive 仅终审不再生成)。这是 advisory 核对(不阻断 verify 完成),但 module-impact 与实际严重背离应记为风险。
207
- 8. **smoke 纪律(local.yaml 配置 commands.smoke 或本变更判级 integration/deployment-critical 时执行以下纪律;本步 prompt 为静态导出,命中条件以文本内嵌说明注入——未命中时本段不适用)**:
207
+ 8. **smoke 纪律(local.yaml 配置 commands.smoke 或本变更命中 evidence:true 声明危险面时执行以下纪律;本步 prompt 为静态导出,命中条件以文本内嵌说明注入——未命中时本段不适用)**:
208
208
  ${REVIEW_CHECKLISTS.verify.map((item) => ' - ' + item).join('\n')}
209
209
 
210
210
  ### verify-result.md 章节结构(骨架已含,占位替换即可)
package/src/taskcard.js CHANGED
@@ -128,6 +128,9 @@ constraints:
128
128
  精确文件路径(仓根相对、正斜杠),当前不存在、将由本 task 新建的文件加
129
129
  NEW: 前缀(如 NEW:src/foo.js);禁 glob(src/**)、禁目录前缀(src/dir/)、
130
130
  禁绝对路径;无明确文件级意图时保留 [] 占位行不动。
131
+ implementation/acceptance 里的源码位置同样写仓根相对全路径+行号(src/foo.js:123)——
132
+ 裸文件名在 docs-check 层1 靠 basename 全仓扫描找候选,找不到候选或关键词
133
+ 窗口不匹配即失效,到 pre-push 才拦(2026-09-19 实证 64 处返工)。
131
134
  可选字段按需插进上方 frontmatter(规则见 taskcard-rules):
132
135
  repo: 仅跨仓 task 填(local.yaml repos: 注册的仓 key;缺省=main。allowed_paths 相对该仓根写,
133
136
  禁止带仓库名前缀/绝对路径——review 对账按仓根相对路径匹配,带前缀永不命中)