@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
@@ -2,17 +2,21 @@
2
2
  """Knowledge candidate generation from an archived change's summary-data.json.
3
3
 
4
4
  The archive workflow has already filtered once: review findings were produced by
5
- an independent reviewer and then adjudicated, and knownRisks are evidence-derived
6
- facts. This module turns those two and only those two — into KnowledgeCandidate
7
- records for the archive package's ``candidates/knowledge.json``.
5
+ an independent reviewer and then adjudicated, knownRisks are evidence-derived
6
+ facts, and decisions are structured records adopted upstream (plan/execute/
7
+ review). This module turns those three — and only those three — into
8
+ KnowledgeCandidate records for the archive package's ``candidates/knowledge.json``.
8
9
 
9
10
  Mapping is fixed by docs/superpowers/specs/2026-08-18-three-views-data-flow-design.md
10
- ("知识来源的选定")::
11
+ ("知识来源的选定"), extended 2026-08-23 with the decisions source::
11
12
 
12
13
  disposition = FIXED -> pitfall RED 0.95 / YELLOW 0.85
13
14
  disposition = ACCEPTED_RISK | DEFERRED -> risk RED 0.95 / YELLOW 0.85
14
15
  knownRisks[] -> risk 0.85
16
+ decisions[status=adopted] -> record's entry_type (decision |
17
+ requirement | api-contract) 0.85
15
18
  severity = OK | disposition = NOT_APPLICABLE -> dropped
19
+ decisions[status != adopted] -> kept in summary, not knowledge
16
20
 
17
21
  Dispositions outside the adopted set (OPEN / UNKNOWN) are dropped too: an
18
22
  unadjudicated finding is not yet knowledge. maintenanceNotes, finalStatusReasons
@@ -42,6 +46,16 @@ _DISPOSITION_ENTRY_TYPES = {
42
46
  _SEVERITY_CONFIDENCE = {"RED": 0.95, "YELLOW": 0.85}
43
47
  _KNOWN_RISK_CONFIDENCE = 0.85
44
48
 
49
+ # decisions[](来自 change 的 evidence/decisions.json,经 summary.decisions 传入)
50
+ # 与 findings 的裁决门槛同源:只有已采纳(adopted)的决策才成为候选——
51
+ # proposed/rejected/superseded 留在 summary 里做记录,但不构成知识。
52
+ # entry_type 直接取自记录,取值与 knowledgeCandidateEntryTypeSchema 对齐;
53
+ # source 对应 candidateProvenanceSourceKindSchema 的枚举。
54
+ _DECISION_ENTRY_TYPES = {"decision", "requirement", "api-contract"}
55
+ _DECISION_STATUSES = {"adopted", "proposed", "rejected", "superseded"}
56
+ _DECISION_SOURCE_KINDS = {"plan", "review", "manual", "archive"}
57
+ _DECISION_CONFIDENCE = 0.85
58
+
45
59
  _MAX_KEYWORDS = 32
46
60
  _MAX_KEYWORD_CHARS = 80
47
61
  _MAX_BODY_CHARS = 20_000
@@ -204,6 +218,86 @@ def _risk_candidate(
204
218
  }
205
219
 
206
220
 
221
+ def _decision_candidate(
222
+ record: dict[str, Any],
223
+ *,
224
+ change_key: str,
225
+ archive_id: str,
226
+ producer_version: str,
227
+ created_at: str,
228
+ ) -> dict[str, Any] | None:
229
+ """Project one adopted design decision / requirement / API contract entry.
230
+
231
+ Every field is copied from the record (written upstream by a human or an
232
+ agent during plan/execute/review); nothing is inferred at archive time.
233
+ """
234
+ title = _text(record.get("title"))
235
+ entry_type = _text(record.get("entry_type"))
236
+ status = _text(record.get("status")).lower()
237
+ if not title or entry_type not in _DECISION_ENTRY_TYPES or status != "adopted":
238
+ return None
239
+
240
+ rationale = _text(record.get("rationale"))
241
+ path = _text(record.get("path"))
242
+ line = record.get("line")
243
+ location = _location(path, line)
244
+ segments = _path_segments(path)
245
+ record_id = _text(record.get("id"))
246
+ source = _text(record.get("source"))
247
+ if source not in _DECISION_SOURCE_KINDS:
248
+ source = "plan"
249
+ raw_keywords = record.get("keywords")
250
+ record_keywords = (
251
+ [item for item in raw_keywords if isinstance(item, str)]
252
+ if isinstance(raw_keywords, list)
253
+ else []
254
+ )
255
+
256
+ body_lines = [title]
257
+ if rationale:
258
+ body_lines.append(f"理由:{rationale}")
259
+ if location:
260
+ body_lines.append(f"位置:{location}")
261
+ body_lines.append(f"类型:{entry_type}")
262
+ body = "\n".join(body_lines)[:_MAX_BODY_CHARS]
263
+ keywords = _keywords(
264
+ *record_keywords,
265
+ segments[-1] if segments else "",
266
+ segments[-2] if len(segments) >= 2 else "",
267
+ entry_type,
268
+ )
269
+ if path and location != path:
270
+ source_refs = [f"{path}#L{line}"]
271
+ elif path:
272
+ source_refs = [path]
273
+ else:
274
+ source_refs = [f"archive:{archive_id}"]
275
+
276
+ return {
277
+ "schema_version": SCHEMA_VERSION,
278
+ "candidate_id": _candidate_id(
279
+ change_key, "decision", record_id or f"{title}\0{path}\0{line}"
280
+ ),
281
+ "source_change_key": change_key,
282
+ "source_refs": source_refs,
283
+ "summary": title,
284
+ "reusability_scope": segments[0] if segments else "project",
285
+ "content_hash": _content_hash(entry_type, title, body, keywords),
286
+ "confidence": _DECISION_CONFIDENCE,
287
+ "status": "pending",
288
+ "entry_type": entry_type,
289
+ "body": body,
290
+ "keywords": keywords,
291
+ "provenance": {
292
+ "source_kind": source,
293
+ "source_ref": f"archive:{archive_id}#{record_id}" if record_id else f"archive:{archive_id}",
294
+ "producer": PRODUCER,
295
+ "producer_version": producer_version,
296
+ "created_at": created_at,
297
+ },
298
+ }
299
+
300
+
207
301
  def build_knowledge_candidates(
208
302
  summary: dict[str, Any],
209
303
  *,
@@ -252,6 +346,446 @@ def build_knowledge_candidates(
252
346
  created_at=created_at,
253
347
  ))
254
348
 
349
+ decisions = summary.get("decisions")
350
+ if isinstance(decisions, list):
351
+ for record in decisions:
352
+ if isinstance(record, dict):
353
+ collect(_decision_candidate(
354
+ record,
355
+ change_key=change_key,
356
+ archive_id=archive_id,
357
+ producer_version=producer_version,
358
+ created_at=created_at,
359
+ ))
360
+
361
+ return candidates
362
+
363
+
364
+ # Dispositions that mean "not yet adjudicated". A finding in this state with a
365
+ # knowledge-carrying severity is dropped by the mapping above — correctly — but
366
+ # the drop must be visible, or an archive with real findings looks identical to
367
+ # an archive with nothing worth keeping (both ship an empty candidates file).
368
+ _UNADJUDICATED_DISPOSITIONS = {"", "OPEN", "UNKNOWN"}
369
+
370
+
371
+ def count_unadjudicated_findings(summary: dict[str, Any]) -> int:
372
+ """Count RED/YELLOW reviewFindings whose disposition is not yet adjudicated.
373
+
374
+ These are the findings the mapping table silently drops. Callers use the
375
+ count to warn when an archive would otherwise show "ready / 0 results"
376
+ despite carrying real, unprocessed review signal.
377
+ """
378
+ if not isinstance(summary, dict):
379
+ return 0
380
+ findings = summary.get("reviewFindings")
381
+ if not isinstance(findings, list):
382
+ return 0
383
+ count = 0
384
+ for finding in findings:
385
+ if not isinstance(finding, dict):
386
+ continue
387
+ severity = _text(finding.get("severity"))
388
+ disposition = _text(finding.get("disposition")).upper()
389
+ if severity in _SEVERITIES and disposition in _UNADJUDICATED_DISPOSITIONS:
390
+ count += 1
391
+ return count
392
+
393
+
394
+ # --- plan/design-derived knowledge candidates ---------------------------------
395
+ #
396
+ # reviewFindings/knownRisks/decisions 只覆盖“经对抗评审的变更”。没有评审的简单
397
+ # 变更(无 RED/YELLOW 发现、无 knownRisks、无 adopted decisions)仍产出了
398
+ # 经用户确认批准的 design/plan/test-scenarios——这些也是值得沉淀的知识。
399
+ # 这里把 plans/*.md(v2 finalize 派生的机器契约)解析回结构化的自然内容,
400
+ # 与 summary 三源并列,但 confidence 略低(机器派生而非独立评审)。
401
+
402
+ _PLAN_CONFIDENCE = 0.85
403
+ _PLAN_SOURCE_KIND = "plan"
404
+
405
+
406
+ def _unescape_markdown(value: str) -> str:
407
+ """Reverse the renderer's markdown escaping for clean knowledge text.
408
+
409
+ harness-plan finalize 的渲染器对自由文本做了反斜杠/实体转义。知识候选存
410
+ 的是自然语言,不需要保留渲染转义。顺序有讲究:先反转义实体,再反转义
411
+ 反斜杠序列(从长到短)。
412
+ """
413
+ value = (
414
+ value.replace("&lt;", "<")
415
+ .replace("&gt;", ">")
416
+ .replace("&amp;", "&")
417
+ .replace("<br>", "\n")
418
+ )
419
+ return (
420
+ value.replace("\\`", "`")
421
+ .replace("\\#", "#")
422
+ .replace("\\*", "*")
423
+ .replace("\\[", "[")
424
+ .replace("\\]", "]")
425
+ .replace("\\\\", "\\")
426
+ )
427
+
428
+
429
+ def _markdown_sections(text: str) -> dict[str, list[str]]:
430
+ """Split a v2 rendered markdown artifact into its ``## Header`` sections.
431
+
432
+ Returns ``{header: [lines...]}``. Only the ``##`` level is split; ``###``
433
+ and ``####`` content stays inside its parent section's lines.
434
+ """
435
+ sections: dict[str, list[str]] = {}
436
+ current: str | None = None
437
+ for line in text.splitlines():
438
+ if line.startswith("## ") and not line.startswith("### "):
439
+ current = line[3:].strip()
440
+ sections[current] = []
441
+ elif current is not None:
442
+ sections[current].append(line)
443
+ return sections
444
+
445
+
446
+ def _plan_source_refs(change_key: str, package_path: str) -> list[str]:
447
+ """source_refs must exist in the package (core-v1 containment check)."""
448
+ return [package_path]
449
+
450
+
451
+ def _plan_candidate(
452
+ *,
453
+ change_key: str,
454
+ archive_id: str,
455
+ producer_version: str,
456
+ created_at: str,
457
+ kind: str,
458
+ entry_type: str,
459
+ summary: str,
460
+ body: str,
461
+ keywords: list[str],
462
+ source_refs: list[str],
463
+ reusability_scope: str = "project",
464
+ ) -> dict[str, Any]:
465
+ return {
466
+ "schema_version": SCHEMA_VERSION,
467
+ "candidate_id": _candidate_id(change_key, kind, summary),
468
+ "source_change_key": change_key,
469
+ "source_refs": source_refs,
470
+ "summary": summary,
471
+ "reusability_scope": reusability_scope,
472
+ "content_hash": _content_hash(entry_type, summary, body, keywords),
473
+ "confidence": _PLAN_CONFIDENCE,
474
+ "status": "pending",
475
+ "entry_type": entry_type,
476
+ "body": body,
477
+ "keywords": keywords,
478
+ "provenance": {
479
+ "source_kind": _PLAN_SOURCE_KIND,
480
+ "source_ref": f"archive:{archive_id}",
481
+ "producer": PRODUCER,
482
+ "producer_version": producer_version,
483
+ "created_at": created_at,
484
+ },
485
+ }
486
+
487
+
488
+ def _requirements_from_design(
489
+ design_text: str,
490
+ *,
491
+ change_key: str,
492
+ archive_id: str,
493
+ producer_version: str,
494
+ created_at: str,
495
+ ) -> list[dict[str, Any]]:
496
+ """Parse ``## Requirements`` from design.md into requirement candidates.
497
+
498
+ Each line is ``- requirement:sha256:... [kind]: text`` where kind is
499
+ behavior | invariant | failure_behavior.
500
+ """
501
+ sections = _markdown_sections(design_text)
502
+ lines = sections.get("Requirements", [])
503
+ out: list[dict[str, Any]] = []
504
+ for line in lines:
505
+ stripped = line.strip()
506
+ if not stripped.startswith("- "):
507
+ continue
508
+ prefix = stripped[2:]
509
+ # kind 位于第一个 `]: ` 之前的方括号内。
510
+ close_bracket = prefix.find("]")
511
+ if close_bracket <= 0 or not prefix.startswith("requirement:"):
512
+ continue
513
+ kind = prefix[1:close_bracket].strip()
514
+ if kind not in {"behavior", "invariant", "failure_behavior"}:
515
+ continue
516
+ colon = prefix.find(": ", close_bracket + 1)
517
+ if colon == -1:
518
+ continue
519
+ text = _unescape_markdown(prefix[colon + 2:].strip())
520
+ if not text:
521
+ continue
522
+ entry_type = "requirement"
523
+ body = f"需求类型:{kind}\n{text}"
524
+ keywords = _keywords(kind, entry_type)
525
+ out.append(_plan_candidate(
526
+ change_key=change_key,
527
+ archive_id=archive_id,
528
+ producer_version=producer_version,
529
+ created_at=created_at,
530
+ kind="requirement",
531
+ entry_type=entry_type,
532
+ summary=text,
533
+ body=body,
534
+ keywords=keywords,
535
+ source_refs=_plan_source_refs(change_key, f"plans/{change_key}-design.md"),
536
+ ))
537
+ return out
538
+
539
+
540
+ def _risks_from_design(
541
+ design_text: str,
542
+ *,
543
+ change_key: str,
544
+ archive_id: str,
545
+ producer_version: str,
546
+ created_at: str,
547
+ ) -> list[dict[str, Any]]:
548
+ """Parse ``## Risks`` (``- risk`` + `` - Mitigation: ...``) into risk candidates."""
549
+ sections = _markdown_sections(design_text)
550
+ lines = sections.get("Risks", [])
551
+ out: list[dict[str, Any]] = []
552
+ index = 0
553
+ while index < len(lines):
554
+ stripped = lines[index].strip()
555
+ if not stripped.startswith("- "):
556
+ index += 1
557
+ continue
558
+ risk = _unescape_markdown(stripped[2:].strip())
559
+ if not risk or risk == "None.":
560
+ index += 1
561
+ continue
562
+ mitigation = ""
563
+ if index + 1 < len(lines) and lines[index + 1].strip().startswith("- Mitigation:"):
564
+ mitigation = _unescape_markdown(
565
+ lines[index + 1].strip()[len("- Mitigation:"):].strip()
566
+ )
567
+ index += 1
568
+ body = risk if not mitigation else f"{risk}\n缓解:{mitigation}"
569
+ out.append(_plan_candidate(
570
+ change_key=change_key,
571
+ archive_id=archive_id,
572
+ producer_version=producer_version,
573
+ created_at=created_at,
574
+ kind="risk",
575
+ entry_type="risk",
576
+ summary=risk,
577
+ body=body,
578
+ keywords=_keywords("risk"),
579
+ source_refs=_plan_source_refs(change_key, f"plans/{change_key}-design.md"),
580
+ ))
581
+ index += 1
582
+ return out
583
+
584
+
585
+ def _invariants_from_design(
586
+ design_text: str,
587
+ *,
588
+ change_key: str,
589
+ archive_id: str,
590
+ producer_version: str,
591
+ created_at: str,
592
+ ) -> list[dict[str, Any]]:
593
+ """Parse ``## Invariants`` bullet list into requirement candidates."""
594
+ sections = _markdown_sections(design_text)
595
+ out: list[dict[str, Any]] = []
596
+ for line in sections.get("Invariants", []):
597
+ stripped = line.strip()
598
+ if not stripped.startswith("- "):
599
+ continue
600
+ text = _unescape_markdown(stripped[2:].strip())
601
+ if not text or text == "None.":
602
+ continue
603
+ out.append(_plan_candidate(
604
+ change_key=change_key,
605
+ archive_id=archive_id,
606
+ producer_version=producer_version,
607
+ created_at=created_at,
608
+ kind="invariant",
609
+ entry_type="requirement",
610
+ summary=text,
611
+ body=f"需求类型:invariant\n{text}",
612
+ keywords=_keywords("invariant", "requirement"),
613
+ source_refs=_plan_source_refs(change_key, f"plans/{change_key}-design.md"),
614
+ ))
615
+ return out
616
+
617
+
618
+ def _tasks_from_plan(
619
+ plan_text: str,
620
+ *,
621
+ change_key: str,
622
+ archive_id: str,
623
+ producer_version: str,
624
+ created_at: str,
625
+ ) -> list[dict[str, Any]]:
626
+ """Parse ``## Tasks`` from plan.md into implementation candidates.
627
+
628
+ Task headings are ``### T1``; the objective is the non-empty text between
629
+ the heading and the first ``- `` metadata bullet.
630
+ """
631
+ sections = _markdown_sections(plan_text)
632
+ lines = sections.get("Tasks", [])
633
+ out: list[dict[str, Any]] = []
634
+ index = 0
635
+ while index < len(lines):
636
+ stripped = lines[index].strip()
637
+ if not stripped.startswith("### "):
638
+ index += 1
639
+ continue
640
+ task_id = stripped[4:].strip()
641
+ index += 1
642
+ objective_parts: list[str] = []
643
+ while index < len(lines):
644
+ current = lines[index].strip()
645
+ if current.startswith("### ") or current.startswith("- "):
646
+ break
647
+ if current:
648
+ objective_parts.append(current)
649
+ index += 1
650
+ objective = " ".join(objective_parts).strip()
651
+ if not objective:
652
+ continue
653
+ body = f"任务:{task_id}\n{objective}"
654
+ out.append(_plan_candidate(
655
+ change_key=change_key,
656
+ archive_id=archive_id,
657
+ producer_version=producer_version,
658
+ created_at=created_at,
659
+ kind="task",
660
+ entry_type="implementation",
661
+ summary=objective,
662
+ body=body,
663
+ keywords=_keywords(task_id, "implementation"),
664
+ source_refs=_plan_source_refs(change_key, f"plans/{change_key}-plan.md"),
665
+ ))
666
+ return out
667
+
668
+
669
+ def _scenarios_from_test_scenarios(
670
+ scenarios_text: str,
671
+ *,
672
+ change_key: str,
673
+ archive_id: str,
674
+ producer_version: str,
675
+ created_at: str,
676
+ ) -> list[dict[str, Any]]:
677
+ """Parse ``## <id>: <title>`` headings into test-evidence candidates."""
678
+ out: list[dict[str, Any]] = []
679
+ for line in scenarios_text.splitlines():
680
+ stripped = line.strip()
681
+ if not stripped.startswith("## ") or stripped.startswith("### "):
682
+ continue
683
+ heading = stripped[3:].strip()
684
+ if heading == "Coverage":
685
+ continue
686
+ if ":" not in heading:
687
+ continue
688
+ scenario_id, title = heading.split(":", 1)
689
+ title = title.strip()
690
+ if not title:
691
+ continue
692
+ out.append(_plan_candidate(
693
+ change_key=change_key,
694
+ archive_id=archive_id,
695
+ producer_version=producer_version,
696
+ created_at=created_at,
697
+ kind="scenario",
698
+ entry_type="test-evidence",
699
+ summary=title,
700
+ body=f"场景:{scenario_id.strip()}\n{title}",
701
+ keywords=_keywords(scenario_id.strip(), "test-evidence"),
702
+ source_refs=_plan_source_refs(
703
+ change_key, f"plans/{change_key}-test-scenarios.md"
704
+ ),
705
+ ))
706
+ return out
707
+
708
+
709
+ def build_plan_candidates(
710
+ archive_dir,
711
+ *,
712
+ change_key: str,
713
+ archive_id: str,
714
+ producer_version: str,
715
+ created_at: str,
716
+ ) -> list[dict[str, Any]]:
717
+ """Extract knowledge candidates from the archive's plans/*.md artifacts.
718
+
719
+ Complements ``build_knowledge_candidates`` (summary 三源)。没有评审的简单
720
+ 变更仍然产出 plans/*.md;这些是经用户确认批准的结构化真相源,parse 回来
721
+ 就是可沉淀的知识。缺文件/解析失败返回 [](软失败)。
722
+ """
723
+ candidates: list[dict[str, Any]] = []
724
+ seen_ids: set[str] = set()
725
+
726
+ def collect(items: list[dict[str, Any]]) -> None:
727
+ for candidate in items:
728
+ if candidate["candidate_id"] in seen_ids:
729
+ continue
730
+ seen_ids.add(candidate["candidate_id"])
731
+ candidates.append(candidate)
732
+
733
+ design_path = archive_dir / "plans" / f"{change_key}-design.md"
734
+ if design_path.is_file():
735
+ try:
736
+ design_text = design_path.read_text(encoding="utf-8-sig")
737
+ except OSError:
738
+ design_text = ""
739
+ collect(_requirements_from_design(
740
+ design_text,
741
+ change_key=change_key,
742
+ archive_id=archive_id,
743
+ producer_version=producer_version,
744
+ created_at=created_at,
745
+ ))
746
+ collect(_risks_from_design(
747
+ design_text,
748
+ change_key=change_key,
749
+ archive_id=archive_id,
750
+ producer_version=producer_version,
751
+ created_at=created_at,
752
+ ))
753
+ collect(_invariants_from_design(
754
+ design_text,
755
+ change_key=change_key,
756
+ archive_id=archive_id,
757
+ producer_version=producer_version,
758
+ created_at=created_at,
759
+ ))
760
+
761
+ plan_path = archive_dir / "plans" / f"{change_key}-plan.md"
762
+ if plan_path.is_file():
763
+ try:
764
+ plan_text = plan_path.read_text(encoding="utf-8-sig")
765
+ except OSError:
766
+ plan_text = ""
767
+ collect(_tasks_from_plan(
768
+ plan_text,
769
+ change_key=change_key,
770
+ archive_id=archive_id,
771
+ producer_version=producer_version,
772
+ created_at=created_at,
773
+ ))
774
+
775
+ scenarios_path = archive_dir / "plans" / f"{change_key}-test-scenarios.md"
776
+ if scenarios_path.is_file():
777
+ try:
778
+ scenarios_text = scenarios_path.read_text(encoding="utf-8-sig")
779
+ except OSError:
780
+ scenarios_text = ""
781
+ collect(_scenarios_from_test_scenarios(
782
+ scenarios_text,
783
+ change_key=change_key,
784
+ archive_id=archive_id,
785
+ producer_version=producer_version,
786
+ created_at=created_at,
787
+ ))
788
+
255
789
  return candidates
256
790
 
257
791
 
@@ -2,5 +2,5 @@
2
2
  "schemaVersion": 1,
3
3
  "overlay": "none",
4
4
  "agent": "cursor",
5
- "coreHash": "b246bb49cee55535"
5
+ "coreHash": "041ded3368e8c2df"
6
6
  }
@@ -3,7 +3,7 @@ name: harness-archive
3
3
  description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档)到 .harness/archive/,含归档元数据。仅当用户显式调用
4
4
  /harness-archive 时使用;不得被其他阶段 skill 自动接续触发。
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=b246bb49cee55535; overlay=none; agent=cursor; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=041ded3368e8c2df; overlay=none; agent=cursor; do not edit -->
7
7
  # harness-archive — 变更归档
8
8
 
9
9
  ## Purpose
@@ -67,10 +67,39 @@ powershell.exe -NoProfile -ExecutionPolicy Bypass -File "harness-skills/harness-
67
67
  - `changedFiles`:path/summary/insertions/deletions —— 来自 `git diff --numstat <base>..<head>`;
68
68
  - `reviewSummary`:red/yellow + redFixed/redConfirmed/yellowFixed/yellowDeferred 修复进度;
69
69
  - `maintenanceNotes`:给后续维护者看的结论;
70
- - `knownRisks`:剩余风险或人工确认项。
70
+ - `knownRisks`:剩余风险或人工确认项;
71
+ - `decisions`:已采纳的设计决策/需求/API 契约 —— 来自 `evidence/decisions.json`(见下节),生成器只做校验与透传,不从 markdown 提取。
71
72
 
72
73
  报告必须突出业务目标和维护者结论。所有统计数字只能来自 events、summary-data、ledger 或 manifest,不得手写另一套。历史 archive 没有 `events.ndjson` 时,允许从 ledger/log/manifest 回放,并在 `reportPipeline.sources` 中记录来源。
73
74
 
75
+ ## evidence/decisions.json(可选,知识沉淀入口)
76
+
77
+ 重要设计决策、长期约束、API 契约要进入平台知识库的唯一通道:在 plan/execute/review 阶段由人或 agent 把**已采纳**的结论写入 `.harness/changes/<change>/evidence/decisions.json`(schema_version 1):
78
+
79
+ ```json
80
+ {
81
+ "schema_version": 1,
82
+ "decisions": [
83
+ {
84
+ "id": "D-001",
85
+ "title": "一句话结论(必填,≤500 字)",
86
+ "rationale": "为什么(可选,≤4000 字)",
87
+ "entry_type": "decision | requirement | api-contract",
88
+ "status": "adopted | proposed | rejected | superseded",
89
+ "path": "docs/design/x.md(可选,相对路径,溯源用)",
90
+ "line": 42,
91
+ "keywords": ["可选,≤32 个"],
92
+ "source": "plan | review | manual | archive"
93
+ }
94
+ ]
95
+ }
96
+ ```
97
+
98
+ - 只有 `status: "adopted"` 的记录会成为知识候选(`entry_type` 原样落到知识条目上);其余状态保留在 summary 里做记录。
99
+ - 与 reviewFindings 的裁决门槛同源:**筛选必须在上游发生**——不要把讨论过程原文倒进来,归档时不做任何 LLM 提取。
100
+ - 不合 schema 的记录会被丢弃并在 `maintenanceNotes` 留一条计数说明;丢弃不无声。
101
+ - 未裁决(OPEN/UNKNOWN)的 RED/YELLOW findings 若导致候选为 0,finalize 会显式告警提示先裁决再 republish。
102
+
74
103
  ## 平台展示与数据校验
75
104
 
76
105
  平台监控直接读取 `reports/final/summary-data.json`,归档阶段不再生成本地 HTML 报告,也不得由模型临场维护第二份展示数据。
@@ -213,5 +213,6 @@
213
213
  "uncommittedTestEvidence": [],
214
214
  "maintenanceNotes": [],
215
215
  "knownRisks": [],
216
+ "decisions": [],
216
217
  "manualActions": []
217
218
  }
@@ -3,7 +3,7 @@ name: harness-codebase-map
3
3
  description: 分析现有代码库并生成 .harness/codebase/map/
4
4
  下的结构化代码库地图。用于陌生项目理解、重大改造前梳理、harness-sync 提示 map 过期后的人工刷新。
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=b246bb49cee55535; overlay=none; agent=cursor; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=041ded3368e8c2df; overlay=none; agent=cursor; do not edit -->
7
7
  # harness-codebase-map — 代码库地图
8
8
 
9
9
  ## Purpose
@@ -4,7 +4,7 @@ description: 执行阶段:按变更簇执行 TDD
4
4
  编码循环(RED→GREEN→REFACTOR→编译验证),随后完成单元/接口/数据兼容验证并输出测试报告。仅当用户显式调用
5
5
  /harness-execute 时使用;不得因用户提到编码/实现/测试就自动触发,也不得被其他阶段 skill 自动接续。
6
6
  ---
7
- <!-- generated by harness_deploy.py; core=b246bb49cee55535; overlay=none; agent=cursor; do not edit -->
7
+ <!-- generated by harness_deploy.py; core=041ded3368e8c2df; overlay=none; agent=cursor; do not edit -->
8
8
  # harness-execute — 执行(编码 + 验证)
9
9
 
10
10
  > 2026-08 阶段合并:原 `run`(编码)与 `test`(验证)合并为单一 `execute` 阶段。
@@ -2,7 +2,7 @@
2
2
  name: harness-knowledge-ingest
3
3
  description: 确认归档 ZIP 已上传并由 Hunter Platform 在服务端解包、校验和入库。客户端不再构建或维护本地知识索引。
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=b246bb49cee55535; overlay=none; agent=cursor; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=041ded3368e8c2df; overlay=none; agent=cursor; do not edit -->
6
6
  # harness-knowledge-ingest
7
7
 
8
8
  知识 ingest 完全由 Hunter Platform 负责。归档完成时,客户端生成一个确定性 ZIP;
@@ -2,7 +2,7 @@
2
2
  name: harness-knowledge-query
3
3
  description: 在规划、实现或排查前,通过 hunter-harness CLI 查询远端项目知识库。远端不可用时直接报告不可用,不建立本地索引或离线回退。
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=b246bb49cee55535; overlay=none; agent=cursor; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=041ded3368e8c2df; overlay=none; agent=cursor; do not edit -->
6
6
  # harness-knowledge-query
7
7
 
8
8
  项目知识以 Hunter Platform 的服务端索引为唯一真源。客户端只提交查询并消费结果: