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
@@ -0,0 +1,271 @@
1
+ import type { Command } from "commander";
2
+ import type { EmitContext, HarneryProgramContext } from "../commander.ts";
3
+ import { monorepoRoot, resolveOwner } from "../core/agents/index.ts";
4
+ import { readLiveCoordinationRow } from "../core/agents/state/live-coordination-view.ts";
5
+ import type { ArtifactActor } from "../core/artifacts/index.ts";
6
+ import {
7
+ buildDiagnosticAdvice,
8
+ captureDiagnosticBundle,
9
+ compareDiagnosticBundles,
10
+ DIAGNOSTIC_COMMAND_SCHEMA_VERSION,
11
+ listDiagnosticBundles,
12
+ renderDiagnosticBundleComparison,
13
+ replayDiagnosticBundle,
14
+ showDiagnosticBundle,
15
+ } from "../core/diagnostics/index.ts";
16
+ import {
17
+ buildSupervisorTimeline,
18
+ explainSupervisorFinding,
19
+ readSupervisorExplanation,
20
+ readSupervisorFindings,
21
+ readSupervisorStatus,
22
+ readSupervisorTimeline,
23
+ type SupervisorCapability,
24
+ type SupervisorFinding,
25
+ } from "../core/supervisor/index.ts";
26
+
27
+ export function registerDiagnosticsCommand(
28
+ program: Command,
29
+ emit: EmitContext,
30
+ context?: HarneryProgramContext,
31
+ ): void {
32
+ const root = program
33
+ .command("diagnostics")
34
+ .description("Capture, inspect, and replay sanitized local diagnostic bundles.");
35
+
36
+ root
37
+ .command("list")
38
+ .description("List live findings and managed diagnostic bundles.")
39
+ .action(() => {
40
+ run(emit, () => {
41
+ const repoRoot = requireRepoRoot(context);
42
+ const report = readSupervisorFindings(repoRoot);
43
+ const findings = mergeFindings(report?.active ?? [], report?.transitions ?? []);
44
+ const bundles = listDiagnosticBundles(repoRoot);
45
+ const capability = liveFindingsCapability(repoRoot, report !== undefined);
46
+ emit.data({
47
+ schema_version: DIAGNOSTIC_COMMAND_SCHEMA_VERSION,
48
+ kind: "diagnostic_list",
49
+ findings,
50
+ bundles,
51
+ capability,
52
+ total_findings: findings.length,
53
+ total_bundles: bundles.length,
54
+ });
55
+ });
56
+ });
57
+
58
+ root
59
+ .command("show <ref>")
60
+ .description("Show one finding or validate one diagnostic bundle.")
61
+ .action((ref: string) => {
62
+ run(emit, () => {
63
+ const repoRoot = requireRepoRoot(context);
64
+ const finding = findFinding(repoRoot, ref);
65
+ if (finding) {
66
+ emit.data({
67
+ schema_version: DIAGNOSTIC_COMMAND_SCHEMA_VERSION,
68
+ kind: "diagnostic_finding",
69
+ finding,
70
+ timeline:
71
+ readSupervisorTimeline(repoRoot, finding.id) ?? buildSupervisorTimeline(finding),
72
+ explanation:
73
+ readSupervisorExplanation(repoRoot, finding.id) ?? explainSupervisorFinding(finding),
74
+ });
75
+ return;
76
+ }
77
+ const bundle = showDiagnosticBundle(repoRoot, ref);
78
+ emit.data({
79
+ schema_version: DIAGNOSTIC_COMMAND_SCHEMA_VERSION,
80
+ kind: "diagnostic_bundle",
81
+ bundle: {
82
+ path: bundle.path,
83
+ manifest: bundle.manifest,
84
+ summary: bundle.summary,
85
+ },
86
+ });
87
+ });
88
+ });
89
+
90
+ root
91
+ .command("explain")
92
+ .description("Report bounded local pressure advice without taking action.")
93
+ .option("--bundle <artifact-ref>", "Use a frozen diagnostic bundle instead of live state")
94
+ .option("--json", "Emit structured JSON")
95
+ .action((opts: { bundle?: string; json?: boolean }) => {
96
+ run(emit, () => {
97
+ if (opts.json) emit.config({ format: "json" });
98
+ const repoRoot = requireRepoRoot(context);
99
+ if (opts.bundle) {
100
+ const bundle = showDiagnosticBundle(repoRoot, opts.bundle);
101
+ emit.data({
102
+ schema_version: DIAGNOSTIC_COMMAND_SCHEMA_VERSION,
103
+ kind: "diagnostic_advice",
104
+ source: {
105
+ mode: "frozen",
106
+ artifact_id: bundle.manifest.artifact_id,
107
+ captured_at: bundle.manifest.captured_at,
108
+ },
109
+ advice: bundle.expected.advice,
110
+ });
111
+ return;
112
+ }
113
+ const report = readSupervisorFindings(repoRoot);
114
+ const findings = mergeFindings(report?.active ?? [], report?.transitions ?? []);
115
+ const sourceCapability = liveFindingsCapability(repoRoot, report !== undefined);
116
+ emit.data({
117
+ schema_version: DIAGNOSTIC_COMMAND_SCHEMA_VERSION,
118
+ kind: "diagnostic_advice",
119
+ source: { mode: "live" },
120
+ advice: buildDiagnosticAdvice({
121
+ findings,
122
+ sourceCapability,
123
+ evaluatedAt: new Date().toISOString(),
124
+ }),
125
+ });
126
+ });
127
+ });
128
+
129
+ root
130
+ .command("capture")
131
+ .description("Capture sanitized supervisor inputs into a frozen managed bundle.")
132
+ .option("--finding <id>", "Capture the time range for one finding")
133
+ .option("--from <timestamp>", "Capture observations from this ISO timestamp")
134
+ .option("--to <timestamp>", "Capture observations through this ISO timestamp")
135
+ .option("--days <n>", "Managed artifact retention in days")
136
+ .action((opts: { finding?: string; from?: string; to?: string; days?: string }) => {
137
+ run(emit, () => {
138
+ const repoRoot = requireRepoRoot(context);
139
+ const captured = captureDiagnosticBundle(repoRoot, {
140
+ findingId: opts.finding,
141
+ startAt: opts.from,
142
+ endAt: opts.to,
143
+ retentionDays: opts.days === undefined ? undefined : parseDays(opts.days),
144
+ actor: currentActor(repoRoot),
145
+ });
146
+ emit.data({
147
+ schema_version: DIAGNOSTIC_COMMAND_SCHEMA_VERSION,
148
+ kind: "diagnostic_bundle_capture",
149
+ bundle: {
150
+ path: captured.path,
151
+ artifact_id: captured.manifest.artifact_id,
152
+ captured_at: captured.manifest.captured_at,
153
+ finding_id: captured.manifest.finding_id,
154
+ summary: captured.summary,
155
+ },
156
+ });
157
+ });
158
+ });
159
+
160
+ root
161
+ .command("replay <artifact-ref>")
162
+ .description("Replay a frozen bundle without reading live supervisor state.")
163
+ .action((ref: string) => {
164
+ run(emit, () => {
165
+ emit.data({
166
+ schema_version: DIAGNOSTIC_COMMAND_SCHEMA_VERSION,
167
+ kind: "diagnostic_bundle_replay",
168
+ replay: replayDiagnosticBundle(requireRepoRoot(context), ref),
169
+ });
170
+ });
171
+ });
172
+
173
+ root
174
+ .command("compare <before> <after>")
175
+ .description("Compare two frozen bundles without reading live supervisor state.")
176
+ .option("--json", "Emit structured JSON")
177
+ .action((before: string, after: string, opts: { json?: boolean }) => {
178
+ run(emit, () => {
179
+ const comparison = compareDiagnosticBundles(requireRepoRoot(context), before, after);
180
+ if (opts.json) {
181
+ emit.config({ format: "json" });
182
+ emit.data({
183
+ schema_version: DIAGNOSTIC_COMMAND_SCHEMA_VERSION,
184
+ kind: "diagnostic_bundle_comparison",
185
+ comparison,
186
+ });
187
+ return;
188
+ }
189
+ emit.text(renderDiagnosticBundleComparison(comparison));
190
+ });
191
+ });
192
+ }
193
+
194
+ function liveFindingsCapability(repoRoot: string, reportPresent: boolean): SupervisorCapability {
195
+ if (!reportPresent) {
196
+ return {
197
+ source_kind: "supervisor.findings",
198
+ state: "unsupported",
199
+ reason_code: "source_missing",
200
+ };
201
+ }
202
+ const status = readSupervisorStatus(repoRoot);
203
+ if (status.running) return { source_kind: "supervisor.findings", state: "supported" };
204
+ return {
205
+ source_kind: "supervisor.findings",
206
+ state: "expired",
207
+ reason_code: status.stale
208
+ ? "supervisor_status_stale"
209
+ : status.record
210
+ ? "supervisor_not_running"
211
+ : "supervisor_status_missing",
212
+ };
213
+ }
214
+
215
+ function findFinding(repoRoot: string, id: string): SupervisorFinding | undefined {
216
+ const report = readSupervisorFindings(repoRoot);
217
+ return mergeFindings(report?.active ?? [], report?.transitions ?? []).find(
218
+ (finding) => finding.id === id,
219
+ );
220
+ }
221
+
222
+ function mergeFindings(
223
+ active: readonly SupervisorFinding[],
224
+ transitions: readonly SupervisorFinding[],
225
+ ): SupervisorFinding[] {
226
+ const byId = new Map<string, SupervisorFinding>();
227
+ for (const finding of transitions) byId.set(finding.id, finding);
228
+ for (const finding of active) byId.set(finding.id, finding);
229
+ return [...byId.values()].sort(
230
+ (left, right) =>
231
+ Date.parse(right.observed_at) - Date.parse(left.observed_at) ||
232
+ left.id.localeCompare(right.id),
233
+ );
234
+ }
235
+
236
+ function currentActor(repoRoot: string): ArtifactActor | undefined {
237
+ const instanceId = resolveOwner();
238
+ if (!instanceId) return undefined;
239
+ const heartbeat = readLiveCoordinationRow(repoRoot, instanceId);
240
+ return {
241
+ instance_id: instanceId,
242
+ session_id: heartbeat?.session_id,
243
+ name: heartbeat?.name,
244
+ };
245
+ }
246
+
247
+ function requireRepoRoot(context?: HarneryProgramContext): string {
248
+ const root = context?.repoRoot ?? monorepoRoot();
249
+ if (!root) throw new Error("not inside a Git repository");
250
+ return root;
251
+ }
252
+
253
+ function parseDays(value: string): number {
254
+ const parsed = Number(value);
255
+ if (!Number.isInteger(parsed) || parsed < 1 || parsed > 3_650) {
256
+ throw new Error("--days must be between 1 and 3650");
257
+ }
258
+ return parsed;
259
+ }
260
+
261
+ function run(emit: EmitContext, fn: () => void): void {
262
+ try {
263
+ fn();
264
+ } catch (error) {
265
+ emit.error({
266
+ code: "diagnostics_failed",
267
+ message: error instanceof Error ? error.message : String(error),
268
+ });
269
+ emit.setExitCode(1);
270
+ }
271
+ }
@@ -96,6 +96,7 @@ async function runFetch(
96
96
  redirect: opts.redirect as RequestRedirect,
97
97
  signal: ac.signal,
98
98
  extraHeaders: context?.extraHeaders,
99
+ extraCookies: context?.extraCookies,
99
100
  responseType: "bytes",
100
101
  });
101
102
  } finally {
@@ -4,6 +4,7 @@ import type { Command } from "commander";
4
4
  import type { EmitContext, HarneryProgramContext } from "../commander.ts";
5
5
  import { resolveCoordRoot } from "../core/agents/coord-client.ts";
6
6
  import { DEFAULT_WEB_PORT, resolveWebPort } from "../core/config.ts";
7
+ import { coordRootId, localCoordRootIdUrl } from "../lib/coord-root-id.ts";
7
8
  import { localFilesOriginUrl, localFileViewerUrl } from "../lib/local-file-url.ts";
8
9
 
9
10
  export { FILES_ORIGIN_HOST } from "../lib/local-file-url.ts";
@@ -22,6 +23,92 @@ export interface LocalFileUrl {
22
23
  mode: Exclude<LocalFileUrlMode, "auto">;
23
24
  }
24
25
 
26
+ export type DashboardRootErrorCode =
27
+ | "dashboard_unreachable"
28
+ | "dashboard_identity_unavailable"
29
+ | "dashboard_root_mismatch";
30
+
31
+ export class DashboardRootError extends Error {
32
+ constructor(
33
+ readonly code: DashboardRootErrorCode,
34
+ message: string,
35
+ readonly hint: string,
36
+ ) {
37
+ super(message);
38
+ this.name = "DashboardRootError";
39
+ }
40
+ }
41
+
42
+ interface DashboardRootPayload {
43
+ root_id?: unknown;
44
+ }
45
+
46
+ export type DashboardRootFetch = (
47
+ input: string | URL | Request,
48
+ init?: RequestInit,
49
+ ) => Promise<Response>;
50
+
51
+ /**
52
+ * Prove that the dashboard on the selected port serves the same canonical
53
+ * coordination root used to mint the file URL.
54
+ */
55
+ export async function verifyDashboardRoot(
56
+ coordRoot: string,
57
+ port: number,
58
+ fetchImpl: DashboardRootFetch = fetch,
59
+ ): Promise<void> {
60
+ const url = localCoordRootIdUrl(port);
61
+ let response: Response;
62
+ try {
63
+ response = await fetchImpl(url, {
64
+ headers: { accept: "application/json" },
65
+ signal: AbortSignal.timeout(5_000),
66
+ });
67
+ } catch {
68
+ throw new DashboardRootError(
69
+ "dashboard_unreachable",
70
+ `dashboard is not reachable at http://localhost:${port}`,
71
+ "Start the dashboard for this repository, then retry.",
72
+ );
73
+ }
74
+
75
+ if (!response.ok) {
76
+ throw new DashboardRootError(
77
+ "dashboard_identity_unavailable",
78
+ `dashboard at http://localhost:${port} cannot report its repository identity (HTTP ${response.status})`,
79
+ "Update and restart the dashboard, then retry.",
80
+ );
81
+ }
82
+
83
+ let payload: DashboardRootPayload;
84
+ try {
85
+ payload = (await response.json()) as DashboardRootPayload;
86
+ } catch {
87
+ throw new DashboardRootError(
88
+ "dashboard_identity_unavailable",
89
+ `dashboard at http://localhost:${port} returned an invalid repository identity`,
90
+ "Update and restart the dashboard, then retry.",
91
+ );
92
+ }
93
+
94
+ if (typeof payload.root_id !== "string") {
95
+ throw new DashboardRootError(
96
+ "dashboard_identity_unavailable",
97
+ `dashboard at http://localhost:${port} returned an invalid repository identity`,
98
+ "Update and restart the dashboard, then retry.",
99
+ );
100
+ }
101
+
102
+ const expected = coordRootId(coordRoot);
103
+ if (payload.root_id !== expected) {
104
+ throw new DashboardRootError(
105
+ "dashboard_root_mismatch",
106
+ `dashboard at http://localhost:${port} serves a different repository`,
107
+ "Stop that dashboard and start this repository's dashboard, then retry.",
108
+ );
109
+ }
110
+ }
111
+
25
112
  function isOutsideRoot(relPath: string): boolean {
26
113
  return relPath === "" || relPath === ".." || relPath.startsWith(`..${path.sep}`);
27
114
  }
@@ -92,10 +179,17 @@ export function registerFilesCommand(
92
179
  .option("--coord-root <dir>", "Override the coord root")
93
180
  .option("--raw", "Use the isolated files origin, regardless of extension")
94
181
  .option("--viewer", "Use the dashboard file viewer, regardless of extension")
182
+ .option("--no-verify", "Mint without checking the running dashboard's repository identity")
95
183
  .action(
96
- (
184
+ async (
97
185
  filePath: string,
98
- opts: { port?: string; coordRoot?: string; raw?: boolean; viewer?: boolean },
186
+ opts: {
187
+ port?: string;
188
+ coordRoot?: string;
189
+ raw?: boolean;
190
+ viewer?: boolean;
191
+ verify?: boolean;
192
+ },
99
193
  ) => {
100
194
  if (opts.raw && opts.viewer) {
101
195
  emit.error({
@@ -129,8 +223,14 @@ export function registerFilesCommand(
129
223
  port,
130
224
  mode: opts.raw ? "raw" : opts.viewer ? "viewer" : "auto",
131
225
  });
226
+ if (opts.verify !== false) await verifyDashboardRoot(coordRoot, port);
132
227
  emit.text(`${result.url}\n`);
133
228
  } catch (error) {
229
+ if (error instanceof DashboardRootError) {
230
+ emit.error({ code: error.code, message: error.message, hint: error.hint });
231
+ emit.setExitCode(1);
232
+ return;
233
+ }
134
234
  emit.error({
135
235
  code: "invalid_local_file",
136
236
  message: error instanceof Error ? error.message : "invalid local file path",
@@ -62,6 +62,7 @@ interface CreateOpts {
62
62
  interface RunOpts {
63
63
  adapter?: string;
64
64
  cwd?: string;
65
+ observePressure?: boolean;
65
66
  subscriptionOnly?: boolean;
66
67
  allowApiBilling?: boolean;
67
68
  policy?: string;
@@ -438,6 +439,10 @@ function addServiceOptions(command: Command): Command {
438
439
  .option("--error-backoff-max-ms <n>", "Maximum service-error backoff (default 300000)")
439
440
  .option("--adapter <name>", "Fallback adapter for agent calls without a specialist")
440
441
  .option("--cwd <dir>", "Working directory for child agents")
442
+ .option(
443
+ "--observe-pressure",
444
+ "Record observer-only local pressure before each workflow's first real child dispatch",
445
+ )
441
446
  .option("--subscription-only", "Require stored adapter-login billing")
442
447
  .option("--allow-api-billing", "Permit API-key override billing")
443
448
  .option("--policy <file>", "Host policy JSON/JSONC")
@@ -596,6 +601,9 @@ function registerRunCommand(
596
601
  spawners: registry.spawners(),
597
602
  defaultAdapter: opts.adapter,
598
603
  cwd: opts.cwd,
604
+ diagnosticAdmission: opts.observePressure
605
+ ? { schema_version: 1, mode: "shadow" }
606
+ : undefined,
599
607
  subscriptionOnly:
600
608
  opts.subscriptionOnly === true ? true : workflowSubscriptionOnly(coordRoot),
601
609
  allowApiBilling: opts.allowApiBilling,
@@ -5,13 +5,16 @@ import { resolve } from "node:path";
5
5
  import type { Command } from "commander";
6
6
  import type { EmitContext, HarneryProgramContext } from "../commander.ts";
7
7
  import {
8
+ compressSealedLegacyV1Segments,
8
9
  inventoryLegacyV1Segments,
9
10
  streamLegacyV1Rows,
10
11
  verifyLegacyV1HardFence,
11
12
  writeLegacyV1Canary,
12
13
  } from "../core/events/legacy-storage/index.ts";
13
14
  import {
15
+ cleanEventV3Archives,
14
16
  initializeEventLedgerV3,
17
+ inventoryEventV3Archives,
15
18
  readEventV3ControlState,
16
19
  recoverInvalidEventLedgerV3,
17
20
  sha256V3,
@@ -59,6 +62,39 @@ export function registerLedgerV3Command(
59
62
  }
60
63
  });
61
64
 
65
+ const archives = command
66
+ .command("archives")
67
+ .description("Inventory and enforce bounded retention for complete closed V3 epochs");
68
+
69
+ archives
70
+ .command("list")
71
+ .description("Show closed epochs, retention classifications, and planned actions")
72
+ .option("--root <path>", "Explicit coordination root")
73
+ .action((options: { root?: string }) => {
74
+ try {
75
+ const rows = inventoryEventV3Archives(resolve(options.root ?? coordRoot(context)));
76
+ emit.data({ rows, meta: summarizeArchiveRows(rows) });
77
+ } catch (error) {
78
+ emitFailure(emit, "ledger_v3_archive_inventory_failed", error);
79
+ }
80
+ });
81
+
82
+ archives
83
+ .command("clean")
84
+ .description("Preview closed-epoch deletion; pass --yes to execute the exact current plan")
85
+ .option("--root <path>", "Explicit coordination root")
86
+ .option("--yes", "Delete only epochs still classified expired or over-budget")
87
+ .action((options: { root?: string; yes?: boolean }) => {
88
+ try {
89
+ const rows = cleanEventV3Archives(resolve(options.root ?? coordRoot(context)), {
90
+ yes: options.yes,
91
+ });
92
+ emit.data({ rows, meta: summarizeArchiveRows(rows) });
93
+ } catch (error) {
94
+ emitFailure(emit, "ledger_v3_archive_cleanup_failed", error);
95
+ }
96
+ });
97
+
62
98
  command
63
99
  .command("initialize")
64
100
  .description("Create V3 control state, or archive and replace the current V3 epoch")
@@ -355,6 +391,32 @@ export function registerLedgerV3Command(
355
391
  }
356
392
  });
357
393
 
394
+ command
395
+ .command("legacy-compress")
396
+ .description("Preview verified gzip replacement of sealed non-terminal V1 shards")
397
+ .option("--root <path>", "Explicit coordination root")
398
+ .option("--yes", "Replace only unchanged shards after exact logical-row parity")
399
+ .action(async (options: { root?: string; yes?: boolean }) => {
400
+ try {
401
+ const rows = await compressSealedLegacyV1Segments(
402
+ resolve(options.root ?? coordRoot(context)),
403
+ { yes: options.yes },
404
+ );
405
+ emit.data({
406
+ rows,
407
+ meta: {
408
+ total: rows.length,
409
+ would_compress: rows.filter((row) => row.action === "would-compress").length,
410
+ compressed: rows.filter((row) => row.action === "compressed").length,
411
+ bytes_before: rows.reduce((sum, row) => sum + row.bytes_before, 0),
412
+ bytes_after: rows.reduce((sum, row) => sum + (row.bytes_after ?? row.bytes_before), 0),
413
+ },
414
+ });
415
+ } catch (error) {
416
+ emitFailure(emit, "ledger_v1_compression_failed", error);
417
+ }
418
+ });
419
+
358
420
  command
359
421
  .command("verify-legacy")
360
422
  .description("Stream and validate one loose or manifest-bound gzip legacy segment")
@@ -525,6 +587,26 @@ function sameSortedStrings(left: string[], right: string[]): boolean {
525
587
  );
526
588
  }
527
589
 
590
+ function summarizeArchiveRows(
591
+ rows: Array<{ classification: string; action: string; bytes: number | null }>,
592
+ ): Record<string, unknown> {
593
+ const classifications: Record<string, number> = {};
594
+ for (const row of rows) {
595
+ classifications[row.classification] = (classifications[row.classification] ?? 0) + 1;
596
+ }
597
+ return {
598
+ total: rows.length,
599
+ bytes: rows.reduce((sum, row) => sum + (row.bytes ?? 0), 0),
600
+ classifications,
601
+ would_delete: rows.filter((row) => row.action === "would-delete").length,
602
+ would_delete_bytes: rows.reduce(
603
+ (sum, row) => sum + (row.action === "would-delete" ? (row.bytes ?? 0) : 0),
604
+ 0,
605
+ ),
606
+ deleted: rows.filter((row) => row.action === "deleted").length,
607
+ };
608
+ }
609
+
528
610
  function emitFailure(emit: EmitContext, code: string, error: unknown): never {
529
611
  emit.error({ code, message: error instanceof Error ? error.message : String(error) });
530
612
  throw error;