@pzy560117/codex-harness 0.1.7 → 0.1.9

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 (51) hide show
  1. package/README.md +1 -1
  2. package/package-source/AGENTS.md +18 -1
  3. package/package-source/docs/codex-harness-engineering/templates/bootstrap-codex-harness.ps1 +57 -48
  4. package/package-source/docs/codex-harness-engineering/templates/config/rules/agents.md +3 -3
  5. package/package-source/docs/codex-harness-engineering/templates/docs/project-agents-template.md +8 -1
  6. package/package-source/docs/codex-harness-engineering/templates/docs/task-session-strategy.md +7 -0
  7. package/package-source/docs/codex-harness-engineering/templates/hooks/hook-stop-verify.ps1 +76 -10
  8. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/examples/ticket-filter-demo/task.json +2 -2
  9. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/project-agents-template.md +51 -1
  10. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/controller-loop.md +88 -0
  11. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/failure-triage.md +71 -0
  12. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/harness-audit.md +54 -0
  13. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/implement-one-task.md +18 -15
  14. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/repair-one-finding.md +1 -2
  15. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/review-one-task.md +45 -0
  16. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/review-stage1-spec.md +111 -0
  17. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/review-stage2-quality.md +82 -0
  18. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/visual-evaluator.md +80 -0
  19. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/worker-role/backend-worker.md +41 -0
  20. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/worker-role/docs-worker.md +28 -0
  21. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/worker-role/frontend-worker.md +46 -0
  22. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/worker-role/harness-writer.md +40 -0
  23. package/package-source/docs/codex-harness-engineering/templates/package-assets/docs/codex-harness-engineering/templates/prompts/worker-role/test-runner.md +27 -0
  24. package/package-source/docs/codex-harness-engineering/templates/package-assets/rules/agents.md +6 -3
  25. package/package-source/docs/codex-harness-engineering/templates/package-assets/skills/auto-commit/SKILL.md +1 -1
  26. package/package-source/docs/codex-harness-engineering/templates/package-assets/skills/speckit-plan/SKILL.md +1 -1
  27. package/package-source/docs/codex-harness-engineering/templates/prompts/controller-loop.md +4 -4
  28. package/package-source/docs/codex-harness-engineering/templates/prompts/failure-triage.md +1 -1
  29. package/package-source/docs/codex-harness-engineering/templates/prompts/harness-audit.md +1 -1
  30. package/package-source/docs/codex-harness-engineering/templates/prompts/implement-one-task.md +18 -15
  31. package/package-source/docs/codex-harness-engineering/templates/prompts/repair-one-finding.md +1 -2
  32. package/package-source/docs/codex-harness-engineering/templates/prompts/review-one-task.md +1 -1
  33. package/package-source/docs/codex-harness-engineering/templates/prompts/review-stage1-spec.md +1 -1
  34. package/package-source/docs/codex-harness-engineering/templates/prompts/review-stage2-quality.md +1 -1
  35. package/package-source/docs/codex-harness-engineering/templates/prompts/visual-evaluator.md +1 -1
  36. package/package-source/docs/codex-harness-engineering/templates/prompts/worker-role/backend-worker.md +2 -2
  37. package/package-source/docs/codex-harness-engineering/templates/prompts/worker-role/docs-worker.md +2 -2
  38. package/package-source/docs/codex-harness-engineering/templates/prompts/worker-role/frontend-worker.md +2 -2
  39. package/package-source/docs/codex-harness-engineering/templates/prompts/worker-role/harness-writer.md +4 -4
  40. package/package-source/docs/codex-harness-engineering/templates/prompts/worker-role/test-runner.md +1 -1
  41. package/package-source/docs/codex-harness-engineering/templates/runtime/AGENTS.md +45 -46
  42. package/package-source/docs/codex-harness-engineering/templates/runtime/doctor.ps1 +151 -42
  43. package/package-source/docs/codex-harness-engineering/templates/runtime/project-task-template.json +81 -66
  44. package/package-source/docs/codex-harness-engineering/templates/runtime/smoke-task.json +1 -1
  45. package/package-source/docs/codex-harness-engineering/templates/runtime/task.json +1 -1
  46. package/package-source/docs/codex-harness-engineering/templates/runtime/verify.ps1 +29 -12
  47. package/package-source/docs/codex-harness-engineering/templates/tools/harness/task-structure-lint.ps1 +399 -0
  48. package/package-source/install-manifest.json +1 -1
  49. package/package-source/tools/install/bootstrap-codex-harness.ps1 +23 -10
  50. package/package-source/tools/install/install-agent.ps1 +59 -18
  51. package/package.json +1 -1
@@ -1,61 +1,54 @@
1
- # AGENTS.md
1
+ ## 模板优先
2
2
 
3
- 本文件只保留每次会话都必须知道的 Harness 入口规则。细节按需读取下方深文档,不把长期协议全部塞进入口文件。
3
+ - 需要影响新项目 bootstrap、生成物结构、默认导航层、默认 prompt、默认规则、默认技能、默认上下文模板时,先修改模板 canonical:
4
+ - `docs/codex-harness-engineering/templates/`
5
+ - `tools/harness/templates/`
6
+ - `docs/codex-harness-engineering/templates/package-assets/`
7
+ - 当前仓库根目录下的活跃文档或脚本,只在它本身就是 canonical,或为了验证模板落地效果、保持当前仓库可运行时再同步修改。
8
+ - 如果一次改动同时涉及根目录活跃文件和模板文件,优先说明哪一份是 canonical,避免只修当前仓库、不修模板源。
4
9
 
5
- ## 模板源目录说明
10
+ ## 任务结构硬门禁
6
11
 
7
- - 当你在模板源仓库维护 `templates/runtime/` 时,本文件也同时代表该目录的本地索引。
8
- - 当前目录主要包含:
9
- - `AGENTS.md`:安装到目标项目根目录的入口规则模板
10
- - `codex-loop.ps1` / `doctor.ps1` / `verify.ps1`:driver 与运行时脚本模板
11
- - `project-task-template.json` / `smoke-task.json` / `task.json` / `progress.txt`:任务与运行状态模板
12
- - `task-run-profile.json`:运行策略模板
13
- - `scripts/`:runtime 自检和队列校验脚本
14
- - 维护该目录时,优先确认这些文件是“安装后运行面”,不要把只适用于模板仓库的局部说明大量混入这里。
12
+ - 未经用户明确同意,不得把标准 `task.json` 模板 phase 压缩成更少任务;正式任务队列至少保留 `ANALYSIS-001`、`TESTCASE-001`、`PLAN-001`。
13
+ - P0/P1 项目禁止跳过 `TESTCASE-001`;缺少 `docs/testing/NATURAL_LANGUAGE_TEST_CASES.md`、`ACCEPTANCE_CRITERIA.md`、`TRACEABILITY_MATRIX.md`、`TEST_DATA_MATRIX.md`、`REGRESSION_PLAN.md`、`verify-matrix.md` 任一项,都不得生成最终 `task.json`。
14
+ - `feature_impl` 没有 `qa_contract` 不得进入正式任务队列;`qa_contract` 没有完整 `tdd_contract`、`development_validation`、`acceptance_validation` 不得开始实现。
15
+ - 单个 `feature_impl` 默认不得覆盖超过 3 条主需求;订单、支付、库存、RBAC 必须拆独立任务;前端和后端不得长期混在同一个 story,除非这是明确的 `release` 任务。
15
16
 
16
- ## 核心入口
17
+ ## 子目录 AGENTS 规则
17
18
 
18
- - 本仓库默认采用 `driver-first`:真实任务进入 `task.json`,由 `tools/harness/codex-loop.ps1` 逐个执行。
19
- - `single task` 是当前唯一自动执行模式;每轮 driver 只处理一个 `passes: false` 且依赖已通过的任务。
20
- - 交互开发模式只负责需求收敛、分析、规划和任务输入;方案确认后,默认回到 `task.json -> tools/harness/codex-loop.ps1`。
21
- - 主控会话不直接维护仓库状态文件;`task.json`、`progress.txt`、`traces/` Git 提交由 runtime 链路推进。
22
- - 长会话续跑前,先重读 `docs/ai/CURRENT_TASK.md`、`docs/ai/repo-map.md` 和相关 truth source;不要只靠聊天记忆继续实现。
23
- - 需要理解代码结构或安装包边界时,先读 `docs/ai/repo-map.md`,再进入具体目录或深文档。
24
- - 需要落盘规则、任务、文档、前端、后端或测试内容时,先确认 truth source,再委派匹配的 writer 子代理或进入 driver 任务。
19
+ - 新增业务目录、模块职责变化、目录入口变化、目录级测试命令变化时,必须检查并更新最接近该目录的子目录 `AGENTS.md`。
20
+ - 目录级 `AGENTS.md` 负责承载局部职责、边界、入口、测试命令、复用模式、坑点和禁止事项;不要把这类规则长期堆在根 `AGENTS.md`。
21
+ - 自动托管区块 `AUTO-MODULE-FACTS` 只补动态事实,不等于目录规则完整;即使 facts 已自动刷新,仍需要有人维护手写的局部规则部分。
22
+ - 如果 `task.json.owned_paths`、`docs/ai/repo-map.md` 或模块边界已经明确某目录是独立模块,而该目录缺少子目录 `AGENTS.md`,应视为至少 `warn`,高风险目录应直接阻断进入正式任务队列或实现阶段。
25
23
 
26
- ## 硬约束
24
+ ## 目录级规则
27
25
 
28
- - 启动前 Git 工作区必须干净,除非用户明确说明哪些改动属于本任务;可再生运行产物只能通过 `runtime.git.non_blocking_dirty_paths` 列白名单。
29
- - 不要伪造完成状态:不得手工把未验证任务标记为 `passes: true`,不得绕过 `test_command`、review gate 或 commit gate。
30
- - 不要删除或改写已有任务描述,除非用户明确要求替换模板示例或重建任务队列。
31
- - 修改后必须运行与改动直接对应的验证;文档改动至少运行 `git diff --check`。
32
- - 测试范围从需求收敛阶段开始定义;P0/P1 需求进入实现前必须有可追溯验收、测试数据和证据路径。
33
- - 外部系统、开源栈、第三方平台或真实环境集成需求,完成声明必须包含真实依赖接入、成功态证据和失败态证据。
34
- - 进入实现前必须有当前项目声明的架构约束 truth source,默认路径为 `docs/architecture/constraints.md`,也可由 `task.json.runtime.handoff.truth_sources.architecture` 指向其他路径。
35
- - `feature_impl` 任务必须携带可执行的 `architecture_constraints`、`forbidden_implementations` 和对应验证命令;禁止用测试替身、local-only adapter 或领域原型冒充任务声明的交付路径。
36
- - Stage 1 Review 先审声明的架构约束符合性,再审业务规格;仅当任务要求架构门禁且约束缺失或实现冲突时 FAIL。
37
- - 多 Agent 协作时,禁止多个 Agent 同时修改同一文件或同一组可写路径;必须先按任务、目录、文件组、分支或 PR 隔离。
38
- - 当前轮次结束前必须刷新 `docs/ai/CURRENT_TASK.md` 中的已完成内容、未完成内容、修改文件、测试结果和下一步。
39
- - 阻塞时追加 `progress.txt`,输出 `BLOCKED - 需要人工介入`,然后停止。
40
-
41
- ## 阶段更新规则
42
-
43
- - Stage 01 初始化:更新 `task.json`、`AGENTS.md`、项目路径和验证命令。
44
- - Stage 02 需求收敛:更新 `docs/product/`、Requirement IDs、验收标准和可执行验收示例。
45
- - Stage 03 追溯与架构约束:更新架构约束 truth source、测试追溯矩阵和证据协议。
46
- - Stage 09 DEV-PLAN / 任务拆分:把架构约束、禁止实现和验证命令写入每个相关 `feature_impl`。
47
- - Stage 10-14 实现与集成:只更新任务 owned paths 内的实现、测试和证据。
48
- - Stage 15-16 Review:保持只读审查,输出 findings、证据和 repair queue。
49
- - Stage 17 Verify / Regression:刷新验证证据,不在本阶段第一次补需求或测试范围。
50
- - Archive:更新 `docs/knowledge/`、索引和可复用经验,不升级一次性结论为全局规则。
26
+ - 当某个目录满足以下任一条件时,应优先考虑新增或更新该目录下的 `AGENTS.md`,而不是继续扩充根入口:
27
+ - 目录有独立模块职责或技术栈
28
+ - 目录存在与全仓不同的架构边界
29
+ - 目录有独立入口文件、测试命令或验证方式
30
+ - 目录反复出现相同 review 问题、坑点或禁止事项
31
+ - 子目录 `AGENTS.md` 应重点写:
32
+ - 该目录负责什么 / 不负责什么
33
+ - 入口文件和核心文件
34
+ - 修改前必须先看的文件
35
+ - 本目录的局部架构规则和复用模式
36
+ - 测试 / 构建 / 验证命令
37
+ - 常见坑和禁止事项
38
+ - `docs/ai/repo-map.md` 及模板中的 repo-map 应维护“子目录规则索引”,明确哪些路径已有本地规则、适用于什么场景。
51
39
 
52
40
  ## 必读索引
53
41
 
54
- 如果当前仓库是 thin install 项目,而下面列出的 `docs/harness/*` 或 `docs/knowledge/*` 不在项目根,先读取 `.codex-harness/state/config.json`,再到其中 `packageRoot` 下查同路径文件。
42
+ 如果当前仓库是 thin install 项目,而下面列出的 `docs/harness/*`、`docs/testing/*` 或 `docs/knowledge/*` 不在项目根,先读取 `.codex-harness/state/config.json`,再按文档类型改读 `packageRoot` 下模板镜像中的对应文件:
43
+ - `docs/harness/*` -> `docs/codex-harness-engineering/templates/docs/*`
44
+ - `docs/testing/*` -> `docs/codex-harness-engineering/templates/testing/*`
45
+ - `docs/knowledge/*` -> `docs/codex-harness-engineering/templates/knowledge/*`
55
46
 
47
+ - Harness 分层分析索引:`harness-analysis/README.md`
48
+ - Codex Harness Engineering 总览:`docs/codex-harness-engineering/README.md`
49
+ - Codex 宿主自动加载机制:`docs/codex-harness-engineering/codex-host-runtime-and-autoload.md`
50
+ - Codex 自动加载优化清单:`harness-analysis/10-codex-autoload-optimization-checklist.md`
56
51
  - Harness 架构:`docs/harness/architecture.md`
57
- - 代码地图:`docs/ai/repo-map.md`
58
- - 架构摘要:`docs/ai/architecture-brief.md`
59
52
  - 架构约束包:`docs/architecture/constraints.md` 或 `task.json.runtime.handoff.truth_sources.architecture`
60
53
  - 新项目使用:`docs/harness/new-project-usage.md`
61
54
  - Task 会话与 `task.json` 细则:`docs/harness/task-session-strategy.md`
@@ -64,3 +57,9 @@
64
57
  - Trace 格式:`docs/harness/trace-format.md`
65
58
  - 权限策略:`docs/harness/sandbox-policy.md`
66
59
  - Prompt 与知识集成:`docs/harness/prompt-knowledge-integration.md`
60
+
61
+ ## 当前在做的事情
62
+
63
+ - 正在持续分析当前仓库里的 Codex 宿主层、Harness 控制层、安装工程和桥接层。
64
+ - 当前重点是把“哪些内容会被 Codex 自动加载到上下文、哪些只是运行配置、哪些是 Harness runtime 二次读取”彻底拆清。
65
+ - 所有新增分析文档统一落在 `harness-analysis/`,方法论和模板级说明补充到 `docs/codex-harness-engineering/`。
@@ -57,14 +57,50 @@ function Add-DoctorError {
57
57
  $Errors.Value += $Message
58
58
  }
59
59
 
60
- function Add-DoctorWarning {
61
- param(
62
- [ref]$Warnings,
63
- [string]$Message
64
- )
65
-
66
- $Warnings.Value += $Message
67
- }
60
+ function Add-DoctorWarning {
61
+ param(
62
+ [ref]$Warnings,
63
+ [string]$Message
64
+ )
65
+
66
+ $Warnings.Value += $Message
67
+ }
68
+
69
+ function Invoke-TaskStructureValidation {
70
+ param(
71
+ [string]$Root,
72
+ [ref]$Errors,
73
+ [ref]$Warnings
74
+ )
75
+
76
+ $scriptPath = Join-Path $Root "tools\harness\task-structure-lint.ps1"
77
+ if (-not (Test-Path -LiteralPath $scriptPath -PathType Leaf)) {
78
+ Add-DoctorError -Errors $Errors -Message "缺少 task structure lint: tools\\harness\\task-structure-lint.ps1"
79
+ return
80
+ }
81
+
82
+ try {
83
+ $result = & powershell -NoProfile -ExecutionPolicy Bypass -File $scriptPath -ProjectRoot $Root -JsonOutput | ConvertFrom-Json
84
+ }
85
+ catch {
86
+ Add-DoctorError -Errors $Errors -Message "task structure lint 执行失败: $($_.Exception.Message)"
87
+ return
88
+ }
89
+
90
+ foreach ($finding in @($result.findings)) {
91
+ $message = [string]$finding.message
92
+ if (-not [string]::IsNullOrWhiteSpace([string]$finding.task_id)) {
93
+ $message = "task $($finding.task_id): $message"
94
+ }
95
+
96
+ if ($finding.severity -eq "warning") {
97
+ Add-DoctorWarning -Warnings $Warnings -Message $message
98
+ }
99
+ else {
100
+ Add-DoctorError -Errors $Errors -Message $message
101
+ }
102
+ }
103
+ }
68
104
 
69
105
  function Get-DoctorFileSha256 {
70
106
  param([string]$Path)
@@ -497,9 +533,6 @@ function Test-DoctorThinLegacyResidue {
497
533
  param([string]$Root)
498
534
 
499
535
  $legacyResiduePaths = @(
500
- "docs\harness",
501
- "docs\testing",
502
- "docs\knowledge",
503
536
  "docs\requirement-prep-kit"
504
537
  )
505
538
 
@@ -542,6 +575,41 @@ function Test-DoctorThinLegacyResidue {
542
575
 
543
576
  return $false
544
577
  }
578
+
579
+ function Test-ProjectScopeInstallSurface {
580
+ param(
581
+ [string]$Root,
582
+ [object]$ManifestSnapshot,
583
+ [ref]$Errors
584
+ )
585
+
586
+ if ($null -eq $ManifestSnapshot) {
587
+ return
588
+ }
589
+
590
+ $entries = @($ManifestSnapshot.entries | Where-Object { [string]$_.scope -eq "project" })
591
+ foreach ($entry in $entries) {
592
+ $destinationRaw = [string]$entry.destination
593
+ if ([string]::IsNullOrWhiteSpace($destinationRaw)) {
594
+ continue
595
+ }
596
+
597
+ $normalizedDestination = $destinationRaw.Replace('/', '\').TrimStart('\')
598
+ $expectsDirectory = $destinationRaw.Trim().Replace('\', '/').EndsWith('/', [System.StringComparison]::Ordinal)
599
+ $targetPath = Join-Path $Root $normalizedDestination
600
+
601
+ if ($expectsDirectory) {
602
+ if (-not (Test-Path -LiteralPath $targetPath -PathType Container)) {
603
+ Add-DoctorError -Errors $Errors -Message "project scope 安装缺少目录: $normalizedDestination"
604
+ }
605
+ continue
606
+ }
607
+
608
+ if (-not (Test-Path -LiteralPath $targetPath -PathType Leaf)) {
609
+ Add-DoctorError -Errors $Errors -Message "project scope 安装缺少文件: $normalizedDestination"
610
+ }
611
+ }
612
+ }
545
613
 
546
614
  function Test-DoctorMissingUserPackage {
547
615
  param([object]$HarnessConfigInfo)
@@ -760,7 +828,7 @@ function Test-PackageLock {
760
828
  }
761
829
  }
762
830
 
763
- function Test-InstallManifestSnapshot {
831
+ function Test-InstallManifestSnapshot {
764
832
  param(
765
833
  [string]$Root,
766
834
  [bool]$RequireSnapshot,
@@ -838,9 +906,6 @@ function Test-ThinProjectSurface {
838
906
  }
839
907
 
840
908
  $legacyResiduePaths = @(
841
- "docs\harness",
842
- "docs\testing",
843
- "docs\knowledge",
844
909
  "docs\requirement-prep-kit"
845
910
  )
846
911
 
@@ -879,6 +944,17 @@ function Test-ThinProjectSurface {
879
944
  }
880
945
  }
881
946
  }
947
+
948
+ function Read-InstallManifestSnapshotOrNull {
949
+ param([string]$Root)
950
+
951
+ $snapshotPath = Join-Path $Root ".codex-harness\manifests\install-manifest.json"
952
+ if (-not (Test-Path -LiteralPath $snapshotPath -PathType Leaf)) {
953
+ return $null
954
+ }
955
+
956
+ return Read-JsonFileOrNull -Path $snapshotPath
957
+ }
882
958
 
883
959
  function Test-HarnessConfig {
884
960
  param(
@@ -1017,15 +1093,16 @@ $isThinProjectInstall = $harnessConfigInfo.Exists -and $harnessConfigInfo.Valid
1017
1093
  $isVendorProjectInstall = $harnessConfigInfo.Exists -and $harnessConfigInfo.Valid -and $harnessConfigInfo.InstallScope -eq "vendor"
1018
1094
  $isNotInstalledProject = $baseProjectShape -eq "not-installed"
1019
1095
 
1020
- $requiredRootFiles = @(
1021
- "AGENTS.md",
1096
+ $requiredRootFiles = @(
1097
+ "AGENTS.md",
1022
1098
  "tools\harness\codex-loop.ps1",
1023
1099
  "tools\harness\doctor.ps1",
1100
+ "tools\harness\task-structure-lint.ps1",
1024
1101
  "tools\harness\verify.ps1",
1025
1102
  "tools\install\env-check.ps1",
1026
1103
  "task.json",
1027
1104
  "docs\harness\trace.schema.json"
1028
- )
1105
+ )
1029
1106
 
1030
1107
  $requiredPromptFiles = @(
1031
1108
  ".codex\\prompts\\implement-one-task.md",
@@ -1108,21 +1185,25 @@ if ((Test-Path -LiteralPath $specManifestSchemaPath) -and (-not (Test-JsonFile -
1108
1185
  Add-DoctorError -Errors ([ref]$errors) -Message "spec-manifest.schema.json 不是合法 JSON: docs\\spec\\spec-manifest.schema.json"
1109
1186
  }
1110
1187
 
1111
- if ($isNotInstalledProject) {
1112
- Add-DoctorError -Errors ([ref]$errors) -Message "readiness gate 未检测到 harness config 或 legacy vendor,请先安装 project scope。"
1113
- }
1114
- else {
1188
+ if ($isNotInstalledProject) {
1189
+ Add-DoctorError -Errors ([ref]$errors) -Message "readiness gate 未检测到 harness config 或 legacy vendor,请先安装 project scope。"
1190
+ }
1191
+ else {
1115
1192
  if (-not $isVendorProjectInstall) {
1116
1193
  Test-SpecManifest -Root $resolvedProjectRoot -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1117
1194
  }
1118
1195
 
1119
- Test-HarnessConfig -Root $resolvedProjectRoot -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1120
- Test-PackageLock -Root $resolvedProjectRoot -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1121
- if (-not $isThinProjectInstall) {
1122
- Test-InstallManifest -Root $resolvedProjectRoot -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1123
- }
1124
- Test-InstallManifestSnapshot -Root $resolvedProjectRoot -RequireSnapshot:$harnessConfigInfo.Exists -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1125
- }
1196
+ Test-HarnessConfig -Root $resolvedProjectRoot -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1197
+ Test-PackageLock -Root $resolvedProjectRoot -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1198
+ if (-not $isThinProjectInstall) {
1199
+ Test-InstallManifest -Root $resolvedProjectRoot -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1200
+ }
1201
+ Test-InstallManifestSnapshot -Root $resolvedProjectRoot -RequireSnapshot:$harnessConfigInfo.Exists -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1202
+ if ($isThinProjectInstall) {
1203
+ $installManifestSnapshot = Read-InstallManifestSnapshotOrNull -Root $resolvedProjectRoot
1204
+ Test-ProjectScopeInstallSurface -Root $resolvedProjectRoot -ManifestSnapshot $installManifestSnapshot -Errors ([ref]$errors)
1205
+ }
1206
+ }
1126
1207
 
1127
1208
  if (-not (Test-Path -LiteralPath $taskPath)) {
1128
1209
  if ($isNotInstalledProject) {
@@ -1143,11 +1224,37 @@ elseif (-not $isVendorProjectInstall) {
1143
1224
  Add-DoctorError -Errors ([ref]$errors) -Message "task.json 仍包含模板占位符,请先替换为当前项目真实任务。"
1144
1225
  }
1145
1226
 
1146
- $taskDocument = $taskContent | ConvertFrom-Json
1147
- $runtime = $taskDocument.runtime
1148
- $runProfileRelativePath = $DefaultRunProfile
1149
- if ($null -ne $runtime -and -not [string]::IsNullOrWhiteSpace($runtime.run_profile)) {
1150
- $runProfileRelativePath = $runtime.run_profile
1227
+ $taskDocument = $taskContent | ConvertFrom-Json
1228
+ $runtime = $taskDocument.runtime
1229
+ if ($null -eq $runtime -or [string]::IsNullOrWhiteSpace([string]$runtime.driver)) {
1230
+ Add-DoctorError -Errors ([ref]$errors) -Message "task.json 缺少 runtime.driver"
1231
+ }
1232
+ else {
1233
+ $driverCommand = [string]$runtime.driver
1234
+ if ($driverCommand -match 'tools[\\/]+harness[\\/]+tools[\\/]+harness[\\/]+codex-loop\.ps1') {
1235
+ Add-DoctorError -Errors ([ref]$errors) -Message "task.json 的 runtime.driver 包含重复路径段 tools/harness/tools/harness,请改为 .\\tools\\harness\\codex-loop.ps1"
1236
+ }
1237
+
1238
+ $driverFileMatch = [regex]::Match($driverCommand, '(?i)-File\s+("?)([^"]+)\1')
1239
+ if (-not $driverFileMatch.Success) {
1240
+ Add-DoctorError -Errors ([ref]$errors) -Message "task.json 的 runtime.driver 不是可解析的 PowerShell -File 命令: $driverCommand"
1241
+ }
1242
+ else {
1243
+ $driverRelativePath = $driverFileMatch.Groups[2].Value.Replace('/', '\')
1244
+ if ($driverRelativePath.StartsWith('.\')) {
1245
+ $driverRelativePath = $driverRelativePath.Substring(2)
1246
+ }
1247
+
1248
+ $driverPath = Join-Path $resolvedProjectRoot $driverRelativePath
1249
+ if (-not (Test-Path -LiteralPath $driverPath)) {
1250
+ Add-DoctorError -Errors ([ref]$errors) -Message "task.json 的 runtime.driver 指向不存在的脚本: $driverRelativePath"
1251
+ }
1252
+ }
1253
+ }
1254
+
1255
+ $runProfileRelativePath = $DefaultRunProfile
1256
+ if ($null -ne $runtime -and -not [string]::IsNullOrWhiteSpace($runtime.run_profile)) {
1257
+ $runProfileRelativePath = $runtime.run_profile
1151
1258
  }
1152
1259
 
1153
1260
  $runProfilePath = Join-Path $resolvedProjectRoot $runProfileRelativePath
@@ -1204,7 +1311,7 @@ elseif (-not $isVendorProjectInstall) {
1204
1311
  }
1205
1312
 
1206
1313
  $taskIds = @{}
1207
- foreach ($task in @($taskDocument.tasks)) {
1314
+ foreach ($task in @($taskDocument.tasks)) {
1208
1315
  if ($null -eq $task.id -or [string]::IsNullOrWhiteSpace([string]$task.id)) {
1209
1316
  Add-DoctorError -Errors ([ref]$errors) -Message "存在缺少 id 的任务。"
1210
1317
  continue
@@ -1231,13 +1338,15 @@ elseif (-not $isVendorProjectInstall) {
1231
1338
 
1232
1339
  $requiredTruthSourcesProperty = $task.PSObject.Properties["required_truth_sources"]
1233
1340
  $requiredTruthSources = if ($null -ne $requiredTruthSourcesProperty) { $requiredTruthSourcesProperty.Value } else { @() }
1234
- foreach ($truthSource in @($requiredTruthSources)) {
1235
- if ($allowedTruthSources -notcontains [string]$truthSource) {
1236
- Add-DoctorError -Errors ([ref]$errors) -Message "任务 $($task.id) 使用了未知 required_truth_source: $truthSource"
1237
- }
1238
- }
1239
- }
1240
- }
1341
+ foreach ($truthSource in @($requiredTruthSources)) {
1342
+ if ($allowedTruthSources -notcontains [string]$truthSource) {
1343
+ Add-DoctorError -Errors ([ref]$errors) -Message "任务 $($task.id) 使用了未知 required_truth_source: $truthSource"
1344
+ }
1345
+ }
1346
+ }
1347
+
1348
+ Invoke-TaskStructureValidation -Root $resolvedProjectRoot -Errors ([ref]$errors) -Warnings ([ref]$warnings)
1349
+ }
1241
1350
 
1242
1351
  Write-DoctorReadiness `
1243
1352
  -Root $resolvedProjectRoot `
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "runtime": {
3
- "driver": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\tools/harness/codex-loop.ps1",
3
+ "driver": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\codex-loop.ps1",
4
4
  "trace_dir": "traces",
5
5
  "agent": "codex",
6
6
  "run_profile": ".codex\\task-run-profile.json",
@@ -92,12 +92,13 @@
92
92
  "execution": {
93
93
  "mode": "single"
94
94
  },
95
- "steps": [
96
- "把模板中的 <feature-slug>、用户故事标题、requirement_ids、owned_paths、context_files 和 test_command 全部替换成当前项目真实值",
97
- "确认 task 依赖、优先级、execution.mode 和 non_blocking_dirty_paths 已与当前项目约束一致",
98
- "确认架构约束 truth source 已明确交付形态、公开入口、数据边界、异步边界、测试替身策略、禁止实现和 Definition of Done;如项目不用默认路径,更新 runtime.handoff.truth_sources.architecture",
99
- "确认当前 task.json 已经是正式任务队列,不再保留领域示例、smoke 占位或过期路径"
100
- ],
95
+ "steps": [
96
+ "把模板中的 <feature-slug>、用户故事标题、requirement_ids、owned_paths、context_files 和 test_command 全部替换成当前项目真实值",
97
+ "确认 task 依赖、优先级、execution.mode 和 non_blocking_dirty_paths 已与当前项目约束一致",
98
+ "不得删除 ANALYSIS-001、TESTCASE-001、PLAN-001;未经用户明确批准并记录例外原因,不得压缩标准模板 phase",
99
+ "确认架构约束 truth source 已明确交付形态、公开入口、数据边界、异步边界、测试替身策略、禁止实现和 Definition of Done;如项目不用默认路径,更新 runtime.handoff.truth_sources.architecture",
100
+ "确认当前 task.json 已经是正式任务队列,不再保留领域示例、smoke 占位或过期路径"
101
+ ],
101
102
  "test_command": "git diff --check",
102
103
  "acceptance": [
103
104
  "任务队列只保留当前项目真实阶段与用户故事",
@@ -354,7 +355,9 @@
354
355
  "把后续实现按用户故事顺序映射到 dev-plan、affected tests、验证命令和证据路径",
355
356
  "把自然语言测试用例中的 TDD 候选转换为每个 feature_impl.qa_contract.tdd_contract,并保留 source_case_ids",
356
357
  "把非 TDD 自然语言用例映射到 feature_impl.qa_contract.story_full_chain.source_case_ids、acceptance_validation.source_case_ids、回归计划或 verify-matrix",
358
+ "不要把模板 phase 合并成更少任务;如果用户明确批准压缩,必须在对应任务补充 decomposition_exemption 记录批准范围和原因",
357
359
  "确认每个实现任务都已有 requirement_ids、owned_paths、context_files 和最小可行验收闭环",
360
+ "确认每个 feature_impl 默认不超过 3 条主 requirement_ids;订单、支付、库存、RBAC 拆成独立任务;前端和后端不要长期混在同一个 story",
358
361
  "对涉及用户可见行为、路由、表单、权限、状态流转或关键业务闭环的任务,明确是否要求 docs/testing/e2e-plan.md,并把相关 E2E 命令写进 test_command 或 release 验证链路",
359
362
  "确认每个 feature_impl 任务都携带 architecture_constraints、forbidden_implementations、tdd_contract 和项目真实可执行的 test_command",
360
363
  "明确哪些故事必须串行,哪些依赖可在后续手工改成并行"
@@ -364,6 +367,8 @@
364
367
  "dev-plan、verify-matrix 和 story 级执行顺序保持一致",
365
368
  "每个 feature_impl 的 tdd_contract.red.source_case_ids 均能回溯到 NATURAL_LANGUAGE_TEST_CASES.md",
366
369
  "每个 feature_impl 的非 TDD 自然语言用例均能回溯到 story_full_chain、acceptance_validation、回归计划或 verify-matrix",
370
+ "模板 phase 没有被压缩;如存在压缩或跨层混合,已附带用户批准的 decomposition_exemption",
371
+ "每个 feature_impl 默认不超过 3 条主 requirement_ids,且订单、支付、库存、RBAC 已拆成独立任务",
367
372
  "高风险用户可见任务已经明确是否需要 e2e-plan 与对应 E2E 证据",
368
373
  "实现任务不会把测试替身、local-only adapter 或领域原型伪装成声明的交付路径",
369
374
  "后续实现与 release 任务的验证边界已经明确且可执行"
@@ -487,19 +492,21 @@
487
492
  ],
488
493
  "exemptions": []
489
494
  },
490
- "context_files": [
491
- "docs/product/prd-lite.md",
492
- "docs/product/requirement-interface-matrix.md",
493
- "docs/architecture/constraints.md",
494
- "docs/context/feature-pack.md",
495
- "docs/design/design-brief.md",
496
- "docs/design/component-map.md",
497
- "docs/design/screen-states.md",
498
- "docs/testing/ACCEPTANCE_EXAMPLES.md",
499
- "docs/testing/NATURAL_LANGUAGE_TEST_CASES.md",
500
- "docs/testing/TRACEABILITY_MATRIX.md",
501
- "docs/testing/TEST_STRATEGY.md",
502
- "docs/testing/TEST_DATA_MATRIX.md",
495
+ "context_files": [
496
+ "docs/product/prd-lite.md",
497
+ "docs/product/requirement-interface-matrix.md",
498
+ "docs/architecture/constraints.md",
499
+ "docs/context/feature-pack.md",
500
+ "docs/design/design-brief.md",
501
+ "docs/design/component-map.md",
502
+ "docs/design/screen-states.md",
503
+ "docs/testing/ACCEPTANCE_CRITERIA.md",
504
+ "docs/testing/ACCEPTANCE_EXAMPLES.md",
505
+ "docs/testing/NATURAL_LANGUAGE_TEST_CASES.md",
506
+ "docs/testing/REGRESSION_PLAN.md",
507
+ "docs/testing/TRACEABILITY_MATRIX.md",
508
+ "docs/testing/TEST_STRATEGY.md",
509
+ "docs/testing/TEST_DATA_MATRIX.md",
503
510
  "docs/testing/EVIDENCE_PROTOCOL.md",
504
511
  "docs/testing/test-matrix.md",
505
512
  "docs/testing/verify-matrix.md",
@@ -520,13 +527,14 @@
520
527
  "execution": {
521
528
  "mode": "single"
522
529
  },
523
- "steps": [
524
- "把 US1 标题、requirement_ids、owned_paths、产物路径和独立验证方式替换为真实项目内容",
525
- "把 qa_contract 中的 tdd_contract.source_case_ids、story_full_chain.source_case_ids、acceptance_validation.source_case_ids、入口、数据、动作、Oracle、证据、失败态和 release impact 全部替换为真实内容",
526
- "仅实现首个可单独交付的用户故事,并同步补齐其 affected tests 与必要文档",
527
- "运行与 US1 对应的真实验证命令,必须包含开发验证和代码完成后的故事级验收链路,并记录可回溯证据"
528
- ],
529
- "test_command": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\tools/harness/verify.ps1 -Commands @('<replace-with-project-fitness-check>', '<replace-with-affected-tests>', 'git diff --check')",
530
+ "steps": [
531
+ "把 US1 标题、requirement_ids、owned_paths、产物路径和独立验证方式替换为真实项目内容",
532
+ "把 qa_contract 中的 tdd_contract.source_case_ids、story_full_chain.source_case_ids、acceptance_validation.source_case_ids、入口、数据、动作、Oracle、证据、失败态和 release impact 全部替换为真实内容",
533
+ "单个 feature_impl 默认不超过 3 条主 requirement_ids;订单、支付、库存、RBAC 不要和其他主故事捆绑;前端和后端不要长期混在同一个 story",
534
+ "仅实现首个可单独交付的用户故事,并同步补齐其 affected tests 与必要文档",
535
+ "运行与 US1 对应的真实验证命令,必须包含开发验证和代码完成后的故事级验收链路,并记录可回溯证据"
536
+ ],
537
+ "test_command": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\verify.ps1 -Commands @('<replace-with-project-fitness-check>', '<replace-with-affected-tests>', 'git diff --check')",
530
538
  "acceptance": [
531
539
  "US1 能作为 MVP 独立演示或独立验收",
532
540
  "US1 满足架构约束 truth source,不以测试替身冒充声明交付路径",
@@ -652,19 +660,21 @@
652
660
  ],
653
661
  "exemptions": []
654
662
  },
655
- "context_files": [
656
- "docs/product/prd-lite.md",
657
- "docs/product/requirement-interface-matrix.md",
658
- "docs/architecture/constraints.md",
659
- "docs/context/feature-pack.md",
660
- "docs/design/design-brief.md",
661
- "docs/design/component-map.md",
662
- "docs/design/screen-states.md",
663
- "docs/testing/ACCEPTANCE_EXAMPLES.md",
664
- "docs/testing/NATURAL_LANGUAGE_TEST_CASES.md",
665
- "docs/testing/TRACEABILITY_MATRIX.md",
666
- "docs/testing/TEST_STRATEGY.md",
667
- "docs/testing/TEST_DATA_MATRIX.md",
663
+ "context_files": [
664
+ "docs/product/prd-lite.md",
665
+ "docs/product/requirement-interface-matrix.md",
666
+ "docs/architecture/constraints.md",
667
+ "docs/context/feature-pack.md",
668
+ "docs/design/design-brief.md",
669
+ "docs/design/component-map.md",
670
+ "docs/design/screen-states.md",
671
+ "docs/testing/ACCEPTANCE_CRITERIA.md",
672
+ "docs/testing/ACCEPTANCE_EXAMPLES.md",
673
+ "docs/testing/NATURAL_LANGUAGE_TEST_CASES.md",
674
+ "docs/testing/REGRESSION_PLAN.md",
675
+ "docs/testing/TRACEABILITY_MATRIX.md",
676
+ "docs/testing/TEST_STRATEGY.md",
677
+ "docs/testing/TEST_DATA_MATRIX.md",
668
678
  "docs/testing/EVIDENCE_PROTOCOL.md",
669
679
  "docs/testing/test-matrix.md",
670
680
  "docs/testing/verify-matrix.md",
@@ -685,13 +695,14 @@
685
695
  "execution": {
686
696
  "mode": "single"
687
697
  },
688
- "steps": [
689
- "将 US2 占位内容替换为真实范围、路径、需求编号和验证命令",
690
- "把 qa_contract 中的 tdd_contract.source_case_ids、story_full_chain.source_case_ids、acceptance_validation.source_case_ids、入口、数据、动作、Oracle、证据、失败态和 release impact 全部替换为真实内容",
691
- "确保 US2 可作为独立增量交付,不把未确认范围混入同一任务",
692
- "补齐 US2 的 affected tests、开发验证、代码完成后的故事级验收链路、回归说明和证据路径"
693
- ],
694
- "test_command": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\tools/harness/verify.ps1 -Commands @('<replace-with-project-fitness-check>', '<replace-with-affected-tests>', 'git diff --check')",
698
+ "steps": [
699
+ "将 US2 占位内容替换为真实范围、路径、需求编号和验证命令",
700
+ "把 qa_contract 中的 tdd_contract.source_case_ids、story_full_chain.source_case_ids、acceptance_validation.source_case_ids、入口、数据、动作、Oracle、证据、失败态和 release impact 全部替换为真实内容",
701
+ "单个 feature_impl 默认不超过 3 条主 requirement_ids;订单、支付、库存、RBAC 不要和其他主故事捆绑;前端和后端不要长期混在同一个 story",
702
+ "确保 US2 可作为独立增量交付,不把未确认范围混入同一任务",
703
+ "补齐 US2 的 affected tests、开发验证、代码完成后的故事级验收链路、回归说明和证据路径"
704
+ ],
705
+ "test_command": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\verify.ps1 -Commands @('<replace-with-project-fitness-check>', '<replace-with-affected-tests>', 'git diff --check')",
695
706
  "acceptance": [
696
707
  "US2 范围清晰且不与其他故事混杂",
697
708
  "US2 满足架构约束 truth source,不以测试替身冒充声明交付路径",
@@ -817,18 +828,21 @@
817
828
  ],
818
829
  "exemptions": []
819
830
  },
820
- "context_files": [
821
- "docs/product/prd-lite.md",
822
- "docs/product/requirement-interface-matrix.md",
823
- "docs/architecture/constraints.md",
824
- "docs/context/feature-pack.md",
825
- "docs/design/design-brief.md",
826
- "docs/design/component-map.md",
827
- "docs/design/screen-states.md",
828
- "docs/testing/ACCEPTANCE_EXAMPLES.md",
829
- "docs/testing/TRACEABILITY_MATRIX.md",
830
- "docs/testing/TEST_STRATEGY.md",
831
- "docs/testing/TEST_DATA_MATRIX.md",
831
+ "context_files": [
832
+ "docs/product/prd-lite.md",
833
+ "docs/product/requirement-interface-matrix.md",
834
+ "docs/architecture/constraints.md",
835
+ "docs/context/feature-pack.md",
836
+ "docs/design/design-brief.md",
837
+ "docs/design/component-map.md",
838
+ "docs/design/screen-states.md",
839
+ "docs/testing/ACCEPTANCE_CRITERIA.md",
840
+ "docs/testing/ACCEPTANCE_EXAMPLES.md",
841
+ "docs/testing/NATURAL_LANGUAGE_TEST_CASES.md",
842
+ "docs/testing/REGRESSION_PLAN.md",
843
+ "docs/testing/TRACEABILITY_MATRIX.md",
844
+ "docs/testing/TEST_STRATEGY.md",
845
+ "docs/testing/TEST_DATA_MATRIX.md",
832
846
  "docs/testing/EVIDENCE_PROTOCOL.md",
833
847
  "docs/testing/test-matrix.md",
834
848
  "docs/testing/verify-matrix.md",
@@ -849,13 +863,14 @@
849
863
  "execution": {
850
864
  "mode": "single"
851
865
  },
852
- "steps": [
853
- "将 US3 占位内容替换为真实故事标题、路径、需求编号和验证方式",
854
- "把 qa_contract 中的 tdd_contract.source_case_ids、story_full_chain.source_case_ids、acceptance_validation.source_case_ids、入口、数据、动作、Oracle、证据、失败态和 release impact 全部替换为真实内容",
855
- "只承接剩余优先级最高且可单独验收的增量,不把 release 收口动作混入本故事",
856
- "完成 US3 的实现、测试映射、开发验证、代码完成后的故事级验收链路和证据沉淀"
857
- ],
858
- "test_command": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\tools/harness/verify.ps1 -Commands @('<replace-with-project-fitness-check>', '<replace-with-affected-tests>', 'git diff --check')",
866
+ "steps": [
867
+ "将 US3 占位内容替换为真实故事标题、路径、需求编号和验证方式",
868
+ "把 qa_contract 中的 tdd_contract.source_case_ids、story_full_chain.source_case_ids、acceptance_validation.source_case_ids、入口、数据、动作、Oracle、证据、失败态和 release impact 全部替换为真实内容",
869
+ "单个 feature_impl 默认不超过 3 条主 requirement_ids;订单、支付、库存、RBAC 不要和其他主故事捆绑;前端和后端不要长期混在同一个 story",
870
+ "只承接剩余优先级最高且可单独验收的增量,不把 release 收口动作混入本故事",
871
+ "完成 US3 的实现、测试映射、开发验证、代码完成后的故事级验收链路和证据沉淀"
872
+ ],
873
+ "test_command": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\verify.ps1 -Commands @('<replace-with-project-fitness-check>', '<replace-with-affected-tests>', 'git diff --check')",
859
874
  "acceptance": [
860
875
  "US3 的增量边界和独立验收方式已明确",
861
876
  "US3 满足架构约束 truth source,不以测试替身冒充声明交付路径",
@@ -37,7 +37,7 @@
37
37
  }
38
38
  ],
39
39
  "runtime": {
40
- "driver": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\tools/harness/codex-loop.ps1",
40
+ "driver": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\codex-loop.ps1",
41
41
  "run_profile": ".codex\\task-run-profile.json",
42
42
  "session": {
43
43
  "mode": "fresh-process",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "runtime": {
3
- "driver": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\tools/harness/codex-loop.ps1",
3
+ "driver": "powershell -NoProfile -ExecutionPolicy Bypass -File .\\tools\\harness\\codex-loop.ps1",
4
4
  "trace_dir": "traces",
5
5
  "agent": "codex",
6
6
  "run_profile": ".codex\\task-run-profile.json",