@hunter-harness/workflow-harness 0.2.28 → 0.2.29

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 (138) hide show
  1. package/harness/bundles/general/claude-code/.harness-build.json +1 -1
  2. package/harness/bundles/general/claude-code/contracts/workflow-policy.json +34 -2
  3. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +1 -1
  4. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
  5. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
  6. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
  7. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +1 -1
  8. package/harness/bundles/general/claude-code/harness-review/SKILL.md +1 -1
  9. package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
  10. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +1 -1
  11. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
  12. package/harness/bundles/general/claude-code/harness-test/SKILL.md +26 -2
  13. package/harness/bundles/general/claude-code/harness-test/checklist.md +15 -0
  14. package/harness/bundles/general/claude-code/harness-test/reference.md +28 -4
  15. package/harness/bundles/general/claude-code/scripts/harness_test_runner.py +974 -0
  16. package/harness/bundles/general/claude-code/scripts/harness_workflow_policy.py +87 -0
  17. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  18. package/harness/bundles/general/codebuddy/contracts/workflow-policy.json +34 -2
  19. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
  20. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
  21. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  22. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  23. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +1 -1
  24. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +1 -1
  25. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
  26. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +1 -1
  27. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
  28. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +26 -2
  29. package/harness/bundles/general/codebuddy/harness-test/checklist.md +15 -0
  30. package/harness/bundles/general/codebuddy/harness-test/reference.md +28 -4
  31. package/harness/bundles/general/codebuddy/scripts/harness_test_runner.py +974 -0
  32. package/harness/bundles/general/codebuddy/scripts/harness_workflow_policy.py +87 -0
  33. package/harness/bundles/general/codex/.harness-build.json +1 -1
  34. package/harness/bundles/general/codex/contracts/workflow-policy.json +34 -2
  35. package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
  36. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
  37. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
  38. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
  39. package/harness/bundles/general/codex/harness-plan/SKILL.md +1 -1
  40. package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
  41. package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
  42. package/harness/bundles/general/codex/harness-submit/SKILL.md +1 -1
  43. package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
  44. package/harness/bundles/general/codex/harness-test/SKILL.md +26 -2
  45. package/harness/bundles/general/codex/harness-test/checklist.md +15 -0
  46. package/harness/bundles/general/codex/harness-test/reference.md +28 -4
  47. package/harness/bundles/general/codex/scripts/harness_test_runner.py +974 -0
  48. package/harness/bundles/general/codex/scripts/harness_workflow_policy.py +87 -0
  49. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  50. package/harness/bundles/general/cursor/contracts/workflow-policy.json +34 -2
  51. package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
  52. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
  53. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  54. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
  55. package/harness/bundles/general/cursor/harness-plan/SKILL.md +1 -1
  56. package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
  57. package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
  58. package/harness/bundles/general/cursor/harness-submit/SKILL.md +1 -1
  59. package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
  60. package/harness/bundles/general/cursor/harness-test/SKILL.md +26 -2
  61. package/harness/bundles/general/cursor/harness-test/checklist.md +15 -0
  62. package/harness/bundles/general/cursor/harness-test/reference.md +28 -4
  63. package/harness/bundles/general/cursor/scripts/harness_test_runner.py +974 -0
  64. package/harness/bundles/general/cursor/scripts/harness_workflow_policy.py +87 -0
  65. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  66. package/harness/bundles/java/claude-code/contracts/workflow-policy.json +34 -2
  67. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
  68. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
  69. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
  70. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
  71. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
  72. package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
  73. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +1 -1
  74. package/harness/bundles/java/claude-code/harness-review/SKILL.md +1 -1
  75. package/harness/bundles/java/claude-code/harness-run/SKILL.md +1 -1
  76. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +1 -1
  77. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
  78. package/harness/bundles/java/claude-code/harness-test/SKILL.md +26 -2
  79. package/harness/bundles/java/claude-code/scripts/harness_test_runner.py +974 -0
  80. package/harness/bundles/java/claude-code/scripts/harness_workflow_policy.py +87 -0
  81. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  82. package/harness/bundles/java/codebuddy/contracts/workflow-policy.json +34 -2
  83. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
  84. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
  85. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
  86. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  87. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  88. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
  89. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +1 -1
  90. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +1 -1
  91. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +1 -1
  92. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +1 -1
  93. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
  94. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +26 -2
  95. package/harness/bundles/java/codebuddy/scripts/harness_test_runner.py +974 -0
  96. package/harness/bundles/java/codebuddy/scripts/harness_workflow_policy.py +87 -0
  97. package/harness/bundles/java/codex/.harness-build.json +1 -1
  98. package/harness/bundles/java/codex/contracts/workflow-policy.json +34 -2
  99. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
  100. package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
  101. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
  102. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +1 -1
  103. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
  104. package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
  105. package/harness/bundles/java/codex/harness-plan/SKILL.md +1 -1
  106. package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
  107. package/harness/bundles/java/codex/harness-run/SKILL.md +1 -1
  108. package/harness/bundles/java/codex/harness-submit/SKILL.md +1 -1
  109. package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
  110. package/harness/bundles/java/codex/harness-test/SKILL.md +26 -2
  111. package/harness/bundles/java/codex/scripts/harness_test_runner.py +974 -0
  112. package/harness/bundles/java/codex/scripts/harness_workflow_policy.py +87 -0
  113. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  114. package/harness/bundles/java/cursor/contracts/workflow-policy.json +34 -2
  115. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
  116. package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
  117. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
  118. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  119. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
  120. package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
  121. package/harness/bundles/java/cursor/harness-plan/SKILL.md +1 -1
  122. package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
  123. package/harness/bundles/java/cursor/harness-run/SKILL.md +1 -1
  124. package/harness/bundles/java/cursor/harness-submit/SKILL.md +1 -1
  125. package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
  126. package/harness/bundles/java/cursor/harness-test/SKILL.md +26 -2
  127. package/harness/bundles/java/cursor/scripts/harness_test_runner.py +974 -0
  128. package/harness/bundles/java/cursor/scripts/harness_workflow_policy.py +87 -0
  129. package/harness/manifests/general/claude-code.json +20 -16
  130. package/harness/manifests/general/codebuddy.json +20 -16
  131. package/harness/manifests/general/codex.json +20 -16
  132. package/harness/manifests/general/cursor.json +20 -16
  133. package/harness/manifests/java/claude-code.json +20 -16
  134. package/harness/manifests/java/codebuddy.json +20 -16
  135. package/harness/manifests/java/codex.json +20 -16
  136. package/harness/manifests/java/cursor.json +20 -16
  137. package/hunter-workflow-family.json +2 -2
  138. package/package.json +1 -1
@@ -2,5 +2,5 @@
2
2
  "schemaVersion": 1,
3
3
  "overlay": "none",
4
4
  "agent": "claude-code",
5
- "coreHash": "8b33a3eaa74f46ca"
5
+ "coreHash": "9a2ab44ad7a34065"
6
6
  }
@@ -1,5 +1,36 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
+ "testExecution": {
4
+ "runner": "harness/scripts/harness_test_runner.py",
5
+ "defaultProfile": "safe",
6
+ "maxWorkers": 2,
7
+ "singleInstance": true,
8
+ "processTreeCleanup": true,
9
+ "detachedProcessPreflight": true,
10
+ "confirmationFlag": "--confirm-resource-intensive",
11
+ "confirmationRequiredProfiles": ["system", "full"],
12
+ "resourceIntensiveModules": [
13
+ "test_harness_integration.py",
14
+ "test_harness_service.py"
15
+ ],
16
+ "profiles": {
17
+ "safe": {
18
+ "description": "Default low-load profile; runs regular test modules sequentially in isolated processes.",
19
+ "includesResourceIntensive": false,
20
+ "moduleTimeoutSeconds": 300
21
+ },
22
+ "system": {
23
+ "description": "Runs integration and service-lifecycle modules only after explicit confirmation.",
24
+ "includesResourceIntensive": true,
25
+ "moduleTimeoutSeconds": 600
26
+ },
27
+ "full": {
28
+ "description": "Runs regular modules followed by resource-intensive modules after explicit confirmation.",
29
+ "includesResourceIntensive": true,
30
+ "moduleTimeoutSeconds": 600
31
+ }
32
+ }
33
+ },
3
34
  "riskTiers": {
4
35
  "fast": {
5
36
  "description": "Low-risk docs/comments/non-behavioral config; no API/DB/security/concurrency. Policy notes: checkpointRules apply only when meta/implementation-checkpoints.json defines the entry for this change; missing file/entry = disabled (gate must not require --task).",
@@ -45,8 +76,8 @@
45
76
  "inputs": ["test-scenarios", "verification-ledger"],
46
77
  "artifacts": ["test-reports", "verification-ledger"],
47
78
  "events": ["phase.start", "phase.end", "command", "verification"],
48
- "allowedInteractions": [],
49
- "capabilities": ["gate-begin", "gate-close", "test-guard", "ledger-record"]
79
+ "allowedInteractions": ["resource-intensive-test-confirmation"],
80
+ "capabilities": ["gate-begin", "gate-close", "test-guard", "ledger-record", "resource-safe-test-runner"]
50
81
  },
51
82
  "harness-review": {
52
83
  "phase": "review",
@@ -184,6 +215,7 @@
184
215
  },
185
216
  "interactionWhitelist": {
186
217
  "global": [],
218
+ "harness-test": ["resource-intensive-test-confirmation"],
187
219
  "harness-submit": ["merge-conflict-resolution"],
188
220
  "harness-plan": ["risk-confirmation"]
189
221
  },
@@ -20,7 +20,7 @@ disallowed-tools:
20
20
  - Bash(awk *)
21
21
  - Bash(curl *)
22
22
  ---
23
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
23
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
24
24
  # harness-archive — 变更归档
25
25
 
26
26
  ## Purpose
@@ -20,7 +20,7 @@ disallowed-tools:
20
20
  - Bash(awk *)
21
21
  - Bash(curl *)
22
22
  ---
23
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
23
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
24
24
  # harness-codebase-map — 代码库地图
25
25
 
26
26
  ## Purpose
@@ -20,7 +20,7 @@ disallowed-tools:
20
20
  - Bash(awk *)
21
21
  - Bash(curl *)
22
22
  ---
23
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
23
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
24
24
  # harness-knowledge-ingest
25
25
 
26
26
  从 `.harness/archive/**/reports/final/summary-data.json` 抽取项目知识,生成并维护本地 `.harness/knowledge/` 索引。
@@ -20,7 +20,7 @@ disallowed-tools:
20
20
  - Bash(awk *)
21
21
  - Bash(curl *)
22
22
  ---
23
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
23
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
24
24
  # harness-knowledge-query
25
25
 
26
26
  并行 change 中查询必须传 `--change <change-id>`;成功后以该 change 的 `meta/knowledge-context.json` 为稳定指针。全局 `context-packs/latest.json` 仅向后兼容,不得用于判断多个 active change 的上下文归属。
@@ -20,7 +20,7 @@ disallowed-tools:
20
20
  - Bash(awk *)
21
21
  - Bash(curl *)
22
22
  ---
23
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
23
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
24
24
  # harness-plan — 需求规划
25
25
 
26
26
  ## Purpose
@@ -21,7 +21,7 @@ disallowed-tools:
21
21
  - Bash(curl *)
22
22
  - Bash(codegraph *)
23
23
  ---
24
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
24
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
25
25
  # harness-review — 代码审查
26
26
 
27
27
  ## Purpose
@@ -21,7 +21,7 @@ disallowed-tools:
21
21
  - Bash(curl *)
22
22
  - Bash(codegraph *)
23
23
  ---
24
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
24
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
25
25
  # harness-run — 需求编码
26
26
 
27
27
  ## Purpose
@@ -20,7 +20,7 @@ disallowed-tools:
20
20
  - Bash(awk *)
21
21
  - Bash(curl *)
22
22
  ---
23
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
23
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
24
24
  # harness-submit — 最终提交(含 worktree 合并)
25
25
 
26
26
  ## Purpose
@@ -19,7 +19,7 @@ disallowed-tools:
19
19
  - Bash(awk *)
20
20
  - Bash(curl *)
21
21
  ---
22
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
22
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
23
23
  # harness-sync — 元数据同步
24
24
 
25
25
  ## Purpose
@@ -22,7 +22,7 @@ disallowed-tools:
22
22
  - Bash(node *)
23
23
  - Bash(codegraph *)
24
24
  ---
25
- <!-- generated by harness_deploy.py; core=8b33a3eaa74f46ca; overlay=none; agent=claude-code; do not edit -->
25
+ <!-- generated by harness_deploy.py; core=9a2ab44ad7a34065; overlay=none; agent=claude-code; do not edit -->
26
26
  # harness-test — 测试执行
27
27
 
28
28
  ## Purpose
@@ -67,6 +67,29 @@ disallowed-tools:
67
67
 
68
68
  并行服务测试先运行 `harness_change.py lease-port --change <id> --run-id <run-id> --range <start-end> --json`,再把返回端口传给 `harness_service.py ensure --leased-port <port> --lease-owner <run-id>`。`serviceStart` 的 command/health/overlay 可用 `{leasedPort}` 占位符;用户自启进程仍只进入 Service Gate,禁止 kill。测试清理的 `finally` 中运行 `harness_change.py release-port --change <id> --run-id <run-id> --json`,避免租约池耗尽。
69
69
 
70
+ ### Phase -1:资源安全门(任何测试命令之前)
71
+
72
+ 测试默认使用 `safe` 资源档位,禁止直接执行会把整套测试放进同一长生命周期的裸命令。所有本地测试命令必须由 `harness/scripts/harness_test_runner.py` 托管:
73
+
74
+ ```text
75
+ python harness/scripts/harness_test_runner.py exec --profile safe --timeout-seconds <秒> -- <测试命令及参数>
76
+ ```
77
+
78
+ 对于 Python `unittest` 测试库,必须使用逐模块隔离模式,不得执行裸 `python -m unittest discover ...`:
79
+
80
+ ```text
81
+ python harness/scripts/harness_test_runner.py unittest --profile safe --tests-dir <测试目录>
82
+ ```
83
+
84
+ 资源档位是硬合同:
85
+
86
+ - `safe`:默认;普通测试模块串行执行,每个模块使用全新进程。
87
+ - `system`:只执行服务生命周期、集成等资源密集型模块。
88
+ - `full`:先执行普通模块,再执行资源密集型模块;仍保持逐模块串行。
89
+ - `system` / `full` 只有在用户明确要求资源密集型测试、传入 `--confirm-resource-intensive`,或受控 CI 设置 `CI=true` / `HARNESS_ALLOW_RESOURCE_INTENSIVE_TESTS=1` 时才允许执行。
90
+
91
+ Runner 强制同项目单实例、低调度优先级、逐命令超时、正常结束和异常结束的进程树清理。`HARNESS_TEST_MAX_WORKERS` 默认且最高为 `2`,只能调低,不能调高;技术栈自身的并发参数也必须收敛到该值。Windows detached-service 模块在执行前先做 nested-breakaway 能力探测,受限沙箱不支持时立即返回 `DETACHED_PROCESS_CAPABILITY_UNAVAILABLE`,不得让每个服务用例逐一超时。出现该错误、`TEST_RUN_ALREADY_ACTIVE`、`PROCESS_TREE_ISOLATION_UNAVAILABLE` 或 `TEST_COMMAND_TIMEOUT` 必须停止,不得绕过 Runner 重跑裸命令。完整约束见 `checklist.md`「0.0-A 资源安全档位」。
92
+
70
93
  ### Phase 0:环境准备(主会话执行,需要交互确认)
71
94
 
72
95
  先 `harness_change.py resolve [--change] --json` 解析 change-id;再 **`harness_gate.py begin --phase test --change <id>`**(禁止手工 phase.start / 手写 ledger)。执行各项强制环境检查 + **命令执行模式 preflight (0.1)**;只有首选执行器不可用时,才执行 fallback 执行器探测。
@@ -132,7 +155,7 @@ Phase 1 前先读 `.harness/changes/<change-name>/evidence/verification-ledger.j
132
155
 
133
156
  ### 五、命令与请求超时治理
134
157
 
135
- 所有命令必须有「预期时长 + 超时上限」,超过预期必须输出一次状态行,**不得静默等待**。`durationMs > 10000` → 🟡 SLOW,`> 30000` → ❌ TIMEOUT_RISK。详见 `reference.md`「命令与请求超时治理」。
158
+ 所有命令必须通过资源安全 Runner 设置「预期时长 + 超时上限」,超过预期必须输出一次状态行,**不得静默等待**。测试模块超时或退出时必须清理其进程树;`durationMs > 10000` → 🟡 SLOW,`> 30000` → ❌ TIMEOUT_RISK。详见 `reference.md`「命令与请求超时治理」。
136
159
 
137
160
  ### 五-A、陈旧测试安全修复
138
161
 
@@ -187,6 +210,7 @@ python <skills-root>/scripts/harness_test_guard.py record --project . --change-d
187
210
  本 skill **仅允许**以下 blocking user confirmation;其余默认值 + `decision` 事件:
188
211
 
189
212
  1. **Service Gate**:仅当 `harness_service.py ensure` 返回 `needs-user-decision`(用户进程占端口)时询问处理方式
213
+ 2. **资源密集型测试确认**:仅当发布/验收确实需要 `system` 或 `full` 档位,且用户尚未明确授权时询问;获得授权后传入 `--confirm-resource-intensive`
190
214
 
191
215
  ## 执行日志
192
216
 
@@ -38,6 +38,20 @@ description: harness-test 的 Phase 0 环境准备 + Playwright 探测 + 关门
38
38
 
39
39
  然后确定变更名:用 Glob 搜索 `.harness/changes/*/plans/*-plan.md`(**排除 `.harness/archive/*/`**),读取 frontmatter 提取 `change-name`。
40
40
 
41
+ #### 0.0-A 资源安全档位(所有测试的硬前置)
42
+
43
+ - [ ] 默认选择 `safe`,测试命令由 `harness/scripts/harness_test_runner.py` 托管;禁止裸跑整库 discovery 或工具默认无限并发
44
+ - [ ] Python `unittest` 使用逐模块隔离模式;每个 `test_*.py` 在独立解释器中串行执行,失败默认立即停止
45
+ - [ ] 同项目单实例锁已获得;出现 `TEST_RUN_ALREADY_ACTIVE` 时停止,不得启动第二套测试
46
+ - [ ] `HARNESS_TEST_MAX_WORKERS` 为 `1` 或 `2`,且技术栈自身 worker 参数不高于该值
47
+ - [ ] 每个模块/命令设置明确超时;超时返回 `TEST_COMMAND_TIMEOUT` 并清理整棵进程树
48
+ - [ ] Windows 普通模块使用 kill-on-close Job Object;显式测试 detached service 的模块改用精确 PID 血缘跟踪;其他平台使用独立进程组
49
+ - [ ] Windows detached-service 模块执行前 nested-breakaway preflight 已通过;`DETACHED_PROCESS_CAPABILITY_UNAVAILABLE` 时立即停止并切换到允许该能力的执行环境,不逐用例等待超时
50
+ - [ ] 任一隔离模式返回 `PROCESS_TREE_ISOLATION_UNAVAILABLE` 时停止资源密集型测试
51
+ - [ ] `system` / `full` 属于资源密集型档位:用户明确授权后才传 `--confirm-resource-intensive`;受控 CI 可用 `CI=true`
52
+ - [ ] `safe` 不包含服务生命周期和集成模块;`full` 仍按“普通模块 → 资源密集型模块”顺序串行,不得恢复单进程全量 discovery
53
+ - [ ] 测试前记录已有工作区状态;测试后状态只允许包含本轮预期变化,不要求删除用户原有变更
54
+
41
55
  #### 0.1 命令执行模式 preflight(⚠️ 必须在编译/启动服务/生成执行器之前执行)
42
56
 
43
57
  - [ ] 检查 PowerShell 基础命令:`powershell.exe -NoProfile -Command "$PSVersionTable.PSVersion"` 返回 exitCode=0
@@ -319,6 +333,7 @@ powershell.exe -NoProfile -Command "try { (Invoke-WebRequest -Uri 'http://127.0.
319
333
  - [ ] 检查报告和日志是否包含明文凭证/password/secret/access-key/client-secret
320
334
  - [ ] 检查 `.harness/changes/<change>/runtime/` 是否不会被提交(.gitignore 确认)
321
335
  - [ ] **服务生命周期收尾**:AI_STARTED→Stop-Process / USER_STARTED→提示 / REUSED_EXISTING→保留或确认 / NOT_STARTED→N/A
336
+ - [ ] **资源生命周期收尾**:Runner 单实例锁已释放,测试进程树无新增残留,未对用户原有 Python/Node 进程做宽泛清理
322
337
  - [ ] 检查测试数据是否需要清理
323
338
  - [ ] 检查请求执行器结果是否完整(4 种执行器,未与接口测试执行器混写)
324
339
  - [ ] 检查是否存在慢请求或超时风险
@@ -442,6 +442,29 @@ foreach ($scenario in $scenarios) {
442
442
  $results | ConvertTo-Json -Depth 4
443
443
  ```
444
444
 
445
+ ## 资源安全测试执行
446
+
447
+ ### 档位与确认
448
+
449
+ | 档位 | 默认 | 执行范围 | 确认 |
450
+ |---|:---:|---|---|
451
+ | `safe` | ✅ | 普通模块,逐模块串行 | 不需要 |
452
+ | `system` | ❌ | 服务生命周期、集成等资源密集型模块 | `--confirm-resource-intensive` 或受控 CI |
453
+ | `full` | ❌ | 普通模块后接资源密集型模块,仍逐模块串行 | `--confirm-resource-intensive` 或受控 CI |
454
+
455
+ 通用命令通过 `harness_test_runner.py exec` 托管;Python `unittest` 测试库通过 `harness_test_runner.py unittest` 逐文件执行。不得把“完整验证”解释为单解释器的裸 discovery,也不得同时启动两套同项目测试。
456
+
457
+ ### 资源边界
458
+
459
+ - `HARNESS_TEST_MAX_WORKERS` 默认且最高为 `2`,环境变量只能进一步调低。
460
+ - Runner 获取基于项目绝对路径的单实例锁;活动 owner 存在时返回 `TEST_RUN_ALREADY_ACTIVE`。
461
+ - Runner 降低自身调度优先级,子进程继承该优先级。
462
+ - Windows 普通模块进入 kill-on-close Job Object;显式验证 detached service 的模块不能嵌套 Job,Runner 持续记录从测试根进程派生的精确 PID 血缘并在结束时逐一回收。其他平台进入独立进程组。
463
+ - detached-service 模块启动前先执行两级 nested-breakaway preflight;受限沙箱拒绝时返回 `DETACHED_PROCESS_CAPABILITY_UNAVAILABLE` 并在模块开始前失败,避免所有服务用例各自等待启动超时。
464
+ - 正常返回、失败、超时和中断均执行进程树清理;PID 血缘模式只处理本次测试的后代,不按进程名做全局清理。
465
+ - 单模块超时返回 `TEST_COMMAND_TIMEOUT`;无法建立进程树隔离返回 `PROCESS_TREE_ISOLATION_UNAVAILABLE`。两者都不得以裸命令重试。
466
+ - 清理只作用于 Runner 创建的进程树,禁止 `taskkill /IM python.exe`、`Stop-Process -Name node` 等宽泛清理用户进程。
467
+
445
468
  ## 命令与请求超时治理
446
469
 
447
470
  所有命令必须有"预期时长 + 超时上限",超过预期时长**必须输出一次当前状态**:
@@ -457,6 +480,7 @@ $results | ConvertTo-Json -Depth 4
457
480
  | health probe | < 1s | **3s** | 计入启动状态机 |
458
481
  | 构建工具编译(如 Maven compile) | 10–60s | **180s** | 输出最后 30 行日志后停 |
459
482
  | 测试命令(如 Maven test) | 60–180s | **300s** | 输出失败用例后停 |
483
+ | 资源密集型测试模块 | 60–300s | **600s** | 终止该模块进程树,停止后续模块 |
460
484
  | service start | 30–60s | **120s** | 4.1 启动状态机收敛 |
461
485
 
462
486
  **§5.22 分层耗时与反馈规则**:
@@ -811,10 +835,10 @@ python <skills-root>/scripts/harness_ledger.py can-reuse --change-dir <dir> --ve
811
835
  4. 检查报告和日志是否包含明文凭证/password/secret/access-key/client-secret
812
836
  5. 检查 `.harness/changes/<change>/runtime/` 是否不会被提交(.gitignore 确认)
813
837
  6. **服务生命周期收尾**:AI_STARTED→Stop-Process / USER_STARTED→只提示 / REUSED_EXISTING→保留或用户确认 / NOT_STARTED→N/A
814
- 7. 检查测试数据是否需要清理
815
- 8. 检查请求执行器结果是否完整(4 种执行器表完整、未与接口测试执行器混写)
816
- 9. 检查是否存在慢请求或超时风险
817
- 10. 如果存在未清理测试数据、fallback 请求执行器、慢请求或环境变更 → 至少 🟡WARN
838
+ 7. **资源生命周期收尾**:单实例锁已释放、Runner 管理的进程树无残留;禁止宽泛停止用户原有进程
839
+ 8. 检查测试数据是否需要清理
840
+ 9. 检查请求执行器结果是否完整(4 种执行器表完整、未与接口测试执行器混写)
841
+ 10. 检查是否存在慢请求或超时风险;若有未清理测试数据、fallback、慢请求或环境变更 → 至少 🟡WARN
818
842
 
819
843
  ## 真实 diffHash 生成
820
844