harnery 0.36.0 → 0.38.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 (432) hide show
  1. package/dist/commander.d.ts +9 -0
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +10 -1
  4. package/dist/commands/admission.d.ts +21 -0
  5. package/dist/commands/admission.d.ts.map +1 -0
  6. package/dist/commands/admission.js +565 -0
  7. package/dist/commands/agents.d.ts +7 -0
  8. package/dist/commands/agents.d.ts.map +1 -1
  9. package/dist/commands/agents.js +148 -47
  10. package/dist/commands/artifacts.d.ts.map +1 -1
  11. package/dist/commands/artifacts.js +73 -2
  12. package/dist/commands/browse-ai.d.ts +2 -2
  13. package/dist/commands/browse-ai.d.ts.map +1 -1
  14. package/dist/commands/browse-ai.js +6 -4
  15. package/dist/commands/browse.d.ts.map +1 -1
  16. package/dist/commands/browse.js +360 -21
  17. package/dist/commands/diagnostics.d.ts +4 -0
  18. package/dist/commands/diagnostics.d.ts.map +1 -0
  19. package/dist/commands/diagnostics.js +229 -0
  20. package/dist/commands/fetch.js +1 -0
  21. package/dist/commands/files.d.ts +12 -0
  22. package/dist/commands/files.d.ts.map +1 -1
  23. package/dist/commands/files.js +54 -1
  24. package/dist/commands/governor.d.ts.map +1 -1
  25. package/dist/commands/governor.js +4 -0
  26. package/dist/commands/ledger-v3.d.ts.map +1 -1
  27. package/dist/commands/ledger-v3.js +71 -2
  28. package/dist/commands/qa-record.d.ts +144 -0
  29. package/dist/commands/qa-record.d.ts.map +1 -0
  30. package/dist/commands/qa-record.js +0 -0
  31. package/dist/commands/qa-run.d.ts +8 -0
  32. package/dist/commands/qa-run.d.ts.map +1 -0
  33. package/dist/commands/qa-run.js +396 -0
  34. package/dist/commands/qa-status.d.ts +71 -0
  35. package/dist/commands/qa-status.d.ts.map +1 -0
  36. package/dist/commands/qa-status.js +490 -0
  37. package/dist/commands/qa-verify.d.ts +40 -0
  38. package/dist/commands/qa-verify.d.ts.map +1 -0
  39. package/dist/commands/qa-verify.js +180 -0
  40. package/dist/commands/resources.d.ts +4 -0
  41. package/dist/commands/resources.d.ts.map +1 -0
  42. package/dist/commands/resources.js +29 -0
  43. package/dist/commands/review-pack.d.ts +4 -0
  44. package/dist/commands/review-pack.d.ts.map +1 -0
  45. package/dist/commands/review-pack.js +1001 -0
  46. package/dist/commands/supervisor.d.ts +4 -0
  47. package/dist/commands/supervisor.d.ts.map +1 -0
  48. package/dist/commands/supervisor.js +101 -0
  49. package/dist/commands/web.d.ts.map +1 -1
  50. package/dist/commands/web.js +17 -0
  51. package/dist/commands/workflow.d.ts.map +1 -1
  52. package/dist/commands/workflow.js +4 -0
  53. package/dist/core/agents/cli.js +7 -3
  54. package/dist/core/agents/health.d.ts +17 -0
  55. package/dist/core/agents/health.d.ts.map +1 -0
  56. package/dist/core/agents/health.js +109 -0
  57. package/dist/core/agents/mailbox.d.ts +92 -0
  58. package/dist/core/agents/mailbox.d.ts.map +1 -0
  59. package/dist/core/agents/mailbox.js +325 -0
  60. package/dist/core/agents/qa-signal.d.ts +111 -0
  61. package/dist/core/agents/qa-signal.d.ts.map +1 -0
  62. package/dist/core/agents/qa-signal.js +231 -0
  63. package/dist/core/agents/reconcile-coordination-v3.d.ts +44 -0
  64. package/dist/core/agents/reconcile-coordination-v3.d.ts.map +1 -0
  65. package/dist/core/agents/reconcile-coordination-v3.js +58 -0
  66. package/dist/core/agents/render/prompt-context.d.ts +5 -0
  67. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  68. package/dist/core/agents/render/prompt-context.js +34 -13
  69. package/dist/core/agents/render/session-context.d.ts +8 -0
  70. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  71. package/dist/core/agents/render/session-context.js +34 -3
  72. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
  73. package/dist/core/agents/rules/commit-conflict.js +50 -1
  74. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  75. package/dist/core/agents/rules/stop-hook.js +6 -10
  76. package/dist/core/agents/session-finalizer-v3.js +4 -1
  77. package/dist/core/agents/session-name-display.d.ts +20 -5
  78. package/dist/core/agents/session-name-display.d.ts.map +1 -1
  79. package/dist/core/agents/session-name-display.js +67 -7
  80. package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
  81. package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
  82. package/dist/core/agents/state/heartbeat-writer.d.ts +11 -0
  83. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  84. package/dist/core/agents/state/heartbeat-writer.js +17 -0
  85. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  86. package/dist/core/agents/state/live-coordination-view.js +1 -0
  87. package/dist/core/agents/state/live-coordination-writer.js +5 -0
  88. package/dist/core/artifacts/constants.d.ts +1 -1
  89. package/dist/core/artifacts/constants.js +1 -1
  90. package/dist/core/artifacts/index.d.ts +82 -6
  91. package/dist/core/artifacts/index.d.ts.map +1 -1
  92. package/dist/core/artifacts/index.js +410 -15
  93. package/dist/core/config.d.ts +20 -0
  94. package/dist/core/config.d.ts.map +1 -1
  95. package/dist/core/config.js +59 -0
  96. package/dist/core/diagnostics/advice.d.ts +9 -0
  97. package/dist/core/diagnostics/advice.d.ts.map +1 -0
  98. package/dist/core/diagnostics/advice.js +112 -0
  99. package/dist/core/diagnostics/bundle.d.ts +51 -0
  100. package/dist/core/diagnostics/bundle.d.ts.map +1 -0
  101. package/dist/core/diagnostics/bundle.js +968 -0
  102. package/dist/core/diagnostics/comparison.d.ts +5 -0
  103. package/dist/core/diagnostics/comparison.d.ts.map +1 -0
  104. package/dist/core/diagnostics/comparison.js +444 -0
  105. package/dist/core/diagnostics/contract.d.ts +245 -0
  106. package/dist/core/diagnostics/contract.d.ts.map +1 -0
  107. package/dist/core/diagnostics/contract.js +18 -0
  108. package/dist/core/diagnostics/identity.d.ts +3 -0
  109. package/dist/core/diagnostics/identity.d.ts.map +1 -0
  110. package/dist/core/diagnostics/identity.js +10 -0
  111. package/dist/core/diagnostics/index.d.ts +8 -0
  112. package/dist/core/diagnostics/index.d.ts.map +1 -0
  113. package/dist/core/diagnostics/index.js +7 -0
  114. package/dist/core/diagnostics/replay.d.ts +8 -0
  115. package/dist/core/diagnostics/replay.d.ts.map +1 -0
  116. package/dist/core/diagnostics/replay.js +213 -0
  117. package/dist/core/diagnostics/sanitize.d.ts +9 -0
  118. package/dist/core/diagnostics/sanitize.d.ts.map +1 -0
  119. package/dist/core/diagnostics/sanitize.js +84 -0
  120. package/dist/core/events/legacy-storage/compression.d.ts +13 -0
  121. package/dist/core/events/legacy-storage/compression.d.ts.map +1 -0
  122. package/dist/core/events/legacy-storage/compression.js +107 -0
  123. package/dist/core/events/legacy-storage/index.d.ts +1 -0
  124. package/dist/core/events/legacy-storage/index.d.ts.map +1 -1
  125. package/dist/core/events/legacy-storage/index.js +1 -0
  126. package/dist/core/events/v3/archive-retention.d.ts +33 -0
  127. package/dist/core/events/v3/archive-retention.d.ts.map +1 -0
  128. package/dist/core/events/v3/archive-retention.js +195 -0
  129. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  130. package/dist/core/events/v3/bootstrap.js +10 -0
  131. package/dist/core/events/v3/capabilities.d.ts +1 -1
  132. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  133. package/dist/core/events/v3/capabilities.js +1 -0
  134. package/dist/core/events/v3/coordination-view.d.ts +3 -0
  135. package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
  136. package/dist/core/events/v3/coordination-view.js +69 -8
  137. package/dist/core/events/v3/index.d.ts +1 -0
  138. package/dist/core/events/v3/index.d.ts.map +1 -1
  139. package/dist/core/events/v3/index.js +1 -0
  140. package/dist/core/events/v3/live-routing.d.ts.map +1 -1
  141. package/dist/core/events/v3/live-routing.js +1 -0
  142. package/dist/core/events/v3/producers/hook-base.d.ts +1 -1
  143. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  144. package/dist/core/events/v3/producers/hook-base.js +13 -2
  145. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  146. package/dist/core/events/v3/producers/intake.js +10 -2
  147. package/dist/core/events/v3/producers/recorder.d.ts +39 -0
  148. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  149. package/dist/core/events/v3/producers/recorder.js +350 -17
  150. package/dist/core/hooks/adapter/output.d.ts +8 -0
  151. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  152. package/dist/core/hooks/adapter/output.js +11 -1
  153. package/dist/core/hooks/cli.js +303 -219
  154. package/dist/core/hooks/health.d.ts +59 -0
  155. package/dist/core/hooks/health.d.ts.map +1 -0
  156. package/dist/core/hooks/health.js +84 -0
  157. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  158. package/dist/core/hooks/resolve/transcript.js +10 -3
  159. package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
  160. package/dist/core/hooks/session-name-presence.js +4 -1
  161. package/dist/core/qa-artifacts.d.ts +20 -0
  162. package/dist/core/qa-artifacts.d.ts.map +1 -0
  163. package/dist/core/qa-artifacts.js +110 -0
  164. package/dist/core/resources/contract.d.ts +96 -0
  165. package/dist/core/resources/contract.d.ts.map +1 -0
  166. package/dist/core/resources/contract.js +2 -0
  167. package/dist/core/resources/index.d.ts +6 -0
  168. package/dist/core/resources/index.d.ts.map +1 -0
  169. package/dist/core/resources/index.js +5 -0
  170. package/dist/core/resources/sampler.d.ts +34 -0
  171. package/dist/core/resources/sampler.d.ts.map +1 -0
  172. package/dist/core/resources/sampler.js +458 -0
  173. package/dist/core/resources/service-status.d.ts +3 -0
  174. package/dist/core/resources/service-status.d.ts.map +1 -0
  175. package/dist/core/resources/service-status.js +48 -0
  176. package/dist/core/resources/service.d.ts +26 -0
  177. package/dist/core/resources/service.d.ts.map +1 -0
  178. package/dist/core/resources/service.js +292 -0
  179. package/dist/core/resources/storage.d.ts +13 -0
  180. package/dist/core/resources/storage.d.ts.map +1 -0
  181. package/dist/core/resources/storage.js +30 -0
  182. package/dist/core/storage/atomic-json.d.ts +3 -0
  183. package/dist/core/storage/atomic-json.d.ts.map +1 -0
  184. package/dist/core/storage/atomic-json.js +15 -0
  185. package/dist/core/storage/builtins.d.ts.map +1 -1
  186. package/dist/core/storage/builtins.js +45 -6
  187. package/dist/core/storage/logger.d.ts +2 -0
  188. package/dist/core/storage/logger.d.ts.map +1 -1
  189. package/dist/core/storage/logger.js +2 -0
  190. package/dist/core/storage/query.d.ts +14 -0
  191. package/dist/core/storage/query.d.ts.map +1 -1
  192. package/dist/core/storage/query.js +51 -0
  193. package/dist/core/supervisor/activity.d.ts +4 -0
  194. package/dist/core/supervisor/activity.d.ts.map +1 -0
  195. package/dist/core/supervisor/activity.js +141 -0
  196. package/dist/core/supervisor/contract.d.ts +268 -0
  197. package/dist/core/supervisor/contract.d.ts.map +1 -0
  198. package/dist/core/supervisor/contract.js +35 -0
  199. package/dist/core/supervisor/explanations.d.ts +4 -0
  200. package/dist/core/supervisor/explanations.d.ts.map +1 -0
  201. package/dist/core/supervisor/explanations.js +71 -0
  202. package/dist/core/supervisor/findings.d.ts +20 -0
  203. package/dist/core/supervisor/findings.d.ts.map +1 -0
  204. package/dist/core/supervisor/findings.js +399 -0
  205. package/dist/core/supervisor/history.d.ts +9 -0
  206. package/dist/core/supervisor/history.d.ts.map +1 -0
  207. package/dist/core/supervisor/history.js +46 -0
  208. package/dist/core/supervisor/hook-health-alerts.d.ts +14 -0
  209. package/dist/core/supervisor/hook-health-alerts.d.ts.map +1 -0
  210. package/dist/core/supervisor/hook-health-alerts.js +70 -0
  211. package/dist/core/supervisor/hook-health-storage.d.ts +5 -0
  212. package/dist/core/supervisor/hook-health-storage.d.ts.map +1 -0
  213. package/dist/core/supervisor/hook-health-storage.js +24 -0
  214. package/dist/core/supervisor/hook-health.d.ts +72 -0
  215. package/dist/core/supervisor/hook-health.d.ts.map +1 -0
  216. package/dist/core/supervisor/hook-health.js +203 -0
  217. package/dist/core/supervisor/hooks.d.ts +10 -0
  218. package/dist/core/supervisor/hooks.d.ts.map +1 -0
  219. package/dist/core/supervisor/hooks.js +28 -0
  220. package/dist/core/supervisor/index.d.ts +15 -0
  221. package/dist/core/supervisor/index.d.ts.map +1 -0
  222. package/dist/core/supervisor/index.js +14 -0
  223. package/dist/core/supervisor/log-feed.d.ts +9 -0
  224. package/dist/core/supervisor/log-feed.d.ts.map +1 -0
  225. package/dist/core/supervisor/log-feed.js +103 -0
  226. package/dist/core/supervisor/service.d.ts +29 -0
  227. package/dist/core/supervisor/service.d.ts.map +1 -0
  228. package/dist/core/supervisor/service.js +450 -0
  229. package/dist/core/supervisor/services.d.ts +11 -0
  230. package/dist/core/supervisor/services.d.ts.map +1 -0
  231. package/dist/core/supervisor/services.js +155 -0
  232. package/dist/core/supervisor/status.d.ts +3 -0
  233. package/dist/core/supervisor/status.d.ts.map +1 -0
  234. package/dist/core/supervisor/status.js +48 -0
  235. package/dist/core/supervisor/storage.d.ts +30 -0
  236. package/dist/core/supervisor/storage.d.ts.map +1 -0
  237. package/dist/core/supervisor/storage.js +73 -0
  238. package/dist/core/supervisor/timeline.d.ts +3 -0
  239. package/dist/core/supervisor/timeline.d.ts.map +1 -0
  240. package/dist/core/supervisor/timeline.js +87 -0
  241. package/dist/core/workflow/admission.d.ts +23 -0
  242. package/dist/core/workflow/admission.d.ts.map +1 -0
  243. package/dist/core/workflow/admission.js +136 -0
  244. package/dist/core/workflow/engine.d.ts.map +1 -1
  245. package/dist/core/workflow/engine.js +77 -2
  246. package/dist/core/workflow/index.d.ts +3 -2
  247. package/dist/core/workflow/index.d.ts.map +1 -1
  248. package/dist/core/workflow/index.js +2 -1
  249. package/dist/core/workflow/proof.d.ts +2 -1
  250. package/dist/core/workflow/proof.d.ts.map +1 -1
  251. package/dist/core/workflow/proof.js +39 -1
  252. package/dist/core/workflow/run-state.d.ts +3 -2
  253. package/dist/core/workflow/run-state.d.ts.map +1 -1
  254. package/dist/core/workflow/run-state.js +8 -1
  255. package/dist/core/workflow/types.d.ts +33 -1
  256. package/dist/core/workflow/types.d.ts.map +1 -1
  257. package/dist/core/workflow/types.js +2 -1
  258. package/dist/lib/admission.d.ts +71 -0
  259. package/dist/lib/admission.d.ts.map +1 -0
  260. package/dist/lib/admission.js +264 -0
  261. package/dist/lib/agent-browser/client.d.ts +1 -1
  262. package/dist/lib/agent-browser/client.d.ts.map +1 -1
  263. package/dist/lib/agent-browser/client.js +1 -5
  264. package/dist/lib/browser/capture-fidelity.d.ts +39 -0
  265. package/dist/lib/browser/capture-fidelity.d.ts.map +1 -0
  266. package/dist/lib/browser/capture-fidelity.js +84 -0
  267. package/dist/lib/browser/client.d.ts +46 -1
  268. package/dist/lib/browser/client.d.ts.map +1 -1
  269. package/dist/lib/browser/client.js +168 -9
  270. package/dist/lib/browser/critique.d.ts +38 -1
  271. package/dist/lib/browser/critique.d.ts.map +1 -1
  272. package/dist/lib/browser/critique.js +34 -6
  273. package/dist/lib/browser/index.d.ts +5 -1
  274. package/dist/lib/browser/index.d.ts.map +1 -1
  275. package/dist/lib/browser/index.js +4 -0
  276. package/dist/lib/browser/page-review-judge.d.ts +64 -0
  277. package/dist/lib/browser/page-review-judge.d.ts.map +1 -0
  278. package/dist/lib/browser/page-review-judge.js +270 -0
  279. package/dist/lib/browser/page-review-pack.d.ts +613 -0
  280. package/dist/lib/browser/page-review-pack.d.ts.map +1 -0
  281. package/dist/lib/browser/page-review-pack.js +1751 -0
  282. package/dist/lib/browser/qa-run-contracts.d.ts +377 -0
  283. package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -0
  284. package/dist/lib/browser/qa-run-contracts.js +361 -0
  285. package/dist/lib/browser/qa-run.d.ts +141 -0
  286. package/dist/lib/browser/qa-run.d.ts.map +1 -0
  287. package/dist/lib/browser/qa-run.js +1283 -0
  288. package/dist/lib/browser/request-diagnostics.d.ts +13 -0
  289. package/dist/lib/browser/request-diagnostics.d.ts.map +1 -0
  290. package/dist/lib/browser/request-diagnostics.js +18 -0
  291. package/dist/lib/browser/tiling.d.ts +19 -0
  292. package/dist/lib/browser/tiling.d.ts.map +1 -1
  293. package/dist/lib/browser/tiling.js +28 -0
  294. package/dist/lib/cookies/client.d.ts +9 -0
  295. package/dist/lib/cookies/client.d.ts.map +1 -1
  296. package/dist/lib/cookies/client.js +197 -44
  297. package/dist/lib/cookies/extra.d.ts +18 -0
  298. package/dist/lib/cookies/extra.d.ts.map +1 -0
  299. package/dist/lib/cookies/extra.js +14 -0
  300. package/dist/lib/cookies/index.d.ts +2 -1
  301. package/dist/lib/cookies/index.d.ts.map +1 -1
  302. package/dist/lib/cookies/index.js +2 -1
  303. package/dist/lib/coord-root-id.d.ts +9 -0
  304. package/dist/lib/coord-root-id.d.ts.map +1 -0
  305. package/dist/lib/coord-root-id.js +17 -0
  306. package/dist/lib/durable-job.d.ts +124 -0
  307. package/dist/lib/durable-job.d.ts.map +1 -0
  308. package/dist/lib/durable-job.js +296 -0
  309. package/dist/lib/http/client.d.ts +7 -1
  310. package/dist/lib/http/client.d.ts.map +1 -1
  311. package/dist/lib/http/client.js +2 -0
  312. package/dist/lib/instructions/apply.d.ts +3 -1
  313. package/dist/lib/instructions/apply.d.ts.map +1 -1
  314. package/dist/lib/instructions/apply.js +74 -3
  315. package/dist/lib/instructions/templates.d.ts.map +1 -1
  316. package/dist/lib/instructions/templates.js +11 -2
  317. package/package.json +19 -2
  318. package/src/commander.ts +75 -1
  319. package/src/commands/admission.ts +699 -0
  320. package/src/commands/agents.ts +189 -50
  321. package/src/commands/artifacts.ts +132 -18
  322. package/src/commands/browse-ai.ts +10 -5
  323. package/src/commands/browse.ts +496 -20
  324. package/src/commands/diagnostics.ts +271 -0
  325. package/src/commands/fetch.ts +1 -0
  326. package/src/commands/files.ts +102 -2
  327. package/src/commands/governor.ts +8 -0
  328. package/src/commands/ledger-v3.ts +82 -0
  329. package/src/commands/qa-record.ts +682 -0
  330. package/src/commands/qa-run.ts +503 -0
  331. package/src/commands/qa-status.ts +608 -0
  332. package/src/commands/qa-verify.ts +238 -0
  333. package/src/commands/resources.ts +38 -0
  334. package/src/commands/review-pack.ts +1281 -0
  335. package/src/commands/supervisor.ts +141 -0
  336. package/src/commands/web.ts +19 -0
  337. package/src/commands/workflow.ts +8 -0
  338. package/src/core/agents/cli.ts +7 -3
  339. package/src/core/agents/health.ts +142 -0
  340. package/src/core/agents/mailbox.ts +373 -0
  341. package/src/core/agents/qa-signal.ts +261 -0
  342. package/src/core/agents/reconcile-coordination-v3.ts +77 -0
  343. package/src/core/agents/render/prompt-context.ts +42 -12
  344. package/src/core/agents/render/session-context.ts +37 -3
  345. package/src/core/agents/rules/commit-conflict.ts +58 -1
  346. package/src/core/agents/rules/stop-hook.ts +6 -12
  347. package/src/core/agents/session-finalizer-v3.ts +4 -1
  348. package/src/core/agents/session-name-display.ts +78 -7
  349. package/src/core/agents/state/heartbeat-reader.ts +7 -0
  350. package/src/core/agents/state/heartbeat-writer.ts +23 -0
  351. package/src/core/agents/state/live-coordination-view.ts +1 -0
  352. package/src/core/agents/state/live-coordination-writer.ts +5 -0
  353. package/src/core/artifacts/constants.ts +1 -1
  354. package/src/core/artifacts/index.ts +565 -30
  355. package/src/core/config.ts +134 -2
  356. package/src/core/diagnostics/advice.ts +147 -0
  357. package/src/core/diagnostics/bundle.ts +1250 -0
  358. package/src/core/diagnostics/comparison.ts +565 -0
  359. package/src/core/diagnostics/contract.ts +311 -0
  360. package/src/core/diagnostics/identity.ts +11 -0
  361. package/src/core/diagnostics/index.ts +7 -0
  362. package/src/core/diagnostics/replay.ts +314 -0
  363. package/src/core/diagnostics/sanitize.ts +97 -0
  364. package/src/core/events/legacy-storage/compression.ts +130 -0
  365. package/src/core/events/legacy-storage/index.ts +1 -0
  366. package/src/core/events/v3/archive-retention.ts +251 -0
  367. package/src/core/events/v3/bootstrap.ts +10 -0
  368. package/src/core/events/v3/capabilities.ts +2 -0
  369. package/src/core/events/v3/coordination-view.ts +100 -11
  370. package/src/core/events/v3/index.ts +9 -0
  371. package/src/core/events/v3/live-routing.ts +1 -0
  372. package/src/core/events/v3/producers/hook-base.ts +14 -2
  373. package/src/core/events/v3/producers/intake.ts +10 -2
  374. package/src/core/events/v3/producers/recorder.ts +420 -17
  375. package/src/core/hooks/adapter/output.ts +12 -1
  376. package/src/core/hooks/cli.ts +332 -247
  377. package/src/core/hooks/health.ts +146 -0
  378. package/src/core/hooks/resolve/transcript.ts +10 -3
  379. package/src/core/hooks/session-name-presence.ts +6 -1
  380. package/src/core/qa-artifacts.ts +126 -0
  381. package/src/core/resources/contract.ts +105 -0
  382. package/src/core/resources/index.ts +5 -0
  383. package/src/core/resources/sampler.ts +590 -0
  384. package/src/core/resources/service-status.ts +62 -0
  385. package/src/core/resources/service.ts +337 -0
  386. package/src/core/resources/storage.ts +44 -0
  387. package/src/core/storage/atomic-json.ts +15 -0
  388. package/src/core/storage/builtins.ts +62 -6
  389. package/src/core/storage/logger.ts +2 -0
  390. package/src/core/storage/query.ts +58 -0
  391. package/src/core/supervisor/activity.ts +193 -0
  392. package/src/core/supervisor/contract.ts +312 -0
  393. package/src/core/supervisor/explanations.ts +104 -0
  394. package/src/core/supervisor/findings.ts +788 -0
  395. package/src/core/supervisor/history.ts +61 -0
  396. package/src/core/supervisor/hook-health-alerts.ts +108 -0
  397. package/src/core/supervisor/hook-health-storage.ts +25 -0
  398. package/src/core/supervisor/hook-health.ts +301 -0
  399. package/src/core/supervisor/hooks.ts +35 -0
  400. package/src/core/supervisor/index.ts +14 -0
  401. package/src/core/supervisor/log-feed.ts +131 -0
  402. package/src/core/supervisor/service.ts +511 -0
  403. package/src/core/supervisor/services.ts +203 -0
  404. package/src/core/supervisor/status.ts +59 -0
  405. package/src/core/supervisor/storage.ts +126 -0
  406. package/src/core/supervisor/timeline.ts +133 -0
  407. package/src/core/workflow/admission.ts +215 -0
  408. package/src/core/workflow/engine.ts +93 -1
  409. package/src/core/workflow/index.ts +10 -0
  410. package/src/core/workflow/proof.ts +54 -1
  411. package/src/core/workflow/run-state.ts +13 -1
  412. package/src/core/workflow/types.ts +39 -1
  413. package/src/lib/admission.ts +347 -0
  414. package/src/lib/agent-browser/client.ts +2 -10
  415. package/src/lib/browser/capture-fidelity.ts +98 -0
  416. package/src/lib/browser/client.ts +212 -10
  417. package/src/lib/browser/critique.ts +62 -7
  418. package/src/lib/browser/index.ts +65 -0
  419. package/src/lib/browser/page-review-judge.ts +360 -0
  420. package/src/lib/browser/page-review-pack.ts +2384 -0
  421. package/src/lib/browser/qa-run-contracts.ts +743 -0
  422. package/src/lib/browser/qa-run.ts +1462 -0
  423. package/src/lib/browser/request-diagnostics.ts +27 -0
  424. package/src/lib/browser/tiling.ts +32 -0
  425. package/src/lib/cookies/client.ts +228 -42
  426. package/src/lib/cookies/extra.ts +28 -0
  427. package/src/lib/cookies/index.ts +2 -0
  428. package/src/lib/coord-root-id.ts +23 -0
  429. package/src/lib/durable-job.ts +407 -0
  430. package/src/lib/http/client.ts +13 -1
  431. package/src/lib/instructions/apply.ts +81 -2
  432. package/src/lib/instructions/templates.ts +11 -2
@@ -49,6 +49,15 @@ import {
49
49
  LiveCoordinationAuthorityV3Error,
50
50
  reopenLiveCoordinationGenerationV3,
51
51
  } from "../core/agents/live-authority-v3.ts";
52
+ import {
53
+ isAddressableName,
54
+ MailboxCapacityError,
55
+ type QueueResult,
56
+ queueMailboxMessage,
57
+ suggestNames,
58
+ } from "../core/agents/mailbox.ts";
59
+ import { qaSignalStatusRow } from "../core/agents/qa-signal.ts";
60
+ import { reconcileCoordinationV3 } from "../core/agents/reconcile-coordination-v3.ts";
52
61
  import {
53
62
  listSessionFinalizationRequestsV3,
54
63
  observeHostDisappearedV3,
@@ -83,7 +92,10 @@ import {
83
92
  } from "../core/config.ts";
84
93
  import type { EventTypeV3 } from "../core/events/v3/contract.ts";
85
94
  import { readEventV3ControlState } from "../core/events/v3/control.ts";
86
- import { projectCoordinationViewV3 } from "../core/events/v3/coordination-view.ts";
95
+ import {
96
+ projectCoordinationViewV3,
97
+ readCoordinationViewV3,
98
+ } from "../core/events/v3/coordination-view.ts";
87
99
  import { liveInstanceIdV3 } from "../core/events/v3/live-routing.ts";
88
100
  import {
89
101
  countSummarizedSinceV3,
@@ -435,7 +447,8 @@ export function registerAgentsCommand(
435
447
  cmd
436
448
  .command("reconcile")
437
449
  .description(
438
- "Reconcile archive, idle, parent/run completion, stale, superseded, and host lifecycle signals into V3 session finalization.",
450
+ "Sweep the stale coordination cache, then reconcile archive, idle, parent/run " +
451
+ "completion, stale, superseded, and host lifecycle signals into V3 session finalization.",
439
452
  )
440
453
  .option("--watch", "Keep reconciling until interrupted")
441
454
  .option("--interval-seconds <n>", "Watch interval in seconds")
@@ -485,9 +498,10 @@ export function registerAgentsCommand(
485
498
  cmd
486
499
  .command("ping <name> <message...>")
487
500
  .description(
488
- "Append a 'handoff' entry to a peer agent's journal. Body prefixed with " +
489
- "`from agent-<me>:`. Use to leave actionable coordination notes for peers " +
490
- "currently holding files you need.",
501
+ "Send a message to another agent by name. Works whether or not that agent " +
502
+ "is running: a live peer sees it on their next prompt, and a name with no " +
503
+ "live session gets it queued until a session of that name next starts. " +
504
+ "Only an unknown name is refused.",
491
505
  )
492
506
  .option("--json", "JSON output")
493
507
  .action((name: string, message: string[], opts: { json?: boolean }) => {
@@ -546,7 +560,7 @@ export function registerAgentsCommand(
546
560
  .command("health")
547
561
  .description(
548
562
  "One-screen coord-layer health rollup: heal events, council activity, " +
549
- "zombie detection, and anomalies. Designed for " +
563
+ "heartbeat cache issues, and findings. Designed for " +
550
564
  "daily glance + dashboard ingestion. Reads .harnery/.",
551
565
  )
552
566
  .option("--since <window>", "Window (Nh | Nd). Default: 24h.", "24h")
@@ -747,7 +761,7 @@ async function runSessionReconcile(opts: {
747
761
  }
748
762
  let stopped = false;
749
763
  do {
750
- emit.data(reconcileSessionFinalizationV3(root));
764
+ emit.data(reconcileCoordinationV3(root));
751
765
  if (!opts.watch || stopped) return;
752
766
  await new Promise<void>((resolvePromise) => {
753
767
  const timer = setTimeout(resolvePromise, interval * 1_000);
@@ -2389,6 +2403,12 @@ function runStatus(opts: {
2389
2403
  /* non-fatal: status box should not fail on council errors */
2390
2404
  }
2391
2405
 
2406
+ // Latest page-QA verdict for this session, with the RUNNER's clock. Session
2407
+ // age is not QA time; without this row an operator reads "session 58m" as if
2408
+ // the QA run took 58 minutes. Best-effort by contract — no pointer, a
2409
+ // malformed one, or any read failure renders no row.
2410
+ const qaSignal = qaSignalStatusRow({ coordRoot: root, instanceId: hb.instance_id });
2411
+
2392
2412
  const data = {
2393
2413
  name: displayName,
2394
2414
  instance_id: hb.instance_id,
@@ -2426,6 +2446,7 @@ function runStatus(opts: {
2426
2446
  timestamp_iso: new Date().toISOString(),
2427
2447
  timestamp_local: timeStr,
2428
2448
  ...(quality ? { quality } : {}),
2449
+ ...(qaSignal ? { qa: qaSignal.pointer } : {}),
2429
2450
  ...(finalization ? { finalization } : {}),
2430
2451
  ...(sessionEnd ? { session_end: sessionEnd } : {}),
2431
2452
  };
@@ -2464,6 +2485,10 @@ function runStatus(opts: {
2464
2485
  const idx = rows.findIndex((row) => row[0] === "time");
2465
2486
  rows.splice(idx, 0, ["quality", formatRunQuality(quality.status, quality.signal_ids)]);
2466
2487
  }
2488
+ if (qaSignal) {
2489
+ const idx = rows.findIndex((row) => row[0] === "time");
2490
+ rows.splice(idx, 0, ["qa", qaSignal.value]);
2491
+ }
2467
2492
  if (sessionEnd) {
2468
2493
  const idx = rows.findIndex((row) => row[0] === "time");
2469
2494
  rows.splice(idx, 0, [
@@ -3022,7 +3047,7 @@ interface HealthReport {
3022
3047
  // Heartbeat cache files present in active/ but stale or malformed. These are
3023
3048
  // files the sweep is not catching; a parseable old heartbeat is stale, not
3024
3049
  // evidence of an epoch-like or corrupt timestamp.
3025
- zombies: {
3050
+ heartbeat_cache_issues: {
3026
3051
  count: number;
3027
3052
  samples: string[];
3028
3053
  };
@@ -3038,7 +3063,7 @@ interface HealthReport {
3038
3063
  latest_at: string | null;
3039
3064
  sessions: string[];
3040
3065
  };
3041
- anomalies: string[];
3066
+ findings: string[];
3042
3067
  }
3043
3068
 
3044
3069
  /** Open-span soft watermark per producer state. The producer-state reader
@@ -3091,6 +3116,13 @@ export type EventLedgerHealthV3 =
3091
3116
  /** Times the summary gate failed open (loose write proceeded). */
3092
3117
  mitigation_fail_open: number;
3093
3118
  };
3119
+ coordination_authority: {
3120
+ safe: boolean;
3121
+ global_diagnostics: number;
3122
+ isolated_diagnostics: number;
3123
+ affected_generations: string[];
3124
+ codes: string[];
3125
+ };
3094
3126
  span_pressure: Array<{ instance_id: string; generation_id: string; span_count: number }>;
3095
3127
  collection_errors: string[];
3096
3128
  };
@@ -3270,6 +3302,57 @@ export function collectEventLedgerHealthV3(root: string, nowMs = Date.now()): Ev
3270
3302
  collectionErrors.push(`diagnostic summaries unreadable: ${errorText(error)}`);
3271
3303
  }
3272
3304
 
3305
+ let coordinationAuthority: Extract<
3306
+ EventLedgerHealthV3,
3307
+ { state: "live" }
3308
+ >["coordination_authority"] = {
3309
+ safe: false,
3310
+ global_diagnostics: 0,
3311
+ isolated_diagnostics: 0,
3312
+ affected_generations: [],
3313
+ codes: [],
3314
+ };
3315
+ try {
3316
+ const view = readCoordinationViewV3(root);
3317
+ const globalDiagnostics = view.global_diagnostics.filter(
3318
+ (diagnostic) => diagnostic.authority_blocking,
3319
+ );
3320
+ const isolatedDiagnostics = new Map<string, (typeof globalDiagnostics)[number]>();
3321
+ const affectedGenerations: string[] = [];
3322
+ for (const [generationId, diagnostics] of Object.entries(view.diagnostics_by_generation)) {
3323
+ const blocking = diagnostics.filter((diagnostic) => diagnostic.authority_blocking);
3324
+ if (blocking.length === 0) continue;
3325
+ affectedGenerations.push(generationId);
3326
+ for (const diagnostic of blocking) {
3327
+ isolatedDiagnostics.set(
3328
+ [
3329
+ diagnostic.code,
3330
+ diagnostic.source_code ?? "",
3331
+ diagnostic.event_id ?? "",
3332
+ diagnostic.generation_id ?? "",
3333
+ diagnostic.subject_instance_id ?? "",
3334
+ ].join("\0"),
3335
+ diagnostic,
3336
+ );
3337
+ }
3338
+ }
3339
+ coordinationAuthority = {
3340
+ safe: view.authority_safe,
3341
+ global_diagnostics: globalDiagnostics.length,
3342
+ isolated_diagnostics: isolatedDiagnostics.size,
3343
+ affected_generations: affectedGenerations.sort(),
3344
+ codes: [
3345
+ ...new Set(
3346
+ [...globalDiagnostics, ...isolatedDiagnostics.values()].map(
3347
+ (diagnostic) => diagnostic.source_code ?? diagnostic.code,
3348
+ ),
3349
+ ),
3350
+ ].sort(),
3351
+ };
3352
+ } catch (error) {
3353
+ collectionErrors.push(`coordination authority unreadable: ${errorText(error)}`);
3354
+ }
3355
+
3273
3356
  return {
3274
3357
  state: "live",
3275
3358
  mode: control.state,
@@ -3293,6 +3376,7 @@ export function collectEventLedgerHealthV3(root: string, nowMs = Date.now()): Ev
3293
3376
  recent_by_category: recentByCategory,
3294
3377
  mitigation_fail_open: mitigationFailOpen,
3295
3378
  },
3379
+ coordination_authority: coordinationAuthority,
3296
3380
  span_pressure: spanPressure,
3297
3381
  collection_errors: collectionErrors,
3298
3382
  };
@@ -3946,8 +4030,8 @@ function runHealth(opts: { since: string; json?: boolean }): void {
3946
4030
  // Heartbeat cache issues: files in active/ that are unparseable, nameless,
3947
4031
  // invalidly timestamped, or stale. Old parseable timestamps are ordinary
3948
4032
  // staleness, not evidence of epoch-like timestamp corruption.
3949
- let zombieCount = 0;
3950
- const zombieSamples: string[] = [];
4033
+ let cacheIssueCount = 0;
4034
+ const cacheIssueSamples: string[] = [];
3951
4035
  const STALE_HEARTBEAT_AGE_MS = 24 * 60 * 60 * 1000;
3952
4036
  if (existsSync(activeDir)) {
3953
4037
  for (const file of readdirSync(activeDir)) {
@@ -3960,16 +4044,16 @@ function runHealth(opts: { since: string; json?: boolean }): void {
3960
4044
  hb = null;
3961
4045
  }
3962
4046
  if (!hb || typeof hb.instance_id !== "string") {
3963
- zombieCount++;
3964
- if (zombieSamples.length < 5)
3965
- zombieSamples.push(`${idFromFile.slice(0, 12)} (unparseable/no-id)`);
4047
+ cacheIssueCount++;
4048
+ if (cacheIssueSamples.length < 5)
4049
+ cacheIssueSamples.push(`${idFromFile.slice(0, 12)} (unparseable/no-id)`);
3966
4050
  continue;
3967
4051
  }
3968
4052
  const cacheIssue = classifyHeartbeatCacheIssue(hb, nowMs, STALE_HEARTBEAT_AGE_MS);
3969
4053
  if (cacheIssue) {
3970
- zombieCount++;
3971
- if (zombieSamples.length < 5) {
3972
- zombieSamples.push(`${idFromFile.slice(0, 12)} (${cacheIssue})`);
4054
+ cacheIssueCount++;
4055
+ if (cacheIssueSamples.length < 5) {
4056
+ cacheIssueSamples.push(`${idFromFile.slice(0, 12)} (${cacheIssue})`);
3973
4057
  }
3974
4058
  }
3975
4059
  }
@@ -3985,11 +4069,11 @@ function runHealth(opts: { since: string; json?: boolean }): void {
3985
4069
  }
3986
4070
  }
3987
4071
 
3988
- // Anomaly detection.
3989
- const anomalies: string[] = [];
4072
+ // Finding detection.
4073
+ const findings: string[] = [];
3990
4074
  for (const { agent, count } of healTopAgents) {
3991
4075
  if (count >= 5) {
3992
- anomalies.push(
4076
+ findings.push(
3993
4077
  `${agent} self-healed ${count}x in ${opts.since}; possible idle-prune loop or PID instability`,
3994
4078
  );
3995
4079
  }
@@ -4000,7 +4084,7 @@ function runHealth(opts: { since: string; json?: boolean }): void {
4000
4084
  activeAgents.source === "event-ledger-v3"
4001
4085
  ? "lifecycle reconciliation may be delayed"
4002
4086
  : "heal mechanism may not be firing";
4003
- anomalies.push(
4087
+ findings.push(
4004
4088
  `${activeAgents.stale} active ${noun}(s) without activity for ${Math.floor(freshnessCutoffSecs() / 60)}min; ${action}`,
4005
4089
  );
4006
4090
  }
@@ -4009,31 +4093,33 @@ function runHealth(opts: { since: string; json?: boolean }): void {
4009
4093
  (schema) => schema !== expectedSchema,
4010
4094
  );
4011
4095
  if (unexpectedSchemas.length > 0) {
4012
- anomalies.push(
4096
+ findings.push(
4013
4097
  `Unexpected active-agent schema versions in use: ${unexpectedSchemas.join(", ")} (expected ${expectedSchema})`,
4014
4098
  );
4015
4099
  }
4016
- // Only recent hook failures are active anomalies. Historical rows remain in
4100
+ // Only recent hook failures are active findings. Historical rows remain in
4017
4101
  // the report with exact error signatures and their latest timestamp.
4018
4102
  if (hookErrors.last1h > 0) {
4019
4103
  const top = hookErrors.recentTopErrors[0];
4020
4104
  const detail = top ? `: top '${top.error.slice(0, 80)}' x${top.count} (${top.phase})` : "";
4021
- anomalies.push(`agent-hook errored ${hookErrors.last1h}x in the last hour${detail}`);
4105
+ findings.push(`agent-hook errored ${hookErrors.last1h}x in the last hour${detail}`);
4022
4106
  }
4023
4107
  if (stream.cursor_backlog > 500) {
4024
- anomalies.push(
4108
+ findings.push(
4025
4109
  `projection cursor is ${stream.cursor_backlog} events behind; drain lagging (stop projection may be failing)`,
4026
4110
  );
4027
4111
  }
4028
- // Raw V3 stream size is not an anomaly; catalog rotation bounds readers.
4112
+ // Raw V3 stream size is not a finding; catalog rotation bounds readers.
4029
4113
  if ((sweptByReason.unparseable ?? 0) > 0) {
4030
- anomalies.push(
4114
+ findings.push(
4031
4115
  `${sweptByReason.unparseable} heartbeat(s) swept as unparseable in ${opts.since}; possible corruption or a non-atomic writer`,
4032
4116
  );
4033
4117
  }
4034
- if (zombieCount > 0) {
4035
- anomalies.push(
4036
- `${zombieCount} heartbeat cache issue(s) in active/ (${zombieSamples.join(", ")}); stale or malformed files the sweep isn't reaping`,
4118
+ if (cacheIssueCount > 0) {
4119
+ findings.push(
4120
+ `${cacheIssueCount} heartbeat cache issue(s) in active/ (${cacheIssueSamples.join(", ")}); ` +
4121
+ "rows the last sweep deliberately kept (malformed but mtime-fresh, or neither audit " +
4122
+ "write could persist), or that aged past the freshness cutoff since it ran",
4037
4123
  );
4038
4124
  }
4039
4125
  if (stopRemediation.total > 0) {
@@ -4041,11 +4127,22 @@ function runHealth(opts: { since: string; json?: boolean }): void {
4041
4127
  stopRemediation.sessions.length > 0
4042
4128
  ? ` (sessions: ${stopRemediation.sessions.map((s) => s.slice(0, 8)).join(", ")})`
4043
4129
  : "";
4044
- anomalies.push(
4130
+ findings.push(
4045
4131
  `stop-hook remediation cap exhausted ${stopRemediation.total}x in ${opts.since}${who}; these sessions ended turns without the end-of-turn ritual — check why their evidence never lands`,
4046
4132
  );
4047
4133
  }
4048
4134
  if (eventLedger.state === "live") {
4135
+ const authority = eventLedger.coordination_authority;
4136
+ if (authority.global_diagnostics > 0) {
4137
+ findings.push(
4138
+ `${authority.global_diagnostics} global coordination authority diagnostic(s): ${authority.codes.join(", ")}`,
4139
+ );
4140
+ }
4141
+ if (authority.isolated_diagnostics > 0) {
4142
+ findings.push(
4143
+ `${authority.isolated_diagnostics} coordination authority diagnostic(s) isolated to ${authority.affected_generations.length} generation(s): ${authority.codes.join(", ")}`,
4144
+ );
4145
+ }
4049
4146
  // Open spans whose generation has no open turn: the turn ended without its
4050
4147
  // tool spans closing, so an explicit end can only queue, never finalize.
4051
4148
  const orphanGenerations = eventLedger.open_spans.generations.filter(
@@ -4056,17 +4153,17 @@ function runHealth(opts: { since: string; json?: boolean }): void {
4056
4153
  (sum, generation) => sum + generation.span_count,
4057
4154
  0,
4058
4155
  );
4059
- anomalies.push(
4156
+ findings.push(
4060
4157
  `${orphanSpans} open tool span(s) across ${orphanGenerations.length} generation(s) with no open turn; orphaned spans block clean session end`,
4061
4158
  );
4062
4159
  }
4063
4160
  for (const pressure of eventLedger.span_pressure) {
4064
- anomalies.push(
4161
+ findings.push(
4065
4162
  `${pressure.instance_id} (${pressure.generation_id}) holds ${pressure.span_count} open spans (soft watermark ${SPAN_PRESSURE_SOFT_WATERMARK}; the reader's 256-span cap makes the state unreadable)`,
4066
4163
  );
4067
4164
  }
4068
4165
  for (const collectionError of eventLedger.collection_errors) {
4069
- anomalies.push(`event-ledger health: ${collectionError}`);
4166
+ findings.push(`event-ledger health: ${collectionError}`);
4070
4167
  }
4071
4168
  }
4072
4169
 
@@ -4111,14 +4208,14 @@ function runHealth(opts: { since: string; json?: boolean }): void {
4111
4208
  recent_top_errors: hookErrors.recentTopErrors,
4112
4209
  },
4113
4210
  stream,
4114
- zombies: { count: zombieCount, samples: zombieSamples },
4211
+ heartbeat_cache_issues: { count: cacheIssueCount, samples: cacheIssueSamples },
4115
4212
  event_ledger: eventLedger,
4116
4213
  stop_remediation: {
4117
4214
  total: stopRemediation.total,
4118
4215
  latest_at: stopRemediation.latestAt,
4119
4216
  sessions: stopRemediation.sessions,
4120
4217
  },
4121
- anomalies,
4218
+ findings,
4122
4219
  };
4123
4220
 
4124
4221
  if (opts.json) {
@@ -4186,6 +4283,7 @@ function renderHealthBox(report: HealthReport): void {
4186
4283
  )
4187
4284
  .join(", ");
4188
4285
  ledgerStr = [
4286
+ `authority ${ledger.coordination_authority.safe ? "safe" : "unsafe"}${ledger.coordination_authority.isolated_diagnostics > 0 ? ` (${ledger.coordination_authority.isolated_diagnostics} isolated)` : ""}`,
4189
4287
  `open spans ${ledger.open_spans.total}${orphanGenerations > 0 ? ` (${orphanGenerations} gen turn-closed)` : ""}`,
4190
4288
  `pending ends ${ledger.pending_finalizations.length}${pendingAges ? ` (${pendingAges})` : ""}`,
4191
4289
  `intake ${ledger.intake_spool.total}`,
@@ -4211,12 +4309,12 @@ function renderHealthBox(report: HealthReport): void {
4211
4309
  ["event ledger", ledgerStr],
4212
4310
  [
4213
4311
  "cache issues",
4214
- report.zombies.count === 0
4312
+ report.heartbeat_cache_issues.count === 0
4215
4313
  ? "0"
4216
- : `${report.zombies.count} (${report.zombies.samples.join(", ")})`,
4314
+ : `${report.heartbeat_cache_issues.count} (${report.heartbeat_cache_issues.samples.join(", ")})`,
4217
4315
  ],
4218
4316
  ["councils", councilParts.join(", ")],
4219
- ["anomalies", report.anomalies.length === 0 ? "(clean)" : `${report.anomalies.length} flagged`],
4317
+ ["findings", report.findings.length === 0 ? "(clean)" : `${report.findings.length} flagged`],
4220
4318
  ];
4221
4319
 
4222
4320
  const localTime = formatLocalTime(new Date(report.generated_at));
@@ -4224,9 +4322,9 @@ function renderHealthBox(report: HealthReport): void {
4224
4322
 
4225
4323
  process.stdout.write(`${formatBox(title, rows)}\n`); // lint-ok-emission: chat-paste path; mirrors runStatus's direct write so the box surfaces in both TTY + harn-session-teed contexts
4226
4324
 
4227
- if (report.anomalies.length > 0) {
4325
+ if (report.findings.length > 0) {
4228
4326
  process.stdout.write("\n"); // lint-ok-emission: same chat-paste path
4229
- for (const a of report.anomalies) {
4327
+ for (const a of report.findings) {
4230
4328
  process.stdout.write(` ! ${a}\n`); // lint-ok-emission: same
4231
4329
  }
4232
4330
  }
@@ -4660,18 +4758,52 @@ function runPing(name: string, message: string, opts: { json?: boolean }): void
4660
4758
  );
4661
4759
  process.exit(1);
4662
4760
  }
4761
+ const coordRoot = monorepoRoot();
4663
4762
  const peerOwner = resolveOwnerByName(name);
4664
- if (!peerOwner) {
4763
+
4764
+ // A name with no live session is the common case, not an error: the agent it
4765
+ // refers to may have ended minutes ago and may come back under the same name.
4766
+ // Refuse only a name that no agent has ever held, which is a typo — queueing
4767
+ // that would swallow the message silently.
4768
+ if (!peerOwner && coordRoot && !isAddressableName(coordRoot, name)) {
4769
+ const suggestions = suggestNames(coordRoot, name);
4665
4770
  emit.error({
4666
- code: "no_peer",
4667
- message: `no live agent named "${name}" (case-insensitive). Run \`${resolveBinName()} agents list\` to see who's active.`,
4771
+ code: "unknown_agent",
4772
+ message:
4773
+ `no agent has ever been named "${name}". ` +
4774
+ (suggestions.length > 0 ? `Did you mean ${suggestions.join(", ")}? ` : "") +
4775
+ `Run \`${resolveBinName()} agents list\` for live sessions.`,
4668
4776
  });
4669
4777
  process.exit(1);
4670
4778
  }
4779
+
4671
4780
  const myHb = readCurrentCoordinationRow(myOwner);
4672
4781
  const fromName = myHb?.name ?? "anonymous";
4673
4782
  const body = `from agent-${fromName}: ${message.trim()}`;
4674
- const doc = appendEntry(peerOwner, "handoff", body);
4783
+
4784
+ // A live recipient gets the journal entry immediately, so a peer reading
4785
+ // their own journal mid-session sees it without waiting for a prompt. A
4786
+ // dormant recipient has no journal to write to yet; the drain writes it into
4787
+ // whichever session picks the message up.
4788
+ const doc = peerOwner ? appendEntry(peerOwner, "handoff", body) : null;
4789
+
4790
+ let queued: QueueResult;
4791
+ try {
4792
+ queued = queueMailboxMessage({
4793
+ coordRoot: coordRoot ?? process.cwd(),
4794
+ toName: name,
4795
+ fromName,
4796
+ fromInstanceId: myOwner,
4797
+ body: message.trim(),
4798
+ journaled: Boolean(peerOwner),
4799
+ });
4800
+ } catch (error) {
4801
+ if (error instanceof MailboxCapacityError) {
4802
+ emit.error({ code: `mailbox_${error.reason_code}`, message: error.message });
4803
+ process.exit(1);
4804
+ }
4805
+ throw error;
4806
+ }
4675
4807
 
4676
4808
  // Canonical delivery record: sender is the envelope owner, recipient rides
4677
4809
  // in data, so read-only observers can render the communication without
@@ -4683,18 +4815,21 @@ function runPing(name: string, message: string, opts: { json?: boolean }): void
4683
4815
  observation: {
4684
4816
  event_type: "coord.message_observed",
4685
4817
  direction: "sent",
4686
- subject: peerOwner,
4818
+ subject: peerOwner ?? `name:${queued.message.to_name}`,
4687
4819
  body: message.trim(),
4688
4820
  },
4689
4821
  });
4690
4822
 
4691
4823
  const data = {
4692
- peer: name,
4824
+ peer: queued.message.to_name,
4693
4825
  peer_instance_id: peerOwner,
4826
+ delivery: peerOwner ? ("live" as const) : ("queued" as const),
4827
+ message_id: queued.message.message_id,
4828
+ pending: queued.pending,
4694
4829
  from: fromName,
4695
4830
  body,
4696
- journal_path: doc.path,
4697
- journal_bytes: doc.bytes,
4831
+ journal_path: doc?.path ?? null,
4832
+ journal_bytes: doc?.bytes ?? null,
4698
4833
  };
4699
4834
 
4700
4835
  if (opts.json) {
@@ -4703,7 +4838,11 @@ function runPing(name: string, message: string, opts: { json?: boolean }): void
4703
4838
  return;
4704
4839
  }
4705
4840
  emit.data(data);
4706
- emit.text(`pinged agent-${name}: "${truncate(message.trim(), 80)}"\n`);
4841
+ emit.text(
4842
+ peerOwner
4843
+ ? `delivered to agent-${data.peer} (live; they see it on their next prompt): "${truncate(message.trim(), 80)}"\n`
4844
+ : `queued for agent-${data.peer} (no live session; delivered when a session of that name next starts): "${truncate(message.trim(), 80)}"\n`,
4845
+ );
4707
4846
  }
4708
4847
 
4709
4848
  async function runWait(