@hunter-harness/workflow-harness 0.3.1 → 0.4.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 (402) hide show
  1. package/harness/bundles/general/claude-code/.harness-build.json +1 -1
  2. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +1 -1
  3. package/harness/bundles/general/claude-code/harness-archive/reference.md +30 -1
  4. package/harness/bundles/general/claude-code/harness-archive/templates/summary-data-template.json +1 -0
  5. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
  6. package/harness/bundles/general/claude-code/harness-execute/SKILL.md +1 -1
  7. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
  8. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
  9. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +1 -1
  10. package/harness/bundles/general/claude-code/harness-pull/SKILL.md +1 -1
  11. package/harness/bundles/general/claude-code/harness-push/SKILL.md +1 -1
  12. package/harness/bundles/general/claude-code/harness-review/SKILL.md +1 -1
  13. package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
  14. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +1 -1
  15. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
  16. package/harness/bundles/general/claude-code/harness-test/SKILL.md +1 -1
  17. package/harness/bundles/general/claude-code/scripts/harness_archive.py +146 -8
  18. package/harness/bundles/general/claude-code/scripts/harness_deploy.py +1 -1
  19. package/harness/bundles/general/claude-code/scripts/harness_knowledge_candidates.py +538 -4
  20. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  21. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
  22. package/harness/bundles/general/codebuddy/harness-archive/reference.md +30 -1
  23. package/harness/bundles/general/codebuddy/harness-archive/templates/summary-data-template.json +1 -0
  24. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
  25. package/harness/bundles/general/codebuddy/harness-execute/SKILL.md +1 -1
  26. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  27. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  28. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +1 -1
  29. package/harness/bundles/general/codebuddy/harness-pull/SKILL.md +1 -1
  30. package/harness/bundles/general/codebuddy/harness-push/SKILL.md +1 -1
  31. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +1 -1
  32. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
  33. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +1 -1
  34. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
  35. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +1 -1
  36. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +146 -8
  37. package/harness/bundles/general/codebuddy/scripts/harness_deploy.py +1 -1
  38. package/harness/bundles/general/codebuddy/scripts/harness_knowledge_candidates.py +538 -4
  39. package/harness/bundles/general/codex/.harness-build.json +1 -1
  40. package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
  41. package/harness/bundles/general/codex/harness-archive/reference.md +30 -1
  42. package/harness/bundles/general/codex/harness-archive/templates/summary-data-template.json +1 -0
  43. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
  44. package/harness/bundles/general/codex/harness-execute/SKILL.md +1 -1
  45. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
  46. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
  47. package/harness/bundles/general/codex/harness-plan/SKILL.md +1 -1
  48. package/harness/bundles/general/codex/harness-pull/SKILL.md +1 -1
  49. package/harness/bundles/general/codex/harness-push/SKILL.md +1 -1
  50. package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
  51. package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
  52. package/harness/bundles/general/codex/harness-submit/SKILL.md +1 -1
  53. package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
  54. package/harness/bundles/general/codex/harness-test/SKILL.md +1 -1
  55. package/harness/bundles/general/codex/scripts/harness_archive.py +146 -8
  56. package/harness/bundles/general/codex/scripts/harness_deploy.py +1 -1
  57. package/harness/bundles/general/codex/scripts/harness_knowledge_candidates.py +538 -4
  58. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  59. package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
  60. package/harness/bundles/general/cursor/harness-archive/reference.md +30 -1
  61. package/harness/bundles/general/cursor/harness-archive/templates/summary-data-template.json +1 -0
  62. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
  63. package/harness/bundles/general/cursor/harness-execute/SKILL.md +1 -1
  64. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  65. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
  66. package/harness/bundles/general/cursor/harness-plan/SKILL.md +1 -1
  67. package/harness/bundles/general/cursor/harness-pull/SKILL.md +1 -1
  68. package/harness/bundles/general/cursor/harness-push/SKILL.md +1 -1
  69. package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
  70. package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
  71. package/harness/bundles/general/cursor/harness-submit/SKILL.md +1 -1
  72. package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
  73. package/harness/bundles/general/cursor/harness-test/SKILL.md +1 -1
  74. package/harness/bundles/general/cursor/scripts/harness_archive.py +146 -8
  75. package/harness/bundles/general/cursor/scripts/harness_deploy.py +1 -1
  76. package/harness/bundles/general/cursor/scripts/harness_knowledge_candidates.py +538 -4
  77. package/harness/bundles/general/pi/.harness-build.json +6 -0
  78. package/harness/bundles/general/pi/CONTEXT.md +98 -0
  79. package/harness/bundles/general/pi/README.md +478 -0
  80. package/harness/bundles/general/pi/contracts/build-profile-v3.schema.json +302 -0
  81. package/harness/bundles/general/pi/contracts/ci-metrics.schema.json +36 -0
  82. package/harness/bundles/general/pi/contracts/doctor-capability.schema.json +43 -0
  83. package/harness/bundles/general/pi/contracts/external-platform-observation.schema.json +62 -0
  84. package/harness/bundles/general/pi/contracts/fixtures/managed-execution.json +341 -0
  85. package/harness/bundles/general/pi/contracts/process-identity.schema.json +132 -0
  86. package/harness/bundles/general/pi/contracts/run-session.schema.json +142 -0
  87. package/harness/bundles/general/pi/contracts/service-retirement-receipt.schema.json +85 -0
  88. package/harness/bundles/general/pi/contracts/service-session.schema.json +147 -0
  89. package/harness/bundles/general/pi/contracts/workflow-policy.json +574 -0
  90. package/harness/bundles/general/pi/harness-archive/SKILL.md +322 -0
  91. package/harness/bundles/general/pi/harness-archive/checklist.md +71 -0
  92. package/harness/bundles/general/pi/harness-archive/reference.md +150 -0
  93. package/harness/bundles/general/pi/harness-archive/scripts/gen-manifest.ps1 +31 -0
  94. package/harness/bundles/general/pi/harness-archive/templates/summary-data-template.json +218 -0
  95. package/harness/bundles/general/pi/harness-codebase-map/SKILL.md +116 -0
  96. package/harness/bundles/general/pi/harness-codebase-map/checklist.md +126 -0
  97. package/harness/bundles/general/pi/harness-codebase-map/reference.md +364 -0
  98. package/harness/bundles/general/pi/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
  99. package/harness/bundles/general/pi/harness-codebase-map/templates/CONCERNS.md +49 -0
  100. package/harness/bundles/general/pi/harness-codebase-map/templates/CONVENTIONS.md +57 -0
  101. package/harness/bundles/general/pi/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
  102. package/harness/bundles/general/pi/harness-codebase-map/templates/STACK.md +55 -0
  103. package/harness/bundles/general/pi/harness-codebase-map/templates/STRUCTURE.md +69 -0
  104. package/harness/bundles/general/pi/harness-codebase-map/templates/TESTING.md +64 -0
  105. package/harness/bundles/general/pi/harness-codebase-map/templates/map-manifest.schema.json +73 -0
  106. package/harness/bundles/general/pi/harness-codebase-map/templates/map-summary.md +64 -0
  107. package/harness/bundles/general/pi/harness-execute/SKILL.md +170 -0
  108. package/harness/bundles/general/pi/harness-knowledge-ingest/SKILL.md +103 -0
  109. package/harness/bundles/general/pi/harness-knowledge-query/SKILL.md +97 -0
  110. package/harness/bundles/general/pi/harness-plan/SKILL.md +158 -0
  111. package/harness/bundles/general/pi/harness-plan/checklist.md +243 -0
  112. package/harness/bundles/general/pi/harness-plan/protocols.md +133 -0
  113. package/harness/bundles/general/pi/harness-plan/reference.md +468 -0
  114. package/harness/bundles/general/pi/harness-pull/SKILL.md +55 -0
  115. package/harness/bundles/general/pi/harness-push/SKILL.md +83 -0
  116. package/harness/bundles/general/pi/harness-review/SKILL.md +175 -0
  117. package/harness/bundles/general/pi/harness-review/checklist.md +124 -0
  118. package/harness/bundles/general/pi/harness-review/protocols.md +69 -0
  119. package/harness/bundles/general/pi/harness-review/reference.md +114 -0
  120. package/harness/bundles/general/pi/harness-run/SKILL.md +188 -0
  121. package/harness/bundles/general/pi/harness-run/checklist.md +279 -0
  122. package/harness/bundles/general/pi/harness-run/protocols.md +141 -0
  123. package/harness/bundles/general/pi/harness-run/reference.md +886 -0
  124. package/harness/bundles/general/pi/harness-submit/SKILL.md +182 -0
  125. package/harness/bundles/general/pi/harness-submit/checklist.md +452 -0
  126. package/harness/bundles/general/pi/harness-submit/reference.md +152 -0
  127. package/harness/bundles/general/pi/harness-sync/SKILL.md +72 -0
  128. package/harness/bundles/general/pi/harness-sync/reference.md +176 -0
  129. package/harness/bundles/general/pi/harness-test/SKILL.md +250 -0
  130. package/harness/bundles/general/pi/harness-test/checklist.md +359 -0
  131. package/harness/bundles/general/pi/harness-test/pitfalls-java.md +14 -0
  132. package/harness/bundles/general/pi/harness-test/pitfalls.md +307 -0
  133. package/harness/bundles/general/pi/harness-test/reference.md +880 -0
  134. package/harness/bundles/general/pi/harness-test/scripts/runtime-helpers.mjs +216 -0
  135. package/harness/bundles/general/pi/protocols/archive-report-protocol.md +196 -0
  136. package/harness/bundles/general/pi/protocols/ci-layering-protocol.md +22 -0
  137. package/harness/bundles/general/pi/protocols/evidence-based-reporting-protocol.md +134 -0
  138. package/harness/bundles/general/pi/protocols/execution-session-protocol.md +52 -0
  139. package/harness/bundles/general/pi/protocols/external-platform-protocol.md +27 -0
  140. package/harness/bundles/general/pi/protocols/ledger-protocol.md +365 -0
  141. package/harness/bundles/general/pi/protocols/memory-closeout-protocol.md +21 -0
  142. package/harness/bundles/general/pi/protocols/model-routing-protocol.md +22 -0
  143. package/harness/bundles/general/pi/protocols/powershell-protocol.md +238 -0
  144. package/harness/bundles/general/pi/protocols/registry-governance-protocol.md +31 -0
  145. package/harness/bundles/general/pi/protocols/report-pipeline-protocol.md +172 -0
  146. package/harness/bundles/general/pi/protocols/sensitive-info-protocol.md +110 -0
  147. package/harness/bundles/general/pi/protocols/state-layout-protocol.md +209 -0
  148. package/harness/bundles/general/pi/protocols/submit-protocol.md +78 -0
  149. package/harness/bundles/general/pi/protocols/verification-graph-protocol.md +32 -0
  150. package/harness/bundles/general/pi/scripts/harness_adoption_metrics.py +391 -0
  151. package/harness/bundles/general/pi/scripts/harness_apidoc.py +53 -0
  152. package/harness/bundles/general/pi/scripts/harness_archive.py +11345 -0
  153. package/harness/bundles/general/pi/scripts/harness_change.py +1626 -0
  154. package/harness/bundles/general/pi/scripts/harness_check_gate.py +113 -0
  155. package/harness/bundles/general/pi/scripts/harness_context.py +1774 -0
  156. package/harness/bundles/general/pi/scripts/harness_deploy.py +968 -0
  157. package/harness/bundles/general/pi/scripts/harness_efficiency.py +443 -0
  158. package/harness/bundles/general/pi/scripts/harness_environment.py +1690 -0
  159. package/harness/bundles/general/pi/scripts/harness_events.py +2234 -0
  160. package/harness/bundles/general/pi/scripts/harness_events_sync.py +1425 -0
  161. package/harness/bundles/general/pi/scripts/harness_execution_contracts.py +596 -0
  162. package/harness/bundles/general/pi/scripts/harness_fixback.py +1975 -0
  163. package/harness/bundles/general/pi/scripts/harness_gate.py +3816 -0
  164. package/harness/bundles/general/pi/scripts/harness_headless.py +37 -0
  165. package/harness/bundles/general/pi/scripts/harness_integration.py +2564 -0
  166. package/harness/bundles/general/pi/scripts/harness_knowledge_candidates.py +796 -0
  167. package/harness/bundles/general/pi/scripts/harness_ledger.py +3556 -0
  168. package/harness/bundles/general/pi/scripts/harness_migration_head.py +220 -0
  169. package/harness/bundles/general/pi/scripts/harness_orchestration.py +344 -0
  170. package/harness/bundles/general/pi/scripts/harness_paths.py +676 -0
  171. package/harness/bundles/general/pi/scripts/harness_phase.py +1726 -0
  172. package/harness/bundles/general/pi/scripts/harness_plan_aggregate.py +249 -0
  173. package/harness/bundles/general/pi/scripts/harness_plan_finalize.py +1016 -0
  174. package/harness/bundles/general/pi/scripts/harness_preflight.py +650 -0
  175. package/harness/bundles/general/pi/scripts/harness_process.py +1065 -0
  176. package/harness/bundles/general/pi/scripts/harness_profile.py +1817 -0
  177. package/harness/bundles/general/pi/scripts/harness_report_model.py +442 -0
  178. package/harness/bundles/general/pi/scripts/harness_retry.py +175 -0
  179. package/harness/bundles/general/pi/scripts/harness_review.py +631 -0
  180. package/harness/bundles/general/pi/scripts/harness_runtime.py +2243 -0
  181. package/harness/bundles/general/pi/scripts/harness_service.py +3355 -0
  182. package/harness/bundles/general/pi/scripts/harness_state.py +365 -0
  183. package/harness/bundles/general/pi/scripts/harness_sync.py +407 -0
  184. package/harness/bundles/general/pi/scripts/harness_test_cleanup.py +175 -0
  185. package/harness/bundles/general/pi/scripts/harness_test_guard.py +1899 -0
  186. package/harness/bundles/general/pi/scripts/harness_test_runner.py +1586 -0
  187. package/harness/bundles/general/pi/scripts/harness_verification.py +593 -0
  188. package/harness/bundles/general/pi/scripts/harness_workflow_policy.py +266 -0
  189. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  190. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
  191. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
  192. package/harness/bundles/java/claude-code/harness-archive/reference.md +30 -1
  193. package/harness/bundles/java/claude-code/harness-archive/templates/summary-data-template.json +1 -0
  194. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
  195. package/harness/bundles/java/claude-code/harness-execute/SKILL.md +1 -1
  196. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
  197. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
  198. package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
  199. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +1 -1
  200. package/harness/bundles/java/claude-code/harness-pull/SKILL.md +1 -1
  201. package/harness/bundles/java/claude-code/harness-push/SKILL.md +1 -1
  202. package/harness/bundles/java/claude-code/harness-review/SKILL.md +1 -1
  203. package/harness/bundles/java/claude-code/harness-run/SKILL.md +1 -1
  204. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +1 -1
  205. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
  206. package/harness/bundles/java/claude-code/harness-test/SKILL.md +1 -1
  207. package/harness/bundles/java/claude-code/scripts/harness_archive.py +146 -8
  208. package/harness/bundles/java/claude-code/scripts/harness_deploy.py +1 -1
  209. package/harness/bundles/java/claude-code/scripts/harness_knowledge_candidates.py +538 -4
  210. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  211. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
  212. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
  213. package/harness/bundles/java/codebuddy/harness-archive/reference.md +30 -1
  214. package/harness/bundles/java/codebuddy/harness-archive/templates/summary-data-template.json +1 -0
  215. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
  216. package/harness/bundles/java/codebuddy/harness-execute/SKILL.md +1 -1
  217. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  218. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  219. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
  220. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +1 -1
  221. package/harness/bundles/java/codebuddy/harness-pull/SKILL.md +1 -1
  222. package/harness/bundles/java/codebuddy/harness-push/SKILL.md +1 -1
  223. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +1 -1
  224. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +1 -1
  225. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +1 -1
  226. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
  227. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +1 -1
  228. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +146 -8
  229. package/harness/bundles/java/codebuddy/scripts/harness_deploy.py +1 -1
  230. package/harness/bundles/java/codebuddy/scripts/harness_knowledge_candidates.py +538 -4
  231. package/harness/bundles/java/codex/.harness-build.json +1 -1
  232. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
  233. package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
  234. package/harness/bundles/java/codex/harness-archive/reference.md +30 -1
  235. package/harness/bundles/java/codex/harness-archive/templates/summary-data-template.json +1 -0
  236. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
  237. package/harness/bundles/java/codex/harness-execute/SKILL.md +1 -1
  238. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +1 -1
  239. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
  240. package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
  241. package/harness/bundles/java/codex/harness-plan/SKILL.md +1 -1
  242. package/harness/bundles/java/codex/harness-pull/SKILL.md +1 -1
  243. package/harness/bundles/java/codex/harness-push/SKILL.md +1 -1
  244. package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
  245. package/harness/bundles/java/codex/harness-run/SKILL.md +1 -1
  246. package/harness/bundles/java/codex/harness-submit/SKILL.md +1 -1
  247. package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
  248. package/harness/bundles/java/codex/harness-test/SKILL.md +1 -1
  249. package/harness/bundles/java/codex/scripts/harness_archive.py +146 -8
  250. package/harness/bundles/java/codex/scripts/harness_deploy.py +1 -1
  251. package/harness/bundles/java/codex/scripts/harness_knowledge_candidates.py +538 -4
  252. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  253. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
  254. package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
  255. package/harness/bundles/java/cursor/harness-archive/reference.md +30 -1
  256. package/harness/bundles/java/cursor/harness-archive/templates/summary-data-template.json +1 -0
  257. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
  258. package/harness/bundles/java/cursor/harness-execute/SKILL.md +1 -1
  259. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  260. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
  261. package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
  262. package/harness/bundles/java/cursor/harness-plan/SKILL.md +1 -1
  263. package/harness/bundles/java/cursor/harness-pull/SKILL.md +1 -1
  264. package/harness/bundles/java/cursor/harness-push/SKILL.md +1 -1
  265. package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
  266. package/harness/bundles/java/cursor/harness-run/SKILL.md +1 -1
  267. package/harness/bundles/java/cursor/harness-submit/SKILL.md +1 -1
  268. package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
  269. package/harness/bundles/java/cursor/harness-test/SKILL.md +1 -1
  270. package/harness/bundles/java/cursor/scripts/harness_archive.py +146 -8
  271. package/harness/bundles/java/cursor/scripts/harness_deploy.py +1 -1
  272. package/harness/bundles/java/cursor/scripts/harness_knowledge_candidates.py +538 -4
  273. package/harness/bundles/java/pi/.harness-build.json +6 -0
  274. package/harness/bundles/java/pi/CONTEXT.md +98 -0
  275. package/harness/bundles/java/pi/README.md +478 -0
  276. package/harness/bundles/java/pi/contracts/build-profile-v3.schema.json +302 -0
  277. package/harness/bundles/java/pi/contracts/ci-metrics.schema.json +36 -0
  278. package/harness/bundles/java/pi/contracts/doctor-capability.schema.json +43 -0
  279. package/harness/bundles/java/pi/contracts/external-platform-observation.schema.json +62 -0
  280. package/harness/bundles/java/pi/contracts/fixtures/managed-execution.json +341 -0
  281. package/harness/bundles/java/pi/contracts/process-identity.schema.json +132 -0
  282. package/harness/bundles/java/pi/contracts/run-session.schema.json +142 -0
  283. package/harness/bundles/java/pi/contracts/service-retirement-receipt.schema.json +85 -0
  284. package/harness/bundles/java/pi/contracts/service-session.schema.json +147 -0
  285. package/harness/bundles/java/pi/contracts/workflow-policy.json +574 -0
  286. package/harness/bundles/java/pi/harness-apidoc/SKILL.md +97 -0
  287. package/harness/bundles/java/pi/harness-apidoc/checklist.md +142 -0
  288. package/harness/bundles/java/pi/harness-apidoc/reference.md +233 -0
  289. package/harness/bundles/java/pi/harness-archive/SKILL.md +322 -0
  290. package/harness/bundles/java/pi/harness-archive/checklist.md +71 -0
  291. package/harness/bundles/java/pi/harness-archive/reference.md +150 -0
  292. package/harness/bundles/java/pi/harness-archive/scripts/gen-manifest.ps1 +31 -0
  293. package/harness/bundles/java/pi/harness-archive/templates/summary-data-template.json +218 -0
  294. package/harness/bundles/java/pi/harness-codebase-map/SKILL.md +116 -0
  295. package/harness/bundles/java/pi/harness-codebase-map/checklist.md +126 -0
  296. package/harness/bundles/java/pi/harness-codebase-map/reference.md +364 -0
  297. package/harness/bundles/java/pi/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
  298. package/harness/bundles/java/pi/harness-codebase-map/templates/CONCERNS.md +49 -0
  299. package/harness/bundles/java/pi/harness-codebase-map/templates/CONVENTIONS.md +57 -0
  300. package/harness/bundles/java/pi/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
  301. package/harness/bundles/java/pi/harness-codebase-map/templates/STACK.md +55 -0
  302. package/harness/bundles/java/pi/harness-codebase-map/templates/STRUCTURE.md +69 -0
  303. package/harness/bundles/java/pi/harness-codebase-map/templates/TESTING.md +64 -0
  304. package/harness/bundles/java/pi/harness-codebase-map/templates/map-manifest.schema.json +73 -0
  305. package/harness/bundles/java/pi/harness-codebase-map/templates/map-summary.md +64 -0
  306. package/harness/bundles/java/pi/harness-execute/SKILL.md +170 -0
  307. package/harness/bundles/java/pi/harness-knowledge-ingest/SKILL.md +103 -0
  308. package/harness/bundles/java/pi/harness-knowledge-query/SKILL.md +97 -0
  309. package/harness/bundles/java/pi/harness-package/SKILL.md +94 -0
  310. package/harness/bundles/java/pi/harness-package/checklist.md +322 -0
  311. package/harness/bundles/java/pi/harness-package/reference.md +210 -0
  312. package/harness/bundles/java/pi/harness-plan/SKILL.md +158 -0
  313. package/harness/bundles/java/pi/harness-plan/checklist.md +243 -0
  314. package/harness/bundles/java/pi/harness-plan/protocols.md +133 -0
  315. package/harness/bundles/java/pi/harness-plan/reference.md +468 -0
  316. package/harness/bundles/java/pi/harness-pull/SKILL.md +55 -0
  317. package/harness/bundles/java/pi/harness-push/SKILL.md +83 -0
  318. package/harness/bundles/java/pi/harness-review/SKILL.md +175 -0
  319. package/harness/bundles/java/pi/harness-review/checklist.md +124 -0
  320. package/harness/bundles/java/pi/harness-review/protocols.md +69 -0
  321. package/harness/bundles/java/pi/harness-review/reference.md +114 -0
  322. package/harness/bundles/java/pi/harness-run/SKILL.md +206 -0
  323. package/harness/bundles/java/pi/harness-run/checklist.md +252 -0
  324. package/harness/bundles/java/pi/harness-run/protocols.md +141 -0
  325. package/harness/bundles/java/pi/harness-run/reference.md +820 -0
  326. package/harness/bundles/java/pi/harness-submit/SKILL.md +189 -0
  327. package/harness/bundles/java/pi/harness-submit/checklist.md +452 -0
  328. package/harness/bundles/java/pi/harness-submit/reference.md +152 -0
  329. package/harness/bundles/java/pi/harness-sync/SKILL.md +72 -0
  330. package/harness/bundles/java/pi/harness-sync/reference.md +176 -0
  331. package/harness/bundles/java/pi/harness-test/SKILL.md +264 -0
  332. package/harness/bundles/java/pi/harness-test/checklist.md +320 -0
  333. package/harness/bundles/java/pi/harness-test/pitfalls-java.md +16 -0
  334. package/harness/bundles/java/pi/harness-test/pitfalls.md +307 -0
  335. package/harness/bundles/java/pi/harness-test/reference.md +792 -0
  336. package/harness/bundles/java/pi/harness-test/scripts/runtime-helpers.mjs +216 -0
  337. package/harness/bundles/java/pi/protocols/archive-report-protocol.md +196 -0
  338. package/harness/bundles/java/pi/protocols/ci-layering-protocol.md +22 -0
  339. package/harness/bundles/java/pi/protocols/evidence-based-reporting-protocol.md +134 -0
  340. package/harness/bundles/java/pi/protocols/execution-session-protocol.md +52 -0
  341. package/harness/bundles/java/pi/protocols/external-platform-protocol.md +27 -0
  342. package/harness/bundles/java/pi/protocols/ledger-protocol.md +365 -0
  343. package/harness/bundles/java/pi/protocols/memory-closeout-protocol.md +21 -0
  344. package/harness/bundles/java/pi/protocols/model-routing-protocol.md +22 -0
  345. package/harness/bundles/java/pi/protocols/powershell-protocol.md +238 -0
  346. package/harness/bundles/java/pi/protocols/registry-governance-protocol.md +31 -0
  347. package/harness/bundles/java/pi/protocols/report-pipeline-protocol.md +172 -0
  348. package/harness/bundles/java/pi/protocols/sensitive-info-protocol.md +110 -0
  349. package/harness/bundles/java/pi/protocols/state-layout-protocol.md +209 -0
  350. package/harness/bundles/java/pi/protocols/submit-protocol.md +78 -0
  351. package/harness/bundles/java/pi/protocols/verification-graph-protocol.md +32 -0
  352. package/harness/bundles/java/pi/scripts/harness_adoption_metrics.py +391 -0
  353. package/harness/bundles/java/pi/scripts/harness_apidoc.py +53 -0
  354. package/harness/bundles/java/pi/scripts/harness_archive.py +11345 -0
  355. package/harness/bundles/java/pi/scripts/harness_change.py +1626 -0
  356. package/harness/bundles/java/pi/scripts/harness_check_gate.py +113 -0
  357. package/harness/bundles/java/pi/scripts/harness_context.py +1774 -0
  358. package/harness/bundles/java/pi/scripts/harness_deploy.py +968 -0
  359. package/harness/bundles/java/pi/scripts/harness_efficiency.py +443 -0
  360. package/harness/bundles/java/pi/scripts/harness_environment.py +1690 -0
  361. package/harness/bundles/java/pi/scripts/harness_events.py +2234 -0
  362. package/harness/bundles/java/pi/scripts/harness_events_sync.py +1425 -0
  363. package/harness/bundles/java/pi/scripts/harness_execution_contracts.py +596 -0
  364. package/harness/bundles/java/pi/scripts/harness_fixback.py +1975 -0
  365. package/harness/bundles/java/pi/scripts/harness_gate.py +3816 -0
  366. package/harness/bundles/java/pi/scripts/harness_headless.py +37 -0
  367. package/harness/bundles/java/pi/scripts/harness_integration.py +2564 -0
  368. package/harness/bundles/java/pi/scripts/harness_knowledge_candidates.py +796 -0
  369. package/harness/bundles/java/pi/scripts/harness_ledger.py +3556 -0
  370. package/harness/bundles/java/pi/scripts/harness_migration_head.py +220 -0
  371. package/harness/bundles/java/pi/scripts/harness_orchestration.py +344 -0
  372. package/harness/bundles/java/pi/scripts/harness_paths.py +676 -0
  373. package/harness/bundles/java/pi/scripts/harness_phase.py +1726 -0
  374. package/harness/bundles/java/pi/scripts/harness_plan_aggregate.py +249 -0
  375. package/harness/bundles/java/pi/scripts/harness_plan_finalize.py +1016 -0
  376. package/harness/bundles/java/pi/scripts/harness_preflight.py +650 -0
  377. package/harness/bundles/java/pi/scripts/harness_process.py +1065 -0
  378. package/harness/bundles/java/pi/scripts/harness_profile.py +1817 -0
  379. package/harness/bundles/java/pi/scripts/harness_report_model.py +442 -0
  380. package/harness/bundles/java/pi/scripts/harness_retry.py +175 -0
  381. package/harness/bundles/java/pi/scripts/harness_review.py +631 -0
  382. package/harness/bundles/java/pi/scripts/harness_runtime.py +2243 -0
  383. package/harness/bundles/java/pi/scripts/harness_service.py +3355 -0
  384. package/harness/bundles/java/pi/scripts/harness_state.py +365 -0
  385. package/harness/bundles/java/pi/scripts/harness_sync.py +407 -0
  386. package/harness/bundles/java/pi/scripts/harness_test_cleanup.py +175 -0
  387. package/harness/bundles/java/pi/scripts/harness_test_guard.py +1899 -0
  388. package/harness/bundles/java/pi/scripts/harness_test_runner.py +1586 -0
  389. package/harness/bundles/java/pi/scripts/harness_verification.py +593 -0
  390. package/harness/bundles/java/pi/scripts/harness_workflow_policy.py +266 -0
  391. package/harness/manifests/general/claude-code.json +19 -19
  392. package/harness/manifests/general/codebuddy.json +19 -19
  393. package/harness/manifests/general/codex.json +19 -19
  394. package/harness/manifests/general/cursor.json +19 -19
  395. package/harness/manifests/general/pi.json +475 -0
  396. package/harness/manifests/java/claude-code.json +21 -21
  397. package/harness/manifests/java/codebuddy.json +21 -21
  398. package/harness/manifests/java/codex.json +21 -21
  399. package/harness/manifests/java/cursor.json +21 -21
  400. package/harness/manifests/java/pi.json +499 -0
  401. package/hunter-workflow-family.json +2 -2
  402. package/package.json +1 -1
@@ -0,0 +1,216 @@
1
+ #!/usr/bin/env node
2
+ // runtime-helpers.mjs — BOM-safe JSON I/O + test-identifier sanitizer + runner payload validation + credential scan.
3
+ // 变更簇 5 (spec §3.4): BOM-safe Runner, identifier sanitizer, 凭据边界.
4
+ //
5
+ // 设计目标:
6
+ // - readJsonUtf8BomSafe: 容忍 UTF-8 BOM (U+FEFF), credential-cache.json 等文件可能被 PS5.1 写入 BOM
7
+ // - writeJsonUtf8NoBom: 原子写 (temp+rename), UTF-8 no BOM, LF — 结果/报告文件字节稳定
8
+ // - sanitizeTestIdentifier: 按 pattern/maxLength/prefix 生成稳定标识; 超长截断 + 原文名短 hash 防碰撞
9
+ // - validateRunnerPayload: Runner 生成前本地校验 payload schema/必填/identifier, 测试脚本错误不得请求服务后才发现
10
+ // - findCredentialValues: 扫描 profile/Markdown/docs 中的凭据明文值 (sensitive-info-protocol §1)
11
+ //
12
+ // Node ≥18 ESM, stdlib only. 输出 JSON 内容确定性 (不含 Math.random); 仅临时文件名用 randomBytes.
13
+
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+ import crypto from 'node:crypto';
17
+
18
+ export const BOM = 0xfeff;
19
+ export const DEFAULT_IDENTIFIER_PATTERN = '^[A-Za-z][A-Za-z0-9_-]*$';
20
+ export const DEFAULT_IDENTIFIER_MAX_LENGTH = 64;
21
+ const HASH_LEN = 8;
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // BOM-safe JSON I/O
25
+ // ---------------------------------------------------------------------------
26
+
27
+ /** Strip a single leading UTF-8 BOM (U+FEFF) from text. No-op if absent. */
28
+ export function stripBom(text) {
29
+ return text.codePointAt(0) === BOM ? text.slice(1) : text;
30
+ }
31
+
32
+ /** Read a JSON file, tolerating a leading UTF-8 BOM. Throws on invalid JSON. */
33
+ export function readJsonUtf8BomSafe(filePath) {
34
+ const raw = fs.readFileSync(filePath, 'utf8');
35
+ return JSON.parse(stripBom(raw));
36
+ }
37
+
38
+ /** Atomically write JSON as UTF-8 (no BOM), LF, 2-space indent, trailing newline.
39
+ * Writes to a temp file then renames — readers never see a half-written file. */
40
+ export function writeJsonUtf8NoBom(filePath, value) {
41
+ const json = JSON.stringify(value, null, 2) + '\n';
42
+ const dir = path.dirname(filePath);
43
+ fs.mkdirSync(dir, { recursive: true });
44
+ const tmp = `${filePath}.${process.pid}.${crypto.randomBytes(6).toString('hex')}.tmp`;
45
+ fs.writeFileSync(tmp, json, 'utf8');
46
+ try {
47
+ fs.renameSync(tmp, filePath);
48
+ } catch (err) {
49
+ try {
50
+ fs.unlinkSync(tmp);
51
+ } catch {
52
+ /* best-effort cleanup */
53
+ }
54
+ throw err;
55
+ }
56
+ }
57
+
58
+ // ---------------------------------------------------------------------------
59
+ // sanitizeTestIdentifier
60
+ // ---------------------------------------------------------------------------
61
+
62
+ /**
63
+ * Sanitize a change/test name into a stable identifier matching the default
64
+ * pattern `^[A-Za-z][A-Za-z0-9_-]*$`.
65
+ *
66
+ * - runs of chars outside [A-Za-z0-9_-] → '_'
67
+ * - prepend `prefix_` when prefix given; ensure leading letter (prepend 'T')
68
+ * - if over maxLength: truncate and append a short sha256 hash of the ORIGINAL
69
+ * name, so two near-identical long names that collide after truncation stay
70
+ * distinct (UT-023). Hash is deterministic — no Math.random.
71
+ *
72
+ * @returns {string} identifier matching the default pattern, length ≤ maxLength.
73
+ */
74
+ export function sanitizeTestIdentifier({
75
+ name,
76
+ pattern = DEFAULT_IDENTIFIER_PATTERN,
77
+ maxLength = DEFAULT_IDENTIFIER_MAX_LENGTH,
78
+ prefix = '',
79
+ }) {
80
+ const raw = String(name ?? '');
81
+ let base = prefix ? `${prefix}_` : '';
82
+ base += raw.replace(/[^A-Za-z0-9_-]+/g, '_');
83
+ // leading letter (pattern ^[A-Za-z]); prepend 'T' if first char is _ or digit
84
+ if (!/^[A-Za-z]/.test(base)) base = `T${base}`;
85
+ if (base.length <= maxLength) return base;
86
+ const hash = crypto.createHash('sha256').update(raw, 'utf8').digest('hex').slice(0, HASH_LEN);
87
+ const reserve = HASH_LEN + 1; // '_' + hash
88
+ const cap = Math.max(1, maxLength - reserve);
89
+ let truncated = base.slice(0, cap).replace(/_+$/, '');
90
+ // if truncation removed the leading letter guarantee, restore it
91
+ if (!/^[A-Za-z]/.test(truncated)) truncated = `T${truncated}`;
92
+ return `${truncated}_${hash}`;
93
+ }
94
+
95
+ /** Compile a pattern safely; returns null if invalid. */
96
+ function safeRegex(pattern) {
97
+ try {
98
+ return new RegExp(`^(?:${pattern})$`);
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
103
+
104
+ /** True if id matches pattern. Invalid pattern → false. */
105
+ export function matchesPattern(id, pattern = DEFAULT_IDENTIFIER_PATTERN) {
106
+ const re = safeRegex(pattern);
107
+ return re ? re.test(String(id)) : false;
108
+ }
109
+
110
+ // ---------------------------------------------------------------------------
111
+ // validateRunnerPayload — Runner 生成前本地校验
112
+ // ---------------------------------------------------------------------------
113
+
114
+ const HTTP_METHODS = /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)$/i;
115
+
116
+ /**
117
+ * Validate a runner payload (array of API test scenarios) BEFORE generating or
118
+ * executing the runner. Catches script/schema errors locally so they don't
119
+ * surface only after a service request (spec §3.4 point 3).
120
+ *
121
+ * Scenario required fields: id, method, url. id must match identifierPattern
122
+ * and be unique. method must be a known HTTP method.
123
+ *
124
+ * @returns {{ ok: boolean, errors: Array<{code: string, field: string, message: string}> }}
125
+ */
126
+ export function validateRunnerPayload(payload, opts = {}) {
127
+ const errors = [];
128
+ const pattern = opts.identifierPattern || DEFAULT_IDENTIFIER_PATTERN;
129
+ const re = safeRegex(pattern);
130
+
131
+ if (!Array.isArray(payload)) {
132
+ return {
133
+ ok: false,
134
+ errors: [{ code: 'PAYLOAD_NOT_ARRAY', field: 'payload', message: 'payload must be an array of scenarios' }],
135
+ };
136
+ }
137
+ if (payload.length === 0) {
138
+ errors.push({ code: 'PAYLOAD_EMPTY', field: 'payload', message: 'payload has no scenarios' });
139
+ }
140
+
141
+ const seenIds = new Set();
142
+ payload.forEach((scn, i) => {
143
+ const where = `scenarios[${i}]`;
144
+ if (!scn || typeof scn !== 'object' || Array.isArray(scn)) {
145
+ errors.push({ code: 'SCENARIO_NOT_OBJECT', field: where, message: 'scenario must be an object' });
146
+ return;
147
+ }
148
+ for (const f of ['id', 'method', 'url']) {
149
+ if (scn[f] === undefined || scn[f] === null || scn[f] === '') {
150
+ errors.push({ code: 'MISSING_FIELD', field: `${where}.${f}`, message: `required field '${f}' missing or empty` });
151
+ }
152
+ }
153
+ if (scn.id !== undefined && scn.id !== null && scn.id !== '') {
154
+ const idStr = String(scn.id);
155
+ if (re && !re.test(idStr)) {
156
+ errors.push({ code: 'INVALID_IDENTIFIER', field: `${where}.id`, message: `id '${idStr}' does not match pattern ${pattern}` });
157
+ }
158
+ if (seenIds.has(idStr)) {
159
+ errors.push({ code: 'DUPLICATE_ID', field: `${where}.id`, message: `duplicate id '${idStr}'` });
160
+ } else {
161
+ seenIds.add(idStr);
162
+ }
163
+ }
164
+ if (scn.method !== undefined && scn.method !== null && scn.method !== '') {
165
+ if (!HTTP_METHODS.test(String(scn.method))) {
166
+ errors.push({ code: 'INVALID_METHOD', field: `${where}.method`, message: `unknown HTTP method '${scn.method}'` });
167
+ }
168
+ }
169
+ });
170
+
171
+ return { ok: errors.length === 0, errors };
172
+ }
173
+
174
+ // ---------------------------------------------------------------------------
175
+ // findCredentialValues — 凭据明文扫描 (sensitive-info-protocol §1)
176
+ // ---------------------------------------------------------------------------
177
+
178
+ // 值占位符或 env 引用 (不会被当作凭据明文): <*_REDACTED> / ${ENV} / $ENV
179
+ // 前缀匹配 ${ENV (无需闭合 }) — value 正则在 } 处停止, 仍应识别为 env 引用。
180
+ const SAFE_VALUE = /<\w+_REDACTED>|\$\{[A-Z0-9_]+|\$[A-Z][A-Z0-9_]*\b/;
181
+
182
+ const CRED_PATTERNS = [
183
+ // password / passwd / pwd = 或 : 后跟值 (字段名可带 JSON/YAML 引号)
184
+ { code: 'PASSWORD_VALUE', re: /"?password"?\s*[:=]\s*(['"]?)([^'"\s,;)}\n]+)\1/i, group: 2 },
185
+ // token / access_token / api_key / apikey / secret / accessKey / secretAccessKey
186
+ { code: 'SECRET_VALUE', re: /(?:"?(?:access_token|apikey|api_key|secretAccessKey|accessKey|secret|token)"?)\s*[:=]\s*(['"]?)([^'"\s,;)}\n]+)\1/i, group: 2 },
187
+ // Authorization: Bearer <jwt-ish>
188
+ { code: 'AUTH_HEADER', re: /Authorization\s*:\s*Bearer\s+([A-Za-z0-9_.-]{10,})/i, group: 1 },
189
+ // jdbc url with password=
190
+ { code: 'DB_PASSWORD', re: /jdbc:[^\s?]*[?&]password=([^&\s]+)/i, group: 1 },
191
+ ];
192
+
193
+ /**
194
+ * Scan text for credential VALUES per sensitive-info-protocol §1.
195
+ * Placeholders (`<TOKEN_REDACTED>`) and env refs (`${DB_PASSWORD}` / `$DB_PASSWORD`)
196
+ * are NOT flagged — credential config may carry env keys, not values (spec §3.4 point 4).
197
+ *
198
+ * @returns {Array<{ line: number, code: string, snippet: string }>}
199
+ */
200
+ export function findCredentialValues(text) {
201
+ const findings = [];
202
+ const lines = String(text ?? '').split(/\r?\n/);
203
+ lines.forEach((line, idx) => {
204
+ for (const { code, re, group } of CRED_PATTERNS) {
205
+ const m = line.match(re);
206
+ if (!m) continue;
207
+ const value = m[group] || '';
208
+ if (SAFE_VALUE.test(value)) continue; // placeholder / env ref — safe
209
+ // Redact the captured credential value in the snippet so reports/logs
210
+ // never leak it; field name + line number remain for locating the finding.
211
+ const snippet = (value ? line.replace(value, '<REDACTED>') : line).trim().slice(0, 80);
212
+ findings.push({ line: idx + 1, code, snippet });
213
+ }
214
+ });
215
+ return findings;
216
+ }
@@ -0,0 +1,196 @@
1
+ ---
2
+ description: harness-archive 的结构化归档与 summary-data 校验协议。用于减少重复产物、提升数据准确性和平台展示一致性。
3
+ ---
4
+
5
+ # Archive Report Protocol
6
+
7
+ ## 原则
8
+
9
+ 归档不应维护与平台重复的展示文件。常规入口是 `harness_archive.py execute`:它一次性完成状态采集与自动门禁,再复用预检结果调用 finalize。finalize 执行 cleanup → **freeze(事件 cutoff)** → collect → source consistency → summary validate → archive-meta。模型仅通过 events 写入维护结论。`meta/archive-meta.md` 由 finalize 生成,禁止手写。历史 archive 回放用 `harness_archive.py replay`(只读,不写 archive-meta / 不跑 cleanup)。
10
+
11
+ `knownRisks` 仅收录 severity∈{warning,error,critical} 的 issue 事件;无 severity 的 issue 进入 `maintenanceNotes`。`finalStatusReasons` 解释 CONDITIONAL_OK/WARN/FAIL 原因。finalize 在 before-manifest 前 cleanup:删除 lock/pid/launcher/credential,截断超大日志。
12
+
13
+ 详见 `report-pipeline-protocol.md`。本协议保留 archive final report 的维度要求,report pipeline 负责把这些维度程序化生成和校验。
14
+
15
+ ## 必备产物
16
+
17
+ 归档目录必须包含:
18
+
19
+ ```text
20
+ archive-meta.md
21
+ archive-manifest-before.json
22
+ archive-manifest-after.json
23
+ summary-data.json
24
+ events.ndjson(新流程推荐;历史 archive 可缺失)
25
+ ```
26
+
27
+ ## summary-data.json
28
+
29
+ 结构来源为 `harness-archive/templates/summary-data-template.json`(schemaVersion 2.3)。默认由 `harness_archive.py finalize` 生成;历史回放用 `harness_archive.py replay`。
30
+
31
+ ```json
32
+ {
33
+ "schemaVersion": "2.3",
34
+ "changeName": "...",
35
+ "businessGoal": "本次变更为了做什么",
36
+ "finalCommit": "...",
37
+ "finalCommitBranch": "origin/...",
38
+ "baseCommit": "...",
39
+ "diffStat": {"filesChanged": 0, "insertions": 0, "deletions": 0, "range": "<base>..<head>"},
40
+ "stageStatus": {
41
+ "plan": "OK/FAIL",
42
+ "run": "WARN/OK/FAIL",
43
+ "test": "OK/PARTIAL/BLOCKED/FAIL",
44
+ "review": "ADVISORY",
45
+ "submit": "OK/WARN/FAIL",
46
+ "archive": "OK/FAIL"
47
+ },
48
+ "durations": {
49
+ "totalLabel": "约 N 分",
50
+ "totalMinutes": 0,
51
+ "stages": [{"stage":"plan","skill":"harness-plan","startedAt":"...","endedAt":"...","minutes":0,"result":"OK"}]
52
+ },
53
+ "skillCalls": [{"skill":"harness-plan","count":1,"result":"OK"}],
54
+ "verification": {
55
+ "unitTests": {"run": 0, "failures": 0, "errors": 0, "skipped": 0, "passRate": "183/185"},
56
+ "apiTests": {"total": 0, "passed": 0, "failed": 0, "blocked": 0, "passRate": "34/35"},
57
+ "coverageDisplay": "29/29"
58
+ },
59
+ "timeline": [],
60
+ "changedFiles": [{"path":"...","summary":"...","insertions":0,"deletions":0}],
61
+ "artifacts": [],
62
+ "reviewSummary": {"status":"ADVISORY","red":0,"yellow":0,"redFixed":0,"redConfirmed":0,"yellowFixed":0,"yellowDeferred":0,"summary":""},
63
+ "archiveManifest": {},
64
+ "uncommittedTestEvidence": [],
65
+ "maintenanceNotes": [],
66
+ "knownRisks": [],
67
+ "manualActions": [],
68
+ "reportPipeline": {
69
+ "schema_version": 1,
70
+ "generated_at": "...",
71
+ "event_count": 0,
72
+ "sources": [],
73
+ "phases": {},
74
+ "commands": [],
75
+ "verificationChecks": [],
76
+ "artifacts": [],
77
+ "validationIssues": [],
78
+ "sourceConsistency": {"ok": true, "issues": []}
79
+ }
80
+ }
81
+ ```
82
+
83
+ `summary-data.json` 的数字必须全部来自 events、ledger 或 manifest,不得手写另一套统计。
84
+
85
+ ### 数据采集来源(禁止手写统计)
86
+
87
+ - `diffStat` / `changedFiles[].insertions`/`deletions`:来自 `git diff --numstat <base>..<head>` 与 `git diff --stat <base>..<head>`,不得手写。
88
+ - `durations`:从 `logs/execution-log.md` 各 `[N] harness-<skill>` 小节的 `开始`/`结束`/`耗时` 解析;`totalMinutes` 为各 stage `minutes` 之和。含用户确认等待的阶段须在该 stage 的 `result` 或 `maintenanceNotes` 注明,不得把等待时间伪装成纯执行时间。
89
+ - `skillCalls`:从 execution-log 统计每个 `harness-<skill>` 小节出现次数(含重入)及结果。
90
+ - `verification` 各项及 `passRate`:来自 `evidence/verification-ledger.json`,不得手写通过率。
91
+ - `reviewSummary.redFixed`/`redConfirmed`/`yellowFixed`/`yellowDeferred`:从 review 报告清单 + 后续修复提交 diff 比对得出,不得手写。
92
+ - `artifacts[]`:本次变更构建出的可分发 package 产物(如 `.jar`/`.war`/`.zip`/`.tar`/`.gz`/`.dll`/`.exe`/`.whl`/`.nupkg` 等)。来自项目构建输出目录扫描(按构建工具识别产物路径,如 Maven `target/*.jar`、Gradle `build/libs/*`、npm `dist/*`、.NET `bin/Release/*`),每项记录 `name`(basename)、`path`(相对仓库根)、`size`、`sha256`(`Get-FileHash -Algorithm SHA256` 计算),不得手写。无构建产物时留空数组,平台不展示空卡片。注意:归档 manifest(`archive-manifest-after.json`)记录的是 `.harness/archive/` 目录文件,不包含项目构建产物,两者不可混用。
93
+ - `reportPipeline.commands[]` / `verificationChecks[]` / `validationIssues[]`:来自 `events.ndjson`、ledger、validate 结果。旧 archive 无 events 时可从 ledger/log/manifest 回放,不得编造。
94
+
95
+ ## manifest/checksum
96
+
97
+ archive 前后生成文件清单,包含 path、size、sha256。before/after 统计不一致时,不得删除原目录。
98
+
99
+ manifest 必须使用固定脚本生成,禁止内联包含 `$`、`$_`、`@{}`、script block、管道 JSON 输出的 PowerShell:
100
+
101
+ ```powershell
102
+ powershell.exe -NoProfile -ExecutionPolicy Bypass -File "harness-skills/harness-archive/scripts/gen-manifest.ps1" -RootPath ".harness/changes/<change>" -OutputPath ".harness/changes/<change>/evidence/archive-manifest-before.json"
103
+ ```
104
+
105
+ 最终报告必须区分:
106
+
107
+ - movedFiles:实际移动的文件数;
108
+ - generatedFiles:archive 过程中生成的文件数;
109
+ - totalArchiveFiles:归档目录最终文件总数。
110
+
111
+ ## Durable archive
112
+
113
+ 同一工作区内从 `changes/` move 到 `archive/` 只属于 local archive。需要抗工作区删除时,finalize 必须配置独立 `--durable-root`:
114
+
115
+ - payload 以整树 digest 写入 `<durable-root>/objects/sha256/<digest>/payload/`,对象不可变且可内容寻址;
116
+ - `<durable-root>/receipts/<archive-id>.json` 记录 digest、来源 identity、保留策略与验证时间;
117
+ - durable 写入采用 staging → hash/readback verify → atomic publish;失败时保留原 change,且不得留下可被误认成功的 local archive;
118
+ - `restore-durable` 先验证 receipt 与对象 digest,只恢复到不存在的目标,完成后再次比对整树 digest;
119
+ - 成功状态区分 `ARCHIVED_DURABLE` 与 `ARCHIVED_LOCAL_ONLY`,后者必须进入 knownRisks。
120
+
121
+ ## 页面内容
122
+
123
+ 平台归档摘要必须突出:
124
+
125
+ 1. 本次变更业务目标;
126
+ 2. 代码变更统计(diffStat:文件数 / insertions / deletions);
127
+ 3. 各阶段耗时与 Skill 调用统计(durations / skillCalls);
128
+ 4. 验证结果与复用/重测来源(含通过率);
129
+ 5. review advisory 摘要(含修复进度:已修复 / 已确认 / 留后续);
130
+ 6. 给后续维护者的结论;
131
+ 7. 已知风险或人工确认项。
132
+
133
+ 禁止出现顶部 `N/A`、正文 `100%` 这类互相矛盾的数据。
134
+
135
+
136
+ ## summary-data 信息密度要求
137
+
138
+ `summary-data.json` 至少包含 `verification`、`artifacts`、`reviewSummary`、`archiveManifest`、`maintenanceNotes`、`knownRisks`、`manualActions`。平台只读取该 JSON,不重新推理或维护第二套统计。
139
+
140
+ `artifacts` 与 `uncommittedTestEvidence` 为空数组时,平台不展示对应卡片,避免空态噪音;非空时才展示。字段在 JSON 中始终保留,仅控制界面展示。
141
+
142
+ ## 数据校验
143
+
144
+ `validate` 是 finalize 的内嵌同进程步骤(不存在独立 `report validate` CLI)。validate error 存在时,finalize 恢复原 changes 目录并 exit 非 0,绝不删除原 changes 目录。warning 保留在报告中,但不会被误判为 validate error。Hunter Platform 直接读取已校验的 `summary-data.json`。
145
+
146
+ 正常完成时,`baseCommit` 与产品 tip 相同属于 `ARCHIVE_BASE_EQUALS_FEATURE_TIP`,必须在暂存前阻断。不得手工改 ledger 或 state snapshot。已有提交确属本变更时,使用 `adopt-existing-range` 生成绑定仓库、ownership 和 diffHash 的不可变收据;主动废弃或被替代时允许零产品增量,但必须记录中文原因,且固定 `releaseEligible=false`。
147
+
148
+ 候选收据缺失时,`execute` 可以复用身份一致、范围完整的 `unitTestFull` ledger 自动生成本地候选认证。提交只改变 commit 身份而产品树和验证输入未变化时,允许安全重绑定到当前 HEAD;该过程不得执行测试。门禁策略未声明数据库能力且未要求 `dbCompatibility` 时,数据库投影为带原因的 `NOT_APPLICABLE`,不得把缺少无关数据库证据升级为归档错误。
149
+
150
+ ## 冻结优先 finalize 与两层一致性(schemaVersion 2.3 起)
151
+
152
+ finalize 在 collect 之前**冻结事件事实**:所有 archive-fact 事件落盘并 fsync 后,写入唯一的 `phase.end` 与 `evidence/evidence-cutoff.json`(`eventCount` + `sha256` + `frozenAt`)。cutoff 之后**禁止再向归档 events.ndjson 追加任何事件**;后续校验结果与 manifest 比对只写入 finalize JSON payload 与 maintenance outbox,不回写事件流。collect 是纯函数:stage/timeline/durations 全部由冻结事件推导,**不存在选择性 patch 步骤**。
153
+
154
+ 两层 validator 顺序执行,任何一层失败都恢复原 change 目录并非零退出:
155
+
156
+ 1. **source consistency**(`validate_source_consistency`):summary 事实对照冻结来源——`event_count` 对 cutoff、verification 对 ledger typed metrics projection、review 计数对 sidecars。结果写入 `reportPipeline.sourceConsistency = {ok, issues}`;`ok=false` 时 issue code 含 `event-count-mismatch` / `verification-mismatch`。
157
+ 2. **summary consistency**(`validate_summary_data`):检查最终状态与验证结果是否矛盾,以及结构化字段是否满足归档要求。
158
+
159
+ ## versioned repair(不改写原归档)
160
+
161
+ `replay` 保持只读。归档后发现不一致时,用显式修复:
162
+
163
+ ```powershell
164
+ python harness/scripts/harness_archive.py repair --archive-dir ".harness/archive/<archive-id>" --json
165
+ ```
166
+
167
+ repair 先在 archive 外生成候选 derived version。来源校验与数据校验均通过后,才以不可变新版本写入 `derived/v<N>/{summary-data.json, repair-record.json}`,并把 `derived/authoritative.json` pointer 指向该版本;**原 summary-data.json 与 manifest 永不覆盖**。知识层只从 authoritative pointer 指向且 hash 校验通过的版本提取条目。
168
+
169
+ ## 归档包与服务端知识 ingest(§8)
170
+
171
+ archive close 的破坏性事务只执行确定性 close:
172
+
173
+ ```text
174
+ execute(one-shot status + gate) -> manifest -> move -> collect -> validate -> compare
175
+ -> 生成确定性核心 ZIP -> 上传并等待服务端持久化/ingest 收据 -> stop AI service -> return
176
+ ```
177
+
178
+ close 不再运行 `harness_knowledge.py`,也不写本地 outbox/index。服务端先保存原 ZIP,再安全
179
+ 解包发布核心文件并重建项目语义索引;客户端以 package hash 与 `knowledge_status` 作为收据。
180
+ 失败时本地归档保持有效,待上传 ZIP 保留供同包重试,不允许改走散文件 push 或本地索引。
181
+
182
+ ## 最终状态
183
+
184
+ 当 `apiTests.status=USER_SKIPPED` 或 `dbCompatibility=BLOCKED_BY_DBA` 时,最终状态不得写纯 `OK`,必须写:
185
+
186
+ ```text
187
+ CONDITIONAL_OK
188
+ ```
189
+
190
+ 并在 `knownRisks` / `manualActions` 中说明风险接受和后续人工动作。
191
+
192
+ ## 未提交测试证据
193
+
194
+ run/test 本轮新增、更新或安全修复且被 `.gitignore` 忽略的测试,必须先由 `test-tracking.json` + `harness_test_guard.py stage` 精确提交;这类测试不得继续作为“未提交证据”收尾,也不得计入可复用 P0 验证后随 worktree 删除。
195
+
196
+ `uncommittedTestEvidence` 只兼容历史归档或明确只读的外部证据:归档到 `backups/uncommitted-tests/`,记录文件名、验证范围与未提交原因,并在 `summary-data.json` 中记录风险。若它是本轮可修改的回归测试,则 archive 必须阻断并要求先走精确跟踪流程。
@@ -0,0 +1,22 @@
1
+ # CI 分层与构建产物复用协议
2
+
3
+ 所有项目将远端验证拆成四层,触发条件和产物身份必须彼此独立:
4
+
5
+ | 层 | 默认触发 | 工作内容 |
6
+ |---|---|---|
7
+ | `fast` | push / pull request | 影响选择后的格式、合同和单元门禁;分钟级反馈 |
8
+ | `candidate` | 冻结产品 identity 后手动触发 | 完整测试、真实栈、安全扫描、SBOM;每个 identity 最多一次 |
9
+ | `evidence-only` | 证据路径变化或候选证据续跑 | 校验 schema、hash、identity;禁止重新构建产品镜像 |
10
+ | `release` | 已通过候选的受控发布 | 校验既有 artifact/digest,附加发布标签并部署;禁止再次构建 |
11
+
12
+ ## 必需控制
13
+
14
+ - 同分支同层启用 concurrency cancellation,取消过时运行;
15
+ - `candidate` 构建的镜像和制品以提交、产品树和环境 identity 命名并记录 digest;
16
+ - 产品路径冻结后,候选通过前不得夹带证据提交;候选通过后只允许 evidence-only 路径变化;
17
+ - 未知路径或影响图无法证明边界时扩大验证,不能缩小;
18
+ - Linux、Docker、shell 权限等行为先在受控 Linux 环境运行 canary;
19
+ - 发布层只消费候选产物,不执行源码构建;
20
+ - runner minutes、缓存命中和关键路径耗时写入周期报告,以实际基线评价优化。
21
+
22
+ 项目可用自身 CI 语法实现该协议,但层名、身份和收据语义保持一致。
@@ -0,0 +1,134 @@
1
+ ---
2
+ description: harness 全流程的证据化报告协议。所有 skill 输出必须区分 ✅真实成功 / 🟡静态验证或跳过 / ❌失败或被拒绝。由原 harness-plan/evidence-based-reporting.md 迁移。
3
+ ---
4
+
5
+ # Evidence-Based Reporting Protocol
6
+
7
+ > 本协议适用于所有 harness-skills 的最终输出。禁止把"静态验证"写成"测试通过",禁止把"命令被拒绝"写成"成功"。
8
+
9
+ ## 状态分类
10
+
11
+ 所有 skill 的最终输出必须使用以下三类状态标记:
12
+
13
+ | 标记 | 含义 | 使用场景 |
14
+ |:----:|------|----------|
15
+ | ✅ | **已真实执行并成功** | 有构建成功证据(Java=`BUILD SUCCESS`;前端/Python 按各自工具成功标志) / git 成功信息 / 文件实际存在 / exit code 0 等明确证据 |
16
+ | 🟡 | **静态验证 / 用户确认跳过 / 证据不足** | 1. TDD 降级:仅做静态逻辑验证,未执行真实单元测试<br>2. 用户明确跳过 test/review<br>3. 命令执行但证据不充分<br>4. 需部署后验证的场景 |
17
+ | ❌ | **执行失败 / 被 hook 拒绝 / 未验证** | 1. 命令被 hook 拒绝(Denied / PreToolUse:Bash hook error)<br>2. exit code 非 0<br>3. 输出无有效 stdout<br>4. 场景未覆盖且未验证 |
18
+
19
+ ## 禁止的表述
20
+
21
+ | 禁止表述 | 正确表述 | 原因 |
22
+ |----------|----------|------|
23
+ | "测试全部通过" | 🟡 静态逻辑验证通过,未执行真实单元测试 | TDD 降级时没有真实测试 |
24
+ | "编译成功" | ❌ 编译命令被 hook 拒绝 | 命令没有成功执行 |
25
+ | "打包成功" | ❌ 打包命令输出不包含构建成功证据 | 没有明确证据 |
26
+ | "拉取成功" | ❌ git pull 命令被 Denied | 命令被 hook 拦截 |
27
+ | "推送成功" | ❌ git push 返回非 0 exit code | 推送实际失败 |
28
+ | "覆盖率 100%" | 🟡 静态验证覆盖率 100%,未运行真实测试 | 覆盖率来源不实 |
29
+
30
+ ## 编译验证状态映射
31
+
32
+ | 构建工具输出 | 状态标记 |
33
+ |-----------|:--------:|
34
+ | 包含构建成功证据(Java=`BUILD SUCCESS`;前端/Python 按各自工具成功标志) | ✅ 编译成功 |
35
+ | 包含构建失败标志(Java=`BUILD FAILURE`;前端/Python 按各自工具失败标志) | ❌ 编译失败 |
36
+ | 命令被 hook 拒绝 | ❌ 编译命令被拒绝 |
37
+ | 无输出 / 超时 | ❌ 编译状态未知 |
38
+ | 仅部分模块编译(跳过无关模块) | ✅ 目标模块编译成功 |
39
+
40
+ ## 测试验证状态映射
41
+
42
+ | 情况 | 状态标记 | 报告表述 |
43
+ |------|:--------:|----------|
44
+ | 测试命令输出包含测试通过证据(Java=`Tests run: N, Failures: 0`;前端/Python 按各自工具) | ✅ | ✅ 已测试通过:N 个用例,0 失败 |
45
+ | TDD 降级(无测试基础设施) | 🟡 | 🟡 静态验证通过,未执行真实单元测试,待测试基础设施补齐后运行 harness-test |
46
+ | 测试命令被 hook 拒绝 | ❌ | ❌ 测试命令被拒绝,无法确认测试结果 |
47
+ | 测试失败(有 Failures > 0) | ❌ | ❌ 测试失败:N 个用例,M 个失败 |
48
+ | 用户确认跳过测试 | 🟡 | 🟡 用户确认跳过测试 |
49
+
50
+ ## 场景覆盖状态映射
51
+
52
+ | 情况 | 状态标记 |
53
+ |------|:--------:|
54
+ | 有对应测试方法且测试通过 | ✅ 已测试通过 |
55
+ | 代码逻辑已覆盖但未执行测试 | 🟡 静态验证通过,未真实测试 |
56
+ | 代码逻辑未覆盖 | ❌ 未覆盖 |
57
+ | 需要端到端部署验证 | 🟡 待部署后验证 |
58
+ | 用户确认跳过 | 🟡 用户确认跳过 |
59
+
60
+ ## Git 操作状态映射
61
+
62
+ | git 输出 | 状态标记 |
63
+ |----------|:--------:|
64
+ | `Already up to date.` 或实际更新记录 | ✅ 拉取成功 |
65
+ | `Denied: non-ASCII path in Bash` | ❌ 命令被 hook 拒绝 |
66
+ | `To <remote>` + 推送范围 | ✅ 推送成功 |
67
+ | 无输出 | ❌ 状态未知 |
68
+
69
+ ## summary-data.json 状态映射
70
+
71
+ 平台监控直接读取 `summary-data.json`。本地归档不再生成重复的 HTML 报告。
72
+
73
+ 归档前必须执行 `harness_archive.py finalize` 内嵌 validate,或使用 `harness_archive.py replay` 做等价校验。只有 validate 无 error 时,才能宣称报告数据有效;validate error 不得被写成 WARN 或「已完成」。
74
+
75
+ | 数据来源 | 无报告时 |
76
+ |----------|----------|
77
+ | `summary-data.validations.unit/api` | 标记 `NOT_RUN` / `STATIC_ONLY`,不得显示 100% |
78
+ | `summary-data.review` | 标记 `ADVISORY_NOT_RUN`,不得显示 100% |
79
+ | `summary-data.package` | 缺失时标记 `WARN`,不得伪造 package 成功 |
80
+ | `summary-data.stageStatus` | 必须真实展示 ✅OK / 🟡WARN / 🔁REUSED / 📝ADVISORY 等状态 |
81
+
82
+ ## 执行日志状态标注
83
+
84
+ 所有 skill 的 execution-log.md 中,结果字段必须使用以下格式:
85
+
86
+ ```markdown
87
+ - **结果**: ✅OK成功 / 🟡WARN(降级原因) / ❌FAIL(失败原因)
88
+ ```
89
+
90
+ 禁止使用模糊表述如"OK"、"成功"、"完成",必须包含状态标记和具体原因。
91
+
92
+ ## 两维度术语表
93
+
94
+ 本协议的状态标记与 review 的发现严重级是**两个独立维度**,不得混用。下表统一登记各态的边界与关系,避免散落未对齐。
95
+
96
+ ### 维度一:skill 执行状态三态
97
+
98
+ 任何 skill 的最终执行结果必须落到以下三态之一:
99
+
100
+ | 标记 | 含义 | 适用场景 |
101
+ |:----:|------|----------|
102
+ | ✅OK | 已真实执行并成功 | 有构建成功证据 / git 成功信息 / 文件实际存在 / exit code 0 等明确证据 |
103
+ | 🟡WARN(原因) | 静态验证 / 用户确认跳过 / 证据不足 / 降级 | TDD 降级仅静态验证、用户跳过 test/review、命令执行但证据不充分、需部署后验证、远端有新提交需 pull/rebase、用户选择仅本地 commit |
104
+ | ❌FAIL(原因) | 执行失败 / 被 hook 拒绝 / 未验证 | 命令被 hook 拒绝、exit code 非 0、输出无有效 stdout、push 失败/被拒绝、commit 失败、hook 拒绝、场景未覆盖且未验证 |
105
+
106
+ ### 维度二:review 发现严重级(审查发现维度,不等于 skill 执行状态)
107
+
108
+ harness-review 对代码/变更的审查发现按风险分级,反映的是**被审查对象的问题严重度**,而非 review 这个 skill 本身是否执行成功:
109
+
110
+ | 标记 | 含义 | 适用场景 |
111
+ |:----:|------|----------|
112
+ | RED | 高风险建议 | 存在安全/数据/契约级高风险问题,建议阻塞合并 |
113
+ | YELLOW | 中低风险 | 存在中低风险改进项,建议处理但不阻塞 |
114
+ | OK | 无问题 | 审查通过,未发现需处理项 |
115
+
116
+ > 注意:review skill 执行成功(✅OK)不等于发现严重级为 OK;review 发现 RED 时,review skill 本身仍可能是 ✅OK(执行成功并产出了 RED 发现)。
117
+
118
+ ### 条件态 / 跳过态(特殊最终状态)
119
+
120
+ 以下状态用于特定条件下的最终状态表达,不属于上述两个主维度的常规三态:
121
+
122
+ | 标记 | 含义 | 适用场景 |
123
+ |:----:|------|----------|
124
+ | CONDITIONAL_OK | 条件性通过 | API 测试 `USER_SKIPPED` 或 DB 兼容性 `BLOCKED_BY_DBA` 时的归档最终状态,不得写纯 OK,必须在 knownRisks/manualActions 说明风险接受与后续人工动作 |
125
+ | 🔁REUSED | 复用前阶段结果 | 复用了前一阶段验证结果,summary-data 必须显式标记,不得伪装成重新执行 |
126
+ | 📝ADVISORY | 参考性未运行 | review 参考性意见,未作为门禁执行 |
127
+ | ⏭️ | 用户选择跳过 | 用户主动选择跳过某步骤(如仅本地 commit 不 push、跳过 test/review) |
128
+
129
+ ### 两维度关系
130
+
131
+ - skill 执行状态回答"这个步骤跑没跑、成没成";
132
+ - review 发现严重级回答"被审查的东西有没有问题、问题多大";
133
+ - 条件态/跳过态回答"这个步骤的最终结论是什么特殊情况"。
134
+ - 三者独立:例如 test skill 可 ✅OK 执行成功,但 review 发现其覆盖的代码存在 RED 问题;又如 archive 可因 `USER_SKIPPED` 给出 CONDITIONAL_OK,同时 review 发现为 YELLOW。summary-data 必须分别记录,不得用一个维度覆盖另一个。
@@ -0,0 +1,52 @@
1
+ ---
2
+ description: 长时命令、验证调度、环境复用与 fixback 的可恢复执行协议。
3
+ ---
4
+
5
+ # Execution Session Protocol
6
+
7
+ ## 受管运行会话
8
+
9
+ 可能超过交互窗口的命令必须通过 `harness_runtime.py run-start` 创建受管会话,而不是依赖调用方进程持续在线。会话状态位于:
10
+
11
+ ```text
12
+ runtime/run-sessions/<session-id>/
13
+ ├── session.json
14
+ ├── stdout.log
15
+ ├── stderr.log
16
+ └── worker.log
17
+ ```
18
+
19
+ `session.json` 只持久化脱敏身份:命令哈希、环境哈希、产品身份、验证目标、阶段、资源锁、进程身份、心跳、进度、超时和原因码。原始环境变量和敏感 argv 不得写入回执。
20
+
21
+ - `run-status` 可由新进程重连;心跳丢失超过 grace period 才标记 `INCOMPLETE`。
22
+ - `run-log --cursor` 按字节游标增量读取 UTF-8 日志,返回下一游标。
23
+ - `run-cancel` 只终止身份完全匹配的进程树;身份不确定时 fail closed。
24
+ - launcher 尚未启动子进程时失败,状态为 `INCOMPLETE/LAUNCHER_FAILED`;子进程非零退出为 `FAIL/CHILD_EXIT_NONZERO`;超时为 `CANCELLED/TIMEOUT`。
25
+ - `resourceLocks` 通过 `runtime/resource-locks/<lock-hash>.json` 原子独占;冲突会在启动测试进程前返回 `INCOMPLETE/RESOURCE_LOCK_BUSY`,终态写入前必须释放持有的锁。
26
+ - Windows 使用 shell-free argv 和 kill-on-close Job Object;Job Object 绑定失败时必须终止已验证的子进程并返回 `PROCESS_TREE_ISOLATION_UNAVAILABLE`,不得降级为无隔离运行。
27
+
28
+ ## 验证调度
29
+
30
+ `harness_verification.py plan` 对验证 DAG 做拓扑调度。每个目标声明 `dependsOn`、`resourceLocks`、identity 与复用策略。
31
+
32
+ - 只有资源锁不相交的 ready 目标可进入同一 wave。
33
+ - 未声明资源锁且预计大于等于 60 秒的目标自动使用 `harness:unclassified-heavy`,因此默认串行。
34
+ - 冻结后的产品 identity 发生变化时返回 `FROZEN_IDENTITY_DRIFT`,禁止继续执行或复用。
35
+ - 复用和跳过必须记录 `decision`、`reasonCode` 与人类可读 `explanation`;无证据不得返回 `REUSE`。
36
+
37
+ ## 环境会话
38
+
39
+ 环境租约支持两种模式:
40
+
41
+ - `change-session`:同一 change、stack、内容指纹和通过的 canary 可复用。
42
+ - `ephemeral`:每次 acquire 都创建新 session;替换既有 session 前必须提供匹配 stack/environment identity 的 provider reset 回执。
43
+
44
+ 租约获取通过注册锁原子串行化,跨 change 的 writable volume 永不共享。`change-session` 只有在内容指纹非空、environment hash、owner identity、expiry、mode、volume 和 canary 全部匹配时才可复用。内容指纹漂移标记 `STALE_CONTENT`;过期租约不可写。prepare/reuse 写入事实回执;reset/cleanup 只有在 provider operation evidence 为 `OK` 时才可如此命名。单纯释放租约只能记录 `release`,不得声称已清理外部环境。回执写入 change 的 `runtime/environment-receipts/`,文件名使用 stack hash,且不包含凭据明文。
45
+
46
+ ## Fixback 批次
47
+
48
+ Review/Test 回灌通过 `harness_fixback.py` 形成批次。一个批次可包含多条相关问题,但每条问题必须保留可读取的 JSON RED/GREEN 证据。证据必须位于项目或 change state 内,包含 evidence id、状态和产品 identity,并在批次中固定 SHA-256;RED 必须为 `FAIL`,GREEN 必须为 `PASS/OK`。affected verification 与 review 回执必须绑定最终产品 identity,其 `passedGates` 合集覆盖风险扩展后的全部门禁。`freeze-readiness` 会重新校验证据摘要;开放问题、证据漂移或缺门禁均阻止 code freeze。
49
+
50
+ ## 效率摘要
51
+
52
+ `harness_efficiency.py summary` 从运行会话、环境回执和失效回执生成事实型指标:墙钟区间并集、累计活动/资源等待、execution/launcher/verification 尝试、失败分类、环境 prepare/reuse/reset/cleanup、重复且没有新 result digest 的命令和人工 wrapper 数。reset/cleanup 只统计带有效 provider evidence 的回执。归档摘要自动包含该结构;指标不得归责个人,也不得在历史样本不足时虚构 ETA。
@@ -0,0 +1,27 @@
1
+ # 外部平台最终一致性协议
2
+
3
+ 用于 CI、镜像仓库、部署控制面、证据回传等异步外部系统。目标是让网络传输、远端业务状态和本地观察新鲜度彼此独立,避免把“请求成功”误判为“业务成功”。
4
+
5
+ ## 统一观察合同
6
+
7
+ 每次观察至少包含:
8
+
9
+ - `subjectIdentity`:不可变业务对象身份,如提交、镜像 digest、运行 ID 与环境身份的规范化组合;
10
+ - `businessState`:`PENDING/RUNNING/SUCCEEDED/FAILED/CANCELLED/UNKNOWN`;
11
+ - `observationState`:`PENDING/TERMINAL/UNKNOWN`;
12
+ - `freshness`:`FRESH/STALE/UNKNOWN`;
13
+ - `retryable`、`reasonCode`、`observedAt`;
14
+ - 写操作还应携带稳定 `idempotencyKey`。
15
+
16
+ JSON 合同见 `contracts/external-platform-observation.schema.json`。
17
+
18
+ ## 收敛规则
19
+
20
+ 1. 只有身份一致、`freshness=FRESH` 且观察到权威终态,才能宣称完成。
21
+ 2. `TERMINAL + SUCCEEDED` 才是成功;`FAILED/CANCELLED` 必须保留为业务失败,不能被 HTTP 2xx、回调成功或旧缓存覆盖。
22
+ 3. 仅重试 retryable 的传输失败、陈旧观察或非终态;鉴权、参数、身份不匹配与权威失败不得重试成成功。
23
+ 4. 重试必须同时受最大次数、总耗时和退避表约束;预算耗尽输出结构化失败收据。
24
+ 5. 每次轮询继续使用同一 `subjectIdentity`/`idempotencyKey`,身份漂移立即 fail closed。
25
+ 6. 回调只是触发再次观察的信号,最终结论仍以权威读取接口为准。
26
+
27
+ 通用执行内核为 `@hunter-harness/core` 的 `convergeAuthoritativeState`。