svharness 0.15.11 → 0.15.13

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 (43) hide show
  1. package/README.md +106 -2
  2. package/auto/auto-harness-detail-design.md +136 -4
  3. package/auto/skills/svharness/SKILL.md +44 -1
  4. package/auto/templates/auto-pack-req.config.example.yaml +29 -0
  5. package/auto/templates/auto.config.example.yaml +1 -1
  6. package/auto/templates/phase-prompts/S40-adversarial-review.md +31 -0
  7. package/auto/templates/phase-prompts/S40-review.md +22 -0
  8. package/auto/templates/phase-prompts/S40-sample-trace.md +26 -0
  9. package/auto/templates/requirements-review-rubric.yaml +79 -0
  10. package/dist/commands/auto-pack-req.js +70 -0
  11. package/dist/commands/auto.js +16 -1
  12. package/dist/commands/convert.js +2 -0
  13. package/dist/commands/shell-integration.js +29 -56
  14. package/dist/config/merge-options.js +2 -0
  15. package/dist/config/normalize.js +7 -0
  16. package/dist/constants/convert.js +5 -0
  17. package/dist/core/markitdown-client.js +7 -2
  18. package/dist/index.js +77 -5
  19. package/dist/lib/acp-agent-cli-resolver.js +193 -0
  20. package/dist/lib/acp-client.js +4 -2
  21. package/dist/lib/agent-launcher.js +9 -4
  22. package/dist/lib/auto-assets.js +1 -0
  23. package/dist/lib/auto-optimize.js +23 -3
  24. package/dist/lib/auto-orchestrator.js +53 -20
  25. package/dist/lib/auto-pack-req-context.js +88 -0
  26. package/dist/lib/auto-pack-req-finalize.js +28 -0
  27. package/dist/lib/auto-req-pack-review.js +161 -0
  28. package/dist/lib/auto-sample-trace.js +144 -0
  29. package/dist/lib/auto-state.js +124 -15
  30. package/dist/lib/gate-checker.js +20 -10
  31. package/dist/lib/phase-runner.js +13 -2
  32. package/dist/lib/ps-codechat-alias.js +29 -16
  33. package/dist/lib/review-parser.js +14 -0
  34. package/dist/lib/score-aggregator.js +21 -0
  35. package/dist/lib/win-registry.js +1 -1
  36. package/dist/utils/validate-args.js +2 -1
  37. package/package.json +3 -2
  38. package/templates/codechat/Start-CodeChat.ps1 +176 -135
  39. package/templates/codechat/bash.exe.stackdump +29 -0
  40. package/templates/codechat/docs/project-structure.md +59 -0
  41. package/templates/svharness.config.example.yaml +2 -0
  42. package/dist/lib/launch-script-path.js +0 -24
  43. package/templates/codechat/.claude/.env +0 -59
package/README.md CHANGED
@@ -38,6 +38,10 @@ svharness build --config svharness.config.yaml --yes
38
38
  # 全自动模式 —— 资料整理 → 构建 → 审查 → 优化,支持断点续跑
39
39
  svharness auto --work-dir . --auto-approve -y
40
40
 
41
+ # 需求包专项 —— 在 requirements 资料目录直接运行(推荐)
42
+ cd ./requirements && svharness auto_pack_req --yes
43
+ # 或指定资料包根:svharness auto_pack_req ./req-pack --yes
44
+
41
45
  # 一行式 —— 跳过交互,直接生成
42
46
  svharness build --harness-name my-app --arch android-compose --agent qoder --yes
43
47
 
@@ -65,6 +69,8 @@ svharness start-agent --work-dir .
65
69
 
66
70
  **`svharness auto`**:无人值守构建入口。工作目录可以是已有 `<name>-harness/`(从 `.harness-build-state.yaml` 断点续跑),也可以是资料包根(自动检测 `baseline/`、`requirements/`、`references/`、`extra-skills/` 后先执行 build)。配置示例见 `auto/templates/auto.config.example.yaml`。
67
71
 
72
+ **`svharness auto_pack_req`**:需求包专项入口(独立于 `auto`)。**无参数时默认把当前目录当作工作目录**;若当前目录本身是 requirements 资料夹(含 doc/md/pdf 等,目录名任意),则自动视为输入并在**上级目录**创建 harness。也支持传入资料包根(含 `requirements/` 子目录)或已有 harness 根。仅执行 S30 + S40,三维度质量闭环直到综合分 **严格大于** 9.5。配置示例见 `auto/templates/auto-pack-req.config.example.yaml`(`auto_pack_req:` 节)。详细设计见 [`auto/auto-harness-detail-design.md` §2.2.1](./auto/auto-harness-detail-design.md#221-svharness-auto_pack_req-需求包专项)。
73
+
68
74
  生成完成后,在你的 Agent IDE 中说:
69
75
  - "运行 harness-build-skills-main"或"harness-build-skill-orchestrator"即可开始逐步填充内容;
70
76
  - 构建完成后在目标项目中说"应用 harness-apply-skills-main 完成 xxx 功能开发"即可调用 harness。
@@ -234,6 +240,8 @@ svharness wizard
234
240
  | `convert` | 对应 `svharness convert` |
235
241
  | `doctor` | 对应 `svharness doctor` |
236
242
  | `wiki` | 对应 `svharness wiki` |
243
+ | `auto` | 对应 `svharness auto` |
244
+ | `auto_pack_req` | 对应 `svharness auto_pack_req`(需求包 S40 专项) |
237
245
 
238
246
  `build` 节除路径外,可写人类可读说明(仅写入配置文件,供团队阅读):
239
247
 
@@ -289,7 +297,7 @@ svharness build \
289
297
  | `--convert-endpoint <url>` | 可选 | build 自动 convert 使用的 markitdown 服务基址(支持逗号分隔 failover);省略时读 `SVHARNESS_MARKITDOWN_ENDPOINT` | `http://markitdown.desaysz.site` |
290
298
  | `--convert-concurrency <n>` | 可选 | build 自动 convert 并发上传数 | `3` |
291
299
  | `--convert-max-file-mb <n>` | 可选 | build 自动 convert 单文件大小上限(MB) | `50` |
292
- | `--convert-timeout-sec <n>` | 可选 | build 自动 convert 请求超时秒数 | `120` |
300
+ | `--convert-timeout-sec <n>` | 可选 | build 自动 convert 请求超时秒数 | `900`(15 分钟) |
293
301
  | `--convert-force` | 可选 flag | build 自动 convert 覆盖同名 `.md`(否则按 `-1/-2` 追加) | `false` |
294
302
  | `--force` | 可选 flag | 覆写已存在的 harness 目录;同时允许覆盖已注入的 build skills/rules 与项目根 `AGENTS.md` / `CLAUDE.md`(默认遇到已存在文件会跳过) | `false` |
295
303
  | `-y, --yes` | 可选 flag | 跳过所有提示,采用默认值 | `false` |
@@ -540,7 +548,7 @@ svharness convert --verbose --yes
540
548
  | `--endpoint <url>` | 云端 `markitdown_serve` 基址;**逗号分隔**可配置 failover;省略时读 `SVHARNESS_MARKITDOWN_ENDPOINT` | `http://markitdown.desaysz.site` |
541
549
  | `--concurrency <n>` | 并发上传数 | `3` |
542
550
  | `--max-file-mb <n>` | 单文件大小上限(MB),本地 + 服务端双重限流 | `50` |
543
- | `--timeout-sec <n>` | 单请求超时秒数 | `120`(2 分钟) |
551
+ | `--timeout-sec <n>` | 单请求超时秒数 | `900`(15 分钟) |
544
552
  | `--type <type>` | 目标子目录:`requirements`(正式需求)\| `references`(参考资料) | `requirements` |
545
553
  | `--force` | flag,覆盖已存在同名 `.md`(默认自动追加 `-1`、`-2` 后缀) | `false` |
546
554
  | `--split-sheets-suffix <suffix>` | xlsx/xls 按 sheet 拆分的子目录后缀 | `_split` |
@@ -586,6 +594,102 @@ convert-failures.json
586
594
 
587
595
  完整契约、fallback chain、Docker 部署见 [markitdown_serve/README.md](./markitdown_serve/README.md);模块设计见 [tmp/svharnessbuild-detail-design.md §4.10](../tmp/svharnessbuild-detail-design.md#410-文档转换convert-命令--markitdown_serve-远端服务)。
588
596
 
597
+ ### `auto` —— 全自动构建 harness(无人值守)
598
+
599
+ 一条命令完成资料整理 → S10~S80 构建 → S85 七维评审 → 优化循环,直到综合分 ≥ 目标分后 S90 封存。
600
+
601
+ ```bash
602
+ svharness auto [workdir] [options]
603
+ ```
604
+
605
+ 工作目录可以是已有 `<name>-harness/`(断点续跑),也可以是资料包根(自动检测后先 build)。
606
+
607
+ | 参数 | 说明 | 默认值 |
608
+ |------|------|--------|
609
+ | `--work-dir <path>` | 工作目录 | 当前目录 |
610
+ | `--config <path>` | 配置文件(`auto:` 节) | `svharness.config.yaml` |
611
+ | `--target-score <score>` | 目标综合评分 | `9.5` |
612
+ | `--max-optimize-rounds <n>` | 最大优化轮数 | `10` |
613
+ | `--max-phase <phase>` | 只运行到此阶段即停止(如 `S40` 会跳过评审) | — |
614
+ | `--auto-approve` / `-y, --yes` | 无人值守 | `autoApprove` 默认 `true` |
615
+ | `--dry-run` | 打印 prompt,不调用 Agent | `false` |
616
+
617
+ 配置示例:`auto/templates/auto.config.example.yaml`
618
+
619
+ ### `auto_pack_req` —— 需求包全自动条目化(S40 专项)
620
+
621
+ 独立于 `auto`,专门用于需求文档条目化 + 质量闭环,**不污染**完整 harness 构建流程。
622
+
623
+ ```bash
624
+ # 推荐:在 requirements 资料目录直接运行(目录名任意)
625
+ cd ./requirements
626
+ svharness auto_pack_req --yes
627
+
628
+ # 或指定资料包根 / harness 根
629
+ svharness auto_pack_req [workdir] [options]
630
+ ```
631
+
632
+ **工作目录解析**(`[workdir]` 可省略,默认当前目录):
633
+
634
+ | 当前/指定目录 | 行为 |
635
+ |---------------|------|
636
+ | 本身是 requirements 资料夹(含文档文件,目录名任意) | 视为 `--requirements` 输入,在**上级目录**创建 `<name>-harness/` |
637
+ | 资料包根(含 `requirements/` 等子目录) | 在目录内自动检测并创建 harness |
638
+ | 已有 harness 根(或恰好一个 `*-harness/`) | 重置 S40,重做条目化 |
639
+ | 多个 `*-harness/` | 报错,须显式指定路径 |
640
+
641
+ **内置默认**:`targetScore=9.5`(须**严格大于**)、`maxOptimizeRounds=10`、`sampleCount=7`、`autoApprove=true`、`yes=true`
642
+
643
+ **评分模型**:
644
+
645
+ ```
646
+ 综合分 = 机械门禁 × 0.40 + 对抗验证 × 0.30 + 抽样验证 × 0.30
647
+ ```
648
+
649
+ | 维度 | 权重 | 说明 |
650
+ |------|------|------|
651
+ | 机械门禁 | 40% | `verify --strict` + `doctor --mode requirements --strict` 全通过;任一失败机械分=0 |
652
+ | 对抗验证 | 30% | 独立 Reviewer Agent 逐 block 挑刺(禁止读 Builder 自评) |
653
+ | 抽样验证 | 30% | 从 `requirements/md` 随机抽 N 片段,反向追溯 yaml 产物是否可支撑开发 |
654
+
655
+ **通过条件**(AND):`综合分 > targetScore` + 硬门禁全通过 + `critical_count=0`
656
+
657
+ **两种入口**:
658
+
659
+ | 模式 | 检测条件 | 行为 |
660
+ |------|----------|------|
661
+ | 资料包新建 | 无 `harness.yaml` | `runMaterialsPrepAndBuild` → S30+S40 |
662
+ | 已有 harness 重做 | 存在 `harness.yaml` | 重置 `S40=PENDING` → 只跑 S40 |
663
+
664
+ **主要参数**:
665
+
666
+ | 参数 | 说明 | 默认值 |
667
+ |------|------|--------|
668
+ | `--requirements <path>` | 需求文档路径 | 自动检测 |
669
+ | `--target-score <score>` | 目标综合评分(须严格大于) | `9.5` |
670
+ | `--max-optimize-rounds <n>` | 最大优化轮数 | `10` |
671
+ | `--sample-count <n>` | 抽样验证片段数 | `7` |
672
+ | `--config <path>` | 配置文件(`auto_pack_req:` 节) | — |
673
+ | `--dry-run` | 打印 S40 + 三维度评审 prompt | `false` |
674
+
675
+ **典型用法**:
676
+
677
+ ```bash
678
+ cd ./requirements && svharness auto_pack_req --yes
679
+ svharness auto_pack_req ./req-pack --yes
680
+ svharness auto_pack_req ./my-app-harness --requirements ./docs --yes
681
+ svharness auto_pack_req --config auto-pack-req.config.yaml --dry-run
682
+ ```
683
+
684
+ **产物**(不执行 S90):
685
+
686
+ - `requirements/yaml/*.yaml`、`requirements/coverage-report.yaml`
687
+ - `auto-review/第N轮需求自评报告.md`、`第N轮对抗评审.md`、`第N轮抽样验证报告.md`
688
+ - `auto-review/auto-score.json`、`auto-review/pack-req-complete.json`
689
+
690
+ 配置示例:`auto/templates/auto-pack-req.config.example.yaml`
691
+ 详细设计:[`auto/auto-harness-detail-design.md` §2.2.1](./auto/auto-harness-detail-design.md#221-svharness-auto_pack_req-需求包专项)
692
+
589
693
  ### `wiki` —— 对任意代码工程生成 baseline wiki(v0.15+)
590
694
 
591
695
  独立子命令,**不依赖 harness 生命周期**,直接对任意代码工程目录就地扫描生成 wiki。与 `build` 内置 wiki 共用同一 repowiki 核心,但不拷贝 code、不创建 harness 骨架。
@@ -1,6 +1,6 @@
1
1
  # auto-harness 详细设计方案
2
2
 
3
- > **文档定位**:`svharness auto` 模式的完整设计书,面向本系统的开发者与维护者。
3
+ > **文档定位**:`svharness auto` 与 `svharness auto_pack_req` 模式的完整设计书,面向本系统的开发者与维护者。
4
4
  > **上级文档**:`svharnessbuild/README.md`(CLI 总体规范)、`svharnessbuild/tmp/svharnessbuild-detail-design.md`(SDD)。
5
5
  > **参照工程**:[snarktank/ralph](https://github.com/snarktank/ralph)(外循环思路)。
6
6
  > **版本**:v2.6(2026-06-26,任意错误不中断 + CostTracker 超限兜底优化)
@@ -309,6 +309,105 @@ async function resolveHarnessRoot(workDir: string): Promise<string | null> {
309
309
 
310
310
  > `harness.yaml` 通常位于 `<work-dir>/<name>-harness/harness.yaml`,而非项目根直接子级。`--work-dir` 可指向资料包根或 harness 根;Orchestrator 先执行上述解析再进入主循环。
311
311
 
312
+ ### 2.2.1 `svharness auto_pack_req` — 需求包专项
313
+
314
+ > **定位**:独立于 `svharness auto` 的 preset 命令,内部固定 `scope=requirements`,不暴露 `--scope` CLI 参数。复用 `AutoOrchestrator` + `PhaseRunner`,不新建 orchestrator 类。
315
+
316
+ #### 命令形态
317
+
318
+ ```bash
319
+ # 推荐:在 requirements 资料目录直接运行(目录名任意)
320
+ cd ./requirements && svharness auto_pack_req --yes
321
+
322
+ # 或指定资料包根 / harness 根
323
+ svharness auto_pack_req [workdir] [options]
324
+ ```
325
+
326
+ 实现入口:`src/commands/auto-pack-req.ts` → `resolveAutoPackReqWorkContext()` → 注入 preset opts → 调用 `runAuto()`。
327
+
328
+ #### 工作目录解析(`[workdir]` 可省略)
329
+
330
+ 无参数时默认 `process.cwd()`,按以下优先级识别:
331
+
332
+ | 当前目录 | 行为 |
333
+ |----------|------|
334
+ | harness 根(或恰好一个 `*-harness/`) | 重置 S40,重做条目化 |
335
+ | 资料包根(含 `requirements/`、`baseline/` 等子目录) | 在目录内自动检测并 `build` |
336
+ | **requirements 资料夹**(含 doc/md/pdf 等,**目录名任意**) | 将当前目录固定为 `--requirements` 输入,在**上级目录**创建 `<name>-harness/` |
337
+ | 其它 | 按资料包根处理(与 `auto` 一致) |
338
+
339
+ 示例:在 `req-pack/requirements/` 内执行 `svharness auto_pack_req --yes`,等价于在 `req-pack/` 执行并指定 `--requirements ./requirements`。
340
+
341
+ #### 内置默认(可被 CLI / 配置覆盖)
342
+
343
+ | 参数 | 默认值 |
344
+ |------|--------|
345
+ | `scope` | `requirements`(内部固定) |
346
+ | `targetScore` | `9.5`(通过条件为**严格大于**) |
347
+ | `maxOptimizeRounds` | `10` |
348
+ | `sampleCount` | `7` |
349
+ | `autoApprove` / `yes` | `true` |
350
+
351
+ 配置文件节:`auto_pack_req:`(示例见 `auto/templates/auto-pack-req.config.example.yaml`)。
352
+
353
+ #### 两种入口
354
+
355
+ | 模式 | 检测 | 行为 |
356
+ |------|------|------|
357
+ | 资料包新建 | `resolveHarnessRoot(workDir)` 为 null | `runMaterialsPrepAndBuild` → 仅跑 `S30_convert_docs` + `S40_extract_requirements` |
358
+ | 已有 harness 重做 | 存在 `harness.yaml` | `resetS40ForRerun()` 将 `S40_extract_requirements.status=PENDING`,不动 S50~S90 |
359
+
360
+ 阶段白名单(`SCOPE_PHASES.requirements`):
361
+
362
+ ```typescript
363
+ ['S30_convert_docs', 'S40_extract_requirements']
364
+ ```
365
+
366
+ #### 三维度质量闭环
367
+
368
+ ```
369
+ 综合分 = 机械门禁分 × 0.40 + 对抗验证分 × 0.30 + 抽样验证分 × 0.30
370
+ ```
371
+
372
+ | 维度 | 权重 | 实现 |
373
+ |------|------|------|
374
+ | 机械门禁 | 40% | `runMechanicalGates({ scope: 'requirements' })`:`verify --strict` + `doctor --mode requirements --strict`;任一失败机械分=0 |
375
+ | 对抗验证 | 30% | ACP + `S40-adversarial-review.md`;禁止读 Builder 自评报告 |
376
+ | 抽样验证 | 30% | `auto-sample-trace.ts` 生成 `sample-fragments.json` + ACP + `S40-sample-trace.md` 反向追溯 |
377
+
378
+ 每轮评审流程(`runReqPackReview`):
379
+
380
+ 1. 机械门禁
381
+ 2. `writeSampleFragmentsFile()` — 从 `requirements/md` 随机抽 N 片段
382
+ 3. Builder 自评 — `S40-review.md`(产出 gap 表供优化,**不计入**综合分权重)
383
+ 4. 对抗验证 — `S40-adversarial-review.md`
384
+ 5. 抽样验证 — `S40-sample-trace.md`
385
+ 6. `computeReqPackScore()` 加权 → 写 `auto-review/auto-score.json`
386
+
387
+ **通过条件**(AND):
388
+
389
+ - `composite_score > targetScore`
390
+ - `gate_pass === true`(verify=0、doctor=0、critical=0)
391
+ - 不执行 `finalizeAutoHarness`(S90);改为写 `auto-review/pack-req-complete.json`
392
+
393
+ #### 优化循环 scope 隔离
394
+
395
+ - `SCOPE_ALLOWED_PHASES.requirements` 仅含 `S40_extract_requirements`
396
+ - `invalidateDownstream` 在 requirements scope 下**不调用**(避免 S50+ 标 OUTDATED)
397
+ - 优化 prompt 仍复用 `optimize-plan.md` / `optimize-implement.md`
398
+
399
+ #### 关键文件
400
+
401
+ | 类型 | 路径 |
402
+ |------|------|
403
+ | CLI 入口 | `src/commands/auto-pack-req.ts` |
404
+ | 三维度评审 | `src/lib/auto-req-pack-review.ts` |
405
+ | 抽样生成 | `src/lib/auto-sample-trace.ts` |
406
+ | 评分公式 | `src/lib/score-aggregator.ts` → `computeReqPackScore` |
407
+ | 完成标记 | `src/lib/auto-pack-req-finalize.ts` |
408
+ | Prompt | `auto/templates/phase-prompts/S40-review.md` 等 |
409
+ | Rubric | `auto/templates/requirements-review-rubric.yaml` |
410
+
312
411
  ### 2.3 典型运行输出
313
412
 
314
413
  ```
@@ -391,7 +490,7 @@ program
391
490
  .option('--no-force', '禁用自动 force(目标目录存在时不覆盖)')
392
491
  // === 质量与流程控制 ===
393
492
  .option('--target-score <score>', '目标综合评分(默认 9.5)', '9.5')
394
- .option('--max-optimize-rounds <n>','最大优化轮数(默认 5)', '5')
493
+ .option('--max-optimize-rounds <n>','最大优化轮数(默认 10)', '10')
395
494
  .option('--checkpoint <phase>', '到达此阶段前暂停等待人工确认(如 S85)')
396
495
  .option('--max-phase <phase>', '只运行到此阶段即停止(调试用)')
397
496
  .option('--dry-run', '打印各阶段 prompt 和命令,不实际执行')
@@ -712,7 +811,7 @@ class CostTracker {
712
811
  **默认建议**(v2.6 提升):
713
812
 
714
813
  - `--max-total-calls 100`(约 $30–$100 API 成本,覆盖完整构建+多轮优化)
715
- - `--max-optimize-rounds 5`(默认值不变)
814
+ - `--max-optimize-rounds 10`(默认值)
716
815
 
717
816
  ### 4.5 完成标记协议
718
817
 
@@ -2259,7 +2358,7 @@ auto:
2259
2358
 
2260
2359
  # 质量目标
2261
2360
  targetScore: 9.5
2262
- maxOptimizeRounds: 5
2361
+ maxOptimizeRounds: 10
2263
2362
  mechanicalWeight: 0.30 # 机械指标占综合分比例(默认 30%)
2264
2363
  reviewWeight: 0.70 # 评审 Agent 占综合分比例(默认 70%)
2265
2364
 
@@ -2801,3 +2900,36 @@ if (autoRepair) { tryAutoRepair(); } ← 在循环外
2801
2900
  mark SKIPPED + writeBuildState + continue ← 在循环外
2802
2901
  ```
2803
2902
 
2903
+ ---
2904
+
2905
+ ## 附录:v2.7 实现修订记录(auto_pack_req)
2906
+
2907
+ 新增 `svharness auto_pack_req` 命令,作为 `auto` 的 preset 包装,专门服务 S40 需求条目化三维度质量闭环。
2908
+
2909
+ | # | 文件 | 修订内容 | 类型 |
2910
+ |---|------|---------|------|
2911
+ | 1 | `src/commands/auto-pack-req.ts` | 新增 preset 入口;已有 harness 时 `resetS40ForRerun` | 新增 |
2912
+ | 2 | `src/index.ts` | 注册 `auto_pack_req [workdir]` 子命令 | 新增 |
2913
+ | 3 | `src/types/auto-types.ts` | `AutoScope`、`SampleFragment`、`ReqPackScoreSnapshot` 等 | 新增 |
2914
+ | 4 | `src/lib/auto-orchestrator.ts` | `scope=requirements` 走 `runReqPackReview` + `finalizeReqPack` | 增强 |
2915
+ | 5 | `src/lib/phase-runner.ts` | `SCOPE_PHASES` 白名单 | 增强 |
2916
+ | 6 | `src/lib/gate-checker.ts` | requirements scope 使用 `doctor --mode requirements` | 增强 |
2917
+ | 7 | `src/lib/score-aggregator.ts` | `computeReqPackScore` 三维度公式 | 新增 |
2918
+ | 8 | `src/lib/auto-req-pack-review.ts` | 机械 + 自评 + 对抗 + 抽样评审编排 | 新增 |
2919
+ | 9 | `src/lib/auto-sample-trace.ts` | 从 md 随机抽片段写 `sample-fragments.json` | 新增 |
2920
+ | 10 | `src/lib/auto-optimize.ts` | requirements scope 仅允许重跑 S40 | 增强 |
2921
+ | 11 | `auto/templates/phase-prompts/S40-*.md` | 三维度评审 prompt | 新增 |
2922
+ | 12 | `auto/templates/requirements-review-rubric.yaml` | 评审契约 SSOT | 新增 |
2923
+ | 13 | `auto/templates/auto-pack-req.config.example.yaml` | 配置示例 | 新增 |
2924
+
2925
+ ```
2926
+ auto_pack_req 与 auto 关系:
2927
+
2928
+ svharness auto_pack_req
2929
+ └── runAutoPackReq() 注入 scope=requirements preset
2930
+ └── runAuto() → AutoOrchestrator
2931
+ ├── PhaseRunner(S30+S40 only)
2932
+ ├── runReqPackReview()(三维度)
2933
+ └── finalizeReqPack()(非 S90)
2934
+ ```
2935
+
@@ -169,7 +169,7 @@ svharness auto [--work-dir <path>] [options]
169
169
  | `--arch <arch>` | 架构模板 | `android-compose` |
170
170
  | `--harness-name <name>` | harness 名称(资料包模式必填) | — |
171
171
  | `--target-score <score>` | 目标综合评分 | `9.5` |
172
- | `--max-optimize-rounds <n>` | 最大优化轮数 | `5` |
172
+ | `--max-optimize-rounds <n>` | 最大优化轮数 | `10` |
173
173
  | `--auto-approve` | 自动通过表单门禁 | `false` |
174
174
  | `-y, --yes` | 跳过所有交互确认 | `false` |
175
175
  | `--max-total-calls <n>` | ACP 调用次数上限 | `30` |
@@ -193,6 +193,49 @@ svharness auto --config auto.config.yaml --auto-approve
193
193
 
194
194
  **首次运行自动注入**:首次执行 `svharness auto` 时,CLI 会自动将 `svharness` skill 注入到 `~/.claude/skills/svharness/`,使 Claude Code 能识别 `/svharness` 命令。之后可在任意项目中对 Agent 说"自动构建 harness"触发。
195
195
 
196
+ ### `svharness auto_pack_req` — 需求包全自动条目化(S40 专项)
197
+
198
+ 独立于 `auto` 命令,专门用于需求文档条目化 + 三维度质量闭环,不污染完整 harness 构建流程。
199
+
200
+ ```bash
201
+ # 推荐:在 requirements 资料目录直接运行(目录名任意)
202
+ cd ./requirements && svharness auto_pack_req --yes
203
+
204
+ svharness auto_pack_req [workdir] [options]
205
+ ```
206
+
207
+ **工作目录**:无参数时默认当前目录。若当前目录本身是 requirements 资料夹(含 doc/md/pdf 等),自动视为输入并在上级目录创建 harness。
208
+
209
+ **内置默认**:`targetScore=9.5`(须**严格大于**)、`maxOptimizeRounds=10`、`sampleCount=7`、`autoApprove=true`、`yes=true`
210
+
211
+ **评分模型**:
212
+ ```
213
+ 综合分 = 机械门禁 × 0.40 + 对抗验证 × 0.30 + 抽样验证 × 0.30
214
+ ```
215
+
216
+ | 维度 | 说明 |
217
+ |------|------|
218
+ | 机械门禁 | `verify --strict` + `doctor --mode requirements --strict` 全通过 |
219
+ | 对抗验证 | 独立 Reviewer Agent 逐 block 挑刺(不读 Builder 自评) |
220
+ | 抽样验证 | 从 `requirements/md` 随机抽 N 片段反向追溯 yaml 产物 |
221
+
222
+ **两种入口**:
223
+ - **资料包新建**:目录下无 `harness.yaml` → 创建 harness → S30+S40
224
+ - **已有 harness 重做**:检测到 `harness.yaml` → 重置 S40=PENDING → 只跑 S40
225
+
226
+ **典型用法**:
227
+
228
+ ```bash
229
+ cd ./requirements && svharness auto_pack_req --yes
230
+ svharness auto_pack_req ./req-pack --yes
231
+ svharness auto_pack_req ./existing-harness --requirements ./docs --yes
232
+ svharness auto_pack_req --dry-run
233
+ ```
234
+
235
+ 配置模板:`auto/templates/auto-pack-req.config.example.yaml`(`auto_pack_req:` 节)
236
+
237
+ **产物**:`requirements/yaml/`、`auto-review/pack-req-complete.json`(不执行 S90 封存)
238
+
196
239
  ### `svharness shell` — Windows 右键菜单和别名管理
197
240
 
198
241
  ```bash
@@ -0,0 +1,29 @@
1
+ version: 1
2
+
3
+ defaults:
4
+ yes: true
5
+ verbose: false
6
+
7
+ auto_pack_req:
8
+ workDir: .
9
+ harnessName: my-req-pack
10
+ goal: "描述此需求包的条目化目的"
11
+ arch: documents
12
+ agent: claude-code
13
+
14
+ requirements: ./requirements
15
+
16
+ targetScore: 9.5
17
+ maxOptimizeRounds: 10
18
+ sampleCount: 7
19
+ autoApprove: true
20
+
21
+ acpMode: auto
22
+ acpTimeoutMs: 600000
23
+ maxRetriesPerPhase: 2
24
+ maxTotalCalls: 100
25
+ budgetUsd: null
26
+ costAlertThreshold: 5
27
+
28
+ convertEndpoint: "http://markitdown.desaysz.site"
29
+ dryRun: false
@@ -23,7 +23,7 @@ auto:
23
23
 
24
24
  # 质量目标与流程控制。
25
25
  targetScore: 9.5
26
- maxOptimizeRounds: 5
26
+ maxOptimizeRounds: 10
27
27
  maxPhase: null
28
28
  checkpoint: null
29
29
  autoApprove: true
@@ -0,0 +1,31 @@
1
+ 你是**独立**的需求审计 Agent(未参与 S40 条目化构建)。当前任务:对 {{HARNESS_ROOT}} 执行第 {{ROUND}} 轮对抗性验证。
2
+
3
+ ## 硬约束(违反则任务失败)
4
+ - **禁止读取** `auto-review/第{{ROUND}}轮需求自评报告.md` 及任何 Builder 自评内容。
5
+ - 仅基于源文档与产物独立审查。
6
+
7
+ ## 项目上下文
8
+ - 构建目的:{{AUTO_GOAL}}
9
+ - 机械门禁:doctor exit={{DOCTOR_EXIT}},verify exit={{VERIFY_EXIT}}
10
+
11
+ ## 审查方法
12
+ 1. 读取 `requirements/_work/structure-index.json`,逐 block 对照 `requirements/yaml/*.yaml`。
13
+ 2. 挑刺重点:
14
+ - 遗漏条目(block 无对应 requirement 且无合理 waived)
15
+ - `source_excerpt` 缩略或占位语(「见上文」「同前」)
16
+ - `description` 信息缩减(条件/数值/枚举/时序丢失)
17
+ - waived 条目缺少 `aggregation_reason`
18
+ 3. 读取 `{{HARNESS_ROOT}}/auto/requirements-review-rubric.yaml` 中 adversarial 维度。
19
+
20
+ ## 产出要求
21
+ 1. 写入 `{{HARNESS_ROOT}}/auto-review/第{{ROUND}}轮对抗评审.md`。
22
+ 2. frontmatter 必须包含:
23
+ - `round: {{ROUND}}`
24
+ - `score.adversarial.coverage`(0-10)
25
+ - `score.adversarial.fidelity`(0-10)
26
+ - `score.adversarial.completeness`(0-10)
27
+ - `score.adversarial.average`(三项平均,0-10)
28
+ - `issues`(数组,每项含 severity/category/description/unit_id 或 block_id)
29
+ - `critical_count`(issues 中 severity=critical 的数量)
30
+ 3. 正文列出发现的问题清单。
31
+ 4. 输出末尾:`<AUTO_SIGNAL>ADV_REVIEW_DONE</AUTO_SIGNAL>`。
@@ -0,0 +1,22 @@
1
+ 你是 harness 构建 Agent。当前任务:对 {{HARNESS_ROOT}} 执行第 {{ROUND}} 轮 S40 需求自评。
2
+
3
+ ## 项目上下文
4
+ - 构建目的:{{AUTO_GOAL}}
5
+ - 机械门禁:doctor exit={{DOCTOR_EXIT}},verify exit={{VERIFY_EXIT}},文件齐全度={{FILE_COMPLETENESS_PCT}}%
6
+
7
+ ## 评审契约
8
+ 1. 读取 `{{HARNESS_ROOT}}/auto/requirements-review-rubric.yaml`。
9
+ 2. 仅评审 **requirements** 维度(不评 wiki/specs/references 等)。
10
+ 3. 检查 `requirements/yaml/*.yaml`、`requirements/coverage-report.yaml`、`requirements/_work/verify-gaps.json`。
11
+
12
+ ## 产出要求
13
+ 1. 写入 `{{HARNESS_ROOT}}/auto-review/第{{ROUND}}轮需求自评报告.md`。
14
+ 2. frontmatter 必须包含:
15
+ - `round: {{ROUND}}`
16
+ - `score.dimensions.requirements`(0-10)
17
+ - `gates.doctor_exit` / `gates.verify_exit` / `gates.file_completeness_pct`
18
+ - `gate_pass`(布尔)
19
+ - `critical_count`
20
+ - `modifications_required`
21
+ 3. 正文必须包含「修改建议汇总」表(优先级 | 阶段 | 问题 | 建议动作),供优化 Agent 读取。
22
+ 4. 输出末尾:`<AUTO_SIGNAL>REQ_REVIEW_DONE</AUTO_SIGNAL>`。
@@ -0,0 +1,26 @@
1
+ 你是需求抽样验证 Agent。当前任务:对 {{HARNESS_ROOT}} 执行第 {{ROUND}} 轮反向追溯抽样验证。
2
+
3
+ ## 项目上下文
4
+ - 构建目的:{{AUTO_GOAL}}
5
+ - 抽样片段文件:{{SAMPLE_FRAGMENTS_PATH}}
6
+
7
+ ## 验证方法(Sample-based Reverse Trace)
8
+ 1. 读取 `{{SAMPLE_FRAGMENTS_PATH}}` 中的 `fragments[]`。
9
+ 2. 对每个片段,在 `requirements/yaml/*.yaml` 中**反向查找**对应条目。
10
+ 3. 对每个片段评三个子维度(0-10):
11
+ - **traceability**:能否找到对应 `unit_id`
12
+ - **fidelity**:`source_excerpt` 是否覆盖片段关键信息(条件/数值/枚举/时序)
13
+ - **usability**:`description` + `acceptance` 是否足以支撑开发者直接实现功能
14
+ 4. 读取 `{{HARNESS_ROOT}}/auto/requirements-review-rubric.yaml` 中 sample_trace 维度。
15
+
16
+ ## 产出要求
17
+ 1. 写入 `{{HARNESS_ROOT}}/auto-review/第{{ROUND}}轮抽样验证报告.md`。
18
+ 2. frontmatter 必须包含:
19
+ - `round: {{ROUND}}`
20
+ - `score.sample_trace.traceability`(所有片段平均,0-10)
21
+ - `score.sample_trace.fidelity`(0-10)
22
+ - `score.sample_trace.usability`(0-10)
23
+ - `score.sample_trace.average`(三项平均,0-10)
24
+ - `score.sample_trace.items`(数组,每项含 fragment_id、found_unit_id、traceability、fidelity、usability、note)
25
+ 3. 正文含逐片段验证明细表。
26
+ 4. 输出末尾:`<AUTO_SIGNAL>SAMPLE_TRACE_DONE</AUTO_SIGNAL>`。
@@ -0,0 +1,79 @@
1
+ # requirements-review-rubric.yaml — auto_pack_req 三维度评审契约
2
+ version: "1.0"
3
+
4
+ scope: requirements
5
+
6
+ dimensions:
7
+ - id: requirements
8
+ weight_composite: 0.0
9
+ title: Builder 自评(requirements 维度)
10
+ role: gap_generation
11
+ questions:
12
+ - 需求文档是否充分解析?覆盖率是否 100%?
13
+ - source_excerpt 是否保真?有无压缩导致细节丢失?
14
+ - unit_id / source_anchor 是否可索引?
15
+ evidence_hints:
16
+ - requirements/coverage-report.yaml
17
+ - requirements/yaml/*.yaml
18
+ - requirements/_work/verify-gaps.json
19
+
20
+ - id: adversarial
21
+ weight_composite: 0.30
22
+ title: 对抗性验证
23
+ role: scoring
24
+ questions:
25
+ - 逐 block 对照 structure-index,是否有遗漏条目?
26
+ - source_excerpt 是否缩略或使用占位语?
27
+ - description 是否缩减了条件/数值/枚举/时序?
28
+ - waived 条目是否有 aggregation_reason?
29
+ sub_scores:
30
+ - coverage
31
+ - fidelity
32
+ - completeness
33
+ evidence_hints:
34
+ - requirements/_work/structure-index.json
35
+ - requirements/yaml/*.yaml
36
+
37
+ - id: sample_trace
38
+ weight_composite: 0.30
39
+ title: 抽样反向追溯验证
40
+ role: scoring
41
+ questions:
42
+ - 随机源文档片段能否在 yaml 中找到 unit_id?
43
+ - source_excerpt 是否覆盖片段关键信息?
44
+ - description + acceptance 是否足以支撑功能开发?
45
+ sub_scores:
46
+ - traceability
47
+ - fidelity
48
+ - usability
49
+ evidence_hints:
50
+ - auto-review/sample-fragments.json
51
+ - requirements/md/*.md
52
+ - requirements/yaml/*.yaml
53
+
54
+ mechanical_gate:
55
+ weight_composite: 0.40
56
+ checks:
57
+ - svharness requirements verify --strict exit 0
58
+ - svharness doctor --mode requirements --strict exit 0
59
+ - coverage_ratio == 1
60
+ - critical_count == 0
61
+
62
+ pass_criteria:
63
+ composite_score_gt: 9.5
64
+ gate_pass: true
65
+ critical_count: 0
66
+
67
+ modification_summary_columns:
68
+ - priority
69
+ - phase
70
+ - problem
71
+ - action
72
+ - status
73
+
74
+ outputs:
75
+ self_review: "auto-review/第{n}轮需求自评报告.md"
76
+ adversarial: "auto-review/第{n}轮对抗评审.md"
77
+ sample_trace: "auto-review/第{n}轮抽样验证报告.md"
78
+ score_snapshot: auto-review/auto-score.json
79
+ complete_marker: auto-review/pack-req-complete.json
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runAutoPackReq = runAutoPackReq;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const config_1 = require("../config");
10
+ const logger_1 = require("../utils/logger");
11
+ const auto_state_1 = require("../lib/auto-state");
12
+ const auto_pack_req_context_1 = require("../lib/auto-pack-req-context");
13
+ const auto_1 = require("./auto");
14
+ const PACK_REQ_DEFAULTS = {
15
+ scope: 'requirements',
16
+ targetScore: 9.5,
17
+ maxOptimizeRounds: 10,
18
+ autoApprove: true,
19
+ yes: true,
20
+ sampleCount: 7,
21
+ };
22
+ async function runAutoPackReq(positionalWorkdir, opts, cmd) {
23
+ const loaded = (0, config_1.loadConfig)({ configPath: opts.config });
24
+ const autoSection = loaded?.config.auto_pack_req ?? loaded?.config.auto;
25
+ const merged = {
26
+ ...(0, config_1.mergeAutoOptions)(opts, autoSection, loaded?.config.defaults, cmd),
27
+ ...PACK_REQ_DEFAULTS,
28
+ ...opts,
29
+ scope: 'requirements',
30
+ targetScore: opts.targetScore ?? autoSection?.targetScore ?? PACK_REQ_DEFAULTS.targetScore,
31
+ maxOptimizeRounds: opts.maxOptimizeRounds ?? autoSection?.maxOptimizeRounds ?? PACK_REQ_DEFAULTS.maxOptimizeRounds,
32
+ sampleCount: opts.sampleCount ?? autoSection?.sampleCount ?? 7,
33
+ autoApprove: opts.autoApprove ?? true,
34
+ yes: opts.yes ?? true,
35
+ };
36
+ const workCtx = await (0, auto_pack_req_context_1.resolveAutoPackReqWorkContext)(positionalWorkdir, merged.workDir, merged.requirements);
37
+ const runOpts = {
38
+ ...merged,
39
+ ...(workCtx.requirementsPath ? { requirements: workCtx.requirementsPath } : {}),
40
+ };
41
+ if (workCtx.harnessRoot) {
42
+ logger_1.logger.info(`[auto_pack_req] 检测到已有 harness:${workCtx.harnessRoot},将重做 S40`);
43
+ await resetS40ForRerun(workCtx.harnessRoot);
44
+ }
45
+ else if (workCtx.mode === 'requirements-cwd') {
46
+ logger_1.logger.info(`[auto_pack_req] 当前目录识别为 requirements 输入:${workCtx.requirementsPath}`);
47
+ logger_1.logger.info(`[auto_pack_req] 将在上级目录创建 harness:${workCtx.workDir}`);
48
+ }
49
+ else {
50
+ logger_1.logger.info('[auto_pack_req] 资料包模式:将创建 harness 并执行 S30+S40');
51
+ }
52
+ await (0, auto_1.runAuto)(workCtx.workDir, runOpts, cmd);
53
+ }
54
+ async function resetS40ForRerun(harnessRoot) {
55
+ const statePath = node_path_1.default.join(harnessRoot, '.harness-build-state.yaml');
56
+ if (!(await fs_extra_1.default.pathExists(statePath)))
57
+ return;
58
+ const state = await (0, auto_state_1.readBuildState)(harnessRoot);
59
+ if (!state.phases.S40_extract_requirements)
60
+ return;
61
+ state.phases.S40_extract_requirements = {
62
+ ...state.phases.S40_extract_requirements,
63
+ status: 'PENDING',
64
+ };
65
+ delete state.phases.S40_extract_requirements.outdated_reason;
66
+ state.current_phase = 'S40_extract_requirements';
67
+ state.next_action = 'auto_pack_req 已重置 S40,等待重新条目化';
68
+ await (0, auto_state_1.writeBuildState)(harnessRoot, state);
69
+ logger_1.logger.success('已重置 S40_extract_requirements 为 PENDING');
70
+ }