harnery 0.34.1 → 0.36.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 (692) hide show
  1. package/dist/commander.d.ts +30 -5
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +124 -94
  4. package/dist/commands/agents.d.ts +37 -6
  5. package/dist/commands/agents.d.ts.map +1 -1
  6. package/dist/commands/agents.js +466 -371
  7. package/dist/commands/backup.d.ts.map +1 -1
  8. package/dist/commands/backup.js +10 -10
  9. package/dist/commands/browse-session.d.ts.map +1 -1
  10. package/dist/commands/browse-session.js +12 -0
  11. package/dist/commands/browse.d.ts +1 -1
  12. package/dist/commands/browse.d.ts.map +1 -1
  13. package/dist/commands/browse.js +31 -6
  14. package/dist/commands/conversations.d.ts +10 -0
  15. package/dist/commands/conversations.d.ts.map +1 -0
  16. package/dist/commands/conversations.js +201 -0
  17. package/dist/commands/decision.d.ts.map +1 -1
  18. package/dist/commands/decision.js +2 -2
  19. package/dist/commands/deinit.d.ts.map +1 -1
  20. package/dist/commands/deinit.js +5 -0
  21. package/dist/commands/docs.d.ts.map +1 -1
  22. package/dist/commands/docs.js +13 -2
  23. package/dist/commands/doctor.d.ts +5 -0
  24. package/dist/commands/doctor.d.ts.map +1 -1
  25. package/dist/commands/doctor.js +51 -7
  26. package/dist/commands/events.d.ts.map +1 -1
  27. package/dist/commands/events.js +18 -1
  28. package/dist/commands/fetch.js +6 -5
  29. package/dist/commands/files.d.ts +22 -0
  30. package/dist/commands/files.d.ts.map +1 -0
  31. package/dist/commands/files.js +113 -0
  32. package/dist/commands/governor.js +14 -12
  33. package/dist/commands/inbox.d.ts +5 -0
  34. package/dist/commands/inbox.d.ts.map +1 -0
  35. package/dist/commands/inbox.js +57 -0
  36. package/dist/commands/init.d.ts +4 -5
  37. package/dist/commands/init.d.ts.map +1 -1
  38. package/dist/commands/init.js +63 -13
  39. package/dist/commands/ledger-v3.d.ts.map +1 -1
  40. package/dist/commands/ledger-v3.js +347 -1
  41. package/dist/commands/logs.d.ts +4 -0
  42. package/dist/commands/logs.d.ts.map +1 -0
  43. package/dist/commands/logs.js +169 -0
  44. package/dist/commands/messages.d.ts +5 -0
  45. package/dist/commands/messages.d.ts.map +1 -0
  46. package/dist/commands/messages.js +45 -0
  47. package/dist/commands/outline.d.ts +1 -1
  48. package/dist/commands/outline.d.ts.map +1 -1
  49. package/dist/commands/outline.js +2 -2
  50. package/dist/commands/presence.d.ts.map +1 -1
  51. package/dist/commands/presence.js +2 -2
  52. package/dist/commands/read.d.ts +1 -1
  53. package/dist/commands/read.d.ts.map +1 -1
  54. package/dist/commands/read.js +2 -2
  55. package/dist/commands/semantic.d.ts +4 -0
  56. package/dist/commands/semantic.d.ts.map +1 -0
  57. package/dist/commands/semantic.js +199 -0
  58. package/dist/commands/storage.d.ts +4 -0
  59. package/dist/commands/storage.d.ts.map +1 -0
  60. package/dist/commands/storage.js +238 -0
  61. package/dist/commands/tunnel.d.ts +5 -1
  62. package/dist/commands/tunnel.d.ts.map +1 -1
  63. package/dist/commands/tunnel.js +44 -31
  64. package/dist/commands/web.d.ts +3 -0
  65. package/dist/commands/web.d.ts.map +1 -1
  66. package/dist/commands/web.js +84 -7
  67. package/dist/commands/work.js +3 -3
  68. package/dist/commands/workflow.js +13 -13
  69. package/dist/core/adapters/profiles.d.ts +1 -1
  70. package/dist/core/agents/canonical-emit.d.ts +3 -0
  71. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  72. package/dist/core/agents/canonical-emit.js +12 -0
  73. package/dist/core/agents/claim-path.d.ts +11 -0
  74. package/dist/core/agents/claim-path.d.ts.map +1 -0
  75. package/dist/core/agents/claim-path.js +22 -0
  76. package/dist/core/agents/cli.js +209 -39
  77. package/dist/core/agents/coord-client.d.ts +29 -3
  78. package/dist/core/agents/coord-client.d.ts.map +1 -1
  79. package/dist/core/agents/coord-client.js +88 -9
  80. package/dist/core/agents/live-authority-v3.d.ts +47 -1
  81. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  82. package/dist/core/agents/live-authority-v3.js +245 -13
  83. package/dist/core/agents/live-lifecycle-v3.js +9 -4
  84. package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
  85. package/dist/core/agents/live-observation-v3.js +8 -3
  86. package/dist/core/agents/render/prompt-context.d.ts +9 -3
  87. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  88. package/dist/core/agents/render/prompt-context.js +36 -17
  89. package/dist/core/agents/rules/stop-hook.d.ts +2 -0
  90. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  91. package/dist/core/agents/rules/stop-hook.js +115 -22
  92. package/dist/core/agents/rules/verdict.d.ts +1 -0
  93. package/dist/core/agents/rules/verdict.d.ts.map +1 -1
  94. package/dist/core/agents/session-events.d.ts.map +1 -1
  95. package/dist/core/agents/session-events.js +4 -0
  96. package/dist/core/agents/session-finalization-state-v3.js +1 -1
  97. package/dist/core/agents/session-finalizer-v3.js +5 -1
  98. package/dist/core/agents/session-name-display.d.ts +1 -0
  99. package/dist/core/agents/session-name-display.d.ts.map +1 -1
  100. package/dist/core/agents/session-name-display.js +8 -1
  101. package/dist/core/agents/state/activity-log.d.ts +3 -0
  102. package/dist/core/agents/state/activity-log.d.ts.map +1 -1
  103. package/dist/core/agents/state/activity-log.js +6 -3
  104. package/dist/core/agents/state/heartbeat-reader.d.ts +46 -0
  105. package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -0
  106. package/dist/core/agents/state/heartbeat-reader.js +25 -0
  107. package/dist/core/agents/state/heartbeat-writer.d.ts +9 -48
  108. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  109. package/dist/core/agents/state/heartbeat-writer.js +34 -34
  110. package/dist/core/agents/state/live-coordination-view.d.ts +6 -8
  111. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  112. package/dist/core/agents/state/live-coordination-view.js +16 -67
  113. package/dist/core/agents/state/live-coordination-writer.d.ts +12 -0
  114. package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -0
  115. package/dist/core/agents/state/live-coordination-writer.js +92 -0
  116. package/dist/core/agents/state/names.d.ts +9 -1
  117. package/dist/core/agents/state/names.d.ts.map +1 -1
  118. package/dist/core/agents/state/names.js +190 -182
  119. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  120. package/dist/core/agents/state/stale-sweep.js +23 -5
  121. package/dist/core/artifacts/constants.d.ts +5 -0
  122. package/dist/core/artifacts/constants.d.ts.map +1 -0
  123. package/dist/core/artifacts/constants.js +4 -0
  124. package/dist/core/artifacts/index.d.ts +24 -3
  125. package/dist/core/artifacts/index.d.ts.map +1 -1
  126. package/dist/core/artifacts/index.js +96 -8
  127. package/dist/core/config.d.ts +62 -4
  128. package/dist/core/config.d.ts.map +1 -1
  129. package/dist/core/config.js +98 -4
  130. package/dist/core/conversations/archive.d.ts +49 -0
  131. package/dist/core/conversations/archive.d.ts.map +1 -0
  132. package/dist/core/conversations/archive.js +136 -0
  133. package/dist/core/conversations/catalog.d.ts +10 -0
  134. package/dist/core/conversations/catalog.d.ts.map +1 -0
  135. package/dist/core/conversations/catalog.js +72 -0
  136. package/dist/core/conversations/context-pack.d.ts +6 -0
  137. package/dist/core/conversations/context-pack.d.ts.map +1 -0
  138. package/dist/core/conversations/context-pack.js +60 -0
  139. package/dist/core/conversations/contract.d.ts +155 -0
  140. package/dist/core/conversations/contract.d.ts.map +1 -0
  141. package/dist/core/conversations/contract.js +1 -0
  142. package/dist/core/conversations/evaluation.d.ts +16 -0
  143. package/dist/core/conversations/evaluation.d.ts.map +1 -0
  144. package/dist/core/conversations/evaluation.js +9 -0
  145. package/dist/core/conversations/index.d.ts +10 -0
  146. package/dist/core/conversations/index.d.ts.map +1 -0
  147. package/dist/core/conversations/index.js +9 -0
  148. package/dist/core/conversations/lifecycle.d.ts +28 -0
  149. package/dist/core/conversations/lifecycle.d.ts.map +1 -0
  150. package/dist/core/conversations/lifecycle.js +29 -0
  151. package/dist/core/conversations/normalize.d.ts +14 -0
  152. package/dist/core/conversations/normalize.d.ts.map +1 -0
  153. package/dist/core/conversations/normalize.js +82 -0
  154. package/dist/core/conversations/query.d.ts +8 -0
  155. package/dist/core/conversations/query.d.ts.map +1 -0
  156. package/dist/core/conversations/query.js +280 -0
  157. package/dist/core/conversations/search-index.d.ts +9 -0
  158. package/dist/core/conversations/search-index.d.ts.map +1 -0
  159. package/dist/core/conversations/search-index.js +29 -0
  160. package/dist/core/events/legacy-storage/canary.d.ts +18 -0
  161. package/dist/core/events/legacy-storage/canary.d.ts.map +1 -0
  162. package/dist/core/events/legacy-storage/canary.js +150 -0
  163. package/dist/core/events/legacy-storage/fence.d.ts +15 -0
  164. package/dist/core/events/legacy-storage/fence.d.ts.map +1 -0
  165. package/dist/core/events/legacy-storage/fence.js +115 -0
  166. package/dist/core/events/legacy-storage/index.d.ts +6 -0
  167. package/dist/core/events/legacy-storage/index.d.ts.map +1 -0
  168. package/dist/core/events/legacy-storage/index.js +5 -0
  169. package/dist/core/events/legacy-storage/inventory.d.ts +10 -0
  170. package/dist/core/events/legacy-storage/inventory.d.ts.map +1 -0
  171. package/dist/core/events/legacy-storage/inventory.js +40 -0
  172. package/dist/core/events/legacy-storage/manifest.d.ts +23 -0
  173. package/dist/core/events/legacy-storage/manifest.d.ts.map +1 -0
  174. package/dist/core/events/legacy-storage/manifest.js +108 -0
  175. package/dist/core/events/legacy-storage/reader.d.ts +15 -0
  176. package/dist/core/events/legacy-storage/reader.d.ts.map +1 -0
  177. package/dist/core/events/legacy-storage/reader.js +154 -0
  178. package/dist/core/events/v3/authority-outbox.d.ts +7 -2
  179. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  180. package/dist/core/events/v3/authority-outbox.js +16 -3
  181. package/dist/core/events/v3/base-contract.d.ts +851 -16
  182. package/dist/core/events/v3/base-contract.d.ts.map +1 -1
  183. package/dist/core/events/v3/base-contract.js +50 -7
  184. package/dist/core/events/v3/bootstrap.d.ts +39 -0
  185. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  186. package/dist/core/events/v3/bootstrap.js +167 -3
  187. package/dist/core/events/v3/capabilities.d.ts +11 -0
  188. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  189. package/dist/core/events/v3/capabilities.js +26 -3
  190. package/dist/core/events/v3/control-witness.d.ts +44 -0
  191. package/dist/core/events/v3/control-witness.d.ts.map +1 -0
  192. package/dist/core/events/v3/control-witness.js +233 -0
  193. package/dist/core/events/v3/control-writer.d.ts +4 -0
  194. package/dist/core/events/v3/control-writer.d.ts.map +1 -0
  195. package/dist/core/events/v3/control-writer.js +16 -0
  196. package/dist/core/events/v3/control.d.ts +8 -2
  197. package/dist/core/events/v3/control.d.ts.map +1 -1
  198. package/dist/core/events/v3/control.js +46 -18
  199. package/dist/core/events/v3/coordination-transaction-recovery.d.ts +42 -0
  200. package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -0
  201. package/dist/core/events/v3/coordination-transaction-recovery.js +342 -0
  202. package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
  203. package/dist/core/events/v3/coordination-view.js +16 -1
  204. package/dist/core/events/v3/generated.d.ts +1 -1
  205. package/dist/core/events/v3/generated.js +1 -1
  206. package/dist/core/events/v3/index.d.ts +8 -5
  207. package/dist/core/events/v3/index.d.ts.map +1 -1
  208. package/dist/core/events/v3/index.js +7 -4
  209. package/dist/core/events/v3/latency.d.ts +31 -1
  210. package/dist/core/events/v3/latency.d.ts.map +1 -1
  211. package/dist/core/events/v3/latency.js +127 -3
  212. package/dist/core/events/v3/live-route-observer.d.ts +31 -0
  213. package/dist/core/events/v3/live-route-observer.d.ts.map +1 -0
  214. package/dist/core/events/v3/live-route-observer.js +58 -0
  215. package/dist/core/events/v3/live-routing.d.ts +42 -20
  216. package/dist/core/events/v3/live-routing.d.ts.map +1 -1
  217. package/dist/core/events/v3/live-routing.js +153 -41
  218. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  219. package/dist/core/events/v3/producers/command-recorder.js +10 -1
  220. package/dist/core/events/v3/producers/coordination-recorder.d.ts +11 -1
  221. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  222. package/dist/core/events/v3/producers/coordination-recorder.js +90 -13
  223. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts +129 -0
  224. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -0
  225. package/dist/core/events/v3/producers/diagnostic-summaries.js +499 -0
  226. package/dist/core/events/v3/producers/hook-base.d.ts +17 -1
  227. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  228. package/dist/core/events/v3/producers/hook-base.js +83 -2
  229. package/dist/core/events/v3/producers/intake.d.ts +13 -0
  230. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  231. package/dist/core/events/v3/producers/intake.js +36 -2
  232. package/dist/core/events/v3/producers/producer-state-observer.d.ts +8 -0
  233. package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -0
  234. package/dist/core/events/v3/producers/producer-state-observer.js +45 -0
  235. package/dist/core/events/v3/producers/recorder.d.ts +117 -1
  236. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  237. package/dist/core/events/v3/producers/recorder.js +992 -27
  238. package/dist/core/events/v3/reader.d.ts +51 -0
  239. package/dist/core/events/v3/reader.d.ts.map +1 -1
  240. package/dist/core/events/v3/reader.js +181 -1
  241. package/dist/core/events/v3/rotation-config.d.ts +9 -0
  242. package/dist/core/events/v3/rotation-config.d.ts.map +1 -0
  243. package/dist/core/events/v3/rotation-config.js +91 -0
  244. package/dist/core/events/v3/runtime-build.d.ts +11 -0
  245. package/dist/core/events/v3/runtime-build.d.ts.map +1 -0
  246. package/dist/core/events/v3/runtime-build.js +39 -0
  247. package/dist/core/events/v3/runtime-identity.d.ts +5 -0
  248. package/dist/core/events/v3/runtime-identity.d.ts.map +1 -0
  249. package/dist/core/events/v3/runtime-identity.js +18 -0
  250. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +52 -0
  251. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -0
  252. package/dist/core/events/v3/runtime-telemetry-capabilities.js +54 -0
  253. package/dist/core/events/v3/support-storage/classify.d.ts +46 -0
  254. package/dist/core/events/v3/support-storage/classify.d.ts.map +1 -0
  255. package/dist/core/events/v3/support-storage/classify.js +149 -0
  256. package/dist/core/events/v3/support-storage/eligibility.d.ts +29 -0
  257. package/dist/core/events/v3/support-storage/eligibility.d.ts.map +1 -0
  258. package/dist/core/events/v3/support-storage/eligibility.js +35 -0
  259. package/dist/core/events/v3/support-storage/index.d.ts +10 -0
  260. package/dist/core/events/v3/support-storage/index.d.ts.map +1 -0
  261. package/dist/core/events/v3/support-storage/index.js +9 -0
  262. package/dist/core/events/v3/support-storage/inventory.d.ts +30 -0
  263. package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -0
  264. package/dist/core/events/v3/support-storage/inventory.js +94 -0
  265. package/dist/core/events/v3/support-storage/logical-authority.d.ts +14 -0
  266. package/dist/core/events/v3/support-storage/logical-authority.d.ts.map +1 -0
  267. package/dist/core/events/v3/support-storage/logical-authority.js +104 -0
  268. package/dist/core/events/v3/support-storage/maintenance.d.ts +98 -0
  269. package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -0
  270. package/dist/core/events/v3/support-storage/maintenance.js +352 -0
  271. package/dist/core/events/v3/support-storage/pack-contract.d.ts +59 -0
  272. package/dist/core/events/v3/support-storage/pack-contract.d.ts.map +1 -0
  273. package/dist/core/events/v3/support-storage/pack-contract.js +249 -0
  274. package/dist/core/events/v3/support-storage/pack-reader.d.ts +34 -0
  275. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -0
  276. package/dist/core/events/v3/support-storage/pack-reader.js +258 -0
  277. package/dist/core/events/v3/support-storage/pack-writer.d.ts +30 -0
  278. package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -0
  279. package/dist/core/events/v3/support-storage/pack-writer.js +268 -0
  280. package/dist/core/events/v3/support-storage/recovery.d.ts +15 -0
  281. package/dist/core/events/v3/support-storage/recovery.d.ts.map +1 -0
  282. package/dist/core/events/v3/support-storage/recovery.js +22 -0
  283. package/dist/core/events/v3/turn-telemetry.d.ts +21 -6
  284. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
  285. package/dist/core/events/v3/turn-telemetry.js +32 -2
  286. package/dist/core/events/v3/writer.d.ts +13 -1
  287. package/dist/core/events/v3/writer.d.ts.map +1 -1
  288. package/dist/core/events/v3/writer.js +126 -12
  289. package/dist/core/governor/plan-read.d.ts.map +1 -1
  290. package/dist/core/governor/plan-read.js +5 -21
  291. package/dist/core/governor/planning.js +6 -8
  292. package/dist/core/governor/service-read.d.ts +12 -0
  293. package/dist/core/governor/service-read.d.ts.map +1 -1
  294. package/dist/core/governor/service-read.js +266 -2
  295. package/dist/core/governor/service.d.ts +1 -0
  296. package/dist/core/governor/service.d.ts.map +1 -1
  297. package/dist/core/governor/service.js +53 -18
  298. package/dist/core/guard/evidence-v3.d.ts.map +1 -1
  299. package/dist/core/guard/evidence-v3.js +2 -0
  300. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  301. package/dist/core/hooks/adapter/events.js +1 -0
  302. package/dist/core/hooks/adapter/output.d.ts +4 -2
  303. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  304. package/dist/core/hooks/adapter/output.js +13 -5
  305. package/dist/core/hooks/adapter/parse.d.ts +3 -0
  306. package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
  307. package/dist/core/hooks/adapter/parse.js +14 -0
  308. package/dist/core/hooks/adapter/runtime-telemetry.d.ts +142 -0
  309. package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -0
  310. package/dist/core/hooks/adapter/runtime-telemetry.js +869 -0
  311. package/dist/core/hooks/cli.js +318 -61
  312. package/dist/core/hooks/effects/image-capture.d.ts +1 -1
  313. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  314. package/dist/core/hooks/effects/image-capture.js +4 -2
  315. package/dist/core/hooks/remediation-cap.d.ts +39 -0
  316. package/dist/core/hooks/remediation-cap.d.ts.map +1 -0
  317. package/dist/core/hooks/remediation-cap.js +63 -0
  318. package/dist/core/hooks/resolve/coord-root.d.ts +22 -9
  319. package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
  320. package/dist/core/hooks/resolve/coord-root.js +92 -11
  321. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  322. package/dist/core/hooks/resolve/owner.js +5 -0
  323. package/dist/core/hooks/resolve/transcript.d.ts +33 -9
  324. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  325. package/dist/core/hooks/resolve/transcript.js +33 -10
  326. package/dist/core/inbox/contract.d.ts +64 -0
  327. package/dist/core/inbox/contract.d.ts.map +1 -0
  328. package/dist/core/inbox/contract.js +13 -0
  329. package/dist/core/inbox/index.d.ts +5 -0
  330. package/dist/core/inbox/index.d.ts.map +1 -0
  331. package/dist/core/inbox/index.js +4 -0
  332. package/dist/core/inbox/lifecycle.d.ts +22 -0
  333. package/dist/core/inbox/lifecycle.d.ts.map +1 -0
  334. package/dist/core/inbox/lifecycle.js +41 -0
  335. package/dist/core/inbox/service.d.ts +36 -0
  336. package/dist/core/inbox/service.d.ts.map +1 -0
  337. package/dist/core/inbox/service.js +210 -0
  338. package/dist/core/inbox/watcher.d.ts +7 -0
  339. package/dist/core/inbox/watcher.d.ts.map +1 -0
  340. package/dist/core/inbox/watcher.js +26 -0
  341. package/dist/core/presence/codec-digest.d.ts.map +1 -1
  342. package/dist/core/presence/codec-digest.js +14 -3
  343. package/dist/core/presence/relay-client.d.ts +1 -0
  344. package/dist/core/presence/relay-client.d.ts.map +1 -1
  345. package/dist/core/presence/relay-client.js +52 -8
  346. package/dist/core/semantic/adapters.d.ts +37 -0
  347. package/dist/core/semantic/adapters.d.ts.map +1 -0
  348. package/dist/core/semantic/adapters.js +360 -0
  349. package/dist/core/semantic/contract.d.ts +1072 -0
  350. package/dist/core/semantic/contract.d.ts.map +1 -0
  351. package/dist/core/semantic/contract.js +331 -0
  352. package/dist/core/semantic/evidence.d.ts +11 -0
  353. package/dist/core/semantic/evidence.d.ts.map +1 -0
  354. package/dist/core/semantic/evidence.js +262 -0
  355. package/dist/core/semantic/index.d.ts +14 -0
  356. package/dist/core/semantic/index.d.ts.map +1 -0
  357. package/dist/core/semantic/index.js +13 -0
  358. package/dist/core/semantic/once.d.ts +38 -0
  359. package/dist/core/semantic/once.d.ts.map +1 -0
  360. package/dist/core/semantic/once.js +364 -0
  361. package/dist/core/semantic/prompt.d.ts +12 -0
  362. package/dist/core/semantic/prompt.d.ts.map +1 -0
  363. package/dist/core/semantic/prompt.js +83 -0
  364. package/dist/core/semantic/review.d.ts +144 -0
  365. package/dist/core/semantic/review.d.ts.map +1 -0
  366. package/dist/core/semantic/review.js +544 -0
  367. package/dist/core/semantic/routes.d.ts +10 -0
  368. package/dist/core/semantic/routes.d.ts.map +1 -0
  369. package/dist/core/semantic/routes.js +21 -0
  370. package/dist/core/semantic/scheduler.d.ts +27 -0
  371. package/dist/core/semantic/scheduler.d.ts.map +1 -0
  372. package/dist/core/semantic/scheduler.js +91 -0
  373. package/dist/core/semantic/service-status.d.ts +51 -0
  374. package/dist/core/semantic/service-status.d.ts.map +1 -0
  375. package/dist/core/semantic/service-status.js +140 -0
  376. package/dist/core/semantic/service.d.ts +52 -0
  377. package/dist/core/semantic/service.d.ts.map +1 -0
  378. package/dist/core/semantic/service.js +559 -0
  379. package/dist/core/semantic/soak.d.ts +75 -0
  380. package/dist/core/semantic/soak.d.ts.map +1 -0
  381. package/dist/core/semantic/soak.js +476 -0
  382. package/dist/core/semantic/storage.d.ts +81 -0
  383. package/dist/core/semantic/storage.d.ts.map +1 -0
  384. package/dist/core/semantic/storage.js +180 -0
  385. package/dist/core/semantic/usage.d.ts +43 -0
  386. package/dist/core/semantic/usage.d.ts.map +1 -0
  387. package/dist/core/semantic/usage.js +193 -0
  388. package/dist/core/semantic/validate.d.ts +18 -0
  389. package/dist/core/semantic/validate.d.ts.map +1 -0
  390. package/dist/core/semantic/validate.js +207 -0
  391. package/dist/core/storage/buffer.d.ts +28 -0
  392. package/dist/core/storage/buffer.d.ts.map +1 -0
  393. package/dist/core/storage/buffer.js +101 -0
  394. package/dist/core/storage/builtins.d.ts +3 -0
  395. package/dist/core/storage/builtins.d.ts.map +1 -0
  396. package/dist/core/storage/builtins.js +683 -0
  397. package/dist/core/storage/catalog.d.ts +19 -0
  398. package/dist/core/storage/catalog.d.ts.map +1 -0
  399. package/dist/core/storage/catalog.js +365 -0
  400. package/dist/core/storage/config.d.ts +16 -0
  401. package/dist/core/storage/config.d.ts.map +1 -0
  402. package/dist/core/storage/config.js +311 -0
  403. package/dist/core/storage/contract.d.ts +275 -0
  404. package/dist/core/storage/contract.d.ts.map +1 -0
  405. package/dist/core/storage/contract.js +3 -0
  406. package/dist/core/storage/durable-history.d.ts +36 -0
  407. package/dist/core/storage/durable-history.d.ts.map +1 -0
  408. package/dist/core/storage/durable-history.js +606 -0
  409. package/dist/core/storage/health.d.ts +4 -0
  410. package/dist/core/storage/health.d.ts.map +1 -0
  411. package/dist/core/storage/health.js +65 -0
  412. package/dist/core/storage/index.d.ts +16 -0
  413. package/dist/core/storage/index.d.ts.map +1 -0
  414. package/dist/core/storage/index.js +15 -0
  415. package/dist/core/storage/inventory.d.ts +25 -0
  416. package/dist/core/storage/inventory.d.ts.map +1 -0
  417. package/dist/core/storage/inventory.js +666 -0
  418. package/dist/core/storage/jsonl.d.ts +52 -0
  419. package/dist/core/storage/jsonl.d.ts.map +1 -0
  420. package/dist/core/storage/jsonl.js +156 -0
  421. package/dist/core/storage/log-retention.d.ts +52 -0
  422. package/dist/core/storage/log-retention.d.ts.map +1 -0
  423. package/dist/core/storage/log-retention.js +419 -0
  424. package/dist/core/storage/logger.d.ts +82 -0
  425. package/dist/core/storage/logger.d.ts.map +1 -0
  426. package/dist/core/storage/logger.js +411 -0
  427. package/dist/core/storage/maintenance-providers.d.ts +26 -0
  428. package/dist/core/storage/maintenance-providers.d.ts.map +1 -0
  429. package/dist/core/storage/maintenance-providers.js +141 -0
  430. package/dist/core/storage/maintenance.d.ts +125 -0
  431. package/dist/core/storage/maintenance.d.ts.map +1 -0
  432. package/dist/core/storage/maintenance.js +609 -0
  433. package/dist/core/storage/metrics.d.ts +60 -0
  434. package/dist/core/storage/metrics.d.ts.map +1 -0
  435. package/dist/core/storage/metrics.js +134 -0
  436. package/dist/core/storage/policy.d.ts +7 -0
  437. package/dist/core/storage/policy.d.ts.map +1 -0
  438. package/dist/core/storage/policy.js +110 -0
  439. package/dist/core/storage/process-log.d.ts +38 -0
  440. package/dist/core/storage/process-log.d.ts.map +1 -0
  441. package/dist/core/storage/process-log.js +165 -0
  442. package/dist/core/storage/query.d.ts +34 -0
  443. package/dist/core/storage/query.d.ts.map +1 -0
  444. package/dist/core/storage/query.js +295 -0
  445. package/dist/core/storage/receipts.d.ts +23 -0
  446. package/dist/core/storage/receipts.d.ts.map +1 -0
  447. package/dist/core/storage/receipts.js +117 -0
  448. package/dist/core/storage/segments.d.ts +84 -0
  449. package/dist/core/storage/segments.d.ts.map +1 -0
  450. package/dist/core/storage/segments.js +542 -0
  451. package/dist/core/storage/sink-graph.d.ts +65 -0
  452. package/dist/core/storage/sink-graph.d.ts.map +1 -0
  453. package/dist/core/storage/sink-graph.js +213 -0
  454. package/dist/core/storage/storm-control.d.ts +23 -0
  455. package/dist/core/storage/storm-control.d.ts.map +1 -0
  456. package/dist/core/storage/storm-control.js +59 -0
  457. package/dist/core/work/state.d.ts.map +1 -1
  458. package/dist/core/work/state.js +10 -14
  459. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  460. package/dist/core/workflow/live-session-v3.js +2 -1
  461. package/dist/index.d.ts +2 -0
  462. package/dist/index.d.ts.map +1 -1
  463. package/dist/index.js +2 -0
  464. package/dist/lazy-commands.d.ts +26 -0
  465. package/dist/lazy-commands.d.ts.map +1 -0
  466. package/dist/lazy-commands.js +210 -0
  467. package/dist/lib/browser/client.d.ts +11 -0
  468. package/dist/lib/browser/client.d.ts.map +1 -1
  469. package/dist/lib/browser/client.js +13 -0
  470. package/dist/lib/browser/index.d.ts +1 -0
  471. package/dist/lib/browser/index.d.ts.map +1 -1
  472. package/dist/lib/browser/standalone-html.d.ts +25 -0
  473. package/dist/lib/browser/standalone-html.d.ts.map +1 -0
  474. package/dist/lib/browser/standalone-html.js +284 -0
  475. package/dist/lib/docs-lint.d.ts +2 -0
  476. package/dist/lib/docs-lint.d.ts.map +1 -1
  477. package/dist/lib/docs-lint.js +45 -80
  478. package/dist/lib/docs-metadata-audit.d.ts +3 -0
  479. package/dist/lib/docs-metadata-audit.d.ts.map +1 -1
  480. package/dist/lib/docs-metadata-audit.js +13 -23
  481. package/dist/lib/docs-metadata-sync.d.ts +1 -0
  482. package/dist/lib/docs-metadata-sync.d.ts.map +1 -1
  483. package/dist/lib/docs-metadata-sync.js +28 -10
  484. package/dist/lib/docs-repository-view.d.ts +22 -0
  485. package/dist/lib/docs-repository-view.d.ts.map +1 -0
  486. package/dist/lib/docs-repository-view.js +185 -0
  487. package/dist/lib/http/client.d.ts +11 -5
  488. package/dist/lib/http/client.d.ts.map +1 -1
  489. package/dist/lib/http/client.js +22 -4
  490. package/dist/lib/http/index.d.ts +1 -1
  491. package/dist/lib/http/index.d.ts.map +1 -1
  492. package/dist/lib/http/index.js +1 -1
  493. package/dist/lib/indexer-exclusions.d.ts +27 -0
  494. package/dist/lib/indexer-exclusions.d.ts.map +1 -0
  495. package/dist/lib/indexer-exclusions.js +176 -0
  496. package/dist/lib/instructions/apply.d.ts.map +1 -1
  497. package/dist/lib/instructions/apply.js +1 -0
  498. package/dist/lib/instructions/templates.d.ts +2 -0
  499. package/dist/lib/instructions/templates.d.ts.map +1 -1
  500. package/dist/lib/instructions/templates.js +149 -4
  501. package/dist/lib/local-file-url.d.ts +9 -0
  502. package/dist/lib/local-file-url.d.ts.map +1 -0
  503. package/dist/lib/local-file-url.js +20 -0
  504. package/dist/lib/web-performance.d.ts +118 -0
  505. package/dist/lib/web-performance.d.ts.map +1 -0
  506. package/dist/lib/web-performance.js +192 -0
  507. package/package.json +34 -2
  508. package/schemas/config.schema.json +58 -0
  509. package/schemas/event-v3.schema.json +3073 -581
  510. package/src/commander.ts +462 -93
  511. package/src/commands/agents.ts +617 -355
  512. package/src/commands/backup.ts +18 -14
  513. package/src/commands/browse-session.ts +12 -0
  514. package/src/commands/browse.ts +31 -9
  515. package/src/commands/conversations.ts +279 -0
  516. package/src/commands/decision.ts +8 -2
  517. package/src/commands/deinit.ts +6 -0
  518. package/src/commands/docs.ts +25 -6
  519. package/src/commands/doctor.ts +75 -9
  520. package/src/commands/events.ts +21 -1
  521. package/src/commands/fetch.ts +7 -6
  522. package/src/commands/files.ts +143 -0
  523. package/src/commands/governor.ts +13 -12
  524. package/src/commands/inbox.ts +61 -0
  525. package/src/commands/init.ts +78 -16
  526. package/src/commands/ledger-v3.ts +421 -1
  527. package/src/commands/logs.ts +224 -0
  528. package/src/commands/messages.ts +61 -0
  529. package/src/commands/outline.ts +6 -2
  530. package/src/commands/presence.ts +7 -2
  531. package/src/commands/read.ts +6 -2
  532. package/src/commands/semantic.ts +244 -0
  533. package/src/commands/storage.ts +310 -0
  534. package/src/commands/tunnel.ts +66 -52
  535. package/src/commands/web.ts +92 -7
  536. package/src/commands/work.ts +3 -3
  537. package/src/commands/workflow.ts +13 -13
  538. package/src/core/agents/canonical-emit.ts +15 -0
  539. package/src/core/agents/claim-path.ts +23 -0
  540. package/src/core/agents/cli.ts +259 -53
  541. package/src/core/agents/coord-client.ts +92 -8
  542. package/src/core/agents/live-authority-v3.ts +342 -14
  543. package/src/core/agents/live-lifecycle-v3.ts +14 -4
  544. package/src/core/agents/live-observation-v3.ts +13 -3
  545. package/src/core/agents/render/prompt-context.ts +40 -16
  546. package/src/core/agents/rules/stop-hook.ts +129 -25
  547. package/src/core/agents/rules/verdict.ts +1 -0
  548. package/src/core/agents/session-events.ts +4 -0
  549. package/src/core/agents/session-finalization-state-v3.ts +1 -1
  550. package/src/core/agents/session-finalizer-v3.ts +4 -1
  551. package/src/core/agents/session-name-display.ts +9 -1
  552. package/src/core/agents/state/activity-log.ts +7 -2
  553. package/src/core/agents/state/heartbeat-reader.ts +69 -0
  554. package/src/core/agents/state/heartbeat-writer.ts +47 -84
  555. package/src/core/agents/state/live-coordination-view.ts +17 -81
  556. package/src/core/agents/state/live-coordination-writer.ts +141 -0
  557. package/src/core/agents/state/names.ts +190 -182
  558. package/src/core/agents/state/stale-sweep.ts +25 -5
  559. package/src/core/artifacts/constants.ts +4 -0
  560. package/src/core/artifacts/index.ts +113 -8
  561. package/src/core/config.ts +126 -5
  562. package/src/core/conversations/archive.ts +237 -0
  563. package/src/core/conversations/catalog.ts +79 -0
  564. package/src/core/conversations/context-pack.ts +72 -0
  565. package/src/core/conversations/contract.ts +178 -0
  566. package/src/core/conversations/evaluation.ts +30 -0
  567. package/src/core/conversations/index.ts +9 -0
  568. package/src/core/conversations/lifecycle.ts +63 -0
  569. package/src/core/conversations/normalize.ts +105 -0
  570. package/src/core/conversations/query.ts +318 -0
  571. package/src/core/conversations/search-index.ts +48 -0
  572. package/src/core/events/legacy-storage/canary.ts +177 -0
  573. package/src/core/events/legacy-storage/fence.ts +129 -0
  574. package/src/core/events/legacy-storage/index.ts +5 -0
  575. package/src/core/events/legacy-storage/inventory.ts +51 -0
  576. package/src/core/events/legacy-storage/manifest.ts +136 -0
  577. package/src/core/events/legacy-storage/reader.ts +178 -0
  578. package/src/core/events/v3/authority-outbox.ts +22 -1
  579. package/src/core/events/v3/base-contract.ts +56 -7
  580. package/src/core/events/v3/bootstrap.ts +195 -2
  581. package/src/core/events/v3/capabilities.ts +37 -3
  582. package/src/core/events/v3/control-witness.ts +339 -0
  583. package/src/core/events/v3/control-writer.ts +16 -0
  584. package/src/core/events/v3/control.ts +54 -18
  585. package/src/core/events/v3/coordination-transaction-recovery.ts +477 -0
  586. package/src/core/events/v3/coordination-view.ts +17 -1
  587. package/src/core/events/v3/generated.ts +1 -1
  588. package/src/core/events/v3/index.ts +26 -2
  589. package/src/core/events/v3/latency.ts +213 -2
  590. package/src/core/events/v3/live-route-observer.ts +80 -0
  591. package/src/core/events/v3/live-routing.ts +182 -45
  592. package/src/core/events/v3/producers/command-recorder.ts +10 -1
  593. package/src/core/events/v3/producers/coordination-recorder.ts +112 -15
  594. package/src/core/events/v3/producers/diagnostic-summaries.ts +593 -0
  595. package/src/core/events/v3/producers/hook-base.ts +116 -2
  596. package/src/core/events/v3/producers/intake.ts +48 -2
  597. package/src/core/events/v3/producers/producer-state-observer.ts +52 -0
  598. package/src/core/events/v3/producers/recorder.ts +1403 -30
  599. package/src/core/events/v3/reader.ts +243 -2
  600. package/src/core/events/v3/rotation-config.ts +98 -0
  601. package/src/core/events/v3/runtime-build.ts +41 -0
  602. package/src/core/events/v3/runtime-identity.ts +16 -0
  603. package/src/core/events/v3/runtime-telemetry-capabilities.ts +143 -0
  604. package/src/core/events/v3/support-storage/classify.ts +209 -0
  605. package/src/core/events/v3/support-storage/eligibility.ts +58 -0
  606. package/src/core/events/v3/support-storage/index.ts +9 -0
  607. package/src/core/events/v3/support-storage/inventory.ts +135 -0
  608. package/src/core/events/v3/support-storage/logical-authority.ts +117 -0
  609. package/src/core/events/v3/support-storage/maintenance.ts +501 -0
  610. package/src/core/events/v3/support-storage/pack-contract.ts +337 -0
  611. package/src/core/events/v3/support-storage/pack-reader.ts +346 -0
  612. package/src/core/events/v3/support-storage/pack-writer.ts +352 -0
  613. package/src/core/events/v3/support-storage/recovery.ts +43 -0
  614. package/src/core/events/v3/turn-telemetry.ts +66 -5
  615. package/src/core/events/v3/writer.ts +168 -16
  616. package/src/core/governor/plan-read.ts +5 -18
  617. package/src/core/governor/planning.ts +5 -8
  618. package/src/core/governor/service-read.ts +320 -2
  619. package/src/core/governor/service.ts +49 -22
  620. package/src/core/guard/evidence-v3.ts +1 -0
  621. package/src/core/hooks/adapter/events.ts +1 -0
  622. package/src/core/hooks/adapter/output.ts +12 -5
  623. package/src/core/hooks/adapter/parse.ts +16 -0
  624. package/src/core/hooks/adapter/runtime-telemetry.ts +1200 -0
  625. package/src/core/hooks/cli.ts +342 -64
  626. package/src/core/hooks/effects/image-capture.ts +4 -1
  627. package/src/core/hooks/remediation-cap.ts +83 -0
  628. package/src/core/hooks/resolve/coord-root.ts +91 -11
  629. package/src/core/hooks/resolve/owner.ts +4 -0
  630. package/src/core/hooks/resolve/transcript.ts +55 -11
  631. package/src/core/inbox/contract.ts +81 -0
  632. package/src/core/inbox/index.ts +4 -0
  633. package/src/core/inbox/lifecycle.ts +104 -0
  634. package/src/core/inbox/service.ts +305 -0
  635. package/src/core/inbox/watcher.ts +36 -0
  636. package/src/core/presence/codec-digest.ts +15 -9
  637. package/src/core/presence/relay-client.ts +55 -7
  638. package/src/core/semantic/adapters.ts +452 -0
  639. package/src/core/semantic/contract.ts +430 -0
  640. package/src/core/semantic/evidence.ts +336 -0
  641. package/src/core/semantic/index.ts +201 -0
  642. package/src/core/semantic/once.ts +496 -0
  643. package/src/core/semantic/prompt.ts +96 -0
  644. package/src/core/semantic/review.ts +803 -0
  645. package/src/core/semantic/routes.ts +30 -0
  646. package/src/core/semantic/scheduler.ts +151 -0
  647. package/src/core/semantic/service-status.ts +212 -0
  648. package/src/core/semantic/service.ts +681 -0
  649. package/src/core/semantic/soak.ts +638 -0
  650. package/src/core/semantic/storage.ts +300 -0
  651. package/src/core/semantic/usage.ts +272 -0
  652. package/src/core/semantic/validate.ts +243 -0
  653. package/src/core/storage/buffer.ts +124 -0
  654. package/src/core/storage/builtins.ts +916 -0
  655. package/src/core/storage/catalog.ts +467 -0
  656. package/src/core/storage/config.ts +423 -0
  657. package/src/core/storage/contract.ts +342 -0
  658. package/src/core/storage/durable-history.ts +738 -0
  659. package/src/core/storage/health.ts +76 -0
  660. package/src/core/storage/index.ts +15 -0
  661. package/src/core/storage/inventory.ts +859 -0
  662. package/src/core/storage/jsonl.ts +213 -0
  663. package/src/core/storage/log-retention.ts +555 -0
  664. package/src/core/storage/logger.ts +546 -0
  665. package/src/core/storage/maintenance-providers.ts +200 -0
  666. package/src/core/storage/maintenance.ts +929 -0
  667. package/src/core/storage/metrics.ts +199 -0
  668. package/src/core/storage/policy.ts +141 -0
  669. package/src/core/storage/process-log.ts +203 -0
  670. package/src/core/storage/query.ts +360 -0
  671. package/src/core/storage/receipts.ts +162 -0
  672. package/src/core/storage/segments.ts +721 -0
  673. package/src/core/storage/sink-graph.ts +343 -0
  674. package/src/core/storage/storm-control.ts +91 -0
  675. package/src/core/work/state.ts +12 -21
  676. package/src/core/workflow/live-session-v3.ts +2 -4
  677. package/src/index.ts +2 -0
  678. package/src/lazy-commands.ts +294 -0
  679. package/src/lib/browser/client.ts +21 -0
  680. package/src/lib/browser/index.ts +4 -0
  681. package/src/lib/browser/standalone-html.ts +312 -0
  682. package/src/lib/docs-lint.ts +58 -77
  683. package/src/lib/docs-metadata-audit.ts +26 -21
  684. package/src/lib/docs-metadata-sync.ts +32 -9
  685. package/src/lib/docs-repository-view.ts +220 -0
  686. package/src/lib/http/client.ts +44 -8
  687. package/src/lib/http/index.ts +6 -1
  688. package/src/lib/indexer-exclusions.ts +173 -0
  689. package/src/lib/instructions/apply.ts +1 -0
  690. package/src/lib/instructions/templates.ts +154 -4
  691. package/src/lib/local-file-url.ts +31 -0
  692. package/src/lib/web-performance.ts +335 -0
@@ -30,6 +30,8 @@ export interface StopHookRequest {
30
30
  adapter?: string;
31
31
  now_ms?: number;
32
32
  turn_window?: { start_ms: number; end_ms: number };
33
+ stop_hook_active?: boolean;
34
+ status_box_present_strict?: boolean;
33
35
  bypass?: boolean;
34
36
  workflow_child?: boolean;
35
37
  }
@@ -107,15 +109,24 @@ export function evaluateStopHookV3Events(
107
109
  "generation_id" in event.scope &&
108
110
  event.scope.generation_id === generationId,
109
111
  );
112
+ const fallbackStartMs = Math.max(0, endMs - 5 * 60 * 1000);
113
+ const claudeContinuation = req.adapter === "claude-code" && req.stop_hook_active === true;
114
+ const resolvedStart = resolveTurnStart(ownerEvents, endMs, claudeContinuation);
115
+ const resolvedStartMs = eventTimeMs(resolvedStart);
110
116
  const startMs =
111
117
  req.turn_window?.start_ms ??
112
- resolveTurnStartMs(ownerEvents, endMs, Math.max(0, endMs - 5 * 60 * 1000));
118
+ (Number.isFinite(resolvedStartMs) ? resolvedStartMs : fallbackStartMs);
113
119
  const inTurn = ownerEvents.filter((event) => {
114
120
  const time = eventTimeMs(event);
115
121
  return Number.isFinite(time) && time >= startMs && time <= endMs;
116
122
  });
117
123
 
118
- const usedTool = inTurn.some((event) => event.event_type === "tool.requested");
124
+ const policyEvents =
125
+ claudeContinuation && resolvedStart
126
+ ? originalTurnEvents(ownerEvents, resolvedStart, endMs)
127
+ : inTurn;
128
+ const usedTool = policyEvents.some((event) => event.event_type === "tool.requested");
129
+ const cycleAnchor = remediationCycleAnchor(resolvedStart, startMs);
119
130
  const statusEvents = inTurn.filter(
120
131
  (event) =>
121
132
  event.event_type === "coord.status_observed" && event.payload.subject_instance_id === owner,
@@ -138,21 +149,32 @@ export function evaluateStopHookV3Events(
138
149
  event.event_type === "turn.completed",
139
150
  );
140
151
  const latestTerminal = turnTerminals.at(-1);
141
- const latestBox = observedBoolean(latestTerminal?.payload.ritual?.status_box_present);
142
- if (req.adapter !== "cursor" && latestBox === undefined) {
152
+ const latestBox = observedBoolean(latestTerminal?.payload.ritual?.status_box_present_strict);
153
+ const strictBoxObservations = turnTerminals
154
+ .map((event) => observedBoolean(event.payload.ritual?.status_box_present_strict))
155
+ .filter((value): value is boolean => value !== undefined);
156
+ const currentStrictBox = claudeContinuation ? req.status_box_present_strict : undefined;
157
+ if (req.adapter !== "cursor" && latestBox === undefined && currentStrictBox === undefined) {
143
158
  return evidenceUnavailable(
144
- "turn.completed has no observed V3 status-box result; Stop remains fail-open",
159
+ "turn.completed has no observed V3 assistant-text status-box result; Stop remains fail-open",
145
160
  );
146
161
  }
147
162
 
148
- const ackPresent = req.adapter === "cursor" ? requiredStatusChecked : latestBox === true;
163
+ const ackPresent =
164
+ req.adapter === "cursor"
165
+ ? requiredStatusChecked
166
+ : claudeContinuation
167
+ ? strictBoxObservations.includes(true) || currentStrictBox === true
168
+ : latestBox === true;
149
169
  const ackBlock =
150
- req.adapter === "cursor" ? () => rule13Block(coordRoot) : () => rule23Block(coordRoot);
170
+ req.adapter === "cursor"
171
+ ? () => rule13Block(coordRoot, req.session_id)
172
+ : () => rule23Block(coordRoot, req.session_id);
151
173
 
152
174
  // Pure prose turns keep the human-visible acknowledgement but do not require
153
175
  // task or final-status mutations. This preserves the pre-V3 policy exactly.
154
176
  if (!usedTool) {
155
- if (!ackPresent) return ackBlock();
177
+ if (!ackPresent) return withCycleAnchor(ackBlock(), cycleAnchor);
156
178
  return {
157
179
  allow: true,
158
180
  exit_code: 0,
@@ -161,9 +183,14 @@ export function evaluateStopHookV3Events(
161
183
  };
162
184
  }
163
185
 
164
- if (!requiredStatusChecked) return rule13Block(coordRoot);
165
- if (!ackPresent) return ackBlock();
166
- if (!taskSet) return rule33Block(coordRoot);
186
+ // Collect EVERY missing signal before returning. Reporting them one at a
187
+ // time made each additional missing signal cost a whole continuation, and
188
+ // every continuation forks a fresh hook process: on a busy multi-agent host
189
+ // the ritual's own enforcement became part of the hook load it polices.
190
+ const pending: VerdictResult[] = [];
191
+ if (!requiredStatusChecked) pending.push(rule13Block(coordRoot, req.session_id));
192
+ if (!ackPresent) pending.push(ackBlock());
193
+ if (!taskSet) pending.push(rule33Block(coordRoot, req.session_id));
167
194
 
168
195
  // Claude Code can prove session-name presentation from assistant-only text.
169
196
  // Cursor cannot expose that text and Codex returned observe-only above.
@@ -176,10 +203,13 @@ export function evaluateStopHookV3Events(
176
203
  !naming.some(({ present }) => present) &&
177
204
  !sessionNameSeenStamped(coordRoot, req.instance_id)
178
205
  ) {
179
- return sessionNameBlock(coordRoot, req.instance_id);
206
+ pending.push(sessionNameBlock(coordRoot, req.instance_id));
180
207
  }
181
208
  }
182
209
 
210
+ const blocked = mergeStopBlocks(pending);
211
+ if (blocked) return withCycleAnchor(blocked, cycleAnchor);
212
+
183
213
  return { allow: true, exit_code: 0, rule: "stop-hook.pass" };
184
214
  }
185
215
 
@@ -211,29 +241,65 @@ function unconditionalVerdict(req: StopHookRequest): VerdictResult | undefined {
211
241
  return undefined;
212
242
  }
213
243
 
214
- function resolveTurnStartMs(
244
+ function resolveTurnStart(
215
245
  ownerEvents: readonly EventV3[],
216
246
  nowMs: number,
217
- fallbackMs: number,
218
- ): number {
247
+ claudeContinuation: boolean,
248
+ ): Extract<EventV3, { event_type: "turn.started" }> | undefined {
219
249
  const turns = ownerEvents.filter(
220
250
  (event): event is Extract<EventV3, { event_type: "turn.started" }> =>
221
251
  event.event_type === "turn.started" && eventTimeMs(event) <= nowMs,
222
252
  );
223
- if (turns.length === 0) return fallbackMs;
253
+ if (turns.length === 0) return undefined;
224
254
 
225
255
  let index = turns.length - 1;
226
256
  let hops = 0;
227
257
  while (index > 0 && hops < MAX_REMEDIATION_WALK_BACK) {
228
258
  const turn = turns[index];
229
- if (!turn?.payload.stop_remediation) break;
259
+ const continuesCycle = claudeContinuation
260
+ ? turn?.provenance.source_event === "claude-code.recovery" &&
261
+ turn.provenance.attestation === "derived"
262
+ : turn?.payload.stop_remediation === true;
263
+ if (!continuesCycle) break;
230
264
  index -= 1;
231
265
  hops += 1;
232
266
  }
233
- return eventTimeMs(turns[index]!);
267
+ return turns[index];
268
+ }
269
+
270
+ function originalTurnEvents(
271
+ ownerEvents: readonly EventV3[],
272
+ turnStart: Extract<EventV3, { event_type: "turn.started" }> | undefined,
273
+ endMs: number,
274
+ ): EventV3[] {
275
+ if (!turnStart) return [];
276
+ const startMs = eventTimeMs(turnStart);
277
+ const terminal = ownerEvents.find(
278
+ (event) => event.event_type === "turn.completed" && eventTimeMs(event) >= startMs,
279
+ );
280
+ const policyEndMs = terminal ? eventTimeMs(terminal) : endMs;
281
+ return ownerEvents.filter((event) => {
282
+ const time = eventTimeMs(event);
283
+ return time >= startMs && time <= policyEndMs;
284
+ });
285
+ }
286
+
287
+ function remediationCycleAnchor(
288
+ turnStart: Extract<EventV3, { event_type: "turn.started" }> | undefined,
289
+ startMs: number,
290
+ ): string {
291
+ if (turnStart && "turn_id" in turnStart.scope && turnStart.scope.turn_id) {
292
+ return turnStart.scope.turn_id;
293
+ }
294
+ return new Date(startMs).toISOString();
295
+ }
296
+
297
+ function withCycleAnchor(verdict: VerdictResult, anchor: string): VerdictResult {
298
+ return { ...verdict, remediation_cycle_anchor: anchor };
234
299
  }
235
300
 
236
- function eventTimeMs(event: EventV3): number {
301
+ function eventTimeMs(event: EventV3 | undefined): number {
302
+ if (!event) return Number.NaN;
237
303
  return Date.parse(event.time.observed_at);
238
304
  }
239
305
 
@@ -271,7 +337,45 @@ function evidenceUnavailable(reason: string): VerdictResult {
271
337
  };
272
338
  }
273
339
 
274
- function rule13Block(coordRoot?: string): VerdictResult {
340
+ /**
341
+ * Remediation commands carry `--session-id` when the session id is known: the
342
+ * remediating tool call may not descend from a pid-map-registered anchor
343
+ * (headless children, Cursor shells), and a ppid-walk that resolves to a
344
+ * DIFFERENT owner records evidence this verdict will never see — the block
345
+ * then repeats forever while the agent complies every time.
346
+ */
347
+ function sessionIdSuffix(sessionId?: string): string {
348
+ return sessionId ? ` --session-id ${sessionId}` : "";
349
+ }
350
+
351
+ /**
352
+ * Fold every failing end-of-turn signal into ONE verdict.
353
+ *
354
+ * The verdict keeps the first failure's rule id, so the `blocked_rule`
355
+ * telemetry and the adapter's `rule=` stderr contract are unchanged; the
356
+ * reason enumerates the rest so a single continuation can repair all of them.
357
+ * Cursor maps the acknowledgement onto rule 1/3, so identical rules dedupe.
358
+ */
359
+ function mergeStopBlocks(blocks: VerdictResult[]): VerdictResult | undefined {
360
+ let primary: VerdictResult | undefined;
361
+ const seen = new Set<string>();
362
+ const reasons: string[] = [];
363
+ for (const block of blocks) {
364
+ if (seen.has(block.rule)) continue;
365
+ seen.add(block.rule);
366
+ if (!primary) primary = block;
367
+ if (block.reason) reasons.push(block.reason);
368
+ }
369
+ if (!primary) return undefined;
370
+ if (reasons.length < 2) return primary;
371
+ const numbered = reasons.map((reason, index) => `${index + 1}. ${reason}`).join("\n");
372
+ return {
373
+ ...primary,
374
+ reason: `End-of-turn ritual: ${reasons.length} signals are missing from this turn. Repair ALL of them in this continuation, then stop.\n${numbered}`,
375
+ };
376
+ }
377
+
378
+ function rule13Block(coordRoot?: string, sessionId?: string): VerdictResult {
275
379
  const missingEvidence = agentsRequireGitFinalization(coordRoot)
276
380
  ? "no end_turn_checked coord.status_observed event found in this turn"
277
381
  : "no coord.status_observed event found in this turn";
@@ -279,16 +383,16 @@ function rule13Block(coordRoot?: string): VerdictResult {
279
383
  allow: false,
280
384
  exit_code: 2,
281
385
  rule: "stop-hook.rule_1_3",
282
- reason: `End-of-turn rule (1/3): ${missingEvidence}; run \`${endOfTurnStatusCommand(coordRoot)}\` as your last tool call.`,
386
+ reason: `End-of-turn rule (1/3): ${missingEvidence}; run \`${endOfTurnStatusCommand(coordRoot)}${sessionIdSuffix(sessionId)}\` as your last tool call.`,
283
387
  };
284
388
  }
285
389
 
286
- function rule23Block(coordRoot?: string): VerdictResult {
390
+ function rule23Block(coordRoot?: string, sessionId?: string): VerdictResult {
287
391
  return {
288
392
  allow: false,
289
393
  exit_code: 2,
290
394
  rule: "stop-hook.rule_2_3",
291
- 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).`,
395
+ reason: `End-of-turn rule (2/3): turn.completed did not observe the agent-status box in your reply text. Paste the \`${endOfTurnStatusCommand(coordRoot)}${sessionIdSuffix(sessionId)}\` output verbatim as a fenced code block (the \`┌─ agent-\` prefix is the detection signal).`,
292
396
  };
293
397
  }
294
398
 
@@ -335,11 +439,11 @@ function sessionNameBlock(coordRoot: string, instanceId: string): VerdictResult
335
439
  };
336
440
  }
337
441
 
338
- function rule33Block(coordRoot?: string): VerdictResult {
442
+ function rule33Block(coordRoot?: string, sessionId?: string): VerdictResult {
339
443
  return {
340
444
  allow: false,
341
445
  exit_code: 2,
342
446
  rule: "stop-hook.rule_3_3",
343
- 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.`,
447
+ reason: `End-of-turn rule (3/3): no coord.task_changed event found in this turn; run \`${resolveBinName(coordRoot)} agents set-task${sessionIdSuffix(sessionId)} "<short focus>"\` to declare what you're working on. Pass an empty string if the turn was purely conversational.`,
344
448
  };
345
449
  }
@@ -10,4 +10,5 @@ export type VerdictResult = {
10
10
  exit_code: 0 | 2;
11
11
  rule: string;
12
12
  reason?: string;
13
+ remediation_cycle_anchor?: string;
13
14
  };
@@ -102,6 +102,10 @@ function recordCommandObservation(type: SessionEventType, fields: Record<string,
102
102
  monotonic_ns: process.hrtime.bigint().toString(),
103
103
  });
104
104
  if (result.state === "generation_unavailable") {
105
+ const expectedLifecycleReopenGap =
106
+ result.reason === "turn_not_started" &&
107
+ hook.session_start_derivation === "approved_lifecycle_reopen";
108
+ if (expectedLifecycleReopenGap) return;
105
109
  writeProducerDiagnosticV3(coordRoot, "command_emit_unjoinable", {
106
110
  type,
107
111
  instance_id: instanceId,
@@ -1,7 +1,7 @@
1
1
  import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
3
  import type { ApprovedSessionEndReasonV3 } from "../events/v3/producers/recorder.ts";
4
- import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../events/v3/writer.ts";
4
+ import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../events/v3/reader.ts";
5
5
 
6
6
  export const SESSION_FINALIZATION_REQUEST_FORMAT_V3 =
7
7
  "harnery-v3-session-finalization-request" as const;
@@ -690,7 +690,10 @@ function ensureRequest(
690
690
  };
691
691
  const observation = buildObservationEvent(coordRoot, record, request, input);
692
692
  request.observation_event_id = observation.event_id as `evt_${string}`;
693
- writeEventV3(coordRoot, observation);
693
+ const durability = writeEventV3(coordRoot, observation, {
694
+ expectedGenesisId: input.route.genesis_id,
695
+ });
696
+ if (durability.state === "epoch_replaced") return null;
694
697
  writeRequest(coordRoot, request, true);
695
698
  return request;
696
699
  }
@@ -36,6 +36,14 @@ export function sessionNameDisplayInstruction(name: string): string {
36
36
  ].join("\n");
37
37
  }
38
38
 
39
+ export function sessionNameDisplayRecoveryInstruction(name: string, binName: string): string {
40
+ return [
41
+ sessionNameDisplayInstruction(name),
42
+ "",
43
+ `If that exact block was already shown but the gate still rejects tools, run \`${binName} agents suggest-name --json\` as the only tool call. That read-only command is exempt and creates a fresh verification boundary.`,
44
+ ].join("\n");
45
+ }
46
+
39
47
  /**
40
48
  * A PostToolUse result should announce the display protocol only when that
41
49
  * exact tool call minted or retried the current suggestion. The coordination row keeps
@@ -143,7 +151,7 @@ export function isSessionNameRemediationCommand(
143
151
  if (!body || /[\n;&|<>`$]/.test(body)) return false;
144
152
  const escapedBin = binName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
145
153
  const pattern = new RegExp(
146
- `^(?:codex-wsl\\s+--\\s+)?${escapedBin}\\s+agents\\s+(?:set-task|status)(?:\\s+.*)?$`,
154
+ `^(?:codex-wsl\\s+--\\s+)?${escapedBin}\\s+agents\\s+(?:set-task|status|suggest-name)(?:\\s+.*)?$`,
147
155
  );
148
156
  return pattern.test(body);
149
157
  }
@@ -20,6 +20,11 @@ import { readLiveCoordinationRow } from "./live-coordination-view.ts";
20
20
  export function resolveShortName(coordRoot: string, instanceId: string | null): string {
21
21
  if (!instanceId) return "agent-unknown";
22
22
  const row = readLiveCoordinationRow(coordRoot, instanceId);
23
- if (row?.name) return `agent-${row.name}`;
24
- return `agent-${instanceId.slice(0, 8)}`;
23
+ return agentDisplayName(instanceId, row?.name);
24
+ }
25
+
26
+ /** Build a collision-resistant agent label even when identity onboarding has
27
+ * not produced a usable display name yet. */
28
+ export function agentDisplayName(instanceId: string, name?: string | null): string {
29
+ return `agent-${name?.trim() || instanceId.slice(0, 8) || "unknown"}`;
25
30
  }
@@ -0,0 +1,69 @@
1
+ /** Read-only access to the generation-bound heartbeat cache. */
2
+
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { dirname, resolve, sep } from "node:path";
5
+ import type { AgentActivity, TaskState } from "./session-state.ts";
6
+
7
+ export interface Heartbeat {
8
+ schema_version?: number;
9
+ instance_id: string;
10
+ name?: string;
11
+ kind?: string;
12
+ agent_id?: string;
13
+ session_id: string;
14
+ /** Native adapter session ID retained only in a generation-bound local projection. */
15
+ native_session_id?: string;
16
+ subagent_call_id?: string;
17
+ model?: string;
18
+ platform?: string;
19
+ started_at?: string;
20
+ last_heartbeat: string;
21
+ files_touched: string[];
22
+ task?: string;
23
+ task_updated_at?: string | null;
24
+ activity?: AgentActivity;
25
+ activity_updated_at?: string;
26
+ activity_source?: string;
27
+ task_state?: TaskState;
28
+ task_state_updated_at?: string;
29
+ task_state_reason?: string;
30
+ /** Session name built on the first non-empty set-task (never rebuilt). */
31
+ suggested_session_name?: string;
32
+ /** Stamped once the suggested name is seen in assistant reply text. */
33
+ session_name_seen_at?: string;
34
+ /** The specific suggested name proven present by the sighting stamp. */
35
+ session_name_seen_for?: string;
36
+ last_status_at?: string;
37
+ current_turn_id?: string;
38
+ parent_instance_id?: string;
39
+ workflow_run_id?: string;
40
+ workflow_agent_id?: string;
41
+ /** Disposable-cache bindings that prove a row belongs to the current V3 generation. */
42
+ v3_instance_id?: `inst_${string}`;
43
+ v3_generation_id?: `gen_${string}`;
44
+ v3_projection_event_id?: string;
45
+ v3_task_state?: "set" | "cleared";
46
+ [extra: string]: unknown;
47
+ }
48
+
49
+ export function heartbeatPath(coordRoot: string, instanceId: string): string {
50
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(instanceId)) {
51
+ throw new Error("instance_id must be 1-128 ASCII letters, digits, hyphens, or underscores");
52
+ }
53
+ const root = resolve(coordRoot, ".harnery", "active");
54
+ const candidate = resolve(root, `${instanceId}.json`);
55
+ if (!candidate.startsWith(`${root}${sep}`) || dirname(candidate) !== root) {
56
+ throw new Error("coordination filename must resolve directly beneath its root");
57
+ }
58
+ return candidate;
59
+ }
60
+
61
+ export function readHeartbeat(coordRoot: string, instanceId: string): Heartbeat | null {
62
+ const path = heartbeatPath(coordRoot, instanceId);
63
+ if (!existsSync(path)) return null;
64
+ try {
65
+ return JSON.parse(readFileSync(path, "utf8")) as Heartbeat;
66
+ } catch {
67
+ return null;
68
+ }
69
+ }
@@ -23,65 +23,12 @@ import {
23
23
  unlinkSync,
24
24
  writeFileSync,
25
25
  } from "node:fs";
26
- import { basename, dirname, join } from "node:path";
27
- import { assertSafeInstanceId, resolveContainedFile } from "../coord-client.ts";
28
- import type { AgentActivity, TaskState } from "./session-state.ts";
26
+ import { dirname, join } from "node:path";
27
+ import { canonicalClaimPath } from "../claim-path.ts";
28
+ import { type Heartbeat, heartbeatPath, readHeartbeat } from "./heartbeat-reader.ts";
29
+ import type { TaskState } from "./session-state.ts";
29
30
 
30
- export interface Heartbeat {
31
- schema_version?: number;
32
- instance_id: string;
33
- name?: string;
34
- kind?: string;
35
- agent_id?: string;
36
- session_id: string;
37
- /** Native adapter session ID retained only in a generation-bound local projection. */
38
- native_session_id?: string;
39
- subagent_call_id?: string;
40
- model?: string;
41
- platform?: string;
42
- started_at?: string;
43
- last_heartbeat: string;
44
- files_touched: string[];
45
- task?: string;
46
- task_updated_at?: string | null;
47
- activity?: AgentActivity;
48
- activity_updated_at?: string;
49
- activity_source?: string;
50
- task_state?: TaskState;
51
- task_state_updated_at?: string;
52
- task_state_reason?: string;
53
- /** Session name built on the first non-empty set-task (never rebuilt). Its
54
- * presence is the "this session has been named" signal the prompt-context
55
- * nudge and the Stop-hook naming rule key on. */
56
- suggested_session_name?: string;
57
- /** Stamped by turn.completed once the suggested name is seen in assistant reply
58
- * text, ending the per-turn transcript scan. */
59
- session_name_seen_at?: string;
60
- /** WHICH name that sighting was for. The scan is skipped only while this
61
- * matches the current suggested name, so a re-minted name is detectable
62
- * again rather than being suppressed by the earlier sighting. */
63
- session_name_seen_for?: string;
64
- last_status_at?: string;
65
- current_turn_id?: string;
66
- parent_instance_id?: string;
67
- workflow_run_id?: string;
68
- workflow_agent_id?: string;
69
- /** Disposable-cache bindings that prove a row belongs to the current V3 generation. */
70
- v3_instance_id?: `inst_${string}`;
71
- v3_generation_id?: `gen_${string}`;
72
- v3_projection_event_id?: string;
73
- v3_task_state?: "set" | "cleared";
74
- [extra: string]: unknown;
75
- }
76
-
77
- function heartbeatPath(coordRoot: string, instanceId: string): string {
78
- assertSafeInstanceId(instanceId);
79
- const safeInstanceId = basename(instanceId);
80
- if (safeInstanceId !== instanceId) {
81
- throw new Error("instance_id must be a direct-child coordination basename");
82
- }
83
- return resolveContainedFile(join(coordRoot, ".harnery", "active"), `${safeInstanceId}.json`);
84
- }
31
+ export { type Heartbeat, readHeartbeat } from "./heartbeat-reader.ts";
85
32
 
86
33
  function nowIsoSeconds(): string {
87
34
  return new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
@@ -94,16 +41,6 @@ function atomicWrite(path: string, content: string): void {
94
41
  renameSync(tmp, path);
95
42
  }
96
43
 
97
- export function readHeartbeat(coordRoot: string, instanceId: string): Heartbeat | null {
98
- const path = heartbeatPath(coordRoot, instanceId);
99
- if (!existsSync(path)) return null;
100
- try {
101
- return JSON.parse(readFileSync(path, "utf8")) as Heartbeat;
102
- } catch {
103
- return null;
104
- }
105
- }
106
-
107
44
  /** Persist operator-facing lifecycle prose in the generation-bound cache only. */
108
45
  export function setLifecycleCache(
109
46
  coordRoot: string,
@@ -171,6 +108,33 @@ export function setIdentityCache(
171
108
  return heartbeat;
172
109
  }
173
110
 
111
+ /** Restore the pool-assigned display name on a generation that was
112
+ * materialized before the adapter's normal SessionStart naming path ran.
113
+ * The durable assignment lives in `.name-history`; this only repairs the
114
+ * disposable generation cache and deliberately leaves durable persona state
115
+ * (`agent_id`) untouched. */
116
+ export function setAssignedNameCache(
117
+ coordRoot: string,
118
+ instanceId: string,
119
+ name: string,
120
+ kind: "session" | "subagent" | "transient" = "session",
121
+ ): Heartbeat | null {
122
+ return mutate(coordRoot, instanceId, (heartbeat) => {
123
+ const suggestedSessionName = heartbeat.suggested_session_name?.replace(
124
+ /^(\[DONE\]\s+)?Agent unknown( - .+)$/,
125
+ `$1Agent ${name}$2`,
126
+ );
127
+ return {
128
+ ...heartbeat,
129
+ name,
130
+ kind: heartbeat.kind ?? kind,
131
+ ...(suggestedSessionName && suggestedSessionName !== heartbeat.suggested_session_name
132
+ ? { suggested_session_name: suggestedSessionName }
133
+ : {}),
134
+ };
135
+ });
136
+ }
137
+
174
138
  /**
175
139
  * Build the copy-pasteable session name from the coord identity + the agent's
176
140
  * description parts. Pure (no coord-state reads) so it's unit-testable; collapses
@@ -221,16 +185,12 @@ export function releaseClaim(
221
185
  instanceId: string,
222
186
  path: string,
223
187
  ): Heartbeat | null {
224
- // files_touched can hold either absolute-under-coordRoot or canonical
225
- // monorepo-relative entries; normalize both sides so release matches
226
- // regardless of the form the caller passes (the old exact-string filter
227
- // silently no-op'd on a form mismatch).
228
- const norm = (p: string): string =>
229
- p.startsWith(`${coordRoot}/`) ? p.slice(coordRoot.length + 1) : p;
230
- const target = norm(path);
188
+ const target = canonicalClaimPath(coordRoot, path);
231
189
  return mutate(coordRoot, instanceId, (hb) => ({
232
190
  ...hb,
233
- files_touched: (hb.files_touched ?? []).filter((p) => norm(p) !== target),
191
+ files_touched: (hb.files_touched ?? []).filter(
192
+ (candidate) => canonicalClaimPath(coordRoot, candidate) !== target,
193
+ ),
234
194
  }));
235
195
  }
236
196
 
@@ -240,12 +200,15 @@ export function acquireClaim(
240
200
  instanceId: string,
241
201
  path: string,
242
202
  ): Heartbeat | null {
243
- const norm = (p: string): string =>
244
- p.startsWith(`${coordRoot}/`) ? p.slice(coordRoot.length + 1) : p;
245
- const target = norm(path);
203
+ const target = canonicalClaimPath(coordRoot, path);
246
204
  return mutate(coordRoot, instanceId, (hb) => ({
247
205
  ...hb,
248
- files_touched: [...new Set([...(hb.files_touched ?? []).map(norm), target])].sort(),
206
+ files_touched: [
207
+ ...new Set([
208
+ ...(hb.files_touched ?? []).map((candidate) => canonicalClaimPath(coordRoot, candidate)),
209
+ target,
210
+ ]),
211
+ ].sort(),
249
212
  }));
250
213
  }
251
214
 
@@ -282,9 +245,7 @@ export function findGroupClaims(
282
245
  if (!groupId || !path) return hits;
283
246
  const activeDir = join(coordRoot, ".harnery", "active");
284
247
  if (!existsSync(activeDir)) return hits;
285
- const norm = (p: string): string =>
286
- p.startsWith(`${coordRoot}/`) ? p.slice(coordRoot.length + 1) : p;
287
- const target = norm(path);
248
+ const target = canonicalClaimPath(coordRoot, path);
288
249
  for (const f of readdirSync(activeDir)) {
289
250
  if (!f.endsWith(".json")) continue;
290
251
  const hbPath = join(activeDir, f);
@@ -298,7 +259,9 @@ export function findGroupClaims(
298
259
  (body.session_id as string | undefined) ?? (body.instance_id as string | undefined);
299
260
  if (peerSession !== groupId) continue;
300
261
  const files = (body.files_touched as string[] | undefined) ?? [];
301
- if (!files.some((candidate) => norm(candidate) === target)) continue;
262
+ if (!files.some((candidate) => canonicalClaimPath(coordRoot, candidate) === target)) {
263
+ continue;
264
+ }
302
265
  hits.push({
303
266
  instance_id: (body.instance_id as string | undefined) ?? f.replace(/\.json$/, ""),
304
267
  session_id: body.session_id as string | undefined,