@hunter-harness/workflow-harness 0.2.49 → 0.2.51

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 (234) hide show
  1. package/harness/bundles/general/claude-code/.harness-build.json +1 -1
  2. package/harness/bundles/general/claude-code/README.md +4 -4
  3. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +11 -3
  4. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +6 -1
  5. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +45 -244
  6. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +41 -112
  7. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +9 -4
  8. package/harness/bundles/general/claude-code/harness-plan/checklist.md +2 -2
  9. package/harness/bundles/general/claude-code/harness-review/SKILL.md +7 -2
  10. package/harness/bundles/general/claude-code/harness-run/SKILL.md +8 -3
  11. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +7 -2
  12. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +12 -7
  13. package/harness/bundles/general/claude-code/harness-sync/reference.md +18 -11
  14. package/harness/bundles/general/claude-code/harness-test/SKILL.md +7 -2
  15. package/harness/bundles/general/claude-code/protocols/archive-report-protocol.md +5 -7
  16. package/harness/bundles/general/claude-code/protocols/state-layout-protocol.md +17 -11
  17. package/harness/bundles/general/claude-code/scripts/harness_archive.py +769 -191
  18. package/harness/bundles/general/claude-code/scripts/harness_events_sync.py +90 -12
  19. package/harness/bundles/general/claude-code/scripts/harness_gate.py +17 -0
  20. package/harness/bundles/general/claude-code/scripts/harness_profile.py +0 -1
  21. package/harness/bundles/general/claude-code/scripts/harness_state.py +3 -5
  22. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  23. package/harness/bundles/general/codebuddy/README.md +4 -4
  24. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +11 -3
  25. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +6 -1
  26. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +42 -230
  27. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +38 -98
  28. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +9 -4
  29. package/harness/bundles/general/codebuddy/harness-plan/checklist.md +2 -2
  30. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +7 -2
  31. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +8 -3
  32. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +7 -2
  33. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +13 -8
  34. package/harness/bundles/general/codebuddy/harness-sync/reference.md +18 -11
  35. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +7 -2
  36. package/harness/bundles/general/codebuddy/protocols/archive-report-protocol.md +5 -7
  37. package/harness/bundles/general/codebuddy/protocols/state-layout-protocol.md +17 -11
  38. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +769 -191
  39. package/harness/bundles/general/codebuddy/scripts/harness_events_sync.py +90 -12
  40. package/harness/bundles/general/codebuddy/scripts/harness_gate.py +17 -0
  41. package/harness/bundles/general/codebuddy/scripts/harness_profile.py +0 -1
  42. package/harness/bundles/general/codebuddy/scripts/harness_state.py +3 -5
  43. package/harness/bundles/general/codex/.harness-build.json +1 -1
  44. package/harness/bundles/general/codex/README.md +4 -4
  45. package/harness/bundles/general/codex/harness-archive/SKILL.md +11 -3
  46. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +6 -1
  47. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +42 -230
  48. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +38 -98
  49. package/harness/bundles/general/codex/harness-plan/SKILL.md +9 -4
  50. package/harness/bundles/general/codex/harness-plan/checklist.md +2 -2
  51. package/harness/bundles/general/codex/harness-review/SKILL.md +7 -2
  52. package/harness/bundles/general/codex/harness-run/SKILL.md +8 -3
  53. package/harness/bundles/general/codex/harness-submit/SKILL.md +7 -2
  54. package/harness/bundles/general/codex/harness-sync/SKILL.md +13 -8
  55. package/harness/bundles/general/codex/harness-sync/reference.md +18 -11
  56. package/harness/bundles/general/codex/harness-test/SKILL.md +7 -2
  57. package/harness/bundles/general/codex/protocols/archive-report-protocol.md +5 -7
  58. package/harness/bundles/general/codex/protocols/state-layout-protocol.md +17 -11
  59. package/harness/bundles/general/codex/scripts/harness_archive.py +769 -191
  60. package/harness/bundles/general/codex/scripts/harness_events_sync.py +90 -12
  61. package/harness/bundles/general/codex/scripts/harness_gate.py +17 -0
  62. package/harness/bundles/general/codex/scripts/harness_profile.py +0 -1
  63. package/harness/bundles/general/codex/scripts/harness_state.py +3 -5
  64. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  65. package/harness/bundles/general/cursor/README.md +4 -4
  66. package/harness/bundles/general/cursor/harness-archive/SKILL.md +11 -3
  67. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +6 -1
  68. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +42 -230
  69. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +38 -98
  70. package/harness/bundles/general/cursor/harness-plan/SKILL.md +9 -4
  71. package/harness/bundles/general/cursor/harness-plan/checklist.md +2 -2
  72. package/harness/bundles/general/cursor/harness-review/SKILL.md +7 -2
  73. package/harness/bundles/general/cursor/harness-run/SKILL.md +8 -3
  74. package/harness/bundles/general/cursor/harness-submit/SKILL.md +7 -2
  75. package/harness/bundles/general/cursor/harness-sync/SKILL.md +13 -8
  76. package/harness/bundles/general/cursor/harness-sync/reference.md +18 -11
  77. package/harness/bundles/general/cursor/harness-test/SKILL.md +7 -2
  78. package/harness/bundles/general/cursor/protocols/archive-report-protocol.md +5 -7
  79. package/harness/bundles/general/cursor/protocols/state-layout-protocol.md +17 -11
  80. package/harness/bundles/general/cursor/scripts/harness_archive.py +769 -191
  81. package/harness/bundles/general/cursor/scripts/harness_events_sync.py +90 -12
  82. package/harness/bundles/general/cursor/scripts/harness_gate.py +17 -0
  83. package/harness/bundles/general/cursor/scripts/harness_profile.py +0 -1
  84. package/harness/bundles/general/cursor/scripts/harness_state.py +3 -5
  85. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  86. package/harness/bundles/java/claude-code/README.md +4 -4
  87. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +7 -2
  88. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +11 -3
  89. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +6 -1
  90. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +45 -244
  91. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +41 -112
  92. package/harness/bundles/java/claude-code/harness-package/SKILL.md +7 -2
  93. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +9 -4
  94. package/harness/bundles/java/claude-code/harness-plan/checklist.md +2 -2
  95. package/harness/bundles/java/claude-code/harness-review/SKILL.md +7 -2
  96. package/harness/bundles/java/claude-code/harness-run/SKILL.md +8 -3
  97. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +7 -2
  98. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +12 -7
  99. package/harness/bundles/java/claude-code/harness-sync/reference.md +18 -11
  100. package/harness/bundles/java/claude-code/harness-test/SKILL.md +7 -2
  101. package/harness/bundles/java/claude-code/protocols/archive-report-protocol.md +5 -7
  102. package/harness/bundles/java/claude-code/protocols/state-layout-protocol.md +17 -11
  103. package/harness/bundles/java/claude-code/scripts/harness_archive.py +769 -191
  104. package/harness/bundles/java/claude-code/scripts/harness_events_sync.py +90 -12
  105. package/harness/bundles/java/claude-code/scripts/harness_gate.py +17 -0
  106. package/harness/bundles/java/claude-code/scripts/harness_profile.py +0 -1
  107. package/harness/bundles/java/claude-code/scripts/harness_state.py +3 -5
  108. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  109. package/harness/bundles/java/codebuddy/README.md +4 -4
  110. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +7 -2
  111. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +11 -3
  112. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +6 -1
  113. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +42 -230
  114. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +38 -98
  115. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +7 -2
  116. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +9 -4
  117. package/harness/bundles/java/codebuddy/harness-plan/checklist.md +2 -2
  118. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +7 -2
  119. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +8 -3
  120. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +7 -2
  121. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +13 -8
  122. package/harness/bundles/java/codebuddy/harness-sync/reference.md +18 -11
  123. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +7 -2
  124. package/harness/bundles/java/codebuddy/protocols/archive-report-protocol.md +5 -7
  125. package/harness/bundles/java/codebuddy/protocols/state-layout-protocol.md +17 -11
  126. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +769 -191
  127. package/harness/bundles/java/codebuddy/scripts/harness_events_sync.py +90 -12
  128. package/harness/bundles/java/codebuddy/scripts/harness_gate.py +17 -0
  129. package/harness/bundles/java/codebuddy/scripts/harness_profile.py +0 -1
  130. package/harness/bundles/java/codebuddy/scripts/harness_state.py +3 -5
  131. package/harness/bundles/java/codex/.harness-build.json +1 -1
  132. package/harness/bundles/java/codex/README.md +4 -4
  133. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +7 -2
  134. package/harness/bundles/java/codex/harness-archive/SKILL.md +11 -3
  135. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +6 -1
  136. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +42 -230
  137. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +38 -98
  138. package/harness/bundles/java/codex/harness-package/SKILL.md +7 -2
  139. package/harness/bundles/java/codex/harness-plan/SKILL.md +9 -4
  140. package/harness/bundles/java/codex/harness-plan/checklist.md +2 -2
  141. package/harness/bundles/java/codex/harness-review/SKILL.md +7 -2
  142. package/harness/bundles/java/codex/harness-run/SKILL.md +8 -3
  143. package/harness/bundles/java/codex/harness-submit/SKILL.md +7 -2
  144. package/harness/bundles/java/codex/harness-sync/SKILL.md +13 -8
  145. package/harness/bundles/java/codex/harness-sync/reference.md +18 -11
  146. package/harness/bundles/java/codex/harness-test/SKILL.md +7 -2
  147. package/harness/bundles/java/codex/protocols/archive-report-protocol.md +5 -7
  148. package/harness/bundles/java/codex/protocols/state-layout-protocol.md +17 -11
  149. package/harness/bundles/java/codex/scripts/harness_archive.py +769 -191
  150. package/harness/bundles/java/codex/scripts/harness_events_sync.py +90 -12
  151. package/harness/bundles/java/codex/scripts/harness_gate.py +17 -0
  152. package/harness/bundles/java/codex/scripts/harness_profile.py +0 -1
  153. package/harness/bundles/java/codex/scripts/harness_state.py +3 -5
  154. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  155. package/harness/bundles/java/cursor/README.md +4 -4
  156. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +7 -2
  157. package/harness/bundles/java/cursor/harness-archive/SKILL.md +11 -3
  158. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +6 -1
  159. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +42 -230
  160. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +38 -98
  161. package/harness/bundles/java/cursor/harness-package/SKILL.md +7 -2
  162. package/harness/bundles/java/cursor/harness-plan/SKILL.md +9 -4
  163. package/harness/bundles/java/cursor/harness-plan/checklist.md +2 -2
  164. package/harness/bundles/java/cursor/harness-review/SKILL.md +7 -2
  165. package/harness/bundles/java/cursor/harness-run/SKILL.md +8 -3
  166. package/harness/bundles/java/cursor/harness-submit/SKILL.md +7 -2
  167. package/harness/bundles/java/cursor/harness-sync/SKILL.md +13 -8
  168. package/harness/bundles/java/cursor/harness-sync/reference.md +18 -11
  169. package/harness/bundles/java/cursor/harness-test/SKILL.md +7 -2
  170. package/harness/bundles/java/cursor/protocols/archive-report-protocol.md +5 -7
  171. package/harness/bundles/java/cursor/protocols/state-layout-protocol.md +17 -11
  172. package/harness/bundles/java/cursor/scripts/harness_archive.py +769 -191
  173. package/harness/bundles/java/cursor/scripts/harness_events_sync.py +90 -12
  174. package/harness/bundles/java/cursor/scripts/harness_gate.py +17 -0
  175. package/harness/bundles/java/cursor/scripts/harness_profile.py +0 -1
  176. package/harness/bundles/java/cursor/scripts/harness_state.py +3 -5
  177. package/harness/manifests/general/claude-code.json +23 -47
  178. package/harness/manifests/general/codebuddy.json +23 -47
  179. package/harness/manifests/general/codex.json +23 -47
  180. package/harness/manifests/general/cursor.json +23 -47
  181. package/harness/manifests/java/claude-code.json +25 -49
  182. package/harness/manifests/java/codebuddy.json +25 -49
  183. package/harness/manifests/java/codex.json +25 -49
  184. package/harness/manifests/java/cursor.json +25 -49
  185. package/hunter-workflow-family.json +4 -4
  186. package/package.json +1 -1
  187. package/harness/bundles/general/claude-code/harness-knowledge-ingest/design.md +0 -842
  188. package/harness/bundles/general/claude-code/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -42
  189. package/harness/bundles/general/claude-code/harness-knowledge-ingest/mcp-config.example.json +0 -10
  190. package/harness/bundles/general/claude-code/harness-knowledge-ingest/reference.md +0 -413
  191. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -7263
  192. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -275
  193. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/design.md +0 -842
  194. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -42
  195. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/mcp-config.example.json +0 -10
  196. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/reference.md +0 -413
  197. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -7263
  198. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -275
  199. package/harness/bundles/general/codex/harness-knowledge-ingest/design.md +0 -842
  200. package/harness/bundles/general/codex/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -42
  201. package/harness/bundles/general/codex/harness-knowledge-ingest/mcp-config.example.json +0 -10
  202. package/harness/bundles/general/codex/harness-knowledge-ingest/reference.md +0 -413
  203. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -7263
  204. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -275
  205. package/harness/bundles/general/cursor/harness-knowledge-ingest/design.md +0 -842
  206. package/harness/bundles/general/cursor/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -42
  207. package/harness/bundles/general/cursor/harness-knowledge-ingest/mcp-config.example.json +0 -10
  208. package/harness/bundles/general/cursor/harness-knowledge-ingest/reference.md +0 -413
  209. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -7263
  210. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -275
  211. package/harness/bundles/java/claude-code/harness-knowledge-ingest/design.md +0 -842
  212. package/harness/bundles/java/claude-code/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -42
  213. package/harness/bundles/java/claude-code/harness-knowledge-ingest/mcp-config.example.json +0 -10
  214. package/harness/bundles/java/claude-code/harness-knowledge-ingest/reference.md +0 -413
  215. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -7263
  216. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -275
  217. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/design.md +0 -842
  218. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -42
  219. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/mcp-config.example.json +0 -10
  220. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/reference.md +0 -413
  221. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -7263
  222. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -275
  223. package/harness/bundles/java/codex/harness-knowledge-ingest/design.md +0 -842
  224. package/harness/bundles/java/codex/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -42
  225. package/harness/bundles/java/codex/harness-knowledge-ingest/mcp-config.example.json +0 -10
  226. package/harness/bundles/java/codex/harness-knowledge-ingest/reference.md +0 -413
  227. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -7263
  228. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -275
  229. package/harness/bundles/java/cursor/harness-knowledge-ingest/design.md +0 -842
  230. package/harness/bundles/java/cursor/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -42
  231. package/harness/bundles/java/cursor/harness-knowledge-ingest/mcp-config.example.json +0 -10
  232. package/harness/bundles/java/cursor/harness-knowledge-ingest/reference.md +0 -413
  233. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -7263
  234. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -275
@@ -119,12 +119,19 @@ def post_json(endpoint: dict[str, str], path: str, body: dict[str, Any]) -> dict
119
119
  return json.loads(response.read().decode("utf-8"))
120
120
 
121
121
 
122
- def sync_change(project: Path, change_dir: Path, *, heartbeat_only: bool = False) -> dict[str, Any]:
122
+ def sync_change(
123
+ project: Path,
124
+ change_dir: Path,
125
+ *,
126
+ heartbeat_only: bool = False,
127
+ run_id: str | None = None,
128
+ change_key: str | None = None,
129
+ ) -> dict[str, Any]:
123
130
  endpoint = load_endpoint(project)
124
131
  if endpoint is None:
125
132
  return {"ok": True, "skipped": True, "reason": "remote credentials not configured"}
126
- change_key = change_dir.name
127
- rid = run_id_for(change_dir)
133
+ resolved_key = change_key or change_dir.name
134
+ rid = run_id or run_id_for(change_dir)
128
135
  project_id = endpoint["project_id"]
129
136
 
130
137
  # Always heartbeat so the console can separate connection vs run status.
@@ -138,20 +145,26 @@ def sync_change(project: Path, change_dir: Path, *, heartbeat_only: bool = False
138
145
  {
139
146
  "protocol_version": "hunter-progress-sync/v1",
140
147
  "run_id": rid,
141
- "change_key": change_key,
148
+ "change_key": resolved_key,
142
149
  "client_time": client_time,
143
- "title": change_key,
150
+ "title": resolved_key,
144
151
  },
145
152
  )
146
153
  except (urllib.error.URLError, TimeoutError, OSError, json.JSONDecodeError) as exc:
147
154
  return {"ok": False, "error": f"heartbeat failed: {exc}", "run_id": rid}
148
155
 
149
156
  if heartbeat_only:
150
- return {"ok": True, "heartbeat": True, "run_id": rid}
157
+ return {"ok": True, "heartbeat": True, "run_id": rid, "change_key": resolved_key}
151
158
 
152
159
  events_file = change_dir / "events.ndjson"
153
160
  if not events_file.is_file():
154
- return {"ok": True, "run_id": rid, "uploaded": 0, "reason": "no events.ndjson"}
161
+ return {
162
+ "ok": True,
163
+ "run_id": rid,
164
+ "change_key": resolved_key,
165
+ "uploaded": 0,
166
+ "reason": "no events.ndjson",
167
+ }
155
168
 
156
169
  lines = events_file.read_text(encoding="utf-8").splitlines()
157
170
  acked = load_cursor(change_dir)
@@ -167,7 +180,7 @@ def sync_change(project: Path, change_dir: Path, *, heartbeat_only: bool = False
167
180
  continue
168
181
  if not isinstance(event, dict):
169
182
  continue
170
- event_id = str(event.get("id") or f"{change_key}:{acked + offset}")
183
+ event_id = str(event.get("id") or f"{resolved_key}:{acked + offset}")
171
184
  payload = sanitize(event)
172
185
  batch.append(
173
186
  {
@@ -181,7 +194,13 @@ def sync_change(project: Path, change_dir: Path, *, heartbeat_only: bool = False
181
194
  )
182
195
  if not batch:
183
196
  save_cursor(change_dir, len(lines))
184
- return {"ok": True, "run_id": rid, "uploaded": 0, "acked_lines": len(lines)}
197
+ return {
198
+ "ok": True,
199
+ "run_id": rid,
200
+ "change_key": resolved_key,
201
+ "uploaded": 0,
202
+ "acked_lines": len(lines),
203
+ }
185
204
 
186
205
  # Drop None phase keys for strict schema.
187
206
  for item in batch:
@@ -195,8 +214,8 @@ def sync_change(project: Path, change_dir: Path, *, heartbeat_only: bool = False
195
214
  {
196
215
  "protocol_version": "hunter-progress-sync/v1",
197
216
  "run_id": rid,
198
- "change_key": change_key,
199
- "title": change_key,
217
+ "change_key": resolved_key,
218
+ "title": resolved_key,
200
219
  "events": batch,
201
220
  },
202
221
  )
@@ -222,6 +241,7 @@ def sync_change(project: Path, change_dir: Path, *, heartbeat_only: bool = False
222
241
  return {
223
242
  "ok": accepted == len(batch),
224
243
  "run_id": rid,
244
+ "change_key": resolved_key,
225
245
  "uploaded": accepted,
226
246
  "batch_size": len(batch),
227
247
  "acked_lines": acked_lines,
@@ -229,10 +249,62 @@ def sync_change(project: Path, change_dir: Path, *, heartbeat_only: bool = False
229
249
  }
230
250
 
231
251
 
252
+ def auto_events_sync(
253
+ project_root: Path,
254
+ change_dir: Path,
255
+ *,
256
+ heartbeat_only: bool = False,
257
+ run_id: str | None = None,
258
+ change_key: str | None = None,
259
+ ) -> dict[str, Any]:
260
+ """Best-effort platform events sync (same style as auto_push_archive_core).
261
+
262
+ Failures become warnings so the caller never rolls back the main workflow.
263
+ """
264
+ project_root = project_root.resolve()
265
+ change_dir = change_dir.resolve()
266
+ if load_endpoint(project_root) is None:
267
+ return {"skipped": True, "reason": "no remote credentials"}
268
+ try:
269
+ result = sync_change(
270
+ project_root,
271
+ change_dir,
272
+ heartbeat_only=heartbeat_only,
273
+ run_id=run_id,
274
+ change_key=change_key,
275
+ )
276
+ except Exception as exc: # noqa: BLE001 — best-effort never blocks caller
277
+ return {
278
+ "skipped": False,
279
+ "ok": False,
280
+ "warning": f"events-sync deferred: {exc}",
281
+ }
282
+ if result.get("skipped"):
283
+ return {"skipped": True, "reason": result.get("reason") or "skipped"}
284
+ if result.get("ok"):
285
+ return {"skipped": False, "ok": True, **{
286
+ key: result[key]
287
+ for key in ("run_id", "change_key", "uploaded", "acked_lines", "heartbeat")
288
+ if key in result
289
+ }}
290
+ return {
291
+ "skipped": False,
292
+ "ok": False,
293
+ "warning": str(result.get("error") or "events-sync failed"),
294
+ **{
295
+ key: result[key]
296
+ for key in ("run_id", "change_key")
297
+ if key in result
298
+ },
299
+ }
300
+
301
+
232
302
  def main(argv: list[str] | None = None) -> int:
233
303
  parser = argparse.ArgumentParser(description="Sync events.ndjson to platform Run monitoring")
234
304
  parser.add_argument("--project", default=".", help="Project root")
235
305
  parser.add_argument("--change-dir", help="Specific change directory")
306
+ parser.add_argument("--run-id", help="Override stable run_id (archive finalize continuity)")
307
+ parser.add_argument("--change-key", help="Override change_key sent to the platform")
236
308
  parser.add_argument("--heartbeat-only", action="store_true")
237
309
  parser.add_argument("--json", action="store_true")
238
310
  args = parser.parse_args(argv)
@@ -243,7 +315,13 @@ def main(argv: list[str] | None = None) -> int:
243
315
  root = project / ".harness" / "changes"
244
316
  changes = sorted(path for path in root.glob("*") if path.is_dir()) if root.is_dir() else []
245
317
  results = [
246
- sync_change(project, change_dir, heartbeat_only=args.heartbeat_only)
318
+ sync_change(
319
+ project,
320
+ change_dir,
321
+ heartbeat_only=args.heartbeat_only,
322
+ run_id=args.run_id,
323
+ change_key=args.change_key,
324
+ )
247
325
  for change_dir in changes
248
326
  ]
249
327
  ok = all(item.get("ok") for item in results) if results else True
@@ -31,6 +31,7 @@ if str(SCRIPTS_DIR) not in sys.path:
31
31
 
32
32
  import harness_change as hc # noqa: E402
33
33
  import harness_events as he # noqa: E402
34
+ import harness_events_sync as hes # noqa: E402
34
35
  import harness_ledger as hl # noqa: E402
35
36
  import harness_paths as hp # noqa: E402
36
37
  import harness_plan_finalize as hpf # noqa: E402
@@ -2213,6 +2214,22 @@ def cmd_begin(args: argparse.Namespace) -> int:
2213
2214
  "gateSeverityMode": severity_mode,
2214
2215
  "gateWarnings": gate_warnings,
2215
2216
  }
2217
+ # C3: best-effort start platform run monitoring (register + running via heartbeat/events).
2218
+ try:
2219
+ monitor = hes.auto_events_sync(project, change_dir)
2220
+ payload["platformMonitor"] = monitor
2221
+ if monitor.get("warning"):
2222
+ warnings_msg = str(monitor["warning"])
2223
+ gate_warnings.append({
2224
+ "code": "PLATFORM_EVENTS_SYNC_WARN",
2225
+ "message": warnings_msg,
2226
+ })
2227
+ payload["gateWarnings"] = gate_warnings
2228
+ except Exception as exc: # noqa: BLE001 — never block phase begin
2229
+ payload["platformMonitor"] = {
2230
+ "ok": False,
2231
+ "warning": f"events-sync hook failed: {exc}",
2232
+ }
2216
2233
  emit(payload, as_json=as_json)
2217
2234
  return 0
2218
2235
 
@@ -852,7 +852,6 @@ def _node_commands(project: Path) -> dict[str, Any]:
852
852
  inputs.extend(
853
853
  [
854
854
  "harness/scripts/*.py",
855
- "harness/harness-knowledge-ingest/scripts/*.py",
856
855
  "harness/harness-test/scripts/*.mjs",
857
856
  "harness/harness-test/scripts/tests/*.mjs",
858
857
  "scripts/*.mjs",
@@ -218,11 +218,9 @@ def discover_segment_files(
218
218
  project / "harness.json",
219
219
  ]
220
220
  codebase_map = list((project / ".harness/codebase/map").glob("**/*"))
221
- knowledge = [
222
- project / ".harness/knowledge/index.json",
223
- project / ".harness/knowledge/status.json",
224
- project / ".harness/knowledge/config.json",
225
- ]
221
+ # Knowledge is remote-only. Keep the segment for schema compatibility, but
222
+ # do not discover or fingerprint local indexes/fallback state.
223
+ knowledge: list[Path] = []
226
224
  change_inputs: list[Path] = []
227
225
  for folder in ("spec", "plans", "meta"):
228
226
  change_inputs.extend((change_dir / folder).glob("**/*"))
@@ -2,5 +2,5 @@
2
2
  "schemaVersion": 1,
3
3
  "overlay": "java",
4
4
  "agent": "codebuddy",
5
- "coreHash": "0c4a64243d3f7bfb"
5
+ "coreHash": "63cbdcb9833a5c07"
6
6
  }
@@ -56,8 +56,8 @@
56
56
  | harness-review | `[Read, Write, Edit, Glob, Grep, Agent, Bash(powershell.exe:*)]` | 同上 |
57
57
  | harness-sync | `[Read, Glob, Grep, Edit, Write, Bash(powershell.exe:*)]` | 同上 |
58
58
  | harness-codebase-map | `[Read, Glob, Grep, Write, Edit, Agent, Bash(powershell.exe:*)]` | 同上 |
59
- | harness-knowledge-query | `[Bash(powershell.exe:*), Read, Write, Edit, Glob, Grep]` | 同上 |
60
- | harness-knowledge-ingest | `[Bash(powershell.exe:*), Read, Write, Edit, Glob, Grep]` | 同上 |
59
+ | harness-knowledge-query | `[Bash(powershell.exe:*), Read, Glob, Grep]` | 同上 |
60
+ | harness-knowledge-ingest | `[Bash(powershell.exe:*), Read, Glob, Grep]` | 同上 |
61
61
 
62
62
  > **blocking user confirmation 不预批准**:各 skill 需要向用户确认时通过普通权限提示调用 `blocking user confirmation`(adapter 映射到 `AskUserQuestion`/`request_user_input`/普通对话),不在 `allowed-tools` 中预批准(遵循 skill-optimizer 规则)。`harness-codebase-map` 额外预批准 `Agent` 用于派发并行 mapper。
63
63
 
@@ -227,8 +227,8 @@ harness-skills/
227
227
  | harness-review | `/harness-review` | 6维度参考性审查(不阻塞后续流程) | `test` | 手动 | `.harness/changes/<cn>/reports/review/` |
228
228
  | harness-submit | `/harness-submit` 或 `/harness-merge`(别名) | commit+push(主目录)/ worktree:本地 commit→--no-ff 合并→push 主分支 | `review` | 手动 | ledger `mergeFinalHash` + 控制台报告 |
229
229
  | harness-archive | `/harness-archive` | 归档产出到 archive/YYYY-MM-DD-<cn>,释放工作区 | `submit` | 手动 | `.harness/archive/YYYY-MM-DD-<cn>/` |
230
- | harness-knowledge-query | `/harness-knowledge-query` | 查询 .harness/knowledge 历史上下文,生成需求 context pack | `sync`/独立 | ✅ | `.harness/knowledge/context-packs/` |
231
- | harness-knowledge-ingest | `/harness-knowledge-ingest` | archive 整理/同步/维护知识索引(promote/demote/audit) | `archive` | ✅ | `.harness/knowledge/index.json` |
230
+ | harness-knowledge-query | `/harness-knowledge-query` | 只查询平台语义知识;无本地索引或离线回退 | 独立 | ✅ | CLI JSON(不落本地知识文件) |
231
+ | harness-knowledge-ingest | `/harness-knowledge-ingest` | 确认归档 ZIP 已由平台保存、解包并 ingest | `archive` | ✅ | 服务端 package/knowledge 收据 |
232
232
 
233
233
  > 生命周期 skill(plan → run → test → review → submit → archive)为**手动触发**:单阶段结束后停止,不自动接续下一阶段(已设 `disable-model-invocation`)。sync / codebase-map / knowledge 等辅助 skill 仍可按需被调用。`harness-run`、`harness-submit`、`harness-archive` 涉及 git 写操作、文件移动或归档,调用前必须确保前置条件已满足。
234
234
  > `<cn>` = change-name,由 harness-plan 阶段7确定。其他 skill 自动扫描未归档变更定位。
@@ -3,7 +3,7 @@ name: harness-apidoc
3
3
  description: 从 Java 后端代码生成结构化前端 API 文档(Controller/VO/ErrorCode)。仅当用户显式调用
4
4
  /harness-apidoc 时使用,不得自动触发。
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=0c4a64243d3f7bfb; overlay=java; agent=codebuddy; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=63cbdcb9833a5c07; overlay=java; agent=codebuddy; do not edit -->
7
7
  # harness-apidoc — 前端接口文档(Java overlay)
8
8
 
9
9
  ## Purpose
@@ -25,7 +25,7 @@ description: 从 Java 后端代码生成结构化前端 API 文档(Controller/
25
25
  6. **implementation-detail** — 自适应执行参考;legacy 缺失 🟡WARN,不阻断
26
26
  7. **test-scenarios** — 测试真相源:`plans/<change>-test-scenarios.md`
27
27
  8. **禁止读取 `docs/superpowers/` 作为正式输入** — 旧草稿仅人工线索
28
- 9. **每个 skill 边界只刷新一次状态快照** — 先运行 `python <skills-root>/scripts/harness_state.py capture --project . --change-dir ".harness/changes/<change-name>" --base <baseCommit> --json`;`changedSegments=[]` 时复用已有 profile/rules/map/knowledge/change/code 指纹,不再重复跑全量 `harness-sync`、知识重建或代码库扫描。只有对应 segment 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
28
+ 9. **每个 skill 边界只刷新一次状态快照** — 先运行 `python <skills-root>/scripts/harness_state.py capture --project . --change-dir ".harness/changes/<change-name>" --base <baseCommit> --json`;`changedSegments=[]` 时复用已有 profile/rules/map/change/code 指纹,不再重复跑全量 `harness-sync` 或代码库扫描。`knowledge` 段仅为兼容空段,知识始终按需远端查询;快照不能替代源码读取和验证门禁。
29
29
 
30
30
  状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
31
31
  > 片段:read-protocol
@@ -54,6 +54,11 @@ description: 从 Java 后端代码生成结构化前端 API 文档(Controller/
54
54
  - 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
55
55
  - 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
56
56
  - 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
57
+
58
+ ## 生成内容语言约定
59
+
60
+ - sync/ingest 等生成的文档、规则、知识条目、架构说明一律**优先使用中文**撰写(标识符、命令、代码、API 字段名保持原文)
61
+ - 面向平台展示的标题/摘要/正文默认中文;仅当用户明确要求或目标系统强制时才用英文
57
62
  > 片段:p0-trust
58
63
 
59
64
  ## 渐进披露
@@ -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=0c4a64243d3f7bfb; overlay=java; agent=codebuddy; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=63cbdcb9833a5c07; overlay=java; agent=codebuddy; do not edit -->
7
7
  # harness-archive — 变更归档
8
8
 
9
9
  ## Purpose
@@ -58,7 +58,7 @@ description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档
58
58
  6. **implementation-detail** — 自适应执行参考;legacy 缺失 🟡WARN,不阻断
59
59
  7. **test-scenarios** — 测试真相源:`plans/<change>-test-scenarios.md`
60
60
  8. **禁止读取 `docs/superpowers/` 作为正式输入** — 旧草稿仅人工线索
61
- 9. **每个 skill 边界只刷新一次状态快照** — 先运行 `python <skills-root>/scripts/harness_state.py capture --project . --change-dir ".harness/changes/<change-name>" --base <baseCommit> --json`;`changedSegments=[]` 时复用已有 profile/rules/map/knowledge/change/code 指纹,不再重复跑全量 `harness-sync`、知识重建或代码库扫描。只有对应 segment 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
61
+ 9. **每个 skill 边界只刷新一次状态快照** — 先运行 `python <skills-root>/scripts/harness_state.py capture --project . --change-dir ".harness/changes/<change-name>" --base <baseCommit> --json`;`changedSegments=[]` 时复用已有 profile/rules/map/change/code 指纹,不再重复跑全量 `harness-sync` 或代码库扫描。`knowledge` 段仅为兼容空段,知识始终按需远端查询;快照不能替代源码读取和验证门禁。
62
62
 
63
63
  状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
64
64
  > 片段:read-protocol
@@ -100,7 +100,10 @@ description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档
100
100
 
101
101
  1. 运行 `python <skills-root>/scripts/harness_archive.py status --change-dir ".harness/changes/<change-name>" --intent release-candidate --json` 前置检查。无 CI 项目若已有完整全量 ledger,先运行 `certify-local`;若用户明确只封存事实,则 status/finalize 均使用 `--intent record-only`。
102
102
  2. `meta/archive-meta.md` **由 `harness_archive.py finalize` 自动生成**(与 summary-data `finalStatus` 同源);**禁止 agent 手写**该文件,手写视为数据丢失。维护者结论写入 events(decision/issue)即可,finalize 会汇总到 summary / archive-meta。
103
- 3. 运行 `python <skills-root>/scripts/harness_archive.py finalize --change-dir ".harness/changes/<change-name>" --archive-root ".harness/archive" --intent <release-candidate|record-only> --json`;读 JSON(cleanup、事件、移动、collect、render、validate、manifest 比对、archive-meta)。finalize 内部负责且仅负责一次 `phase.start` / `phase.end`,调用者不得重复追加。**finalize 不再同步执行知识维护**(§8.2):它写一个 `pending` maintenance-outbox 项即返回,`knowledgeMaintenance=QUEUED`;写 outbox 失败时 `NOT_QUEUED`(warning,不回滚 archive,总状态 CONDITIONAL)。后续由 `harness-sync` / `harness_knowledge.py maintain` 异步推进 outbox。**finalize 失败或 validate 报错时不删除原目录**。
103
+ 3. 运行 `python <skills-root>/scripts/harness_archive.py finalize --change-dir ".harness/changes/<change-name>" --archive-root ".harness/archive" --intent <release-candidate|record-only> --json`;读 JSON(cleanup、事件、移动、collect、render、validate、manifest 比对、archive-meta、ZIP package、上传与服务端 knowledge status)。finalize 内部负责且仅负责一次 `phase.start` / `phase.end`,调用者不得重复追加。**本地不再执行知识维护,也不写 maintenance-outbox**;服务端在归档 ZIP 持久保存并解包后 ingest。**finalize 失败或 validate 报错时不删除原目录**。
104
+ - **归档包上传**:始终先生成一个确定性 ZIP;有远程凭据时再调用 `npx hunter-harness archive upload`。ZIP 仅包含 `summary-data.json`、`spec/**/*.md`、`plans/**/*.md`、`archive-meta.md`、`change-context.json` 和稳定 manifest;明确排除 logs、review/test 报告、HTML、缓存、备份、凭据和临时文件。
105
+ - **失败可恢复**:无论远端凭据是否齐全,都先生成 ZIP 与 `<change-key>.upload.json`;上传或服务端 ingest 失败不破坏本地归档。待上传 ZIP 与逐 change 回执保留在 `.harness/state/local/archive-packages/`,可枚举独立重试。只有 CLI 核验 package hash 且服务端同时返回 `archive_status=durable`、`knowledge_status=ready` 后,才清理对应 ZIP 与回执;`indexing` 记为 pending,不记为失败。
106
+ - **监控终态(C3)**:auto-upload 之后自动 `events-sync`,用归档前 change 路径派生的 `run_id` + 原 `change_key` 上报;失败只记 warning。
104
107
 
105
108
  - **Read `reference.md`** — finalize 输出字段、archive-meta 格式、CONDITIONAL_OK 规则
106
109
  - **Read `templates/summary-data-template.json`** — summary-data 数据结构
@@ -117,6 +120,11 @@ description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档
117
120
  - 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
118
121
  - 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
119
122
  - 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
123
+
124
+ ## 生成内容语言约定
125
+
126
+ - sync/ingest 等生成的文档、规则、知识条目、架构说明一律**优先使用中文**撰写(标识符、命令、代码、API 字段名保持原文)
127
+ - 面向平台展示的标题/摘要/正文默认中文;仅当用户明确要求或目标系统强制时才用英文
120
128
  > 片段:p0-trust
121
129
 
122
130
  ## 关键规则(硬门禁速查)
@@ -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=0c4a64243d3f7bfb; overlay=java; agent=codebuddy; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=63cbdcb9833a5c07; overlay=java; agent=codebuddy; do not edit -->
7
7
  # harness-codebase-map — 代码库地图
8
8
 
9
9
  ## Purpose
@@ -56,6 +56,11 @@ description: 分析现有代码库并生成 .harness/codebase/map/
56
56
  - 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
57
57
  - 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
58
58
  - 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
59
+
60
+ ## 生成内容语言约定
61
+
62
+ - sync/ingest 等生成的文档、规则、知识条目、架构说明一律**优先使用中文**撰写(标识符、命令、代码、API 字段名保持原文)
63
+ - 面向平台展示的标题/摘要/正文默认中文;仅当用户明确要求或目标系统强制时才用英文
59
64
  > 片段:p0-trust · map 额外:文件存在/行数/hash 为证据
60
65
 
61
66
  ## 关键规则