harnery 0.35.0 → 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 (616) 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 -96
  4. package/dist/commands/agents.d.ts +23 -3
  5. package/dist/commands/agents.d.ts.map +1 -1
  6. package/dist/commands/agents.js +379 -198
  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 +5 -4
  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/deinit.d.ts.map +1 -1
  18. package/dist/commands/deinit.js +5 -0
  19. package/dist/commands/docs.d.ts.map +1 -1
  20. package/dist/commands/docs.js +13 -2
  21. package/dist/commands/doctor.d.ts +5 -0
  22. package/dist/commands/doctor.d.ts.map +1 -1
  23. package/dist/commands/doctor.js +51 -7
  24. package/dist/commands/fetch.js +6 -5
  25. package/dist/commands/files.d.ts +22 -0
  26. package/dist/commands/files.d.ts.map +1 -0
  27. package/dist/commands/files.js +113 -0
  28. package/dist/commands/governor.js +14 -12
  29. package/dist/commands/inbox.d.ts +5 -0
  30. package/dist/commands/inbox.d.ts.map +1 -0
  31. package/dist/commands/inbox.js +57 -0
  32. package/dist/commands/init.d.ts +4 -5
  33. package/dist/commands/init.d.ts.map +1 -1
  34. package/dist/commands/init.js +63 -13
  35. package/dist/commands/ledger-v3.d.ts.map +1 -1
  36. package/dist/commands/ledger-v3.js +347 -1
  37. package/dist/commands/logs.d.ts +4 -0
  38. package/dist/commands/logs.d.ts.map +1 -0
  39. package/dist/commands/logs.js +169 -0
  40. package/dist/commands/messages.d.ts +5 -0
  41. package/dist/commands/messages.d.ts.map +1 -0
  42. package/dist/commands/messages.js +45 -0
  43. package/dist/commands/outline.d.ts +1 -1
  44. package/dist/commands/outline.d.ts.map +1 -1
  45. package/dist/commands/outline.js +2 -2
  46. package/dist/commands/read.d.ts +1 -1
  47. package/dist/commands/read.d.ts.map +1 -1
  48. package/dist/commands/read.js +2 -2
  49. package/dist/commands/semantic.d.ts.map +1 -1
  50. package/dist/commands/semantic.js +54 -2
  51. package/dist/commands/storage.d.ts +4 -0
  52. package/dist/commands/storage.d.ts.map +1 -0
  53. package/dist/commands/storage.js +238 -0
  54. package/dist/commands/tunnel.d.ts +5 -1
  55. package/dist/commands/tunnel.d.ts.map +1 -1
  56. package/dist/commands/tunnel.js +44 -31
  57. package/dist/commands/web.d.ts +3 -0
  58. package/dist/commands/web.d.ts.map +1 -1
  59. package/dist/commands/web.js +67 -7
  60. package/dist/commands/work.js +3 -3
  61. package/dist/commands/workflow.js +13 -13
  62. package/dist/core/adapters/profiles.d.ts +1 -1
  63. package/dist/core/agents/cli.js +209 -39
  64. package/dist/core/agents/live-authority-v3.d.ts +47 -1
  65. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  66. package/dist/core/agents/live-authority-v3.js +244 -10
  67. package/dist/core/agents/live-lifecycle-v3.js +6 -1
  68. package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
  69. package/dist/core/agents/live-observation-v3.js +6 -1
  70. package/dist/core/agents/render/prompt-context.d.ts +9 -3
  71. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  72. package/dist/core/agents/render/prompt-context.js +24 -7
  73. package/dist/core/agents/rules/stop-hook.d.ts +2 -0
  74. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  75. package/dist/core/agents/rules/stop-hook.js +94 -13
  76. package/dist/core/agents/rules/verdict.d.ts +1 -0
  77. package/dist/core/agents/rules/verdict.d.ts.map +1 -1
  78. package/dist/core/agents/session-events.d.ts.map +1 -1
  79. package/dist/core/agents/session-events.js +4 -0
  80. package/dist/core/agents/session-finalization-state-v3.js +1 -1
  81. package/dist/core/agents/session-finalizer-v3.js +5 -1
  82. package/dist/core/agents/state/activity-log.d.ts +3 -0
  83. package/dist/core/agents/state/activity-log.d.ts.map +1 -1
  84. package/dist/core/agents/state/activity-log.js +6 -3
  85. package/dist/core/agents/state/heartbeat-writer.d.ts +6 -0
  86. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  87. package/dist/core/agents/state/heartbeat-writer.js +18 -0
  88. package/dist/core/agents/state/live-coordination-view.d.ts +5 -7
  89. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  90. package/dist/core/agents/state/live-coordination-view.js +15 -90
  91. package/dist/core/agents/state/live-coordination-writer.d.ts +12 -0
  92. package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -0
  93. package/dist/core/agents/state/live-coordination-writer.js +92 -0
  94. package/dist/core/artifacts/index.d.ts +21 -0
  95. package/dist/core/artifacts/index.d.ts.map +1 -1
  96. package/dist/core/artifacts/index.js +46 -1
  97. package/dist/core/config.d.ts +62 -4
  98. package/dist/core/config.d.ts.map +1 -1
  99. package/dist/core/config.js +98 -4
  100. package/dist/core/conversations/archive.d.ts +49 -0
  101. package/dist/core/conversations/archive.d.ts.map +1 -0
  102. package/dist/core/conversations/archive.js +136 -0
  103. package/dist/core/conversations/catalog.d.ts +10 -0
  104. package/dist/core/conversations/catalog.d.ts.map +1 -0
  105. package/dist/core/conversations/catalog.js +72 -0
  106. package/dist/core/conversations/context-pack.d.ts +6 -0
  107. package/dist/core/conversations/context-pack.d.ts.map +1 -0
  108. package/dist/core/conversations/context-pack.js +60 -0
  109. package/dist/core/conversations/contract.d.ts +155 -0
  110. package/dist/core/conversations/contract.d.ts.map +1 -0
  111. package/dist/core/conversations/contract.js +1 -0
  112. package/dist/core/conversations/evaluation.d.ts +16 -0
  113. package/dist/core/conversations/evaluation.d.ts.map +1 -0
  114. package/dist/core/conversations/evaluation.js +9 -0
  115. package/dist/core/conversations/index.d.ts +10 -0
  116. package/dist/core/conversations/index.d.ts.map +1 -0
  117. package/dist/core/conversations/index.js +9 -0
  118. package/dist/core/conversations/lifecycle.d.ts +28 -0
  119. package/dist/core/conversations/lifecycle.d.ts.map +1 -0
  120. package/dist/core/conversations/lifecycle.js +29 -0
  121. package/dist/core/conversations/normalize.d.ts +14 -0
  122. package/dist/core/conversations/normalize.d.ts.map +1 -0
  123. package/dist/core/conversations/normalize.js +82 -0
  124. package/dist/core/conversations/query.d.ts +8 -0
  125. package/dist/core/conversations/query.d.ts.map +1 -0
  126. package/dist/core/conversations/query.js +280 -0
  127. package/dist/core/conversations/search-index.d.ts +9 -0
  128. package/dist/core/conversations/search-index.d.ts.map +1 -0
  129. package/dist/core/conversations/search-index.js +29 -0
  130. package/dist/core/events/legacy-storage/canary.d.ts +18 -0
  131. package/dist/core/events/legacy-storage/canary.d.ts.map +1 -0
  132. package/dist/core/events/legacy-storage/canary.js +150 -0
  133. package/dist/core/events/legacy-storage/fence.d.ts +15 -0
  134. package/dist/core/events/legacy-storage/fence.d.ts.map +1 -0
  135. package/dist/core/events/legacy-storage/fence.js +115 -0
  136. package/dist/core/events/legacy-storage/index.d.ts +6 -0
  137. package/dist/core/events/legacy-storage/index.d.ts.map +1 -0
  138. package/dist/core/events/legacy-storage/index.js +5 -0
  139. package/dist/core/events/legacy-storage/inventory.d.ts +10 -0
  140. package/dist/core/events/legacy-storage/inventory.d.ts.map +1 -0
  141. package/dist/core/events/legacy-storage/inventory.js +40 -0
  142. package/dist/core/events/legacy-storage/manifest.d.ts +23 -0
  143. package/dist/core/events/legacy-storage/manifest.d.ts.map +1 -0
  144. package/dist/core/events/legacy-storage/manifest.js +108 -0
  145. package/dist/core/events/legacy-storage/reader.d.ts +15 -0
  146. package/dist/core/events/legacy-storage/reader.d.ts.map +1 -0
  147. package/dist/core/events/legacy-storage/reader.js +154 -0
  148. package/dist/core/events/v3/authority-outbox.d.ts +7 -2
  149. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  150. package/dist/core/events/v3/authority-outbox.js +16 -3
  151. package/dist/core/events/v3/base-contract.d.ts +81 -41
  152. package/dist/core/events/v3/base-contract.d.ts.map +1 -1
  153. package/dist/core/events/v3/base-contract.js +17 -7
  154. package/dist/core/events/v3/bootstrap.d.ts +39 -0
  155. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  156. package/dist/core/events/v3/bootstrap.js +167 -3
  157. package/dist/core/events/v3/capabilities.js +3 -3
  158. package/dist/core/events/v3/control-witness.d.ts +44 -0
  159. package/dist/core/events/v3/control-witness.d.ts.map +1 -0
  160. package/dist/core/events/v3/control-witness.js +233 -0
  161. package/dist/core/events/v3/control-writer.d.ts +4 -0
  162. package/dist/core/events/v3/control-writer.d.ts.map +1 -0
  163. package/dist/core/events/v3/control-writer.js +16 -0
  164. package/dist/core/events/v3/control.d.ts +8 -2
  165. package/dist/core/events/v3/control.d.ts.map +1 -1
  166. package/dist/core/events/v3/control.js +46 -18
  167. package/dist/core/events/v3/coordination-transaction-recovery.d.ts +42 -0
  168. package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -0
  169. package/dist/core/events/v3/coordination-transaction-recovery.js +342 -0
  170. package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
  171. package/dist/core/events/v3/coordination-view.js +16 -1
  172. package/dist/core/events/v3/generated.d.ts +1 -1
  173. package/dist/core/events/v3/generated.js +1 -1
  174. package/dist/core/events/v3/index.d.ts +4 -2
  175. package/dist/core/events/v3/index.d.ts.map +1 -1
  176. package/dist/core/events/v3/index.js +3 -1
  177. package/dist/core/events/v3/live-route-observer.d.ts +31 -0
  178. package/dist/core/events/v3/live-route-observer.d.ts.map +1 -0
  179. package/dist/core/events/v3/live-route-observer.js +58 -0
  180. package/dist/core/events/v3/live-routing.d.ts +13 -21
  181. package/dist/core/events/v3/live-routing.d.ts.map +1 -1
  182. package/dist/core/events/v3/live-routing.js +45 -41
  183. package/dist/core/events/v3/producers/coordination-recorder.d.ts +11 -1
  184. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  185. package/dist/core/events/v3/producers/coordination-recorder.js +76 -10
  186. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts +129 -0
  187. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -0
  188. package/dist/core/events/v3/producers/diagnostic-summaries.js +499 -0
  189. package/dist/core/events/v3/producers/hook-base.js +1 -1
  190. package/dist/core/events/v3/producers/intake.d.ts +7 -0
  191. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  192. package/dist/core/events/v3/producers/intake.js +25 -2
  193. package/dist/core/events/v3/producers/producer-state-observer.d.ts +8 -0
  194. package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -0
  195. package/dist/core/events/v3/producers/producer-state-observer.js +45 -0
  196. package/dist/core/events/v3/producers/recorder.d.ts +55 -1
  197. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  198. package/dist/core/events/v3/producers/recorder.js +353 -24
  199. package/dist/core/events/v3/reader.d.ts +51 -0
  200. package/dist/core/events/v3/reader.d.ts.map +1 -1
  201. package/dist/core/events/v3/reader.js +181 -1
  202. package/dist/core/events/v3/rotation-config.d.ts +9 -0
  203. package/dist/core/events/v3/rotation-config.d.ts.map +1 -0
  204. package/dist/core/events/v3/rotation-config.js +91 -0
  205. package/dist/core/events/v3/runtime-build.d.ts +11 -0
  206. package/dist/core/events/v3/runtime-build.d.ts.map +1 -0
  207. package/dist/core/events/v3/runtime-build.js +39 -0
  208. package/dist/core/events/v3/runtime-identity.d.ts +5 -0
  209. package/dist/core/events/v3/runtime-identity.d.ts.map +1 -0
  210. package/dist/core/events/v3/runtime-identity.js +18 -0
  211. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +6 -5
  212. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -1
  213. package/dist/core/events/v3/runtime-telemetry-capabilities.js +1 -1
  214. package/dist/core/events/v3/support-storage/classify.d.ts +46 -0
  215. package/dist/core/events/v3/support-storage/classify.d.ts.map +1 -0
  216. package/dist/core/events/v3/support-storage/classify.js +149 -0
  217. package/dist/core/events/v3/support-storage/eligibility.d.ts +29 -0
  218. package/dist/core/events/v3/support-storage/eligibility.d.ts.map +1 -0
  219. package/dist/core/events/v3/support-storage/eligibility.js +35 -0
  220. package/dist/core/events/v3/support-storage/index.d.ts +10 -0
  221. package/dist/core/events/v3/support-storage/index.d.ts.map +1 -0
  222. package/dist/core/events/v3/support-storage/index.js +9 -0
  223. package/dist/core/events/v3/support-storage/inventory.d.ts +30 -0
  224. package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -0
  225. package/dist/core/events/v3/support-storage/inventory.js +94 -0
  226. package/dist/core/events/v3/support-storage/logical-authority.d.ts +14 -0
  227. package/dist/core/events/v3/support-storage/logical-authority.d.ts.map +1 -0
  228. package/dist/core/events/v3/support-storage/logical-authority.js +104 -0
  229. package/dist/core/events/v3/support-storage/maintenance.d.ts +98 -0
  230. package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -0
  231. package/dist/core/events/v3/support-storage/maintenance.js +352 -0
  232. package/dist/core/events/v3/support-storage/pack-contract.d.ts +59 -0
  233. package/dist/core/events/v3/support-storage/pack-contract.d.ts.map +1 -0
  234. package/dist/core/events/v3/support-storage/pack-contract.js +249 -0
  235. package/dist/core/events/v3/support-storage/pack-reader.d.ts +34 -0
  236. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -0
  237. package/dist/core/events/v3/support-storage/pack-reader.js +258 -0
  238. package/dist/core/events/v3/support-storage/pack-writer.d.ts +30 -0
  239. package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -0
  240. package/dist/core/events/v3/support-storage/pack-writer.js +268 -0
  241. package/dist/core/events/v3/support-storage/recovery.d.ts +15 -0
  242. package/dist/core/events/v3/support-storage/recovery.d.ts.map +1 -0
  243. package/dist/core/events/v3/support-storage/recovery.js +22 -0
  244. package/dist/core/events/v3/turn-telemetry.d.ts +14 -8
  245. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
  246. package/dist/core/events/v3/turn-telemetry.js +32 -2
  247. package/dist/core/events/v3/writer.d.ts +13 -1
  248. package/dist/core/events/v3/writer.d.ts.map +1 -1
  249. package/dist/core/events/v3/writer.js +126 -12
  250. package/dist/core/governor/plan-read.d.ts.map +1 -1
  251. package/dist/core/governor/plan-read.js +5 -21
  252. package/dist/core/governor/planning.js +6 -8
  253. package/dist/core/governor/service-read.d.ts +12 -0
  254. package/dist/core/governor/service-read.d.ts.map +1 -1
  255. package/dist/core/governor/service-read.js +266 -2
  256. package/dist/core/governor/service.d.ts +1 -0
  257. package/dist/core/governor/service.d.ts.map +1 -1
  258. package/dist/core/governor/service.js +53 -18
  259. package/dist/core/guard/evidence-v3.d.ts.map +1 -1
  260. package/dist/core/guard/evidence-v3.js +2 -0
  261. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  262. package/dist/core/hooks/adapter/events.js +1 -0
  263. package/dist/core/hooks/adapter/output.d.ts +4 -2
  264. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  265. package/dist/core/hooks/adapter/output.js +13 -5
  266. package/dist/core/hooks/adapter/runtime-telemetry.d.ts +27 -4
  267. package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -1
  268. package/dist/core/hooks/adapter/runtime-telemetry.js +307 -6
  269. package/dist/core/hooks/cli.js +212 -30
  270. package/dist/core/hooks/effects/image-capture.d.ts +1 -1
  271. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  272. package/dist/core/hooks/effects/image-capture.js +4 -2
  273. package/dist/core/hooks/remediation-cap.d.ts +8 -3
  274. package/dist/core/hooks/remediation-cap.d.ts.map +1 -1
  275. package/dist/core/hooks/remediation-cap.js +3 -11
  276. package/dist/core/hooks/resolve/coord-root.d.ts +22 -9
  277. package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
  278. package/dist/core/hooks/resolve/coord-root.js +92 -11
  279. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  280. package/dist/core/hooks/resolve/owner.js +5 -0
  281. package/dist/core/hooks/resolve/transcript.d.ts +8 -0
  282. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  283. package/dist/core/hooks/resolve/transcript.js +11 -0
  284. package/dist/core/inbox/contract.d.ts +64 -0
  285. package/dist/core/inbox/contract.d.ts.map +1 -0
  286. package/dist/core/inbox/contract.js +13 -0
  287. package/dist/core/inbox/index.d.ts +5 -0
  288. package/dist/core/inbox/index.d.ts.map +1 -0
  289. package/dist/core/inbox/index.js +4 -0
  290. package/dist/core/inbox/lifecycle.d.ts +22 -0
  291. package/dist/core/inbox/lifecycle.d.ts.map +1 -0
  292. package/dist/core/inbox/lifecycle.js +41 -0
  293. package/dist/core/inbox/service.d.ts +36 -0
  294. package/dist/core/inbox/service.d.ts.map +1 -0
  295. package/dist/core/inbox/service.js +210 -0
  296. package/dist/core/inbox/watcher.d.ts +7 -0
  297. package/dist/core/inbox/watcher.d.ts.map +1 -0
  298. package/dist/core/inbox/watcher.js +26 -0
  299. package/dist/core/presence/codec-digest.d.ts.map +1 -1
  300. package/dist/core/presence/codec-digest.js +14 -3
  301. package/dist/core/presence/relay-client.d.ts +1 -0
  302. package/dist/core/presence/relay-client.d.ts.map +1 -1
  303. package/dist/core/presence/relay-client.js +52 -8
  304. package/dist/core/semantic/adapters.d.ts +11 -8
  305. package/dist/core/semantic/adapters.d.ts.map +1 -1
  306. package/dist/core/semantic/adapters.js +169 -31
  307. package/dist/core/semantic/contract.d.ts +532 -48
  308. package/dist/core/semantic/contract.d.ts.map +1 -1
  309. package/dist/core/semantic/contract.js +104 -3
  310. package/dist/core/semantic/index.d.ts +7 -3
  311. package/dist/core/semantic/index.d.ts.map +1 -1
  312. package/dist/core/semantic/index.js +7 -3
  313. package/dist/core/semantic/once.d.ts +6 -1
  314. package/dist/core/semantic/once.d.ts.map +1 -1
  315. package/dist/core/semantic/once.js +80 -9
  316. package/dist/core/semantic/prompt.d.ts.map +1 -1
  317. package/dist/core/semantic/prompt.js +14 -1
  318. package/dist/core/semantic/review.d.ts +144 -0
  319. package/dist/core/semantic/review.d.ts.map +1 -0
  320. package/dist/core/semantic/review.js +544 -0
  321. package/dist/core/semantic/routes.d.ts +10 -0
  322. package/dist/core/semantic/routes.d.ts.map +1 -0
  323. package/dist/core/semantic/routes.js +21 -0
  324. package/dist/core/semantic/scheduler.d.ts +14 -3
  325. package/dist/core/semantic/scheduler.d.ts.map +1 -1
  326. package/dist/core/semantic/scheduler.js +30 -6
  327. package/dist/core/semantic/service-status.d.ts +20 -0
  328. package/dist/core/semantic/service-status.d.ts.map +1 -1
  329. package/dist/core/semantic/service-status.js +60 -4
  330. package/dist/core/semantic/service.d.ts +1 -0
  331. package/dist/core/semantic/service.d.ts.map +1 -1
  332. package/dist/core/semantic/service.js +104 -15
  333. package/dist/core/semantic/soak.d.ts +75 -0
  334. package/dist/core/semantic/soak.d.ts.map +1 -0
  335. package/dist/core/semantic/soak.js +476 -0
  336. package/dist/core/semantic/storage.d.ts +11 -1
  337. package/dist/core/semantic/storage.d.ts.map +1 -1
  338. package/dist/core/semantic/storage.js +4 -3
  339. package/dist/core/semantic/usage.d.ts +43 -0
  340. package/dist/core/semantic/usage.d.ts.map +1 -0
  341. package/dist/core/semantic/usage.js +193 -0
  342. package/dist/core/semantic/validate.d.ts +3 -1
  343. package/dist/core/semantic/validate.d.ts.map +1 -1
  344. package/dist/core/semantic/validate.js +34 -1
  345. package/dist/core/storage/buffer.d.ts +28 -0
  346. package/dist/core/storage/buffer.d.ts.map +1 -0
  347. package/dist/core/storage/buffer.js +101 -0
  348. package/dist/core/storage/builtins.d.ts +3 -0
  349. package/dist/core/storage/builtins.d.ts.map +1 -0
  350. package/dist/core/storage/builtins.js +683 -0
  351. package/dist/core/storage/catalog.d.ts +19 -0
  352. package/dist/core/storage/catalog.d.ts.map +1 -0
  353. package/dist/core/storage/catalog.js +365 -0
  354. package/dist/core/storage/config.d.ts +16 -0
  355. package/dist/core/storage/config.d.ts.map +1 -0
  356. package/dist/core/storage/config.js +311 -0
  357. package/dist/core/storage/contract.d.ts +275 -0
  358. package/dist/core/storage/contract.d.ts.map +1 -0
  359. package/dist/core/storage/contract.js +3 -0
  360. package/dist/core/storage/durable-history.d.ts +36 -0
  361. package/dist/core/storage/durable-history.d.ts.map +1 -0
  362. package/dist/core/storage/durable-history.js +606 -0
  363. package/dist/core/storage/health.d.ts +4 -0
  364. package/dist/core/storage/health.d.ts.map +1 -0
  365. package/dist/core/storage/health.js +65 -0
  366. package/dist/core/storage/index.d.ts +16 -0
  367. package/dist/core/storage/index.d.ts.map +1 -0
  368. package/dist/core/storage/index.js +15 -0
  369. package/dist/core/storage/inventory.d.ts +25 -0
  370. package/dist/core/storage/inventory.d.ts.map +1 -0
  371. package/dist/core/storage/inventory.js +666 -0
  372. package/dist/core/storage/jsonl.d.ts +52 -0
  373. package/dist/core/storage/jsonl.d.ts.map +1 -0
  374. package/dist/core/storage/jsonl.js +156 -0
  375. package/dist/core/storage/log-retention.d.ts +52 -0
  376. package/dist/core/storage/log-retention.d.ts.map +1 -0
  377. package/dist/core/storage/log-retention.js +419 -0
  378. package/dist/core/storage/logger.d.ts +82 -0
  379. package/dist/core/storage/logger.d.ts.map +1 -0
  380. package/dist/core/storage/logger.js +411 -0
  381. package/dist/core/storage/maintenance-providers.d.ts +26 -0
  382. package/dist/core/storage/maintenance-providers.d.ts.map +1 -0
  383. package/dist/core/storage/maintenance-providers.js +141 -0
  384. package/dist/core/storage/maintenance.d.ts +125 -0
  385. package/dist/core/storage/maintenance.d.ts.map +1 -0
  386. package/dist/core/storage/maintenance.js +609 -0
  387. package/dist/core/storage/metrics.d.ts +60 -0
  388. package/dist/core/storage/metrics.d.ts.map +1 -0
  389. package/dist/core/storage/metrics.js +134 -0
  390. package/dist/core/storage/policy.d.ts +7 -0
  391. package/dist/core/storage/policy.d.ts.map +1 -0
  392. package/dist/core/storage/policy.js +110 -0
  393. package/dist/core/storage/process-log.d.ts +38 -0
  394. package/dist/core/storage/process-log.d.ts.map +1 -0
  395. package/dist/core/storage/process-log.js +165 -0
  396. package/dist/core/storage/query.d.ts +34 -0
  397. package/dist/core/storage/query.d.ts.map +1 -0
  398. package/dist/core/storage/query.js +295 -0
  399. package/dist/core/storage/receipts.d.ts +23 -0
  400. package/dist/core/storage/receipts.d.ts.map +1 -0
  401. package/dist/core/storage/receipts.js +117 -0
  402. package/dist/core/storage/segments.d.ts +84 -0
  403. package/dist/core/storage/segments.d.ts.map +1 -0
  404. package/dist/core/storage/segments.js +542 -0
  405. package/dist/core/storage/sink-graph.d.ts +65 -0
  406. package/dist/core/storage/sink-graph.d.ts.map +1 -0
  407. package/dist/core/storage/sink-graph.js +213 -0
  408. package/dist/core/storage/storm-control.d.ts +23 -0
  409. package/dist/core/storage/storm-control.d.ts.map +1 -0
  410. package/dist/core/storage/storm-control.js +59 -0
  411. package/dist/core/work/state.d.ts.map +1 -1
  412. package/dist/core/work/state.js +10 -14
  413. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  414. package/dist/core/workflow/live-session-v3.js +2 -1
  415. package/dist/index.d.ts +2 -0
  416. package/dist/index.d.ts.map +1 -1
  417. package/dist/index.js +2 -0
  418. package/dist/lazy-commands.d.ts +26 -0
  419. package/dist/lazy-commands.d.ts.map +1 -0
  420. package/dist/lazy-commands.js +210 -0
  421. package/dist/lib/docs-lint.d.ts +2 -0
  422. package/dist/lib/docs-lint.d.ts.map +1 -1
  423. package/dist/lib/docs-lint.js +45 -80
  424. package/dist/lib/docs-metadata-audit.d.ts +3 -0
  425. package/dist/lib/docs-metadata-audit.d.ts.map +1 -1
  426. package/dist/lib/docs-metadata-audit.js +13 -23
  427. package/dist/lib/docs-metadata-sync.d.ts +1 -0
  428. package/dist/lib/docs-metadata-sync.d.ts.map +1 -1
  429. package/dist/lib/docs-metadata-sync.js +28 -10
  430. package/dist/lib/docs-repository-view.d.ts +22 -0
  431. package/dist/lib/docs-repository-view.d.ts.map +1 -0
  432. package/dist/lib/docs-repository-view.js +185 -0
  433. package/dist/lib/http/client.d.ts +11 -5
  434. package/dist/lib/http/client.d.ts.map +1 -1
  435. package/dist/lib/http/client.js +22 -4
  436. package/dist/lib/http/index.d.ts +1 -1
  437. package/dist/lib/http/index.d.ts.map +1 -1
  438. package/dist/lib/http/index.js +1 -1
  439. package/dist/lib/indexer-exclusions.d.ts +27 -0
  440. package/dist/lib/indexer-exclusions.d.ts.map +1 -0
  441. package/dist/lib/indexer-exclusions.js +176 -0
  442. package/dist/lib/instructions/templates.d.ts.map +1 -1
  443. package/dist/lib/instructions/templates.js +5 -0
  444. package/dist/lib/local-file-url.d.ts +9 -0
  445. package/dist/lib/local-file-url.d.ts.map +1 -0
  446. package/dist/lib/local-file-url.js +20 -0
  447. package/dist/lib/web-performance.d.ts +118 -0
  448. package/dist/lib/web-performance.d.ts.map +1 -0
  449. package/dist/lib/web-performance.js +192 -0
  450. package/package.json +29 -2
  451. package/schemas/config.schema.json +58 -0
  452. package/schemas/event-v3.schema.json +324 -112
  453. package/src/commander.ts +462 -95
  454. package/src/commands/agents.ts +517 -190
  455. package/src/commands/backup.ts +18 -14
  456. package/src/commands/browse-session.ts +12 -0
  457. package/src/commands/browse.ts +6 -7
  458. package/src/commands/conversations.ts +279 -0
  459. package/src/commands/deinit.ts +6 -0
  460. package/src/commands/docs.ts +25 -6
  461. package/src/commands/doctor.ts +75 -9
  462. package/src/commands/fetch.ts +7 -6
  463. package/src/commands/files.ts +143 -0
  464. package/src/commands/governor.ts +13 -12
  465. package/src/commands/inbox.ts +61 -0
  466. package/src/commands/init.ts +78 -16
  467. package/src/commands/ledger-v3.ts +421 -1
  468. package/src/commands/logs.ts +224 -0
  469. package/src/commands/messages.ts +61 -0
  470. package/src/commands/outline.ts +6 -2
  471. package/src/commands/read.ts +6 -2
  472. package/src/commands/semantic.ts +66 -1
  473. package/src/commands/storage.ts +310 -0
  474. package/src/commands/tunnel.ts +66 -52
  475. package/src/commands/web.ts +77 -7
  476. package/src/commands/work.ts +3 -3
  477. package/src/commands/workflow.ts +13 -13
  478. package/src/core/agents/cli.ts +259 -53
  479. package/src/core/agents/live-authority-v3.ts +341 -10
  480. package/src/core/agents/live-lifecycle-v3.ts +6 -1
  481. package/src/core/agents/live-observation-v3.ts +6 -1
  482. package/src/core/agents/render/prompt-context.ts +27 -6
  483. package/src/core/agents/rules/stop-hook.ts +107 -16
  484. package/src/core/agents/rules/verdict.ts +1 -0
  485. package/src/core/agents/session-events.ts +4 -0
  486. package/src/core/agents/session-finalization-state-v3.ts +1 -1
  487. package/src/core/agents/session-finalizer-v3.ts +4 -1
  488. package/src/core/agents/state/activity-log.ts +7 -2
  489. package/src/core/agents/state/heartbeat-writer.ts +27 -0
  490. package/src/core/agents/state/live-coordination-view.ts +16 -105
  491. package/src/core/agents/state/live-coordination-writer.ts +141 -0
  492. package/src/core/artifacts/index.ts +64 -1
  493. package/src/core/config.ts +126 -5
  494. package/src/core/conversations/archive.ts +237 -0
  495. package/src/core/conversations/catalog.ts +79 -0
  496. package/src/core/conversations/context-pack.ts +72 -0
  497. package/src/core/conversations/contract.ts +178 -0
  498. package/src/core/conversations/evaluation.ts +30 -0
  499. package/src/core/conversations/index.ts +9 -0
  500. package/src/core/conversations/lifecycle.ts +63 -0
  501. package/src/core/conversations/normalize.ts +105 -0
  502. package/src/core/conversations/query.ts +318 -0
  503. package/src/core/conversations/search-index.ts +48 -0
  504. package/src/core/events/legacy-storage/canary.ts +177 -0
  505. package/src/core/events/legacy-storage/fence.ts +129 -0
  506. package/src/core/events/legacy-storage/index.ts +5 -0
  507. package/src/core/events/legacy-storage/inventory.ts +51 -0
  508. package/src/core/events/legacy-storage/manifest.ts +136 -0
  509. package/src/core/events/legacy-storage/reader.ts +178 -0
  510. package/src/core/events/v3/authority-outbox.ts +22 -1
  511. package/src/core/events/v3/base-contract.ts +17 -7
  512. package/src/core/events/v3/bootstrap.ts +195 -2
  513. package/src/core/events/v3/capabilities.ts +3 -3
  514. package/src/core/events/v3/control-witness.ts +339 -0
  515. package/src/core/events/v3/control-writer.ts +16 -0
  516. package/src/core/events/v3/control.ts +54 -18
  517. package/src/core/events/v3/coordination-transaction-recovery.ts +477 -0
  518. package/src/core/events/v3/coordination-view.ts +17 -1
  519. package/src/core/events/v3/generated.ts +1 -1
  520. package/src/core/events/v3/index.ts +5 -2
  521. package/src/core/events/v3/live-route-observer.ts +80 -0
  522. package/src/core/events/v3/live-routing.ts +64 -46
  523. package/src/core/events/v3/producers/coordination-recorder.ts +95 -10
  524. package/src/core/events/v3/producers/diagnostic-summaries.ts +593 -0
  525. package/src/core/events/v3/producers/hook-base.ts +1 -1
  526. package/src/core/events/v3/producers/intake.ts +30 -2
  527. package/src/core/events/v3/producers/producer-state-observer.ts +52 -0
  528. package/src/core/events/v3/producers/recorder.ts +571 -33
  529. package/src/core/events/v3/reader.ts +243 -2
  530. package/src/core/events/v3/rotation-config.ts +98 -0
  531. package/src/core/events/v3/runtime-build.ts +41 -0
  532. package/src/core/events/v3/runtime-identity.ts +16 -0
  533. package/src/core/events/v3/runtime-telemetry-capabilities.ts +14 -8
  534. package/src/core/events/v3/support-storage/classify.ts +209 -0
  535. package/src/core/events/v3/support-storage/eligibility.ts +58 -0
  536. package/src/core/events/v3/support-storage/index.ts +9 -0
  537. package/src/core/events/v3/support-storage/inventory.ts +135 -0
  538. package/src/core/events/v3/support-storage/logical-authority.ts +117 -0
  539. package/src/core/events/v3/support-storage/maintenance.ts +501 -0
  540. package/src/core/events/v3/support-storage/pack-contract.ts +337 -0
  541. package/src/core/events/v3/support-storage/pack-reader.ts +346 -0
  542. package/src/core/events/v3/support-storage/pack-writer.ts +352 -0
  543. package/src/core/events/v3/support-storage/recovery.ts +43 -0
  544. package/src/core/events/v3/turn-telemetry.ts +58 -7
  545. package/src/core/events/v3/writer.ts +168 -16
  546. package/src/core/governor/plan-read.ts +5 -18
  547. package/src/core/governor/planning.ts +5 -8
  548. package/src/core/governor/service-read.ts +320 -2
  549. package/src/core/governor/service.ts +49 -22
  550. package/src/core/guard/evidence-v3.ts +1 -0
  551. package/src/core/hooks/adapter/events.ts +1 -0
  552. package/src/core/hooks/adapter/output.ts +12 -5
  553. package/src/core/hooks/adapter/runtime-telemetry.ts +408 -13
  554. package/src/core/hooks/cli.ts +226 -32
  555. package/src/core/hooks/effects/image-capture.ts +4 -1
  556. package/src/core/hooks/remediation-cap.ts +12 -6
  557. package/src/core/hooks/resolve/coord-root.ts +91 -11
  558. package/src/core/hooks/resolve/owner.ts +4 -0
  559. package/src/core/hooks/resolve/transcript.ts +18 -0
  560. package/src/core/inbox/contract.ts +81 -0
  561. package/src/core/inbox/index.ts +4 -0
  562. package/src/core/inbox/lifecycle.ts +104 -0
  563. package/src/core/inbox/service.ts +305 -0
  564. package/src/core/inbox/watcher.ts +36 -0
  565. package/src/core/presence/codec-digest.ts +15 -9
  566. package/src/core/presence/relay-client.ts +55 -7
  567. package/src/core/semantic/adapters.ts +200 -41
  568. package/src/core/semantic/contract.ts +135 -3
  569. package/src/core/semantic/index.ts +76 -2
  570. package/src/core/semantic/once.ts +93 -7
  571. package/src/core/semantic/prompt.ts +13 -1
  572. package/src/core/semantic/review.ts +803 -0
  573. package/src/core/semantic/routes.ts +30 -0
  574. package/src/core/semantic/scheduler.ts +49 -5
  575. package/src/core/semantic/service-status.ts +99 -5
  576. package/src/core/semantic/service.ts +116 -15
  577. package/src/core/semantic/soak.ts +638 -0
  578. package/src/core/semantic/storage.ts +20 -6
  579. package/src/core/semantic/usage.ts +272 -0
  580. package/src/core/semantic/validate.ts +31 -0
  581. package/src/core/storage/buffer.ts +124 -0
  582. package/src/core/storage/builtins.ts +916 -0
  583. package/src/core/storage/catalog.ts +467 -0
  584. package/src/core/storage/config.ts +423 -0
  585. package/src/core/storage/contract.ts +342 -0
  586. package/src/core/storage/durable-history.ts +738 -0
  587. package/src/core/storage/health.ts +76 -0
  588. package/src/core/storage/index.ts +15 -0
  589. package/src/core/storage/inventory.ts +859 -0
  590. package/src/core/storage/jsonl.ts +213 -0
  591. package/src/core/storage/log-retention.ts +555 -0
  592. package/src/core/storage/logger.ts +546 -0
  593. package/src/core/storage/maintenance-providers.ts +200 -0
  594. package/src/core/storage/maintenance.ts +929 -0
  595. package/src/core/storage/metrics.ts +199 -0
  596. package/src/core/storage/policy.ts +141 -0
  597. package/src/core/storage/process-log.ts +203 -0
  598. package/src/core/storage/query.ts +360 -0
  599. package/src/core/storage/receipts.ts +162 -0
  600. package/src/core/storage/segments.ts +721 -0
  601. package/src/core/storage/sink-graph.ts +343 -0
  602. package/src/core/storage/storm-control.ts +91 -0
  603. package/src/core/work/state.ts +12 -21
  604. package/src/core/workflow/live-session-v3.ts +2 -4
  605. package/src/index.ts +2 -0
  606. package/src/lazy-commands.ts +294 -0
  607. package/src/lib/docs-lint.ts +58 -77
  608. package/src/lib/docs-metadata-audit.ts +26 -21
  609. package/src/lib/docs-metadata-sync.ts +32 -9
  610. package/src/lib/docs-repository-view.ts +220 -0
  611. package/src/lib/http/client.ts +44 -8
  612. package/src/lib/http/index.ts +6 -1
  613. package/src/lib/indexer-exclusions.ts +173 -0
  614. package/src/lib/instructions/templates.ts +5 -0
  615. package/src/lib/local-file-url.ts +31 -0
  616. package/src/lib/web-performance.ts +335 -0
@@ -0,0 +1,499 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { appendFileSync, chmodSync, closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readdirSync, readFileSync, renameSync, rmdirSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
3
+ import { hostname } from "node:os";
4
+ import { join, resolve } from "node:path";
5
+ import { coordEnv } from "../../../../lib/env.js";
6
+ import { fsyncParentDirectory } from "../../../workflow/durable-record.js";
7
+ import { acquireNoClobberLease } from "../../../workflow/workspaces/leases.js";
8
+ import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../writer.js";
9
+ /**
10
+ * Producer-side bound on duplicate diagnostic file creation.
11
+ *
12
+ * A producer fault can emit the same diagnostic thousands of times per day,
13
+ * and every emission used to become one loose file in the diagnostics spool.
14
+ * This module keeps the first bounded loose exemplars per
15
+ * (category, reason, instance) key and UTC day unchanged, then coalesces
16
+ * further identical emissions into one deterministic summary file per key and
17
+ * window, preserving the exact logical count, first and last times,
18
+ * represented bytes, hourly rate buckets, and bounded exemplar digests.
19
+ *
20
+ * Below the bound the gate creates no state at all: admitted loose filenames
21
+ * carry the key digest as a suffix, and the gate counts a key's emissions for
22
+ * the window from those filenames alone. A summary file and its short-lived
23
+ * per-key lease exist only for a key that actually crossed the bound, so a
24
+ * healthy spool gains zero files and zero directories from this mitigation.
25
+ *
26
+ * The mitigation is fail-open: any count, lease, read, or publish failure
27
+ * admits the loose diagnostic exactly as before and appends to a lock-free,
28
+ * size-capped emergency log. It never deletes, moves, or rewrites an existing
29
+ * loose diagnostic, and it never calls back into the diagnostic writer.
30
+ */
31
+ export const DIAGNOSTIC_SUMMARY_FORMAT = "harnery-v3-diagnostic-summary";
32
+ export const DIAGNOSTIC_SUMMARY_VERSION = 1;
33
+ /**
34
+ * Loose exemplars admitted per (category, reason, instance) key per UTC day
35
+ * before identical emissions coalesce into the key's summary. Frozen from a
36
+ * whole-history measurement: healthy categories peak well under this value
37
+ * per day across ALL keys combined, while a producer fault exceeds it within
38
+ * minutes. The bound is enforced from filename counts without cross-process
39
+ * locking, so simultaneous writers straddling the crossing can admit a few
40
+ * extra exemplars; the bound is a flood stop, not an exact quota.
41
+ */
42
+ export const DIAGNOSTIC_LOOSE_EXEMPLAR_LIMIT = 32;
43
+ /** Bounded exemplar digests retained inside one summary. */
44
+ const SUMMARY_EXEMPLAR_LIMIT = 4;
45
+ /**
46
+ * Hourly rate buckets retained inside one summary. One summary covers one UTC
47
+ * day, so at most 24 buckets are reachable; the margin absorbs clock skew.
48
+ * Consumer windows wider than a day (doctor reads 48h) span multiple
49
+ * day-scoped summary files, not more buckets in one file.
50
+ */
51
+ const SUMMARY_HOUR_BUCKET_LIMIT = 26;
52
+ /** Refuse to publish a summary larger than this; falls open to loose writes. */
53
+ const SUMMARY_MAX_BYTES = 128 * 1024;
54
+ /** Coalesce updates fsync only every Nth increment; a crash between durable
55
+ * points can lose at most this many recent increments from the summary. */
56
+ const SUMMARY_DURABLE_EVERY = 32;
57
+ /** Stop appending to the emergency fail-open log past this size. */
58
+ const MITIGATION_HEALTH_MAX_BYTES = 256 * 1024;
59
+ export const DIAGNOSTIC_MITIGATION_HEALTH_FILE = "mitigation-health.ndjson";
60
+ const LEASE_STALE_AFTER_MS = 5_000;
61
+ const LEASE_RETRIES = 4;
62
+ const LEASE_RETRY_MS = 10;
63
+ const METADATA_KEY_LIMIT = 16;
64
+ const METADATA_VALUE_LIMIT = 256;
65
+ /** Extracts the 15-digit epoch-ms segment of a loose diagnostic order key. */
66
+ const LOOSE_ORDER_KEY_TIMESTAMP = /-(\d{15})-\d{20}-/;
67
+ const sleepCell = new Int32Array(new SharedArrayBuffer(4));
68
+ export function diagnosticSummariesRootV3(coordRoot) {
69
+ return join(resolve(coordRoot), EVENT_V3_LEDGER_RELATIVE_ROOT, "diagnostic-summaries");
70
+ }
71
+ function looseDiagnosticsRootV3(coordRoot) {
72
+ return join(resolve(coordRoot), EVENT_V3_LEDGER_RELATIVE_ROOT, "diagnostics");
73
+ }
74
+ export function diagnosticSummariesEnabledV3() {
75
+ return coordEnv("V3_DIAGNOSTIC_SUMMARIES") !== "0";
76
+ }
77
+ function sanitizeComponent(value, fallback) {
78
+ if (typeof value !== "string" || value.length === 0)
79
+ return fallback;
80
+ const safe = value.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 128);
81
+ return safe.length > 0 ? safe : fallback;
82
+ }
83
+ function keyDigest(category, reason, instanceId) {
84
+ return createHash("sha256")
85
+ .update(`${category}\n${reason}\n${instanceId}`)
86
+ .digest("hex")
87
+ .slice(0, 16);
88
+ }
89
+ function utcDay(nowMs) {
90
+ return new Date(nowMs).toISOString().slice(0, 10);
91
+ }
92
+ function utcHour(nowMs) {
93
+ return new Date(nowMs).toISOString().slice(0, 13);
94
+ }
95
+ function summaryPath(root, category, window, digest) {
96
+ return join(root, `${category}-${window.replaceAll("-", "")}-${digest}.json`);
97
+ }
98
+ function ensureOwnerOnlyDirectory(path) {
99
+ mkdirSync(path, { recursive: true, mode: 0o700 });
100
+ chmodSync(path, 0o700);
101
+ }
102
+ function publishOwnerOnlyJson(path, value, durable) {
103
+ const contents = `${JSON.stringify(value)}\n`;
104
+ if (Buffer.byteLength(contents, "utf8") > SUMMARY_MAX_BYTES) {
105
+ throw new Error("diagnostic summary exceeds its size bound");
106
+ }
107
+ const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
108
+ let fd;
109
+ try {
110
+ fd = openSync(temporary, "wx", 0o600);
111
+ writeFileSync(fd, contents, "utf8");
112
+ if (durable)
113
+ fsyncSync(fd);
114
+ closeSync(fd);
115
+ fd = undefined;
116
+ renameSync(temporary, path);
117
+ if (durable)
118
+ fsyncParentDirectory(path);
119
+ }
120
+ finally {
121
+ if (fd !== undefined)
122
+ closeSync(fd);
123
+ if (existsSync(temporary))
124
+ unlinkSync(temporary);
125
+ }
126
+ }
127
+ function pidIsAlive(pid) {
128
+ if (!Number.isSafeInteger(pid) || pid < 1)
129
+ return false;
130
+ try {
131
+ process.kill(pid, 0);
132
+ return true;
133
+ }
134
+ catch (error) {
135
+ return error.code !== "ESRCH";
136
+ }
137
+ }
138
+ function withKeyLease(root, digest, operation) {
139
+ const leasesDir = join(root, "leases");
140
+ ensureOwnerOnlyDirectory(leasesDir);
141
+ const leaseDir = join(leasesDir, digest);
142
+ const authority = createHash("sha256").update(resolve(root)).digest("hex");
143
+ let lease;
144
+ for (let attempt = 0; attempt < LEASE_RETRIES; attempt += 1) {
145
+ try {
146
+ lease = acquireNoClobberLease({
147
+ path: leaseDir,
148
+ scope: "event-v3-diagnostic-summary",
149
+ authoritySha256: authority,
150
+ staleAfterMs: LEASE_STALE_AFTER_MS,
151
+ validateStaleOwner: (owner) => owner.host === hostname() && !pidIsAlive(owner.pid),
152
+ });
153
+ break;
154
+ }
155
+ catch (error) {
156
+ if (attempt === LEASE_RETRIES - 1)
157
+ throw error;
158
+ Atomics.wait(sleepCell, 0, 0, LEASE_RETRY_MS);
159
+ }
160
+ }
161
+ if (!lease)
162
+ throw new Error("diagnostic summary lease is busy");
163
+ try {
164
+ return operation();
165
+ }
166
+ finally {
167
+ // A durably published result must survive release-time faults (an epoch
168
+ // rotation can remove the lease state mid-operation); stale takeover
169
+ // recovers any residue. The empty lease directory is removed so per-key
170
+ // lease state never outlives the contention that needed it.
171
+ try {
172
+ lease.release();
173
+ }
174
+ catch {
175
+ // Swallowed: the operation's outcome already stands.
176
+ }
177
+ try {
178
+ rmdirSync(leaseDir);
179
+ }
180
+ catch {
181
+ // A concurrent acquirer repopulated it, or release left residue.
182
+ }
183
+ }
184
+ }
185
+ /**
186
+ * Count the key's admitted loose exemplars for a UTC-day window from their
187
+ * digest-suffixed filenames. Files written before this mitigation carry no
188
+ * suffix and are not counted, so a pre-existing flood does not consume the
189
+ * window's exemplar budget.
190
+ */
191
+ function countLooseExemplars(coordRoot, digest, window) {
192
+ const directory = looseDiagnosticsRootV3(coordRoot);
193
+ if (!existsSync(directory))
194
+ return 0;
195
+ const windowStartMs = Date.parse(`${window}T00:00:00.000Z`);
196
+ const windowEndMs = windowStartMs + 24 * 60 * 60 * 1000;
197
+ const suffix = `-${digest}.json`;
198
+ let count = 0;
199
+ for (const name of readdirSync(directory)) {
200
+ if (!name.endsWith(suffix))
201
+ continue;
202
+ const epochMs = Number(LOOSE_ORDER_KEY_TIMESTAMP.exec(name)?.[1]);
203
+ if (Number.isFinite(epochMs) && epochMs >= windowStartMs && epochMs < windowEndMs) {
204
+ count += 1;
205
+ }
206
+ }
207
+ return count;
208
+ }
209
+ function boundedMetadata(metadata) {
210
+ const bounded = {};
211
+ let kept = 0;
212
+ for (const [key, value] of Object.entries(metadata)) {
213
+ if (kept >= METADATA_KEY_LIMIT)
214
+ break;
215
+ if (typeof value === "string" && value.length > METADATA_VALUE_LIMIT)
216
+ continue;
217
+ bounded[key] = value;
218
+ kept += 1;
219
+ }
220
+ return bounded;
221
+ }
222
+ function pruneHourBuckets(buckets, nowMs) {
223
+ const keys = Object.keys(buckets).sort();
224
+ const horizon = utcHour(nowMs - SUMMARY_HOUR_BUCKET_LIMIT * 60 * 60 * 1000);
225
+ const pruned = {};
226
+ for (const key of keys) {
227
+ if (key >= horizon)
228
+ pruned[key] = buckets[key];
229
+ }
230
+ // A pathological clock can still grow the map; hard-cap by newest keys.
231
+ const capped = Object.keys(pruned).sort().slice(-SUMMARY_HOUR_BUCKET_LIMIT);
232
+ const result = {};
233
+ for (const key of capped)
234
+ result[key] = pruned[key];
235
+ return result;
236
+ }
237
+ function freshSummary(category, reason, instanceId, window) {
238
+ return {
239
+ format: DIAGNOSTIC_SUMMARY_FORMAT,
240
+ format_version: DIAGNOSTIC_SUMMARY_VERSION,
241
+ category,
242
+ reason,
243
+ instance_id: instanceId,
244
+ window,
245
+ loose_count: 0,
246
+ summarized_count: 0,
247
+ first_summarized_at: null,
248
+ last_summarized_at: null,
249
+ represented_bytes: 0,
250
+ exemplars: [],
251
+ metadata: {},
252
+ recent_hours: {},
253
+ };
254
+ }
255
+ function readSummaryFile(path) {
256
+ let parsed;
257
+ try {
258
+ const metadata = lstatSync(path);
259
+ if (!metadata.isFile() || metadata.isSymbolicLink())
260
+ return undefined;
261
+ parsed = JSON.parse(readFileSync(path, "utf8"));
262
+ }
263
+ catch {
264
+ return undefined;
265
+ }
266
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
267
+ return undefined;
268
+ const summary = parsed;
269
+ if (summary.format !== DIAGNOSTIC_SUMMARY_FORMAT ||
270
+ summary.format_version !== DIAGNOSTIC_SUMMARY_VERSION ||
271
+ typeof summary.category !== "string" ||
272
+ typeof summary.reason !== "string" ||
273
+ typeof summary.instance_id !== "string" ||
274
+ !/^\d{4}-\d{2}-\d{2}$/.test(summary.window) ||
275
+ !Number.isSafeInteger(summary.loose_count) ||
276
+ summary.loose_count < 0 ||
277
+ !Number.isSafeInteger(summary.summarized_count) ||
278
+ summary.summarized_count < 0 ||
279
+ !Number.isSafeInteger(summary.represented_bytes) ||
280
+ summary.represented_bytes < 0 ||
281
+ !Array.isArray(summary.exemplars) ||
282
+ !summary.recent_hours ||
283
+ typeof summary.recent_hours !== "object" ||
284
+ Array.isArray(summary.recent_hours)) {
285
+ return undefined;
286
+ }
287
+ // Drop malformed rate buckets so a corrupt value can neither poison later
288
+ // increments nor silently diverge windowed counts from the total.
289
+ const hours = {};
290
+ for (const [key, value] of Object.entries(summary.recent_hours)) {
291
+ if (/^\d{4}-\d{2}-\d{2}T\d{2}$/.test(key) && Number.isSafeInteger(value) && value >= 0) {
292
+ hours[key] = value;
293
+ }
294
+ }
295
+ summary.recent_hours = hours;
296
+ return summary;
297
+ }
298
+ /**
299
+ * Append one line to the emergency fail-open log. Lock-free by design: an
300
+ * O_APPEND write of one small line is atomic, so concurrent fail-opens never
301
+ * serialize on shared state. Best-effort, size-capped, and nonrecursive: a
302
+ * failure here is swallowed, never diagnosed, and never blocks the loose
303
+ * fallback write.
304
+ */
305
+ function recordFailOpen(root, stage, nowMs) {
306
+ try {
307
+ ensureOwnerOnlyDirectory(root);
308
+ const path = join(root, DIAGNOSTIC_MITIGATION_HEALTH_FILE);
309
+ try {
310
+ if (statSync(path).size >= MITIGATION_HEALTH_MAX_BYTES)
311
+ return;
312
+ }
313
+ catch {
314
+ // Missing log starts fresh.
315
+ }
316
+ const line = JSON.stringify({ at: new Date(nowMs).toISOString(), stage, pid: process.pid });
317
+ appendFileSync(path, `${line}\n`, { mode: 0o600 });
318
+ }
319
+ catch {
320
+ // The emergency log may undercount when storage is unavailable; it is a
321
+ // signal, not accounting, and must never throw into the producer path.
322
+ }
323
+ }
324
+ function readMitigationHealth(path) {
325
+ let contents;
326
+ let size = 0;
327
+ try {
328
+ const metadata = lstatSync(path);
329
+ if (!metadata.isFile() || metadata.isSymbolicLink())
330
+ return null;
331
+ size = metadata.size;
332
+ contents = readFileSync(path, "utf8");
333
+ }
334
+ catch {
335
+ return null;
336
+ }
337
+ const health = {
338
+ fail_open_count: 0,
339
+ last_fail_open_at: null,
340
+ by_stage: {},
341
+ truncated: size >= MITIGATION_HEALTH_MAX_BYTES,
342
+ };
343
+ for (const line of contents.split("\n")) {
344
+ if (line.trim().length === 0)
345
+ continue;
346
+ // Every non-empty line was one fail-open, even a torn one.
347
+ health.fail_open_count += 1;
348
+ try {
349
+ const row = JSON.parse(line);
350
+ if (typeof row.at === "string")
351
+ health.last_fail_open_at = row.at;
352
+ if (typeof row.stage === "string" && row.stage.length <= 32) {
353
+ if (Object.keys(health.by_stage).length < 16 || health.by_stage[row.stage] !== undefined) {
354
+ health.by_stage[row.stage] = (health.by_stage[row.stage] ?? 0) + 1;
355
+ }
356
+ }
357
+ }
358
+ catch {
359
+ // A torn tail line still counts above.
360
+ }
361
+ }
362
+ return health;
363
+ }
364
+ /**
365
+ * Decide whether one diagnostic emission may become a loose file.
366
+ *
367
+ * Below the per-key bound (counted from digest-suffixed loose filenames) the
368
+ * emission is admitted with the suffix to append, and no summary or lease
369
+ * state is created. At or past the bound the emission is durably coalesced
370
+ * into the key's summary under a short per-key lease and `admit: false` is
371
+ * returned with the summary path. Any mitigation failure, and the disabled
372
+ * gate, admit the loose write exactly as before.
373
+ */
374
+ export function gateProducerDiagnosticV3(coordRoot, input, nowMs = Date.now()) {
375
+ if (!diagnosticSummariesEnabledV3())
376
+ return { admit: true, loose_name_suffix: "" };
377
+ const at = Number.isFinite(nowMs) ? nowMs : Date.now();
378
+ const category = sanitizeComponent(input.category, "unknown");
379
+ const reason = sanitizeComponent(input.reason, "none");
380
+ const instanceId = sanitizeComponent(input.instanceId, "unknown");
381
+ const window = utcDay(at);
382
+ const digest = keyDigest(category, reason, instanceId);
383
+ const admitLoose = { admit: true, loose_name_suffix: `-${digest}` };
384
+ const root = diagnosticSummariesRootV3(coordRoot);
385
+ let stage = "peek";
386
+ try {
387
+ const path = summaryPath(root, category, window, digest);
388
+ if (!readSummaryFile(path)) {
389
+ stage = "count";
390
+ if (countLooseExemplars(coordRoot, digest, window) < DIAGNOSTIC_LOOSE_EXEMPLAR_LIMIT) {
391
+ return admitLoose;
392
+ }
393
+ }
394
+ stage = "coalesce";
395
+ ensureOwnerOnlyDirectory(root);
396
+ return withKeyLease(root, digest, () => {
397
+ const existing = readSummaryFile(path);
398
+ const state = existing ?? freshSummary(category, reason, instanceId, window);
399
+ if (!existing)
400
+ state.loose_count = countLooseExemplars(coordRoot, digest, window);
401
+ const atIso = new Date(at).toISOString();
402
+ state.summarized_count += 1;
403
+ state.first_summarized_at ??= atIso;
404
+ state.last_summarized_at = atIso;
405
+ if (Number.isSafeInteger(input.fingerprint?.bytes) && input.fingerprint.bytes >= 0) {
406
+ state.represented_bytes += input.fingerprint.bytes;
407
+ }
408
+ if (state.exemplars.length < SUMMARY_EXEMPLAR_LIMIT && input.fingerprint) {
409
+ state.exemplars.push({
410
+ bytes: input.fingerprint.bytes,
411
+ sha256: input.fingerprint.sha256,
412
+ });
413
+ }
414
+ if (Object.keys(state.metadata).length === 0) {
415
+ state.metadata = boundedMetadata(input.metadata ?? {});
416
+ }
417
+ const hour = utcHour(at);
418
+ state.recent_hours[hour] = (state.recent_hours[hour] ?? 0) + 1;
419
+ state.recent_hours = pruneHourBuckets(state.recent_hours, at);
420
+ const durable = !existing || state.summarized_count % SUMMARY_DURABLE_EVERY === 0;
421
+ publishOwnerOnlyJson(path, state, durable);
422
+ return { admit: false, summary_path: path };
423
+ });
424
+ }
425
+ catch {
426
+ recordFailOpen(root, stage, at);
427
+ return admitLoose;
428
+ }
429
+ }
430
+ /**
431
+ * Read every summary in the active epoch's `diagnostic-summaries/` subtree.
432
+ * Skips lease state, temp files, and the mitigation health log (which is
433
+ * aggregated into `mitigation_health` instead). Never throws; a missing
434
+ * subtree returns an empty listing.
435
+ */
436
+ export function listDiagnosticSummariesV3(coordRoot) {
437
+ const root = diagnosticSummariesRootV3(coordRoot);
438
+ const listing = {
439
+ summaries: [],
440
+ file_count: 0,
441
+ unreadable_count: 0,
442
+ mitigation_health: null,
443
+ };
444
+ let names;
445
+ try {
446
+ const metadata = lstatSync(root);
447
+ if (!metadata.isDirectory() || metadata.isSymbolicLink())
448
+ return listing;
449
+ names = readdirSync(root);
450
+ }
451
+ catch {
452
+ return listing;
453
+ }
454
+ for (const name of names.sort()) {
455
+ if (name === "leases" || name.includes(".tmp-"))
456
+ continue;
457
+ if (name.startsWith("mitigation-health")) {
458
+ if (name === DIAGNOSTIC_MITIGATION_HEALTH_FILE) {
459
+ listing.mitigation_health = readMitigationHealth(join(root, name));
460
+ }
461
+ continue;
462
+ }
463
+ if (!name.endsWith(".json"))
464
+ continue;
465
+ listing.file_count += 1;
466
+ const summary = readSummaryFile(join(root, name));
467
+ if (summary)
468
+ listing.summaries.push(summary);
469
+ else
470
+ listing.unreadable_count += 1;
471
+ }
472
+ return listing;
473
+ }
474
+ /**
475
+ * Sum summarized-only occurrences inside a lookback window, from hour
476
+ * buckets. Hour-granular and conservative: a bucket is counted only when its
477
+ * whole hour lies inside `[sinceMs, nowMs]`, so a boundary bucket is excluded
478
+ * (up to 59 minutes undercounted) rather than fully included (up to 59
479
+ * minutes overcounted), and a future-dated bucket from clock skew never
480
+ * inflates a window.
481
+ */
482
+ export function countSummarizedSinceV3(summaries, sinceMs, filter, nowMs = Date.now()) {
483
+ let count = 0;
484
+ for (const summary of summaries) {
485
+ if (filter && !filter(summary))
486
+ continue;
487
+ for (const [hour, value] of Object.entries(summary.recent_hours)) {
488
+ const hourStartMs = Date.parse(`${hour}:00:00.000Z`);
489
+ if (Number.isFinite(hourStartMs) &&
490
+ hourStartMs >= sinceMs &&
491
+ hourStartMs <= nowMs &&
492
+ Number.isSafeInteger(value) &&
493
+ value > 0) {
494
+ count += value;
495
+ }
496
+ }
497
+ }
498
+ return count;
499
+ }
@@ -320,7 +320,7 @@ function turnRitualObservation(adapter, evidence) {
320
320
  function inputContextMeasurement(payload, phase) {
321
321
  const metadata = plainRecord(payload.raw.compact_metadata);
322
322
  const usedKeys = phase === "before"
323
- ? ["pre_tokens", "pre_compact_tokens", "used_tokens"]
323
+ ? ["pre_tokens", "pre_compact_tokens", "used_tokens", "context_tokens"]
324
324
  : ["post_tokens", "post_compact_tokens", "used_tokens"];
325
325
  const limitKeys = [
326
326
  "context_window_size",
@@ -65,6 +65,13 @@ export declare function removeIntakeRecordV3(path: string): void;
65
65
  * are reduced to byte counts and digests so the diagnostics spool never holds
66
66
  * prompt, tool input, or tool output bodies (invariant: delivered evidence is
67
67
  * never silently destroyed, and never re-exposed either).
68
+ *
69
+ * Identical emissions are bounded per (category, reason, instance) key and
70
+ * UTC day: past the loose-exemplar limit the emission is coalesced into the
71
+ * key's summary file. Returns the path of the durable record either way (the
72
+ * loose file when admitted, the summary file when coalesced); `undefined`
73
+ * means nothing durable was written. The gate is fail-open, so a mitigation
74
+ * failure still produces the loose file.
68
75
  */
69
76
  export declare function writeProducerDiagnosticV3(coordRoot: string, category: string, record: Record<string, unknown>): string | undefined;
70
77
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../../../../../src/core/events/v3/producers/intake.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D;;;;;;;;;;;GAWG;AAEH,QAAA,MAAM,aAAa,EAAG,wBAAiC,CAAC;AACxD,QAAA,MAAM,cAAc,EAAG,CAAU,CAAC;AAwClC,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,aAAa,CAAC;IAC7B,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC;IAC9B,WAAW,EAAE,OAAO,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACpD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,eAAe,CAAC,EAAE;QAChB,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;QAC/B,oBAAoB,EAAE,OAAO,MAAM,EAAE,CAAC;QACtC,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;QAC/B,kBAAkB,EAAE,OAAO,MAAM,EAAE,CAAC;KACrC,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,MAAM,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACxC;AAUD,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,OAAO,MAAM,EAAE,GAC3B,MAAM,CAER;AA+BD,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,OAAO,MAAM,EAAE,EAC5B,MAAM,EAAE,kBAAkB,GACzB,MAAM,CAOR;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAsB7E;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAc9E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGvD;AAkED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,GAAG,SAAS,CAiBpB"}
1
+ {"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../../../../../src/core/events/v3/producers/intake.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAMtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D;;;;;;;;;;;GAWG;AAEH,QAAA,MAAM,aAAa,EAAG,wBAAiC,CAAC;AACxD,QAAA,MAAM,cAAc,EAAG,CAAU,CAAC;AA4ClC,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,aAAa,CAAC;IAC7B,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC;IAC9B,WAAW,EAAE,OAAO,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACpD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,eAAe,CAAC,EAAE;QAChB,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;QAC/B,oBAAoB,EAAE,OAAO,MAAM,EAAE,CAAC;QACtC,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;QAC/B,kBAAkB,EAAE,OAAO,MAAM,EAAE,CAAC;KACrC,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,MAAM,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACxC;AAUD,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,OAAO,MAAM,EAAE,GAC3B,MAAM,CAER;AA+BD,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,OAAO,MAAM,EAAE,EAC5B,MAAM,EAAE,kBAAkB,GACzB,MAAM,CAOR;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAsB7E;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAc9E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGvD;AAkED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,GAAG,SAAS,CA8BpB"}
@@ -3,6 +3,7 @@ import { chmodSync, closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, open
3
3
  import { join, resolve } from "node:path";
4
4
  import { fsyncParentDirectory } from "../../../workflow/durable-record.js";
5
5
  import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../writer.js";
6
+ import { gateProducerDiagnosticV3, } from "./diagnostic-summaries.js";
6
7
  /**
7
8
  * Durable intake spool for hook signals, plus the producer diagnostics spool.
8
9
  *
@@ -54,6 +55,10 @@ const DIAGNOSTIC_METADATA_KEYS = new Set([
54
55
  "sequence",
55
56
  "expected",
56
57
  "actual",
58
+ "thread_id_present",
59
+ "wslenv_present",
60
+ "wslenv_names",
61
+ "identity_recovery_source",
57
62
  ]);
58
63
  function intakeRoot(coordRoot) {
59
64
  return join(resolve(coordRoot), EVENT_V3_LEDGER_RELATIVE_ROOT, "intake", "hook");
@@ -212,17 +217,35 @@ function validTurnRitual(value) {
212
217
  * are reduced to byte counts and digests so the diagnostics spool never holds
213
218
  * prompt, tool input, or tool output bodies (invariant: delivered evidence is
214
219
  * never silently destroyed, and never re-exposed either).
220
+ *
221
+ * Identical emissions are bounded per (category, reason, instance) key and
222
+ * UTC day: past the loose-exemplar limit the emission is coalesced into the
223
+ * key's summary file. Returns the path of the durable record either way (the
224
+ * loose file when admitted, the summary file when coalesced); `undefined`
225
+ * means nothing durable was written. The gate is fail-open, so a mitigation
226
+ * failure still produces the loose file.
215
227
  */
216
228
  export function writeProducerDiagnosticV3(coordRoot, category, record) {
217
229
  try {
218
230
  const safeCategory = category.replace(/[^a-z0-9_-]/gi, "_").slice(0, 64);
231
+ const redacted = redactDiagnosticRecord(record);
232
+ const { content_fingerprint: fingerprint, ...metadata } = redacted;
233
+ const decision = gateProducerDiagnosticV3(coordRoot, {
234
+ category: safeCategory,
235
+ reason: typeof record.reason === "string" ? record.reason : undefined,
236
+ instanceId: typeof record.instance_id === "string" ? record.instance_id : undefined,
237
+ fingerprint: fingerprint,
238
+ metadata: metadata,
239
+ });
240
+ if (!decision.admit)
241
+ return decision.summary_path;
219
242
  const root = diagnosticsRoot(coordRoot);
220
243
  ensureOwnerOnlyDirectory(root);
221
- const path = join(root, `${safeCategory}-${intakeOrderKey()}.json`);
244
+ const path = join(root, `${safeCategory}-${intakeOrderKey()}${decision.loose_name_suffix}.json`);
222
245
  const contents = `${JSON.stringify({
223
246
  recorded_at: new Date().toISOString(),
224
247
  category: safeCategory,
225
- ...redactDiagnosticRecord(record),
248
+ ...redacted,
226
249
  })}\n`;
227
250
  writeOwnerOnlyFileDurably(path, contents);
228
251
  return path;
@@ -0,0 +1,8 @@
1
+ export interface HookProducerStateSummaryV3 {
2
+ generation_id: `gen_${string}`;
3
+ open_span_count: number;
4
+ turn_open: boolean;
5
+ }
6
+ /** Read the narrow producer-state facts needed by passive coordination views. */
7
+ export declare function listHookProducerStateSummariesV3(coordRoot: string): HookProducerStateSummaryV3[];
8
+ //# sourceMappingURL=producer-state-observer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"producer-state-observer.d.ts","sourceRoot":"","sources":["../../../../../src/core/events/v3/producers/producer-state-observer.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,iFAAiF;AACjF,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CAuChG"}
@@ -0,0 +1,45 @@
1
+ import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ import { readEventV3ControlState } from "../control.js";
4
+ import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../reader.js";
5
+ /** Read the narrow producer-state facts needed by passive coordination views. */
6
+ export function listHookProducerStateSummariesV3(coordRoot) {
7
+ const control = readEventV3ControlState(coordRoot);
8
+ if (control.state !== "candidate" && control.state !== "active")
9
+ return [];
10
+ const producerRoot = join(resolve(coordRoot), EVENT_V3_LEDGER_RELATIVE_ROOT, "private-producers");
11
+ if (!existsSync(producerRoot))
12
+ return [];
13
+ const summaries = [];
14
+ for (const adapter of ["claude-code", "codex", "cursor"]) {
15
+ const directory = join(producerRoot, adapter);
16
+ if (!existsSync(directory))
17
+ continue;
18
+ const directoryMetadata = lstatSync(directory);
19
+ if (!directoryMetadata.isDirectory() || directoryMetadata.isSymbolicLink()) {
20
+ throw new Error("V3 producer state directory is unsafe");
21
+ }
22
+ for (const name of readdirSync(directory).filter((entry) => /^hid_[a-f0-9]{64}\.json$/.test(entry))) {
23
+ const file = join(directory, name);
24
+ const metadata = lstatSync(file);
25
+ if (!metadata.isFile() || metadata.isSymbolicLink())
26
+ continue;
27
+ const value = JSON.parse(readFileSync(file, "utf8"));
28
+ if (value.format !== "harnery-v3-hook-producer" ||
29
+ value.format_version !== 3 ||
30
+ value.adapter !== adapter ||
31
+ value.terminal === true ||
32
+ typeof value.generation_id !== "string" ||
33
+ !/^gen_[a-zA-Z0-9._-]+$/.test(value.generation_id) ||
34
+ !Array.isArray(value.spans)) {
35
+ continue;
36
+ }
37
+ summaries.push({
38
+ generation_id: value.generation_id,
39
+ open_span_count: value.spans.length,
40
+ turn_open: typeof value.current_turn_id === "string",
41
+ });
42
+ }
43
+ }
44
+ return summaries.sort((left, right) => left.generation_id.localeCompare(right.generation_id));
45
+ }