harnery 0.32.0 → 0.34.0

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 (665) hide show
  1. package/README.md +2 -0
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +7 -1
  4. package/dist/commands/adapter.js +2 -2
  5. package/dist/commands/agents.d.ts +144 -1
  6. package/dist/commands/agents.d.ts.map +1 -1
  7. package/dist/commands/agents.js +1408 -565
  8. package/dist/commands/artifacts.d.ts.map +1 -1
  9. package/dist/commands/artifacts.js +7 -6
  10. package/dist/commands/backup.d.ts +1 -1
  11. package/dist/commands/backup.d.ts.map +1 -1
  12. package/dist/commands/backup.js +29 -16
  13. package/dist/commands/browse.d.ts.map +1 -1
  14. package/dist/commands/browse.js +234 -12
  15. package/dist/commands/checkpoint.d.ts.map +1 -1
  16. package/dist/commands/checkpoint.js +3 -2
  17. package/dist/commands/claude-desktop.d.ts +2 -2
  18. package/dist/commands/claude-desktop.d.ts.map +1 -1
  19. package/dist/commands/claude-desktop.js +2 -2
  20. package/dist/commands/context.js +1 -6
  21. package/dist/commands/decision.d.ts.map +1 -1
  22. package/dist/commands/decision.js +22 -38
  23. package/dist/commands/docs.d.ts.map +1 -1
  24. package/dist/commands/docs.js +91 -28
  25. package/dist/commands/doctor.d.ts +4 -2
  26. package/dist/commands/doctor.d.ts.map +1 -1
  27. package/dist/commands/doctor.js +55 -7
  28. package/dist/commands/events.d.ts +5 -0
  29. package/dist/commands/events.d.ts.map +1 -0
  30. package/dist/commands/events.js +189 -0
  31. package/dist/commands/governor.d.ts.map +1 -1
  32. package/dist/commands/governor.js +13 -4
  33. package/dist/commands/init.d.ts +10 -2
  34. package/dist/commands/init.d.ts.map +1 -1
  35. package/dist/commands/init.js +233 -51
  36. package/dist/commands/instructions.d.ts +4 -0
  37. package/dist/commands/instructions.d.ts.map +1 -0
  38. package/dist/commands/instructions.js +100 -0
  39. package/dist/commands/journal.d.ts.map +1 -1
  40. package/dist/commands/journal.js +4 -13
  41. package/dist/commands/ledger-v3.d.ts +5 -0
  42. package/dist/commands/ledger-v3.d.ts.map +1 -0
  43. package/dist/commands/ledger-v3.js +91 -0
  44. package/dist/commands/presence.d.ts.map +1 -1
  45. package/dist/commands/presence.js +15 -6
  46. package/dist/commands/sync.d.ts +1 -1
  47. package/dist/commands/sync.js +1 -1
  48. package/dist/commands/web.d.ts +6 -0
  49. package/dist/commands/web.d.ts.map +1 -1
  50. package/dist/commands/web.js +67 -7
  51. package/dist/commands/work.d.ts.map +1 -1
  52. package/dist/commands/work.js +22 -5
  53. package/dist/core/adapter.d.ts +5 -0
  54. package/dist/core/adapter.d.ts.map +1 -0
  55. package/dist/core/adapter.js +1 -0
  56. package/dist/core/adapters/attest.d.ts +5 -2
  57. package/dist/core/adapters/attest.d.ts.map +1 -1
  58. package/dist/core/adapters/attest.js +8 -3
  59. package/dist/core/adapters/profiles.d.ts +6 -6
  60. package/dist/core/adapters/profiles.d.ts.map +1 -1
  61. package/dist/core/adapters/profiles.js +4 -4
  62. package/dist/core/agents/canonical-emit.d.ts +17 -15
  63. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  64. package/dist/core/agents/canonical-emit.js +27 -25
  65. package/dist/core/agents/cli.js +212 -235
  66. package/dist/core/agents/codex-archive-v3.d.ts +14 -0
  67. package/dist/core/agents/codex-archive-v3.d.ts.map +1 -0
  68. package/dist/core/agents/codex-archive-v3.js +110 -0
  69. package/dist/core/agents/coord-client.d.ts +19 -70
  70. package/dist/core/agents/coord-client.d.ts.map +1 -1
  71. package/dist/core/agents/coord-client.js +65 -155
  72. package/dist/core/agents/finalization.d.ts +4 -1
  73. package/dist/core/agents/finalization.d.ts.map +1 -1
  74. package/dist/core/agents/finalization.js +89 -32
  75. package/dist/core/agents/index.d.ts +5 -5
  76. package/dist/core/agents/index.d.ts.map +1 -1
  77. package/dist/core/agents/index.js +5 -5
  78. package/dist/core/agents/live-authority-v3.d.ts +59 -0
  79. package/dist/core/agents/live-authority-v3.d.ts.map +1 -0
  80. package/dist/core/agents/live-authority-v3.js +233 -0
  81. package/dist/core/agents/live-lifecycle-v3.d.ts +20 -0
  82. package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -0
  83. package/dist/core/agents/live-lifecycle-v3.js +91 -0
  84. package/dist/core/agents/live-observation-v3.d.ts +25 -0
  85. package/dist/core/agents/live-observation-v3.d.ts.map +1 -0
  86. package/dist/core/agents/live-observation-v3.js +157 -0
  87. package/dist/core/agents/render/prompt-context.d.ts +10 -4
  88. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  89. package/dist/core/agents/render/prompt-context.js +61 -55
  90. package/dist/core/agents/render/session-context.d.ts +1 -1
  91. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  92. package/dist/core/agents/render/session-context.js +15 -33
  93. package/dist/core/agents/rules/claim-conflict.d.ts +3 -3
  94. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  95. package/dist/core/agents/rules/claim-conflict.js +79 -127
  96. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
  97. package/dist/core/agents/rules/commit-conflict.js +3 -18
  98. package/dist/core/agents/rules/stop-hook.d.ts +9 -50
  99. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  100. package/dist/core/agents/rules/stop-hook.js +193 -236
  101. package/dist/core/agents/session-events.d.ts +5 -7
  102. package/dist/core/agents/session-events.d.ts.map +1 -1
  103. package/dist/core/agents/session-events.js +127 -95
  104. package/dist/core/agents/session-finalization-state-v3.d.ts +30 -0
  105. package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -0
  106. package/dist/core/agents/session-finalization-state-v3.js +40 -0
  107. package/dist/core/agents/session-finalizer-v3.d.ts +107 -0
  108. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -0
  109. package/dist/core/agents/session-finalizer-v3.js +734 -0
  110. package/dist/core/agents/session-name-display.d.ts +40 -0
  111. package/dist/core/agents/session-name-display.d.ts.map +1 -0
  112. package/dist/core/agents/session-name-display.js +119 -0
  113. package/dist/core/agents/state/activity-log.d.ts +3 -3
  114. package/dist/core/agents/state/activity-log.d.ts.map +1 -1
  115. package/dist/core/agents/state/activity-log.js +7 -16
  116. package/dist/core/agents/state/heartbeat-writer.d.ts +29 -46
  117. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  118. package/dist/core/agents/state/heartbeat-writer.js +59 -199
  119. package/dist/core/agents/state/live-coordination-view.d.ts +31 -0
  120. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -0
  121. package/dist/core/agents/state/live-coordination-view.js +209 -0
  122. package/dist/core/agents/state/session-state.d.ts +45 -0
  123. package/dist/core/agents/state/session-state.d.ts.map +1 -0
  124. package/dist/core/agents/state/session-state.js +90 -0
  125. package/dist/core/agents/state/stale-sweep.d.ts +1 -1
  126. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  127. package/dist/core/agents/state/stale-sweep.js +26 -15
  128. package/dist/core/artifacts/index.d.ts.map +1 -1
  129. package/dist/core/artifacts/index.js +5 -7
  130. package/dist/core/config.d.ts +33 -2
  131. package/dist/core/config.d.ts.map +1 -1
  132. package/dist/core/config.js +98 -2
  133. package/dist/core/context/index.d.ts +1 -4
  134. package/dist/core/context/index.d.ts.map +1 -1
  135. package/dist/core/context/index.js +9 -9
  136. package/dist/core/events/span-parent.d.ts +15 -0
  137. package/dist/core/events/span-parent.d.ts.map +1 -0
  138. package/dist/core/events/span-parent.js +34 -0
  139. package/dist/core/events/v3/advance.d.ts +14 -0
  140. package/dist/core/events/v3/advance.d.ts.map +1 -0
  141. package/dist/core/events/v3/advance.js +134 -0
  142. package/dist/core/events/v3/authority-outbox.d.ts +78 -0
  143. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -0
  144. package/dist/core/events/v3/authority-outbox.js +399 -0
  145. package/dist/core/events/v3/base-builder.d.ts +20 -0
  146. package/dist/core/events/v3/base-builder.d.ts.map +1 -0
  147. package/dist/core/events/v3/base-builder.js +29 -0
  148. package/dist/core/events/v3/base-contract.d.ts +7576 -0
  149. package/dist/core/events/v3/base-contract.d.ts.map +1 -0
  150. package/dist/core/events/v3/base-contract.js +647 -0
  151. package/dist/core/events/v3/bootstrap.d.ts +34 -0
  152. package/dist/core/events/v3/bootstrap.d.ts.map +1 -0
  153. package/dist/core/events/v3/bootstrap.js +175 -0
  154. package/dist/core/events/v3/builder.d.ts +20 -0
  155. package/dist/core/events/v3/builder.d.ts.map +1 -0
  156. package/dist/core/events/v3/builder.js +28 -0
  157. package/dist/core/events/v3/canonical.d.ts +31 -0
  158. package/dist/core/events/v3/canonical.d.ts.map +1 -0
  159. package/dist/core/events/v3/canonical.js +100 -0
  160. package/dist/core/events/v3/capabilities.d.ts +31 -0
  161. package/dist/core/events/v3/capabilities.d.ts.map +1 -0
  162. package/dist/core/events/v3/capabilities.js +107 -0
  163. package/dist/core/events/v3/capability-drift.d.ts +22 -0
  164. package/dist/core/events/v3/capability-drift.d.ts.map +1 -0
  165. package/dist/core/events/v3/capability-drift.js +134 -0
  166. package/dist/core/events/v3/catalog.d.ts +38 -0
  167. package/dist/core/events/v3/catalog.d.ts.map +1 -0
  168. package/dist/core/events/v3/catalog.js +135 -0
  169. package/dist/core/events/v3/clock-order.d.ts +34 -0
  170. package/dist/core/events/v3/clock-order.d.ts.map +1 -0
  171. package/dist/core/events/v3/clock-order.js +35 -0
  172. package/dist/core/events/v3/contract.d.ts +171 -0
  173. package/dist/core/events/v3/contract.d.ts.map +1 -0
  174. package/dist/core/events/v3/contract.js +180 -0
  175. package/dist/core/events/v3/control.d.ts +111 -0
  176. package/dist/core/events/v3/control.d.ts.map +1 -0
  177. package/dist/core/events/v3/control.js +419 -0
  178. package/dist/core/events/v3/coordination-view.d.ts +69 -0
  179. package/dist/core/events/v3/coordination-view.d.ts.map +1 -0
  180. package/dist/core/events/v3/coordination-view.js +119 -0
  181. package/dist/core/events/v3/economics.d.ts +77 -0
  182. package/dist/core/events/v3/economics.d.ts.map +1 -0
  183. package/dist/core/events/v3/economics.js +274 -0
  184. package/dist/core/events/v3/finalization-view.d.ts +26 -0
  185. package/dist/core/events/v3/finalization-view.d.ts.map +1 -0
  186. package/dist/core/events/v3/finalization-view.js +37 -0
  187. package/dist/core/events/v3/fingerprint-keys.d.ts +25 -0
  188. package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -0
  189. package/dist/core/events/v3/fingerprint-keys.js +217 -0
  190. package/dist/core/events/v3/generated.d.ts +4 -0
  191. package/dist/core/events/v3/generated.d.ts.map +1 -0
  192. package/dist/core/events/v3/generated.js +47 -0
  193. package/dist/core/events/v3/ids.d.ts +9 -0
  194. package/dist/core/events/v3/ids.d.ts.map +1 -0
  195. package/dist/core/events/v3/ids.js +25 -0
  196. package/dist/core/events/v3/index.d.ts +35 -0
  197. package/dist/core/events/v3/index.d.ts.map +1 -0
  198. package/dist/core/events/v3/index.js +33 -0
  199. package/dist/core/events/v3/latency.d.ts +63 -0
  200. package/dist/core/events/v3/latency.d.ts.map +1 -0
  201. package/dist/core/events/v3/latency.js +412 -0
  202. package/dist/core/events/v3/live-feed.d.ts +45 -0
  203. package/dist/core/events/v3/live-feed.d.ts.map +1 -0
  204. package/dist/core/events/v3/live-feed.js +246 -0
  205. package/dist/core/events/v3/live-observation.d.ts +35 -0
  206. package/dist/core/events/v3/live-observation.d.ts.map +1 -0
  207. package/dist/core/events/v3/live-observation.js +1 -0
  208. package/dist/core/events/v3/live-routing.d.ts +57 -0
  209. package/dist/core/events/v3/live-routing.d.ts.map +1 -0
  210. package/dist/core/events/v3/live-routing.js +107 -0
  211. package/dist/core/events/v3/producers/command-recorder.d.ts +67 -0
  212. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -0
  213. package/dist/core/events/v3/producers/command-recorder.js +477 -0
  214. package/dist/core/events/v3/producers/command.d.ts +50 -0
  215. package/dist/core/events/v3/producers/command.d.ts.map +1 -0
  216. package/dist/core/events/v3/producers/command.js +135 -0
  217. package/dist/core/events/v3/producers/coordination-recorder.d.ts +53 -0
  218. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -0
  219. package/dist/core/events/v3/producers/coordination-recorder.js +376 -0
  220. package/dist/core/events/v3/producers/coordination.d.ts +90 -0
  221. package/dist/core/events/v3/producers/coordination.d.ts.map +1 -0
  222. package/dist/core/events/v3/producers/coordination.js +229 -0
  223. package/dist/core/events/v3/producers/hook-base.d.ts +54 -0
  224. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -0
  225. package/dist/core/events/v3/producers/hook-base.js +424 -0
  226. package/dist/core/events/v3/producers/hook.d.ts +29 -0
  227. package/dist/core/events/v3/producers/hook.d.ts.map +1 -0
  228. package/dist/core/events/v3/producers/hook.js +71 -0
  229. package/dist/core/events/v3/producers/intake.d.ts +65 -0
  230. package/dist/core/events/v3/producers/intake.d.ts.map +1 -0
  231. package/dist/core/events/v3/producers/intake.js +244 -0
  232. package/dist/core/events/v3/producers/recorder.d.ts +240 -0
  233. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -0
  234. package/dist/core/events/v3/producers/recorder.js +2176 -0
  235. package/dist/core/events/v3/projection.d.ts +101 -0
  236. package/dist/core/events/v3/projection.d.ts.map +1 -0
  237. package/dist/core/events/v3/projection.js +479 -0
  238. package/dist/core/events/v3/reader.d.ts +75 -0
  239. package/dist/core/events/v3/reader.d.ts.map +1 -0
  240. package/dist/core/events/v3/reader.js +778 -0
  241. package/dist/core/events/v3/recovery-record.d.ts +47 -0
  242. package/dist/core/events/v3/recovery-record.d.ts.map +1 -0
  243. package/dist/core/events/v3/recovery-record.js +167 -0
  244. package/dist/core/events/v3/recovery.d.ts +22 -0
  245. package/dist/core/events/v3/recovery.d.ts.map +1 -0
  246. package/dist/core/events/v3/recovery.js +227 -0
  247. package/dist/core/events/v3/span-state.d.ts +52 -0
  248. package/dist/core/events/v3/span-state.d.ts.map +1 -0
  249. package/dist/core/events/v3/span-state.js +142 -0
  250. package/dist/core/events/v3/targets.d.ts +23 -0
  251. package/dist/core/events/v3/targets.d.ts.map +1 -0
  252. package/dist/core/events/v3/targets.js +134 -0
  253. package/dist/core/events/v3/turn-telemetry.d.ts +41 -0
  254. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -0
  255. package/dist/core/events/v3/turn-telemetry.js +168 -0
  256. package/dist/core/events/v3/validate.d.ts +9 -0
  257. package/dist/core/events/v3/validate.d.ts.map +1 -0
  258. package/dist/core/events/v3/validate.js +281 -0
  259. package/dist/core/events/v3/writer.d.ts +56 -0
  260. package/dist/core/events/v3/writer.d.ts.map +1 -0
  261. package/dist/core/events/v3/writer.js +335 -0
  262. package/dist/core/governor/index.d.ts +1 -1
  263. package/dist/core/governor/index.d.ts.map +1 -1
  264. package/dist/core/governor/index.js +1 -1
  265. package/dist/core/governor/plan-api.d.ts +2 -1
  266. package/dist/core/governor/plan-api.d.ts.map +1 -1
  267. package/dist/core/governor/plan-api.js +6 -3
  268. package/dist/core/governor/read.d.ts +1 -1
  269. package/dist/core/governor/read.d.ts.map +1 -1
  270. package/dist/core/governor/read.js +1 -1
  271. package/dist/core/governor/state.d.ts +9 -0
  272. package/dist/core/governor/state.d.ts.map +1 -1
  273. package/dist/core/governor/state.js +40 -3
  274. package/dist/core/guard/config.d.ts +5 -0
  275. package/dist/core/guard/config.d.ts.map +1 -0
  276. package/dist/core/guard/config.js +157 -0
  277. package/dist/core/guard/coordinator.d.ts +14 -0
  278. package/dist/core/guard/coordinator.d.ts.map +1 -0
  279. package/dist/core/guard/coordinator.js +173 -0
  280. package/dist/core/guard/evaluator.d.ts +4 -0
  281. package/dist/core/guard/evaluator.d.ts.map +1 -0
  282. package/dist/core/guard/evaluator.js +242 -0
  283. package/dist/core/guard/evidence-v3.d.ts +15 -0
  284. package/dist/core/guard/evidence-v3.d.ts.map +1 -0
  285. package/dist/core/guard/evidence-v3.js +171 -0
  286. package/dist/core/guard/index.d.ts +10 -0
  287. package/dist/core/guard/index.d.ts.map +1 -0
  288. package/dist/core/guard/index.js +6 -0
  289. package/dist/core/guard/live-source-v3.d.ts +40 -0
  290. package/dist/core/guard/live-source-v3.d.ts.map +1 -0
  291. package/dist/core/guard/live-source-v3.js +128 -0
  292. package/dist/core/guard/storage.d.ts +27 -0
  293. package/dist/core/guard/storage.d.ts.map +1 -0
  294. package/dist/core/guard/storage.js +140 -0
  295. package/dist/core/guard/types.d.ts +119 -0
  296. package/dist/core/guard/types.d.ts.map +1 -0
  297. package/dist/core/guard/types.js +1 -0
  298. package/dist/core/hooks/adapter/detect.d.ts +18 -1
  299. package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
  300. package/dist/core/hooks/adapter/detect.js +29 -0
  301. package/dist/core/hooks/adapter/events.d.ts +7 -4
  302. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  303. package/dist/core/hooks/adapter/events.js +13 -4
  304. package/dist/core/hooks/adapter/output.d.ts +2 -2
  305. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  306. package/dist/core/hooks/adapter/parse.d.ts +7 -4
  307. package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
  308. package/dist/core/hooks/adapter/parse.js +64 -24
  309. package/dist/core/hooks/adapter/wiring.d.ts +30 -4
  310. package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
  311. package/dist/core/hooks/adapter/wiring.js +89 -11
  312. package/dist/core/hooks/cli.d.ts +1 -1
  313. package/dist/core/hooks/cli.js +345 -400
  314. package/dist/core/hooks/codex-authorization.d.ts +30 -0
  315. package/dist/core/hooks/codex-authorization.d.ts.map +1 -0
  316. package/dist/core/hooks/codex-authorization.js +199 -0
  317. package/dist/core/hooks/effects/image-capture.d.ts +20 -34
  318. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  319. package/dist/core/hooks/effects/image-capture.js +212 -221
  320. package/dist/core/hooks/effects/index.d.ts +1 -9
  321. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  322. package/dist/core/hooks/effects/index.js +1 -24
  323. package/dist/core/hooks/events/input-hash.d.ts +7 -0
  324. package/dist/core/hooks/events/input-hash.d.ts.map +1 -0
  325. package/dist/core/hooks/events/input-hash.js +43 -0
  326. package/dist/core/hooks/index.d.ts +4 -3
  327. package/dist/core/hooks/index.d.ts.map +1 -1
  328. package/dist/core/hooks/index.js +2 -3
  329. package/dist/core/hooks/resolve/coord-root.d.ts +1 -1
  330. package/dist/core/hooks/resolve/coord-root.js +1 -1
  331. package/dist/core/hooks/resolve/owner.d.ts +16 -15
  332. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  333. package/dist/core/hooks/resolve/owner.js +51 -42
  334. package/dist/core/hooks/resolve/transcript.d.ts +33 -3
  335. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  336. package/dist/core/hooks/resolve/transcript.js +155 -14
  337. package/dist/core/hooks/session-name-presence.d.ts +9 -10
  338. package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
  339. package/dist/core/hooks/session-name-presence.js +15 -15
  340. package/dist/core/hooks/unsafe-cross-shell.d.ts +1 -1
  341. package/dist/core/hooks/unsafe-cross-shell.d.ts.map +1 -1
  342. package/dist/core/journal/index.d.ts +2 -2
  343. package/dist/core/journal/index.d.ts.map +1 -1
  344. package/dist/core/journal/index.js +9 -22
  345. package/dist/core/presence/blob.d.ts +8 -3
  346. package/dist/core/presence/blob.d.ts.map +1 -1
  347. package/dist/core/presence/blob.js +54 -41
  348. package/dist/core/presence/codec-digest.d.ts +29 -0
  349. package/dist/core/presence/codec-digest.d.ts.map +1 -0
  350. package/dist/core/presence/codec-digest.js +170 -0
  351. package/dist/core/presence/index.js +15 -1
  352. package/dist/core/presence/relay-client.d.ts +1 -1
  353. package/dist/core/presence/relay-client.d.ts.map +1 -1
  354. package/dist/core/presence/relay-client.js +5 -5
  355. package/dist/core/work/index.d.ts +1 -1
  356. package/dist/core/work/index.d.ts.map +1 -1
  357. package/dist/core/work/index.js +1 -1
  358. package/dist/core/work/read.d.ts +1 -1
  359. package/dist/core/work/read.d.ts.map +1 -1
  360. package/dist/core/work/read.js +1 -1
  361. package/dist/core/work/runner.d.ts.map +1 -1
  362. package/dist/core/work/runner.js +6 -0
  363. package/dist/core/work/state.d.ts +9 -0
  364. package/dist/core/work/state.d.ts.map +1 -1
  365. package/dist/core/work/state.js +17 -3
  366. package/dist/core/workflow/engine.js +24 -25
  367. package/dist/core/workflow/live-session-v3.d.ts +19 -0
  368. package/dist/core/workflow/live-session-v3.d.ts.map +1 -0
  369. package/dist/core/workflow/live-session-v3.js +86 -0
  370. package/dist/core/workflow/scope-id.d.ts +3 -0
  371. package/dist/core/workflow/scope-id.d.ts.map +1 -0
  372. package/dist/core/workflow/scope-id.js +5 -0
  373. package/dist/core/workflow/workspaces/leases.d.ts +4 -0
  374. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
  375. package/dist/core/workflow/workspaces/leases.js +53 -19
  376. package/dist/index.d.ts +1 -1
  377. package/dist/index.js +1 -1
  378. package/dist/lib/browser/client.d.ts +41 -0
  379. package/dist/lib/browser/client.d.ts.map +1 -1
  380. package/dist/lib/browser/client.js +203 -0
  381. package/dist/lib/browser/critique.d.ts +28 -2
  382. package/dist/lib/browser/critique.d.ts.map +1 -1
  383. package/dist/lib/browser/critique.js +74 -18
  384. package/dist/lib/browser/geometry.d.ts +1 -1
  385. package/dist/lib/browser/geometry.d.ts.map +1 -1
  386. package/dist/lib/browser/geometry.js +130 -6
  387. package/dist/lib/browser/index.d.ts +3 -0
  388. package/dist/lib/browser/index.d.ts.map +1 -1
  389. package/dist/lib/browser/index.js +3 -0
  390. package/dist/lib/browser/qa-plan.d.ts +174 -0
  391. package/dist/lib/browser/qa-plan.d.ts.map +1 -0
  392. package/dist/lib/browser/qa-plan.js +321 -0
  393. package/dist/lib/browser/qa-reuse.d.ts +99 -0
  394. package/dist/lib/browser/qa-reuse.d.ts.map +1 -0
  395. package/dist/lib/browser/qa-reuse.js +222 -0
  396. package/dist/lib/browser/qa-snapshot.d.ts +64 -0
  397. package/dist/lib/browser/qa-snapshot.d.ts.map +1 -0
  398. package/dist/lib/browser/qa-snapshot.js +171 -0
  399. package/dist/lib/browser/runts.d.ts.map +1 -1
  400. package/dist/lib/browser/runts.js +22 -1
  401. package/dist/lib/browser/tiling.d.ts +71 -0
  402. package/dist/lib/browser/tiling.d.ts.map +1 -0
  403. package/dist/lib/browser/tiling.js +118 -0
  404. package/dist/lib/context/index.d.ts +0 -3
  405. package/dist/lib/context/index.d.ts.map +1 -1
  406. package/dist/lib/context/index.js +20 -42
  407. package/dist/lib/council/index.d.ts +2 -2
  408. package/dist/lib/council/index.d.ts.map +1 -1
  409. package/dist/lib/council/index.js +9 -20
  410. package/dist/lib/docs-frontmatter.d.ts +1 -6
  411. package/dist/lib/docs-frontmatter.d.ts.map +1 -1
  412. package/dist/lib/docs-frontmatter.js +12 -78
  413. package/dist/lib/docs-index.d.ts +9 -0
  414. package/dist/lib/docs-index.d.ts.map +1 -1
  415. package/dist/lib/docs-index.js +32 -3
  416. package/dist/lib/docs-lint.d.ts.map +1 -1
  417. package/dist/lib/docs-lint.js +14 -30
  418. package/dist/lib/docs-metadata-audit.d.ts +19 -0
  419. package/dist/lib/docs-metadata-audit.d.ts.map +1 -0
  420. package/dist/lib/docs-metadata-audit.js +132 -0
  421. package/dist/lib/docs-metadata-managed.d.ts +23 -0
  422. package/dist/lib/docs-metadata-managed.d.ts.map +1 -0
  423. package/dist/lib/docs-metadata-managed.js +78 -0
  424. package/dist/lib/docs-metadata-sync.d.ts +20 -0
  425. package/dist/lib/docs-metadata-sync.d.ts.map +1 -0
  426. package/dist/lib/docs-metadata-sync.js +222 -0
  427. package/dist/lib/docs-metadata-v2-schema.d.ts +273 -0
  428. package/dist/lib/docs-metadata-v2-schema.d.ts.map +1 -0
  429. package/dist/lib/docs-metadata-v2-schema.js +134 -0
  430. package/dist/lib/docs-metadata-v2.d.ts +21 -0
  431. package/dist/lib/docs-metadata-v2.d.ts.map +1 -0
  432. package/dist/lib/docs-metadata-v2.js +424 -0
  433. package/dist/lib/docs-new.d.ts +11 -0
  434. package/dist/lib/docs-new.d.ts.map +1 -0
  435. package/dist/lib/docs-new.js +52 -0
  436. package/dist/lib/docs-sweep.d.ts.map +1 -1
  437. package/dist/lib/docs-sweep.js +45 -29
  438. package/dist/lib/headless/index.d.ts +98 -0
  439. package/dist/lib/headless/index.d.ts.map +1 -0
  440. package/dist/lib/headless/index.js +211 -0
  441. package/dist/lib/identities/assume.d.ts +4 -4
  442. package/dist/lib/identities/assume.d.ts.map +1 -1
  443. package/dist/lib/identities/assume.js +52 -68
  444. package/dist/lib/instructions/apply.d.ts +5 -4
  445. package/dist/lib/instructions/apply.d.ts.map +1 -1
  446. package/dist/lib/instructions/apply.js +32 -20
  447. package/dist/lib/instructions/bundle.d.ts +33 -0
  448. package/dist/lib/instructions/bundle.d.ts.map +1 -0
  449. package/dist/lib/instructions/bundle.js +149 -0
  450. package/dist/lib/instructions/splice.d.ts +0 -1
  451. package/dist/lib/instructions/splice.d.ts.map +1 -1
  452. package/dist/lib/instructions/splice.js +22 -6
  453. package/dist/lib/instructions/templates.d.ts +7 -5
  454. package/dist/lib/instructions/templates.d.ts.map +1 -1
  455. package/dist/lib/instructions/templates.js +79 -9
  456. package/package.json +27 -6
  457. package/schemas/config.schema.json +120 -2
  458. package/schemas/docs-metadata-v2.schema.json +441 -0
  459. package/schemas/event-v3.schema.json +24472 -0
  460. package/src/commander.ts +7 -1
  461. package/src/commands/adapter.ts +2 -2
  462. package/src/commands/agents.ts +1737 -570
  463. package/src/commands/artifacts.ts +7 -6
  464. package/src/commands/backup.ts +29 -21
  465. package/src/commands/browse.ts +349 -8
  466. package/src/commands/checkpoint.ts +4 -3
  467. package/src/commands/claude-desktop.ts +7 -5
  468. package/src/commands/context.ts +1 -6
  469. package/src/commands/decision.ts +27 -44
  470. package/src/commands/docs.ts +100 -33
  471. package/src/commands/doctor.ts +73 -8
  472. package/src/commands/events.ts +256 -0
  473. package/src/commands/governor.ts +18 -4
  474. package/src/commands/init.ts +264 -57
  475. package/src/commands/instructions.ts +129 -0
  476. package/src/commands/journal.ts +4 -13
  477. package/src/commands/ledger-v3.ts +111 -0
  478. package/src/commands/presence.ts +18 -11
  479. package/src/commands/sync.ts +1 -1
  480. package/src/commands/web.ts +67 -8
  481. package/src/commands/work.ts +28 -5
  482. package/src/core/adapter.ts +5 -0
  483. package/src/core/adapters/attest.ts +8 -3
  484. package/src/core/adapters/profiles.ts +4 -6
  485. package/src/core/agents/canonical-emit.ts +39 -28
  486. package/src/core/agents/cli.ts +242 -263
  487. package/src/core/agents/codex-archive-v3.ts +138 -0
  488. package/src/core/agents/coord-client.ts +75 -177
  489. package/src/core/agents/finalization.ts +120 -38
  490. package/src/core/agents/index.ts +5 -5
  491. package/src/core/agents/live-authority-v3.ts +375 -0
  492. package/src/core/agents/live-lifecycle-v3.ts +140 -0
  493. package/src/core/agents/live-observation-v3.ts +216 -0
  494. package/src/core/agents/render/prompt-context.ts +89 -55
  495. package/src/core/agents/render/session-context.ts +23 -32
  496. package/src/core/agents/rules/claim-conflict.ts +85 -126
  497. package/src/core/agents/rules/commit-conflict.ts +3 -14
  498. package/src/core/agents/rules/stop-hook.ts +239 -293
  499. package/src/core/agents/session-events.ts +137 -104
  500. package/src/core/agents/session-finalization-state-v3.ts +90 -0
  501. package/src/core/agents/session-finalizer-v3.ts +953 -0
  502. package/src/core/agents/session-name-display.ts +149 -0
  503. package/src/core/agents/state/activity-log.ts +6 -14
  504. package/src/core/agents/state/heartbeat-writer.ts +98 -242
  505. package/src/core/agents/state/live-coordination-view.ts +290 -0
  506. package/src/core/agents/state/session-state.ts +143 -0
  507. package/src/core/agents/state/stale-sweep.ts +40 -17
  508. package/src/core/artifacts/index.ts +4 -5
  509. package/src/core/config.ts +148 -3
  510. package/src/core/context/index.ts +9 -17
  511. package/src/core/events/span-parent.ts +46 -0
  512. package/src/core/events/v3/advance.ts +168 -0
  513. package/src/core/events/v3/authority-outbox.ts +548 -0
  514. package/src/core/events/v3/base-builder.ts +60 -0
  515. package/src/core/events/v3/base-contract.ts +882 -0
  516. package/src/core/events/v3/bootstrap.ts +226 -0
  517. package/src/core/events/v3/builder.ts +59 -0
  518. package/src/core/events/v3/canonical.ts +153 -0
  519. package/src/core/events/v3/capabilities.ts +171 -0
  520. package/src/core/events/v3/capability-drift.ts +177 -0
  521. package/src/core/events/v3/catalog.ts +202 -0
  522. package/src/core/events/v3/clock-order.ts +41 -0
  523. package/src/core/events/v3/contract.ts +365 -0
  524. package/src/core/events/v3/control.ts +576 -0
  525. package/src/core/events/v3/coordination-view.ts +193 -0
  526. package/src/core/events/v3/economics.ts +384 -0
  527. package/src/core/events/v3/finalization-view.ts +67 -0
  528. package/src/core/events/v3/fingerprint-keys.ts +260 -0
  529. package/src/core/events/v3/generated.ts +48 -0
  530. package/src/core/events/v3/ids.ts +33 -0
  531. package/src/core/events/v3/index.ts +322 -0
  532. package/src/core/events/v3/latency.ts +551 -0
  533. package/src/core/events/v3/live-feed.ts +319 -0
  534. package/src/core/events/v3/live-observation.ts +39 -0
  535. package/src/core/events/v3/live-routing.ts +135 -0
  536. package/src/core/events/v3/producers/command-recorder.ts +631 -0
  537. package/src/core/events/v3/producers/command.ts +201 -0
  538. package/src/core/events/v3/producers/coordination-recorder.ts +538 -0
  539. package/src/core/events/v3/producers/coordination.ts +355 -0
  540. package/src/core/events/v3/producers/hook-base.ts +578 -0
  541. package/src/core/events/v3/producers/hook.ts +119 -0
  542. package/src/core/events/v3/producers/intake.ts +319 -0
  543. package/src/core/events/v3/producers/recorder.ts +2805 -0
  544. package/src/core/events/v3/projection.ts +653 -0
  545. package/src/core/events/v3/reader.ts +1127 -0
  546. package/src/core/events/v3/recovery-record.ts +244 -0
  547. package/src/core/events/v3/recovery.ts +271 -0
  548. package/src/core/events/v3/span-state.ts +187 -0
  549. package/src/core/events/v3/targets.ts +182 -0
  550. package/src/core/events/v3/turn-telemetry.ts +259 -0
  551. package/src/core/events/v3/validate.ts +361 -0
  552. package/src/core/events/v3/writer.ts +419 -0
  553. package/src/core/governor/index.ts +3 -0
  554. package/src/core/governor/plan-api.ts +10 -2
  555. package/src/core/governor/read.ts +3 -0
  556. package/src/core/governor/state.ts +52 -5
  557. package/src/core/guard/config.ts +206 -0
  558. package/src/core/guard/coordinator.ts +227 -0
  559. package/src/core/guard/evaluator.ts +343 -0
  560. package/src/core/guard/evidence-v3.ts +227 -0
  561. package/src/core/guard/index.ts +35 -0
  562. package/src/core/guard/live-source-v3.ts +204 -0
  563. package/src/core/guard/storage.ts +188 -0
  564. package/src/core/guard/types.ts +152 -0
  565. package/src/core/hooks/adapter/detect.ts +28 -1
  566. package/src/core/hooks/adapter/events.ts +15 -6
  567. package/src/core/hooks/adapter/output.ts +7 -2
  568. package/src/core/hooks/adapter/parse.ts +81 -36
  569. package/src/core/hooks/adapter/wiring.ts +119 -13
  570. package/src/core/hooks/cli.ts +398 -422
  571. package/src/core/hooks/codex-authorization.ts +253 -0
  572. package/src/core/hooks/effects/image-capture.ts +228 -238
  573. package/src/core/hooks/effects/index.ts +1 -36
  574. package/src/core/hooks/events/input-hash.ts +47 -0
  575. package/src/core/hooks/index.ts +4 -11
  576. package/src/core/hooks/resolve/coord-root.ts +1 -1
  577. package/src/core/hooks/resolve/owner.ts +52 -45
  578. package/src/core/hooks/resolve/transcript.ts +165 -14
  579. package/src/core/hooks/session-name-presence.ts +14 -15
  580. package/src/core/hooks/unsafe-cross-shell.ts +1 -1
  581. package/src/core/journal/index.ts +15 -22
  582. package/src/core/presence/blob.ts +63 -38
  583. package/src/core/presence/codec-digest.ts +215 -0
  584. package/src/core/presence/index.ts +18 -1
  585. package/src/core/presence/relay-client.ts +5 -5
  586. package/src/core/work/index.ts +3 -0
  587. package/src/core/work/read.ts +3 -0
  588. package/src/core/work/runner.ts +6 -0
  589. package/src/core/work/state.ts +27 -3
  590. package/src/core/workflow/engine.ts +24 -24
  591. package/src/core/workflow/live-session-v3.ts +126 -0
  592. package/src/core/workflow/scope-id.ts +6 -0
  593. package/src/core/workflow/workspaces/leases.ts +56 -19
  594. package/src/index.ts +1 -1
  595. package/src/lib/browser/client.ts +230 -0
  596. package/src/lib/browser/critique.ts +104 -27
  597. package/src/lib/browser/geometry.ts +143 -14
  598. package/src/lib/browser/index.ts +34 -0
  599. package/src/lib/browser/qa-plan.ts +501 -0
  600. package/src/lib/browser/qa-reuse.ts +306 -0
  601. package/src/lib/browser/qa-snapshot.ts +223 -0
  602. package/src/lib/browser/runts.ts +27 -2
  603. package/src/lib/browser/tiling.ts +164 -0
  604. package/src/lib/context/index.ts +22 -46
  605. package/src/lib/council/index.ts +9 -21
  606. package/src/lib/docs-frontmatter.ts +8 -79
  607. package/src/lib/docs-index.ts +33 -3
  608. package/src/lib/docs-lint.ts +15 -29
  609. package/src/lib/docs-metadata-audit.ts +166 -0
  610. package/src/lib/docs-metadata-managed.ts +83 -0
  611. package/src/lib/docs-metadata-sync.ts +262 -0
  612. package/src/lib/docs-metadata-v2-schema.ts +138 -0
  613. package/src/lib/docs-metadata-v2.ts +646 -0
  614. package/src/lib/docs-new.ts +63 -0
  615. package/src/lib/docs-sweep.ts +42 -28
  616. package/src/lib/headless/index.ts +287 -0
  617. package/src/lib/identities/assume.ts +67 -86
  618. package/src/lib/instructions/apply.ts +33 -20
  619. package/src/lib/instructions/bundle.ts +199 -0
  620. package/src/lib/instructions/splice.ts +21 -7
  621. package/src/lib/instructions/templates.ts +85 -13
  622. package/dist/core/agents/cli-emit.d.ts +0 -27
  623. package/dist/core/agents/cli-emit.d.ts.map +0 -1
  624. package/dist/core/agents/cli-emit.js +0 -57
  625. package/dist/core/agents/codex-replay.d.ts +0 -29
  626. package/dist/core/agents/codex-replay.d.ts.map +0 -1
  627. package/dist/core/agents/codex-replay.js +0 -138
  628. package/dist/core/agents/events/consume.d.ts +0 -82
  629. package/dist/core/agents/events/consume.d.ts.map +0 -1
  630. package/dist/core/agents/events/consume.js +0 -195
  631. package/dist/core/agents/events/emit.d.ts +0 -42
  632. package/dist/core/agents/events/emit.d.ts.map +0 -1
  633. package/dist/core/agents/events/emit.js +0 -75
  634. package/dist/core/agents/events/ulid.d.ts +0 -11
  635. package/dist/core/agents/events/ulid.d.ts.map +0 -1
  636. package/dist/core/agents/events/ulid.js +0 -47
  637. package/dist/core/agents/state/heartbeat-projector.d.ts +0 -65
  638. package/dist/core/agents/state/heartbeat-projector.d.ts.map +0 -1
  639. package/dist/core/agents/state/heartbeat-projector.js +0 -527
  640. package/dist/core/hooks/events/emit.d.ts +0 -31
  641. package/dist/core/hooks/events/emit.d.ts.map +0 -1
  642. package/dist/core/hooks/events/emit.js +0 -93
  643. package/dist/core/hooks/events/rotate.d.ts +0 -43
  644. package/dist/core/hooks/events/rotate.d.ts.map +0 -1
  645. package/dist/core/hooks/events/rotate.js +0 -142
  646. package/dist/core/hooks/events/schema.d.ts +0 -312
  647. package/dist/core/hooks/events/schema.d.ts.map +0 -1
  648. package/dist/core/hooks/events/schema.js +0 -12
  649. package/dist/core/hooks/events/ulid.d.ts +0 -10
  650. package/dist/core/hooks/events/ulid.d.ts.map +0 -1
  651. package/dist/core/hooks/events/ulid.js +0 -47
  652. package/dist/lib/docs-frontmatter-migrate.d.ts +0 -33
  653. package/dist/lib/docs-frontmatter-migrate.d.ts.map +0 -1
  654. package/dist/lib/docs-frontmatter-migrate.js +0 -364
  655. package/src/core/agents/cli-emit.ts +0 -64
  656. package/src/core/agents/codex-replay.ts +0 -163
  657. package/src/core/agents/events/consume.ts +0 -254
  658. package/src/core/agents/events/emit.ts +0 -115
  659. package/src/core/agents/events/ulid.ts +0 -51
  660. package/src/core/agents/state/heartbeat-projector.ts +0 -582
  661. package/src/core/hooks/events/emit.ts +0 -125
  662. package/src/core/hooks/events/rotate.ts +0 -151
  663. package/src/core/hooks/events/schema.ts +0 -538
  664. package/src/core/hooks/events/ulid.ts +0 -51
  665. package/src/lib/docs-frontmatter-migrate.ts +0 -427
@@ -1,252 +1,201 @@
1
1
  /**
2
- * Stop-hook verdict: rule 1/3, 2/3, 3/3 enforcement evaluated
3
- * from the canonical event stream alone (no transcript scan).
2
+ * End-of-turn ritual verdict derived from the authoritative V3 event ledger.
4
3
  *
5
- * Codex is observe-only: its Stop continuation can replace the user-facing
6
- * answer in clients that retain only the final continuation response.
7
- *
8
- * Enforced adapters:
9
- * Rule 1/3: `state.status_checked` event with matching turn boundary exists.
10
- * Rule 2/3: latest `turn.stop` event has `status_box_present: true` (or the
11
- * stop currently firing carries that field via the in-flight event
12
- * agent-hook emits before the stop hook runs).
13
- * Rule 3/3: `state.task_set` event with matching turn boundary exists.
14
- * Session-naming rule (at most once per session, CC semantics only): the turn
15
- * whose set-task produced `suggested_session_name` must carry an
16
- * in-window `turn.stop` with `session_name_present: true`.
17
- *
18
- * Pure-prose-turn exemption: when zero `tool.pre_use` events fire in
19
- * the current turn, rules 1/3 and 3/3 do not apply. Rule 2/3 still applies
20
- * as a user-visible mobile cue.
21
- *
22
- * Remediation continuity: an adapter whose Stop channel re-prompts by
23
- * submitting a new user message (Cursor's `followup_message`) opens a fresh
24
- * turn to repair the previous one. Such a turn inherits the window of the turn
25
- * it repairs, so ritual events accumulate instead of alternating. See
26
- * `resolveTurnStartMs`.
4
+ * V3 keeps prompt and reply bodies private. The hook producer records only the
5
+ * structural observations needed here: whether the reply showed the status box
6
+ * and current session name, and whether a prompt was emitted by Harnery's own
7
+ * Cursor remediation channel. Task and status evidence comes from the existing
8
+ * `coord.task_changed` and `coord.status_observed` events.
27
9
  */
28
- import { existsSync, readFileSync } from "node:fs";
29
- import { join } from "node:path";
30
10
  import { agentsRequireGitFinalization, endOfTurnStatusCommand, resolveBinName, } from "../../config.js";
31
- function ackSignalFor(adapter) {
32
- return adapter === "cursor" ? "status_checked" : "status_box_present";
33
- }
34
- const RECENT_EVENT_WINDOW_LINES = 5_000;
35
- /**
36
- * Machine marker that opens a Stop-remediation message. Written by
37
- * `hooks/adapter/output.ts` on the adapters whose Stop channel is a new user
38
- * message, and read back here off `user_prompt.submit.data.prompt_text` to
39
- * recognize a turn Harnery itself opened.
40
- *
41
- * Leading position is deliberate: `prompt_text` is clamped when recorded, so a
42
- * trailing marker could be truncated away on a long reason.
43
- */
11
+ import { readEventV3ControlState } from "../../events/v3/control.js";
12
+ import { liveInstanceIdV3 } from "../../events/v3/live-routing.js";
13
+ import { readLedgerV3 } from "../../events/v3/reader.js";
14
+ import { readLiveCoordinationRow } from "../state/live-coordination-view.js";
44
15
  export const STOP_REMEDIATION_MARKER = "[harnery:stop-remediation";
45
- /** How far back the remediation walk may travel. Adapters cap their own
46
- * followup chains (Cursor's `loop_limit`), and each prompt can appear once per
47
- * observing adapter, so this only guards a pathological stream. */
48
16
  const MAX_REMEDIATION_WALK_BACK = 16;
49
- function isStopRemediationPrompt(event) {
50
- const text = event.data.prompt_text;
51
- if (typeof text !== "string")
52
- return false;
53
- return text.includes(STOP_REMEDIATION_MARKER);
54
- }
55
- /**
56
- * Start of the window this Stop verdict judges.
57
- *
58
- * Normally the most recent `user_prompt.submit`. The exception is the
59
- * remediation chain: Cursor does not continue a turn on Stop, it auto-submits
60
- * our message as a new user turn (`followup_message`). Scoping the verdict to
61
- * that new turn alone makes the ritual unsatisfiable in one pass, because
62
- * remediation itself runs a tool, so the repair turn needs every rule again
63
- * while the signal from the previous turn sits just outside the window. Running
64
- * `set-task` then clears rule 3/3 and fails rule 1/3, running `status` clears
65
- * 1/3 and fails 3/3, and the pair alternates until the adapter's loop cap.
66
- *
67
- * Anchoring the window at the last prompt Harnery did not author makes progress
68
- * monotonic: each repair adds a signal and none are lost, so the chain ends.
69
- * A genuine human prompt always anchors a fresh window, so this cannot be used
70
- * to inherit ritual credit across real turns.
71
- */
72
- function resolveTurnStartMs(ownerEvents, nowMs, fallbackMs) {
73
- // Honor the cutoff: `now_ms` marks what is relevant yet, so a prompt after it
74
- // cannot anchor this turn. In production the cutoff is the clock and nothing
75
- // follows it, but a replay over recorded history passes a past cutoff, and an
76
- // unclamped search would anchor on a later turn and hand back an empty window.
77
- const prompts = ownerEvents.filter((e) => {
78
- if (e.event_type !== "user_prompt.submit")
79
- return false;
80
- const t = Date.parse(e.ts);
81
- return Number.isFinite(t) && t <= nowMs;
82
- });
83
- if (prompts.length === 0)
84
- return fallbackMs;
85
- let index = prompts.length - 1;
86
- let hops = 0;
87
- while (index > 0 && hops < MAX_REMEDIATION_WALK_BACK) {
88
- const prompt = prompts[index];
89
- if (!prompt || !isStopRemediationPrompt(prompt))
90
- break;
91
- index -= 1;
92
- hops += 1;
93
- }
94
- const anchor = prompts[index];
95
- const parsed = anchor ? Date.parse(anchor.ts) : Number.NaN;
96
- return Number.isFinite(parsed) ? parsed : fallbackMs;
97
- }
98
- /**
99
- * Evaluate the Stop-hook verdict. Returns the first failing rule (or allow
100
- * when all three pass). Soft-fails open when the event stream isn't
101
- * readable, fail-open posture on a verdict failure.
102
- */
103
17
  export function evaluateStopHook(coordRoot, req) {
104
- if (req.bypass) {
105
- return {
106
- allow: true,
107
- exit_code: 0,
108
- rule: "stop-hook.bypass",
109
- reason: "HARNERY_AGENT_COORD_BYPASS_STOP=1",
110
- };
111
- }
112
- if (req.workflow_child) {
113
- return {
114
- allow: true,
115
- exit_code: 0,
116
- rule: "stop-hook.workflow_child",
117
- reason: "HARNERY_WORKFLOW_CHILD=1: headless workflow child; ritual not applicable",
118
- };
119
- }
120
- // A blocked Codex Stop does not reject the turn. Codex creates a continuation
121
- // prompt and asks the model to answer again. Some clients retain only that
122
- // final continuation response, so a coordination reminder can replace a
123
- // correct user-facing answer with status output. The Stop path has already
124
- // emitted turn.stop and projected the coordination state before this verdict
125
- // runs. Keep that telemetry, but never continue a Codex turn for this ritual.
126
- if (req.adapter === "codex") {
127
- return {
128
- allow: true,
129
- exit_code: 0,
130
- rule: "stop-hook.codex_observe_only",
131
- reason: "Codex Stop continuations must not replace the user-facing answer",
132
- };
18
+ const unconditional = unconditionalVerdict(req);
19
+ if (unconditional)
20
+ return unconditional;
21
+ const control = readEventV3ControlState(coordRoot);
22
+ if (control.state !== "candidate" && control.state !== "active") {
23
+ return evidenceUnavailable(`V3 control state is ${control.state}; authoritative Stop evidence is unavailable`);
133
24
  }
134
- let events;
135
25
  try {
136
- events = readRecentEvents(coordRoot, RECENT_EVENT_WINDOW_LINES);
26
+ const ledger = control.state === "candidate"
27
+ ? readLedgerV3(coordRoot, { authority: "candidate" })
28
+ : readLedgerV3(coordRoot);
29
+ if (!ledger.complete || ledger.diagnostics.length > 0) {
30
+ return evidenceUnavailable("V3 ledger integrity is not authority-safe; Stop remains fail-open");
31
+ }
32
+ return evaluateStopHookV3Events(coordRoot, req, ledger.events.map(({ event }) => event));
137
33
  }
138
34
  catch {
139
- return {
140
- allow: true,
141
- exit_code: 0,
142
- rule: "stop-hook.fail_open",
143
- reason: "events.ndjson not readable; failing open",
144
- };
35
+ return evidenceUnavailable("V3 ledger is not readable; Stop remains fail-open");
145
36
  }
146
- const ownerEvents = events.filter((e) => e.instance_id === req.instance_id);
147
- if (ownerEvents.length === 0) {
37
+ }
38
+ /** Pure V3 evaluator used by replay and regression tests after authority checks. */
39
+ export function evaluateStopHookV3Events(coordRoot, req, events) {
40
+ const unconditional = unconditionalVerdict(req);
41
+ if (unconditional)
42
+ return unconditional;
43
+ const owner = liveInstanceIdV3(req.instance_id);
44
+ const endMs = req.turn_window?.end_ms ?? req.now_ms ?? Date.now();
45
+ const currentTerminal = [...events]
46
+ .reverse()
47
+ .find((event) => event.event_type === "turn.completed" &&
48
+ event.scope.instance_id === owner &&
49
+ eventTimeMs(event) <= endMs);
50
+ if (currentTerminal?.event_type !== "turn.completed") {
148
51
  return {
149
52
  allow: true,
150
53
  exit_code: 0,
151
54
  rule: "stop-hook.no_history",
152
- reason: "no canonical events for this owner; nothing to evaluate",
55
+ reason: "no authoritative V3 turn terminal for this owner; nothing to evaluate",
153
56
  };
154
57
  }
155
- // Turn window: from the most recent user_prompt.submit (this owner) up to
156
- // either the explicit now_ms or the last event we see, walking back over any
157
- // Harnery-authored Stop-remediation prompts so a repair turn is judged
158
- // together with the turn it repairs (see `resolveTurnStartMs`). Fall back to a
159
- // 5-minute window when no user_prompt.submit is in scope (fresh wiring,
160
- // out-of-window prompt, etc.) so a stale stream doesn't silently pass.
161
- const nowMs = req.now_ms ?? Date.now();
162
- const startMs = req.turn_window
163
- ? req.turn_window.start_ms
164
- : resolveTurnStartMs(ownerEvents, nowMs, nowMs - 5 * 60 * 1000);
165
- const endMs = req.turn_window ? req.turn_window.end_ms : nowMs;
166
- const inTurn = ownerEvents.filter((e) => {
167
- const t = Date.parse(e.ts);
168
- return Number.isFinite(t) && t >= startMs && t <= endMs;
58
+ if (!("generation_id" in currentTerminal.scope)) {
59
+ return evidenceUnavailable("turn.completed has no V3 generation scope; Stop remains fail-open");
60
+ }
61
+ const generationId = currentTerminal.scope.generation_id;
62
+ const ownerEvents = events.filter((event) => event.scope.instance_id === owner &&
63
+ "generation_id" in event.scope &&
64
+ event.scope.generation_id === generationId);
65
+ const startMs = req.turn_window?.start_ms ??
66
+ resolveTurnStartMs(ownerEvents, endMs, Math.max(0, endMs - 5 * 60 * 1000));
67
+ const inTurn = ownerEvents.filter((event) => {
68
+ const time = eventTimeMs(event);
69
+ return Number.isFinite(time) && time >= startMs && time <= endMs;
169
70
  });
170
- const toolPreUseInTurn = inTurn.some((e) => e.event_type === "tool.pre_use");
171
- const statusEvents = inTurn.filter((e) => e.event_type === "state.status_checked");
71
+ const usedTool = inTurn.some((event) => event.event_type === "tool.requested");
72
+ const statusEvents = inTurn.filter((event) => event.event_type === "coord.status_observed" && event.payload.subject_instance_id === owner);
172
73
  const statusChecked = statusEvents.length > 0;
173
74
  const requiredStatusChecked = agentsRequireGitFinalization(coordRoot)
174
- ? statusEvents.some((e) => e.data.git_finalization_checked === true)
75
+ ? statusEvents.some((event) => event.event_type === "coord.status_observed" &&
76
+ event.payload.status === "end_turn_checked")
175
77
  : statusChecked;
176
- const taskSet = inTurn.some((e) => e.event_type === "state.task_set");
177
- // Rule 2/3: status_box_present on the most recent turn.stop for this owner.
178
- // The turn.stop event fires from agent-hook stop, which is wired BEFORE
179
- // the stop-hook verdict, so by the time we evaluate, the just-
180
- // fired turn.stop is already in the stream.
181
- const latestTurnStop = [...inTurn].reverse().find((e) => e.event_type === "turn.stop");
182
- const boxPresent = latestTurnStop ? Boolean(latestTurnStop.data.status_box_present) : false;
183
- // Adapter-aware end-of-turn ack signal (see `ackSignalFor`). On Cursor the
184
- // ack is `status_checked` (running `harn agents status` shows the box inline);
185
- // on Claude Code / Codex it's the transcript-scanned `status_box_present`.
186
- // The matching block helper carries the right "how to fix" message.
187
- const ackSignal = ackSignalFor(req.adapter);
188
- const ackPresent = ackSignal === "status_checked"
189
- ? toolPreUseInTurn
190
- ? requiredStatusChecked
191
- : statusChecked
192
- : boxPresent;
193
- const ackBlock = ackSignal === "status_checked" ? () => rule13Block(coordRoot) : () => rule23Block(coordRoot);
194
- // Pure-prose-turn exemption: only the ack signal applies. Parity
195
- // across adapters: CC requires the box; Cursor requires status_checked.
196
- if (!toolPreUseInTurn) {
197
- if (!ackPresent) {
78
+ const taskSet = inTurn.some((event) => event.event_type === "coord.task_changed" && event.payload.subject_instance_id === owner);
79
+ const turnTerminals = inTurn.filter((event) => event.event_type === "turn.completed");
80
+ const latestTerminal = turnTerminals.at(-1);
81
+ const latestBox = observedBoolean(latestTerminal?.payload.ritual?.status_box_present);
82
+ if (req.adapter !== "cursor" && latestBox === undefined) {
83
+ return evidenceUnavailable("turn.completed has no observed V3 status-box result; Stop remains fail-open");
84
+ }
85
+ const ackPresent = req.adapter === "cursor" ? requiredStatusChecked : latestBox === true;
86
+ const ackBlock = req.adapter === "cursor" ? () => rule13Block(coordRoot) : () => rule23Block(coordRoot);
87
+ // Pure prose turns keep the human-visible acknowledgement but do not require
88
+ // task or final-status mutations. This preserves the pre-V3 policy exactly.
89
+ if (!usedTool) {
90
+ if (!ackPresent)
198
91
  return ackBlock();
199
- }
200
92
  return {
201
93
  allow: true,
202
94
  exit_code: 0,
203
95
  rule: "stop-hook.pure_prose_pass",
204
- reason: "no tool calls this turn; rules 1/3 + 3/3 skipped",
96
+ reason: "no tool calls this turn; task and final-status mutations were not required",
205
97
  };
206
98
  }
207
99
  if (!requiredStatusChecked)
208
100
  return rule13Block(coordRoot);
209
- // On Cursor `ackPresent === statusChecked` (already true here), so this is a
210
- // no-op and rule 2/3 is not enforced; on CC/Codex it's the box-paste check.
211
101
  if (!ackPresent)
212
102
  return ackBlock();
213
103
  if (!taskSet)
214
- return rule33Block();
215
- // Session-naming rule (at most once per session, evaluated last so
216
- // remediation stays monotonic in the established order): the turn whose
217
- // set-task produced the suggested session name must show that name in the
218
- // reply. Claude Code semantics only — Cursor's Stop payload carries neither
219
- // a transcript nor the assistant message, so the fence is undetectable there
220
- // (the same reason rule 2/3 collapses into 1/3 on Cursor), and Codex
221
- // returned observe-only above. Detection rides `turn.stop`'s
222
- // `session_name_present` (assistant-text-only transcript scan), mirroring
223
- // how rule 2/3 rides `status_box_present`.
224
- if (ackSignal === "status_box_present") {
225
- const namingTaskSet = inTurn.find((e) => e.event_type === "state.task_set" &&
226
- e.data.first_of_session === true &&
227
- typeof e.data.suggested_session_name === "string" &&
228
- e.data.suggested_session_name.length > 0);
229
- if (namingTaskSet) {
230
- // ANY in-window turn.stop with the flag satisfies the rule, not just the
231
- // latest: once seen, `session_name_seen_at` is stamped and later
232
- // turn.stops OMIT the field, so a later block on a different rule (whose
233
- // repair fires a fresh turn.stop) must not un-satisfy this one.
234
- const namePresent = inTurn.some((e) => e.event_type === "turn.stop" && e.data.session_name_present === true);
235
- if (!namePresent) {
236
- return sessionNameBlock(String(namingTaskSet.data.suggested_session_name));
237
- }
104
+ return rule33Block(coordRoot);
105
+ // Claude Code can prove session-name presentation from assistant-only text.
106
+ // Cursor cannot expose that text and Codex returned observe-only above.
107
+ if (req.adapter !== "cursor") {
108
+ const naming = turnTerminals
109
+ .map((event) => observedNaming(event.payload.ritual?.session_name))
110
+ .filter((value) => value !== undefined);
111
+ if (naming.some(({ required }) => required) &&
112
+ !naming.some(({ present }) => present) &&
113
+ !sessionNameSeenStamped(coordRoot, req.instance_id)) {
114
+ return sessionNameBlock(coordRoot, req.instance_id);
238
115
  }
239
116
  }
117
+ return { allow: true, exit_code: 0, rule: "stop-hook.pass" };
118
+ }
119
+ function unconditionalVerdict(req) {
120
+ if (req.bypass) {
121
+ return {
122
+ allow: true,
123
+ exit_code: 0,
124
+ rule: "stop-hook.bypass",
125
+ reason: "HARNERY_AGENT_COORD_BYPASS_STOP=1",
126
+ };
127
+ }
128
+ if (req.workflow_child) {
129
+ return {
130
+ allow: true,
131
+ exit_code: 0,
132
+ rule: "stop-hook.workflow_child",
133
+ reason: "HARNERY_WORKFLOW_CHILD=1: headless workflow child; ritual not applicable",
134
+ };
135
+ }
136
+ if (req.adapter === "codex") {
137
+ return {
138
+ allow: true,
139
+ exit_code: 0,
140
+ rule: "stop-hook.codex_observe_only",
141
+ reason: "Codex Stop continuations must not replace the user-facing answer",
142
+ };
143
+ }
144
+ return undefined;
145
+ }
146
+ function resolveTurnStartMs(ownerEvents, nowMs, fallbackMs) {
147
+ const turns = ownerEvents.filter((event) => event.event_type === "turn.started" && eventTimeMs(event) <= nowMs);
148
+ if (turns.length === 0)
149
+ return fallbackMs;
150
+ let index = turns.length - 1;
151
+ let hops = 0;
152
+ while (index > 0 && hops < MAX_REMEDIATION_WALK_BACK) {
153
+ const turn = turns[index];
154
+ if (!turn?.payload.stop_remediation)
155
+ break;
156
+ index -= 1;
157
+ hops += 1;
158
+ }
159
+ return eventTimeMs(turns[index]);
160
+ }
161
+ function eventTimeMs(event) {
162
+ return Date.parse(event.time.observed_at);
163
+ }
164
+ function observedBoolean(value) {
165
+ if (!value || typeof value !== "object" || Array.isArray(value))
166
+ return undefined;
167
+ const observation = value;
168
+ return observation.state === "observed" && typeof observation.value === "boolean"
169
+ ? observation.value
170
+ : undefined;
171
+ }
172
+ function observedNaming(value) {
173
+ if (!value || typeof value !== "object" || Array.isArray(value))
174
+ return undefined;
175
+ const observation = value;
176
+ if (observation.state !== "observed" ||
177
+ !observation.value ||
178
+ typeof observation.value !== "object" ||
179
+ Array.isArray(observation.value)) {
180
+ return undefined;
181
+ }
182
+ const naming = observation.value;
183
+ return typeof naming.required === "boolean" && typeof naming.present === "boolean"
184
+ ? { required: naming.required, present: naming.present }
185
+ : undefined;
186
+ }
187
+ function evidenceUnavailable(reason) {
240
188
  return {
241
189
  allow: true,
242
190
  exit_code: 0,
243
- rule: "stop-hook.pass",
191
+ rule: "stop-hook.v3_evidence_unavailable",
192
+ reason,
244
193
  };
245
194
  }
246
195
  function rule13Block(coordRoot) {
247
196
  const missingEvidence = agentsRequireGitFinalization(coordRoot)
248
- ? "no Git-finalized state.status_checked event found in this turn"
249
- : "no state.status_checked event found in this turn";
197
+ ? "no end_turn_checked coord.status_observed event found in this turn"
198
+ : "no coord.status_observed event found in this turn";
250
199
  return {
251
200
  allow: false,
252
201
  exit_code: 2,
@@ -259,47 +208,55 @@ function rule23Block(coordRoot) {
259
208
  allow: false,
260
209
  exit_code: 2,
261
210
  rule: "stop-hook.rule_2_3",
262
- reason: `End-of-turn rule (2/3): turn.stop did not see the agent-status box in your reply text. Paste the \`${endOfTurnStatusCommand(coordRoot)}\` output verbatim as a fenced code block (the \`┌─ agent-\` prefix is the detection signal).`,
211
+ reason: `End-of-turn rule (2/3): turn.completed did not observe the agent-status box in your reply text. Paste the \`${endOfTurnStatusCommand(coordRoot)}\` output verbatim as a fenced code block (the \`┌─ agent-\` prefix is the detection signal).`,
263
212
  };
264
213
  }
265
- function sessionNameBlock(name) {
214
+ /**
215
+ * A remediation stop cannot land a fresh `turn.completed`: the turn's first
216
+ * stop closed the turn span, continuations open no new one, so the recorder
217
+ * ignores their terminals. When that first terminal lost the transcript flush
218
+ * race and recorded `present: false`, in-window ledger evidence can never
219
+ * change, and the naming rule blocked every retry forever. The sighting stamp
220
+ * on the live coordination row is the durable record that the current
221
+ * suggested name WAS shown in an assistant reply (session-name-presence.ts
222
+ * writes it on the first sighting), so honor it before blocking. Ledger
223
+ * evidence stays primary; the stamp is consulted only after in-window
224
+ * terminals said absent.
225
+ */
226
+ function sessionNameSeenStamped(coordRoot, instanceId) {
227
+ try {
228
+ const row = readLiveCoordinationRow(coordRoot, instanceId);
229
+ return (typeof row?.suggested_session_name === "string" &&
230
+ row.suggested_session_name.length > 0 &&
231
+ row.session_name_seen_for === row.suggested_session_name);
232
+ }
233
+ catch {
234
+ return false;
235
+ }
236
+ }
237
+ function sessionNameBlock(coordRoot, instanceId) {
238
+ let name;
239
+ try {
240
+ name = readLiveCoordinationRow(coordRoot, instanceId)?.suggested_session_name;
241
+ }
242
+ catch {
243
+ // The ledger evidence still authorizes the block; the cache is UX only.
244
+ }
245
+ const instruction = name
246
+ ? `Reproduce it by itself in a fenced code block: ${name}`
247
+ : `Run \`${resolveBinName(coordRoot)} agents suggest-name\`, then reproduce its output by itself in a fenced code block.`;
266
248
  return {
267
249
  allow: false,
268
250
  exit_code: 2,
269
251
  rule: "stop-hook.session_name",
270
- reason: `Session-naming rule: this turn's set-task produced the session name, but your reply doesn't show it. Reproduce it by itself in a fenced code block so the operator can one-click-copy it as the session/tab title: ${name}`,
252
+ reason: `Session-naming rule: V3 observed that the current session name was required but absent. ${instruction}`,
271
253
  };
272
254
  }
273
- function rule33Block() {
255
+ function rule33Block(coordRoot) {
274
256
  return {
275
257
  allow: false,
276
258
  exit_code: 2,
277
259
  rule: "stop-hook.rule_3_3",
278
- reason: `End-of-turn rule (3/3): no state.task_set event found in this turn; run \`${resolveBinName()} agents set-task "<short focus>"\` to declare what you're working on. Pass an empty string if the turn was purely conversational.`,
260
+ reason: `End-of-turn rule (3/3): no coord.task_changed event found in this turn; run \`${resolveBinName(coordRoot)} agents set-task "<short focus>"\` to declare what you're working on. Pass an empty string if the turn was purely conversational.`,
279
261
  };
280
262
  }
281
- /**
282
- * Read the last N JSON lines from events.ndjson. The Stop-hook verdict needs
283
- * just the most recent turn so we tail-read aggressively.
284
- */
285
- function readRecentEvents(coordRoot, maxLines) {
286
- const path = join(coordRoot, ".harnery", "events.ndjson");
287
- if (!existsSync(path))
288
- return [];
289
- const raw = readFileSync(path, "utf8");
290
- const lines = raw.split("\n");
291
- const start = Math.max(0, lines.length - maxLines);
292
- const out = [];
293
- for (let i = start; i < lines.length; i++) {
294
- const line = lines[i];
295
- if (!line?.trim())
296
- continue;
297
- try {
298
- out.push(JSON.parse(line));
299
- }
300
- catch {
301
- /* skip malformed */
302
- }
303
- }
304
- return out;
305
- }
@@ -1,17 +1,15 @@
1
1
  /**
2
2
  * Command/narration event emitter for the coordination layer.
3
3
  *
4
- * `writeSessionEvent` emits command and narration events straight to the
5
- * **canonical** `.harnery/events.ndjson` (alongside the hook events), which the
6
- * `/live` web viewer reads.
4
+ * `writeSessionEvent` records command spans in the canonical V3 ledger.
7
5
  */
8
6
  /** Event types accepted by `writeSessionEvent`. */
9
- export type SessionEventType = "command_start" | "output" | "command_end" | "narration";
7
+ export type SessionEventType = "command.started" | "command.output_observed" | "command.completed";
10
8
  /**
11
9
  * Resolved path of the ndjson sidecar file. Lives inside `.harnery/` so a
12
10
  * containerized reader can pick it up through a single bind mount.
13
11
  */
14
- export declare function canonicalEventsPath(): string;
12
+ export declare function coordinationRootPath(): string;
15
13
  /** Random 8-char hex id for grouping output lines under a single command. */
16
14
  export declare function newCmdId(): string;
17
15
  /**
@@ -24,8 +22,8 @@ export declare function newCmdId(): string;
24
22
  */
25
23
  export declare function readLastIntent(instanceId?: string): string | null;
26
24
  /**
27
- * Emit a command or narration event to `.harnery/events.ndjson`. Best-effort,
28
- * never throws into the caller; telemetry must not break or slow a command.
25
+ * Record a command event in V3. Best-effort, never throws into the caller;
26
+ * telemetry must not break or slow a command.
29
27
  */
30
28
  export declare function writeSessionEvent(type: SessionEventType, fields?: Record<string, unknown>): void;
31
29
  /** Trim long values to keep individual events small. */
@@ -1 +1 @@
1
- {"version":3,"file":"session-events.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,mDAAmD;AACnD,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,QAAQ,GAAG,aAAa,GAAG,WAAW,CAAC;AAExF;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAa5C;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBjE;AA8FD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,gBAAgB,EACtB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,IAAI,CAEN;AAED,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAAO,GAAG,MAAM,CAGxD"}
1
+ {"version":3,"file":"session-events.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,mDAAmD;AACnD,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,GAAG,yBAAyB,GAAG,mBAAmB,CAAC;AAEnG;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBjE;AAkID;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,gBAAgB,EACtB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,IAAI,CAEN;AAED,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAAO,GAAG,MAAM,CAGxD"}