harnery 0.34.1 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (692) hide show
  1. package/dist/commander.d.ts +30 -5
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +124 -94
  4. package/dist/commands/agents.d.ts +37 -6
  5. package/dist/commands/agents.d.ts.map +1 -1
  6. package/dist/commands/agents.js +466 -371
  7. package/dist/commands/backup.d.ts.map +1 -1
  8. package/dist/commands/backup.js +10 -10
  9. package/dist/commands/browse-session.d.ts.map +1 -1
  10. package/dist/commands/browse-session.js +12 -0
  11. package/dist/commands/browse.d.ts +1 -1
  12. package/dist/commands/browse.d.ts.map +1 -1
  13. package/dist/commands/browse.js +31 -6
  14. package/dist/commands/conversations.d.ts +10 -0
  15. package/dist/commands/conversations.d.ts.map +1 -0
  16. package/dist/commands/conversations.js +201 -0
  17. package/dist/commands/decision.d.ts.map +1 -1
  18. package/dist/commands/decision.js +2 -2
  19. package/dist/commands/deinit.d.ts.map +1 -1
  20. package/dist/commands/deinit.js +5 -0
  21. package/dist/commands/docs.d.ts.map +1 -1
  22. package/dist/commands/docs.js +13 -2
  23. package/dist/commands/doctor.d.ts +5 -0
  24. package/dist/commands/doctor.d.ts.map +1 -1
  25. package/dist/commands/doctor.js +51 -7
  26. package/dist/commands/events.d.ts.map +1 -1
  27. package/dist/commands/events.js +18 -1
  28. package/dist/commands/fetch.js +6 -5
  29. package/dist/commands/files.d.ts +22 -0
  30. package/dist/commands/files.d.ts.map +1 -0
  31. package/dist/commands/files.js +113 -0
  32. package/dist/commands/governor.js +14 -12
  33. package/dist/commands/inbox.d.ts +5 -0
  34. package/dist/commands/inbox.d.ts.map +1 -0
  35. package/dist/commands/inbox.js +57 -0
  36. package/dist/commands/init.d.ts +4 -5
  37. package/dist/commands/init.d.ts.map +1 -1
  38. package/dist/commands/init.js +63 -13
  39. package/dist/commands/ledger-v3.d.ts.map +1 -1
  40. package/dist/commands/ledger-v3.js +347 -1
  41. package/dist/commands/logs.d.ts +4 -0
  42. package/dist/commands/logs.d.ts.map +1 -0
  43. package/dist/commands/logs.js +169 -0
  44. package/dist/commands/messages.d.ts +5 -0
  45. package/dist/commands/messages.d.ts.map +1 -0
  46. package/dist/commands/messages.js +45 -0
  47. package/dist/commands/outline.d.ts +1 -1
  48. package/dist/commands/outline.d.ts.map +1 -1
  49. package/dist/commands/outline.js +2 -2
  50. package/dist/commands/presence.d.ts.map +1 -1
  51. package/dist/commands/presence.js +2 -2
  52. package/dist/commands/read.d.ts +1 -1
  53. package/dist/commands/read.d.ts.map +1 -1
  54. package/dist/commands/read.js +2 -2
  55. package/dist/commands/semantic.d.ts +4 -0
  56. package/dist/commands/semantic.d.ts.map +1 -0
  57. package/dist/commands/semantic.js +199 -0
  58. package/dist/commands/storage.d.ts +4 -0
  59. package/dist/commands/storage.d.ts.map +1 -0
  60. package/dist/commands/storage.js +238 -0
  61. package/dist/commands/tunnel.d.ts +5 -1
  62. package/dist/commands/tunnel.d.ts.map +1 -1
  63. package/dist/commands/tunnel.js +44 -31
  64. package/dist/commands/web.d.ts +3 -0
  65. package/dist/commands/web.d.ts.map +1 -1
  66. package/dist/commands/web.js +84 -7
  67. package/dist/commands/work.js +3 -3
  68. package/dist/commands/workflow.js +13 -13
  69. package/dist/core/adapters/profiles.d.ts +1 -1
  70. package/dist/core/agents/canonical-emit.d.ts +3 -0
  71. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  72. package/dist/core/agents/canonical-emit.js +12 -0
  73. package/dist/core/agents/claim-path.d.ts +11 -0
  74. package/dist/core/agents/claim-path.d.ts.map +1 -0
  75. package/dist/core/agents/claim-path.js +22 -0
  76. package/dist/core/agents/cli.js +209 -39
  77. package/dist/core/agents/coord-client.d.ts +29 -3
  78. package/dist/core/agents/coord-client.d.ts.map +1 -1
  79. package/dist/core/agents/coord-client.js +88 -9
  80. package/dist/core/agents/live-authority-v3.d.ts +47 -1
  81. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  82. package/dist/core/agents/live-authority-v3.js +245 -13
  83. package/dist/core/agents/live-lifecycle-v3.js +9 -4
  84. package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
  85. package/dist/core/agents/live-observation-v3.js +8 -3
  86. package/dist/core/agents/render/prompt-context.d.ts +9 -3
  87. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  88. package/dist/core/agents/render/prompt-context.js +36 -17
  89. package/dist/core/agents/rules/stop-hook.d.ts +2 -0
  90. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  91. package/dist/core/agents/rules/stop-hook.js +115 -22
  92. package/dist/core/agents/rules/verdict.d.ts +1 -0
  93. package/dist/core/agents/rules/verdict.d.ts.map +1 -1
  94. package/dist/core/agents/session-events.d.ts.map +1 -1
  95. package/dist/core/agents/session-events.js +4 -0
  96. package/dist/core/agents/session-finalization-state-v3.js +1 -1
  97. package/dist/core/agents/session-finalizer-v3.js +5 -1
  98. package/dist/core/agents/session-name-display.d.ts +1 -0
  99. package/dist/core/agents/session-name-display.d.ts.map +1 -1
  100. package/dist/core/agents/session-name-display.js +8 -1
  101. package/dist/core/agents/state/activity-log.d.ts +3 -0
  102. package/dist/core/agents/state/activity-log.d.ts.map +1 -1
  103. package/dist/core/agents/state/activity-log.js +6 -3
  104. package/dist/core/agents/state/heartbeat-reader.d.ts +46 -0
  105. package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -0
  106. package/dist/core/agents/state/heartbeat-reader.js +25 -0
  107. package/dist/core/agents/state/heartbeat-writer.d.ts +9 -48
  108. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  109. package/dist/core/agents/state/heartbeat-writer.js +34 -34
  110. package/dist/core/agents/state/live-coordination-view.d.ts +6 -8
  111. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  112. package/dist/core/agents/state/live-coordination-view.js +16 -67
  113. package/dist/core/agents/state/live-coordination-writer.d.ts +12 -0
  114. package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -0
  115. package/dist/core/agents/state/live-coordination-writer.js +92 -0
  116. package/dist/core/agents/state/names.d.ts +9 -1
  117. package/dist/core/agents/state/names.d.ts.map +1 -1
  118. package/dist/core/agents/state/names.js +190 -182
  119. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  120. package/dist/core/agents/state/stale-sweep.js +23 -5
  121. package/dist/core/artifacts/constants.d.ts +5 -0
  122. package/dist/core/artifacts/constants.d.ts.map +1 -0
  123. package/dist/core/artifacts/constants.js +4 -0
  124. package/dist/core/artifacts/index.d.ts +24 -3
  125. package/dist/core/artifacts/index.d.ts.map +1 -1
  126. package/dist/core/artifacts/index.js +96 -8
  127. package/dist/core/config.d.ts +62 -4
  128. package/dist/core/config.d.ts.map +1 -1
  129. package/dist/core/config.js +98 -4
  130. package/dist/core/conversations/archive.d.ts +49 -0
  131. package/dist/core/conversations/archive.d.ts.map +1 -0
  132. package/dist/core/conversations/archive.js +136 -0
  133. package/dist/core/conversations/catalog.d.ts +10 -0
  134. package/dist/core/conversations/catalog.d.ts.map +1 -0
  135. package/dist/core/conversations/catalog.js +72 -0
  136. package/dist/core/conversations/context-pack.d.ts +6 -0
  137. package/dist/core/conversations/context-pack.d.ts.map +1 -0
  138. package/dist/core/conversations/context-pack.js +60 -0
  139. package/dist/core/conversations/contract.d.ts +155 -0
  140. package/dist/core/conversations/contract.d.ts.map +1 -0
  141. package/dist/core/conversations/contract.js +1 -0
  142. package/dist/core/conversations/evaluation.d.ts +16 -0
  143. package/dist/core/conversations/evaluation.d.ts.map +1 -0
  144. package/dist/core/conversations/evaluation.js +9 -0
  145. package/dist/core/conversations/index.d.ts +10 -0
  146. package/dist/core/conversations/index.d.ts.map +1 -0
  147. package/dist/core/conversations/index.js +9 -0
  148. package/dist/core/conversations/lifecycle.d.ts +28 -0
  149. package/dist/core/conversations/lifecycle.d.ts.map +1 -0
  150. package/dist/core/conversations/lifecycle.js +29 -0
  151. package/dist/core/conversations/normalize.d.ts +14 -0
  152. package/dist/core/conversations/normalize.d.ts.map +1 -0
  153. package/dist/core/conversations/normalize.js +82 -0
  154. package/dist/core/conversations/query.d.ts +8 -0
  155. package/dist/core/conversations/query.d.ts.map +1 -0
  156. package/dist/core/conversations/query.js +280 -0
  157. package/dist/core/conversations/search-index.d.ts +9 -0
  158. package/dist/core/conversations/search-index.d.ts.map +1 -0
  159. package/dist/core/conversations/search-index.js +29 -0
  160. package/dist/core/events/legacy-storage/canary.d.ts +18 -0
  161. package/dist/core/events/legacy-storage/canary.d.ts.map +1 -0
  162. package/dist/core/events/legacy-storage/canary.js +150 -0
  163. package/dist/core/events/legacy-storage/fence.d.ts +15 -0
  164. package/dist/core/events/legacy-storage/fence.d.ts.map +1 -0
  165. package/dist/core/events/legacy-storage/fence.js +115 -0
  166. package/dist/core/events/legacy-storage/index.d.ts +6 -0
  167. package/dist/core/events/legacy-storage/index.d.ts.map +1 -0
  168. package/dist/core/events/legacy-storage/index.js +5 -0
  169. package/dist/core/events/legacy-storage/inventory.d.ts +10 -0
  170. package/dist/core/events/legacy-storage/inventory.d.ts.map +1 -0
  171. package/dist/core/events/legacy-storage/inventory.js +40 -0
  172. package/dist/core/events/legacy-storage/manifest.d.ts +23 -0
  173. package/dist/core/events/legacy-storage/manifest.d.ts.map +1 -0
  174. package/dist/core/events/legacy-storage/manifest.js +108 -0
  175. package/dist/core/events/legacy-storage/reader.d.ts +15 -0
  176. package/dist/core/events/legacy-storage/reader.d.ts.map +1 -0
  177. package/dist/core/events/legacy-storage/reader.js +154 -0
  178. package/dist/core/events/v3/authority-outbox.d.ts +7 -2
  179. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  180. package/dist/core/events/v3/authority-outbox.js +16 -3
  181. package/dist/core/events/v3/base-contract.d.ts +851 -16
  182. package/dist/core/events/v3/base-contract.d.ts.map +1 -1
  183. package/dist/core/events/v3/base-contract.js +50 -7
  184. package/dist/core/events/v3/bootstrap.d.ts +39 -0
  185. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  186. package/dist/core/events/v3/bootstrap.js +167 -3
  187. package/dist/core/events/v3/capabilities.d.ts +11 -0
  188. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  189. package/dist/core/events/v3/capabilities.js +26 -3
  190. package/dist/core/events/v3/control-witness.d.ts +44 -0
  191. package/dist/core/events/v3/control-witness.d.ts.map +1 -0
  192. package/dist/core/events/v3/control-witness.js +233 -0
  193. package/dist/core/events/v3/control-writer.d.ts +4 -0
  194. package/dist/core/events/v3/control-writer.d.ts.map +1 -0
  195. package/dist/core/events/v3/control-writer.js +16 -0
  196. package/dist/core/events/v3/control.d.ts +8 -2
  197. package/dist/core/events/v3/control.d.ts.map +1 -1
  198. package/dist/core/events/v3/control.js +46 -18
  199. package/dist/core/events/v3/coordination-transaction-recovery.d.ts +42 -0
  200. package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -0
  201. package/dist/core/events/v3/coordination-transaction-recovery.js +342 -0
  202. package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
  203. package/dist/core/events/v3/coordination-view.js +16 -1
  204. package/dist/core/events/v3/generated.d.ts +1 -1
  205. package/dist/core/events/v3/generated.js +1 -1
  206. package/dist/core/events/v3/index.d.ts +8 -5
  207. package/dist/core/events/v3/index.d.ts.map +1 -1
  208. package/dist/core/events/v3/index.js +7 -4
  209. package/dist/core/events/v3/latency.d.ts +31 -1
  210. package/dist/core/events/v3/latency.d.ts.map +1 -1
  211. package/dist/core/events/v3/latency.js +127 -3
  212. package/dist/core/events/v3/live-route-observer.d.ts +31 -0
  213. package/dist/core/events/v3/live-route-observer.d.ts.map +1 -0
  214. package/dist/core/events/v3/live-route-observer.js +58 -0
  215. package/dist/core/events/v3/live-routing.d.ts +42 -20
  216. package/dist/core/events/v3/live-routing.d.ts.map +1 -1
  217. package/dist/core/events/v3/live-routing.js +153 -41
  218. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  219. package/dist/core/events/v3/producers/command-recorder.js +10 -1
  220. package/dist/core/events/v3/producers/coordination-recorder.d.ts +11 -1
  221. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  222. package/dist/core/events/v3/producers/coordination-recorder.js +90 -13
  223. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts +129 -0
  224. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -0
  225. package/dist/core/events/v3/producers/diagnostic-summaries.js +499 -0
  226. package/dist/core/events/v3/producers/hook-base.d.ts +17 -1
  227. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  228. package/dist/core/events/v3/producers/hook-base.js +83 -2
  229. package/dist/core/events/v3/producers/intake.d.ts +13 -0
  230. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  231. package/dist/core/events/v3/producers/intake.js +36 -2
  232. package/dist/core/events/v3/producers/producer-state-observer.d.ts +8 -0
  233. package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -0
  234. package/dist/core/events/v3/producers/producer-state-observer.js +45 -0
  235. package/dist/core/events/v3/producers/recorder.d.ts +117 -1
  236. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  237. package/dist/core/events/v3/producers/recorder.js +992 -27
  238. package/dist/core/events/v3/reader.d.ts +51 -0
  239. package/dist/core/events/v3/reader.d.ts.map +1 -1
  240. package/dist/core/events/v3/reader.js +181 -1
  241. package/dist/core/events/v3/rotation-config.d.ts +9 -0
  242. package/dist/core/events/v3/rotation-config.d.ts.map +1 -0
  243. package/dist/core/events/v3/rotation-config.js +91 -0
  244. package/dist/core/events/v3/runtime-build.d.ts +11 -0
  245. package/dist/core/events/v3/runtime-build.d.ts.map +1 -0
  246. package/dist/core/events/v3/runtime-build.js +39 -0
  247. package/dist/core/events/v3/runtime-identity.d.ts +5 -0
  248. package/dist/core/events/v3/runtime-identity.d.ts.map +1 -0
  249. package/dist/core/events/v3/runtime-identity.js +18 -0
  250. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +52 -0
  251. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -0
  252. package/dist/core/events/v3/runtime-telemetry-capabilities.js +54 -0
  253. package/dist/core/events/v3/support-storage/classify.d.ts +46 -0
  254. package/dist/core/events/v3/support-storage/classify.d.ts.map +1 -0
  255. package/dist/core/events/v3/support-storage/classify.js +149 -0
  256. package/dist/core/events/v3/support-storage/eligibility.d.ts +29 -0
  257. package/dist/core/events/v3/support-storage/eligibility.d.ts.map +1 -0
  258. package/dist/core/events/v3/support-storage/eligibility.js +35 -0
  259. package/dist/core/events/v3/support-storage/index.d.ts +10 -0
  260. package/dist/core/events/v3/support-storage/index.d.ts.map +1 -0
  261. package/dist/core/events/v3/support-storage/index.js +9 -0
  262. package/dist/core/events/v3/support-storage/inventory.d.ts +30 -0
  263. package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -0
  264. package/dist/core/events/v3/support-storage/inventory.js +94 -0
  265. package/dist/core/events/v3/support-storage/logical-authority.d.ts +14 -0
  266. package/dist/core/events/v3/support-storage/logical-authority.d.ts.map +1 -0
  267. package/dist/core/events/v3/support-storage/logical-authority.js +104 -0
  268. package/dist/core/events/v3/support-storage/maintenance.d.ts +98 -0
  269. package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -0
  270. package/dist/core/events/v3/support-storage/maintenance.js +352 -0
  271. package/dist/core/events/v3/support-storage/pack-contract.d.ts +59 -0
  272. package/dist/core/events/v3/support-storage/pack-contract.d.ts.map +1 -0
  273. package/dist/core/events/v3/support-storage/pack-contract.js +249 -0
  274. package/dist/core/events/v3/support-storage/pack-reader.d.ts +34 -0
  275. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -0
  276. package/dist/core/events/v3/support-storage/pack-reader.js +258 -0
  277. package/dist/core/events/v3/support-storage/pack-writer.d.ts +30 -0
  278. package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -0
  279. package/dist/core/events/v3/support-storage/pack-writer.js +268 -0
  280. package/dist/core/events/v3/support-storage/recovery.d.ts +15 -0
  281. package/dist/core/events/v3/support-storage/recovery.d.ts.map +1 -0
  282. package/dist/core/events/v3/support-storage/recovery.js +22 -0
  283. package/dist/core/events/v3/turn-telemetry.d.ts +21 -6
  284. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
  285. package/dist/core/events/v3/turn-telemetry.js +32 -2
  286. package/dist/core/events/v3/writer.d.ts +13 -1
  287. package/dist/core/events/v3/writer.d.ts.map +1 -1
  288. package/dist/core/events/v3/writer.js +126 -12
  289. package/dist/core/governor/plan-read.d.ts.map +1 -1
  290. package/dist/core/governor/plan-read.js +5 -21
  291. package/dist/core/governor/planning.js +6 -8
  292. package/dist/core/governor/service-read.d.ts +12 -0
  293. package/dist/core/governor/service-read.d.ts.map +1 -1
  294. package/dist/core/governor/service-read.js +266 -2
  295. package/dist/core/governor/service.d.ts +1 -0
  296. package/dist/core/governor/service.d.ts.map +1 -1
  297. package/dist/core/governor/service.js +53 -18
  298. package/dist/core/guard/evidence-v3.d.ts.map +1 -1
  299. package/dist/core/guard/evidence-v3.js +2 -0
  300. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  301. package/dist/core/hooks/adapter/events.js +1 -0
  302. package/dist/core/hooks/adapter/output.d.ts +4 -2
  303. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  304. package/dist/core/hooks/adapter/output.js +13 -5
  305. package/dist/core/hooks/adapter/parse.d.ts +3 -0
  306. package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
  307. package/dist/core/hooks/adapter/parse.js +14 -0
  308. package/dist/core/hooks/adapter/runtime-telemetry.d.ts +142 -0
  309. package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -0
  310. package/dist/core/hooks/adapter/runtime-telemetry.js +869 -0
  311. package/dist/core/hooks/cli.js +318 -61
  312. package/dist/core/hooks/effects/image-capture.d.ts +1 -1
  313. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  314. package/dist/core/hooks/effects/image-capture.js +4 -2
  315. package/dist/core/hooks/remediation-cap.d.ts +39 -0
  316. package/dist/core/hooks/remediation-cap.d.ts.map +1 -0
  317. package/dist/core/hooks/remediation-cap.js +63 -0
  318. package/dist/core/hooks/resolve/coord-root.d.ts +22 -9
  319. package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
  320. package/dist/core/hooks/resolve/coord-root.js +92 -11
  321. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  322. package/dist/core/hooks/resolve/owner.js +5 -0
  323. package/dist/core/hooks/resolve/transcript.d.ts +33 -9
  324. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  325. package/dist/core/hooks/resolve/transcript.js +33 -10
  326. package/dist/core/inbox/contract.d.ts +64 -0
  327. package/dist/core/inbox/contract.d.ts.map +1 -0
  328. package/dist/core/inbox/contract.js +13 -0
  329. package/dist/core/inbox/index.d.ts +5 -0
  330. package/dist/core/inbox/index.d.ts.map +1 -0
  331. package/dist/core/inbox/index.js +4 -0
  332. package/dist/core/inbox/lifecycle.d.ts +22 -0
  333. package/dist/core/inbox/lifecycle.d.ts.map +1 -0
  334. package/dist/core/inbox/lifecycle.js +41 -0
  335. package/dist/core/inbox/service.d.ts +36 -0
  336. package/dist/core/inbox/service.d.ts.map +1 -0
  337. package/dist/core/inbox/service.js +210 -0
  338. package/dist/core/inbox/watcher.d.ts +7 -0
  339. package/dist/core/inbox/watcher.d.ts.map +1 -0
  340. package/dist/core/inbox/watcher.js +26 -0
  341. package/dist/core/presence/codec-digest.d.ts.map +1 -1
  342. package/dist/core/presence/codec-digest.js +14 -3
  343. package/dist/core/presence/relay-client.d.ts +1 -0
  344. package/dist/core/presence/relay-client.d.ts.map +1 -1
  345. package/dist/core/presence/relay-client.js +52 -8
  346. package/dist/core/semantic/adapters.d.ts +37 -0
  347. package/dist/core/semantic/adapters.d.ts.map +1 -0
  348. package/dist/core/semantic/adapters.js +360 -0
  349. package/dist/core/semantic/contract.d.ts +1072 -0
  350. package/dist/core/semantic/contract.d.ts.map +1 -0
  351. package/dist/core/semantic/contract.js +331 -0
  352. package/dist/core/semantic/evidence.d.ts +11 -0
  353. package/dist/core/semantic/evidence.d.ts.map +1 -0
  354. package/dist/core/semantic/evidence.js +262 -0
  355. package/dist/core/semantic/index.d.ts +14 -0
  356. package/dist/core/semantic/index.d.ts.map +1 -0
  357. package/dist/core/semantic/index.js +13 -0
  358. package/dist/core/semantic/once.d.ts +38 -0
  359. package/dist/core/semantic/once.d.ts.map +1 -0
  360. package/dist/core/semantic/once.js +364 -0
  361. package/dist/core/semantic/prompt.d.ts +12 -0
  362. package/dist/core/semantic/prompt.d.ts.map +1 -0
  363. package/dist/core/semantic/prompt.js +83 -0
  364. package/dist/core/semantic/review.d.ts +144 -0
  365. package/dist/core/semantic/review.d.ts.map +1 -0
  366. package/dist/core/semantic/review.js +544 -0
  367. package/dist/core/semantic/routes.d.ts +10 -0
  368. package/dist/core/semantic/routes.d.ts.map +1 -0
  369. package/dist/core/semantic/routes.js +21 -0
  370. package/dist/core/semantic/scheduler.d.ts +27 -0
  371. package/dist/core/semantic/scheduler.d.ts.map +1 -0
  372. package/dist/core/semantic/scheduler.js +91 -0
  373. package/dist/core/semantic/service-status.d.ts +51 -0
  374. package/dist/core/semantic/service-status.d.ts.map +1 -0
  375. package/dist/core/semantic/service-status.js +140 -0
  376. package/dist/core/semantic/service.d.ts +52 -0
  377. package/dist/core/semantic/service.d.ts.map +1 -0
  378. package/dist/core/semantic/service.js +559 -0
  379. package/dist/core/semantic/soak.d.ts +75 -0
  380. package/dist/core/semantic/soak.d.ts.map +1 -0
  381. package/dist/core/semantic/soak.js +476 -0
  382. package/dist/core/semantic/storage.d.ts +81 -0
  383. package/dist/core/semantic/storage.d.ts.map +1 -0
  384. package/dist/core/semantic/storage.js +180 -0
  385. package/dist/core/semantic/usage.d.ts +43 -0
  386. package/dist/core/semantic/usage.d.ts.map +1 -0
  387. package/dist/core/semantic/usage.js +193 -0
  388. package/dist/core/semantic/validate.d.ts +18 -0
  389. package/dist/core/semantic/validate.d.ts.map +1 -0
  390. package/dist/core/semantic/validate.js +207 -0
  391. package/dist/core/storage/buffer.d.ts +28 -0
  392. package/dist/core/storage/buffer.d.ts.map +1 -0
  393. package/dist/core/storage/buffer.js +101 -0
  394. package/dist/core/storage/builtins.d.ts +3 -0
  395. package/dist/core/storage/builtins.d.ts.map +1 -0
  396. package/dist/core/storage/builtins.js +683 -0
  397. package/dist/core/storage/catalog.d.ts +19 -0
  398. package/dist/core/storage/catalog.d.ts.map +1 -0
  399. package/dist/core/storage/catalog.js +365 -0
  400. package/dist/core/storage/config.d.ts +16 -0
  401. package/dist/core/storage/config.d.ts.map +1 -0
  402. package/dist/core/storage/config.js +311 -0
  403. package/dist/core/storage/contract.d.ts +275 -0
  404. package/dist/core/storage/contract.d.ts.map +1 -0
  405. package/dist/core/storage/contract.js +3 -0
  406. package/dist/core/storage/durable-history.d.ts +36 -0
  407. package/dist/core/storage/durable-history.d.ts.map +1 -0
  408. package/dist/core/storage/durable-history.js +606 -0
  409. package/dist/core/storage/health.d.ts +4 -0
  410. package/dist/core/storage/health.d.ts.map +1 -0
  411. package/dist/core/storage/health.js +65 -0
  412. package/dist/core/storage/index.d.ts +16 -0
  413. package/dist/core/storage/index.d.ts.map +1 -0
  414. package/dist/core/storage/index.js +15 -0
  415. package/dist/core/storage/inventory.d.ts +25 -0
  416. package/dist/core/storage/inventory.d.ts.map +1 -0
  417. package/dist/core/storage/inventory.js +666 -0
  418. package/dist/core/storage/jsonl.d.ts +52 -0
  419. package/dist/core/storage/jsonl.d.ts.map +1 -0
  420. package/dist/core/storage/jsonl.js +156 -0
  421. package/dist/core/storage/log-retention.d.ts +52 -0
  422. package/dist/core/storage/log-retention.d.ts.map +1 -0
  423. package/dist/core/storage/log-retention.js +419 -0
  424. package/dist/core/storage/logger.d.ts +82 -0
  425. package/dist/core/storage/logger.d.ts.map +1 -0
  426. package/dist/core/storage/logger.js +411 -0
  427. package/dist/core/storage/maintenance-providers.d.ts +26 -0
  428. package/dist/core/storage/maintenance-providers.d.ts.map +1 -0
  429. package/dist/core/storage/maintenance-providers.js +141 -0
  430. package/dist/core/storage/maintenance.d.ts +125 -0
  431. package/dist/core/storage/maintenance.d.ts.map +1 -0
  432. package/dist/core/storage/maintenance.js +609 -0
  433. package/dist/core/storage/metrics.d.ts +60 -0
  434. package/dist/core/storage/metrics.d.ts.map +1 -0
  435. package/dist/core/storage/metrics.js +134 -0
  436. package/dist/core/storage/policy.d.ts +7 -0
  437. package/dist/core/storage/policy.d.ts.map +1 -0
  438. package/dist/core/storage/policy.js +110 -0
  439. package/dist/core/storage/process-log.d.ts +38 -0
  440. package/dist/core/storage/process-log.d.ts.map +1 -0
  441. package/dist/core/storage/process-log.js +165 -0
  442. package/dist/core/storage/query.d.ts +34 -0
  443. package/dist/core/storage/query.d.ts.map +1 -0
  444. package/dist/core/storage/query.js +295 -0
  445. package/dist/core/storage/receipts.d.ts +23 -0
  446. package/dist/core/storage/receipts.d.ts.map +1 -0
  447. package/dist/core/storage/receipts.js +117 -0
  448. package/dist/core/storage/segments.d.ts +84 -0
  449. package/dist/core/storage/segments.d.ts.map +1 -0
  450. package/dist/core/storage/segments.js +542 -0
  451. package/dist/core/storage/sink-graph.d.ts +65 -0
  452. package/dist/core/storage/sink-graph.d.ts.map +1 -0
  453. package/dist/core/storage/sink-graph.js +213 -0
  454. package/dist/core/storage/storm-control.d.ts +23 -0
  455. package/dist/core/storage/storm-control.d.ts.map +1 -0
  456. package/dist/core/storage/storm-control.js +59 -0
  457. package/dist/core/work/state.d.ts.map +1 -1
  458. package/dist/core/work/state.js +10 -14
  459. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  460. package/dist/core/workflow/live-session-v3.js +2 -1
  461. package/dist/index.d.ts +2 -0
  462. package/dist/index.d.ts.map +1 -1
  463. package/dist/index.js +2 -0
  464. package/dist/lazy-commands.d.ts +26 -0
  465. package/dist/lazy-commands.d.ts.map +1 -0
  466. package/dist/lazy-commands.js +210 -0
  467. package/dist/lib/browser/client.d.ts +11 -0
  468. package/dist/lib/browser/client.d.ts.map +1 -1
  469. package/dist/lib/browser/client.js +13 -0
  470. package/dist/lib/browser/index.d.ts +1 -0
  471. package/dist/lib/browser/index.d.ts.map +1 -1
  472. package/dist/lib/browser/standalone-html.d.ts +25 -0
  473. package/dist/lib/browser/standalone-html.d.ts.map +1 -0
  474. package/dist/lib/browser/standalone-html.js +284 -0
  475. package/dist/lib/docs-lint.d.ts +2 -0
  476. package/dist/lib/docs-lint.d.ts.map +1 -1
  477. package/dist/lib/docs-lint.js +45 -80
  478. package/dist/lib/docs-metadata-audit.d.ts +3 -0
  479. package/dist/lib/docs-metadata-audit.d.ts.map +1 -1
  480. package/dist/lib/docs-metadata-audit.js +13 -23
  481. package/dist/lib/docs-metadata-sync.d.ts +1 -0
  482. package/dist/lib/docs-metadata-sync.d.ts.map +1 -1
  483. package/dist/lib/docs-metadata-sync.js +28 -10
  484. package/dist/lib/docs-repository-view.d.ts +22 -0
  485. package/dist/lib/docs-repository-view.d.ts.map +1 -0
  486. package/dist/lib/docs-repository-view.js +185 -0
  487. package/dist/lib/http/client.d.ts +11 -5
  488. package/dist/lib/http/client.d.ts.map +1 -1
  489. package/dist/lib/http/client.js +22 -4
  490. package/dist/lib/http/index.d.ts +1 -1
  491. package/dist/lib/http/index.d.ts.map +1 -1
  492. package/dist/lib/http/index.js +1 -1
  493. package/dist/lib/indexer-exclusions.d.ts +27 -0
  494. package/dist/lib/indexer-exclusions.d.ts.map +1 -0
  495. package/dist/lib/indexer-exclusions.js +176 -0
  496. package/dist/lib/instructions/apply.d.ts.map +1 -1
  497. package/dist/lib/instructions/apply.js +1 -0
  498. package/dist/lib/instructions/templates.d.ts +2 -0
  499. package/dist/lib/instructions/templates.d.ts.map +1 -1
  500. package/dist/lib/instructions/templates.js +149 -4
  501. package/dist/lib/local-file-url.d.ts +9 -0
  502. package/dist/lib/local-file-url.d.ts.map +1 -0
  503. package/dist/lib/local-file-url.js +20 -0
  504. package/dist/lib/web-performance.d.ts +118 -0
  505. package/dist/lib/web-performance.d.ts.map +1 -0
  506. package/dist/lib/web-performance.js +192 -0
  507. package/package.json +34 -2
  508. package/schemas/config.schema.json +58 -0
  509. package/schemas/event-v3.schema.json +3073 -581
  510. package/src/commander.ts +462 -93
  511. package/src/commands/agents.ts +617 -355
  512. package/src/commands/backup.ts +18 -14
  513. package/src/commands/browse-session.ts +12 -0
  514. package/src/commands/browse.ts +31 -9
  515. package/src/commands/conversations.ts +279 -0
  516. package/src/commands/decision.ts +8 -2
  517. package/src/commands/deinit.ts +6 -0
  518. package/src/commands/docs.ts +25 -6
  519. package/src/commands/doctor.ts +75 -9
  520. package/src/commands/events.ts +21 -1
  521. package/src/commands/fetch.ts +7 -6
  522. package/src/commands/files.ts +143 -0
  523. package/src/commands/governor.ts +13 -12
  524. package/src/commands/inbox.ts +61 -0
  525. package/src/commands/init.ts +78 -16
  526. package/src/commands/ledger-v3.ts +421 -1
  527. package/src/commands/logs.ts +224 -0
  528. package/src/commands/messages.ts +61 -0
  529. package/src/commands/outline.ts +6 -2
  530. package/src/commands/presence.ts +7 -2
  531. package/src/commands/read.ts +6 -2
  532. package/src/commands/semantic.ts +244 -0
  533. package/src/commands/storage.ts +310 -0
  534. package/src/commands/tunnel.ts +66 -52
  535. package/src/commands/web.ts +92 -7
  536. package/src/commands/work.ts +3 -3
  537. package/src/commands/workflow.ts +13 -13
  538. package/src/core/agents/canonical-emit.ts +15 -0
  539. package/src/core/agents/claim-path.ts +23 -0
  540. package/src/core/agents/cli.ts +259 -53
  541. package/src/core/agents/coord-client.ts +92 -8
  542. package/src/core/agents/live-authority-v3.ts +342 -14
  543. package/src/core/agents/live-lifecycle-v3.ts +14 -4
  544. package/src/core/agents/live-observation-v3.ts +13 -3
  545. package/src/core/agents/render/prompt-context.ts +40 -16
  546. package/src/core/agents/rules/stop-hook.ts +129 -25
  547. package/src/core/agents/rules/verdict.ts +1 -0
  548. package/src/core/agents/session-events.ts +4 -0
  549. package/src/core/agents/session-finalization-state-v3.ts +1 -1
  550. package/src/core/agents/session-finalizer-v3.ts +4 -1
  551. package/src/core/agents/session-name-display.ts +9 -1
  552. package/src/core/agents/state/activity-log.ts +7 -2
  553. package/src/core/agents/state/heartbeat-reader.ts +69 -0
  554. package/src/core/agents/state/heartbeat-writer.ts +47 -84
  555. package/src/core/agents/state/live-coordination-view.ts +17 -81
  556. package/src/core/agents/state/live-coordination-writer.ts +141 -0
  557. package/src/core/agents/state/names.ts +190 -182
  558. package/src/core/agents/state/stale-sweep.ts +25 -5
  559. package/src/core/artifacts/constants.ts +4 -0
  560. package/src/core/artifacts/index.ts +113 -8
  561. package/src/core/config.ts +126 -5
  562. package/src/core/conversations/archive.ts +237 -0
  563. package/src/core/conversations/catalog.ts +79 -0
  564. package/src/core/conversations/context-pack.ts +72 -0
  565. package/src/core/conversations/contract.ts +178 -0
  566. package/src/core/conversations/evaluation.ts +30 -0
  567. package/src/core/conversations/index.ts +9 -0
  568. package/src/core/conversations/lifecycle.ts +63 -0
  569. package/src/core/conversations/normalize.ts +105 -0
  570. package/src/core/conversations/query.ts +318 -0
  571. package/src/core/conversations/search-index.ts +48 -0
  572. package/src/core/events/legacy-storage/canary.ts +177 -0
  573. package/src/core/events/legacy-storage/fence.ts +129 -0
  574. package/src/core/events/legacy-storage/index.ts +5 -0
  575. package/src/core/events/legacy-storage/inventory.ts +51 -0
  576. package/src/core/events/legacy-storage/manifest.ts +136 -0
  577. package/src/core/events/legacy-storage/reader.ts +178 -0
  578. package/src/core/events/v3/authority-outbox.ts +22 -1
  579. package/src/core/events/v3/base-contract.ts +56 -7
  580. package/src/core/events/v3/bootstrap.ts +195 -2
  581. package/src/core/events/v3/capabilities.ts +37 -3
  582. package/src/core/events/v3/control-witness.ts +339 -0
  583. package/src/core/events/v3/control-writer.ts +16 -0
  584. package/src/core/events/v3/control.ts +54 -18
  585. package/src/core/events/v3/coordination-transaction-recovery.ts +477 -0
  586. package/src/core/events/v3/coordination-view.ts +17 -1
  587. package/src/core/events/v3/generated.ts +1 -1
  588. package/src/core/events/v3/index.ts +26 -2
  589. package/src/core/events/v3/latency.ts +213 -2
  590. package/src/core/events/v3/live-route-observer.ts +80 -0
  591. package/src/core/events/v3/live-routing.ts +182 -45
  592. package/src/core/events/v3/producers/command-recorder.ts +10 -1
  593. package/src/core/events/v3/producers/coordination-recorder.ts +112 -15
  594. package/src/core/events/v3/producers/diagnostic-summaries.ts +593 -0
  595. package/src/core/events/v3/producers/hook-base.ts +116 -2
  596. package/src/core/events/v3/producers/intake.ts +48 -2
  597. package/src/core/events/v3/producers/producer-state-observer.ts +52 -0
  598. package/src/core/events/v3/producers/recorder.ts +1403 -30
  599. package/src/core/events/v3/reader.ts +243 -2
  600. package/src/core/events/v3/rotation-config.ts +98 -0
  601. package/src/core/events/v3/runtime-build.ts +41 -0
  602. package/src/core/events/v3/runtime-identity.ts +16 -0
  603. package/src/core/events/v3/runtime-telemetry-capabilities.ts +143 -0
  604. package/src/core/events/v3/support-storage/classify.ts +209 -0
  605. package/src/core/events/v3/support-storage/eligibility.ts +58 -0
  606. package/src/core/events/v3/support-storage/index.ts +9 -0
  607. package/src/core/events/v3/support-storage/inventory.ts +135 -0
  608. package/src/core/events/v3/support-storage/logical-authority.ts +117 -0
  609. package/src/core/events/v3/support-storage/maintenance.ts +501 -0
  610. package/src/core/events/v3/support-storage/pack-contract.ts +337 -0
  611. package/src/core/events/v3/support-storage/pack-reader.ts +346 -0
  612. package/src/core/events/v3/support-storage/pack-writer.ts +352 -0
  613. package/src/core/events/v3/support-storage/recovery.ts +43 -0
  614. package/src/core/events/v3/turn-telemetry.ts +66 -5
  615. package/src/core/events/v3/writer.ts +168 -16
  616. package/src/core/governor/plan-read.ts +5 -18
  617. package/src/core/governor/planning.ts +5 -8
  618. package/src/core/governor/service-read.ts +320 -2
  619. package/src/core/governor/service.ts +49 -22
  620. package/src/core/guard/evidence-v3.ts +1 -0
  621. package/src/core/hooks/adapter/events.ts +1 -0
  622. package/src/core/hooks/adapter/output.ts +12 -5
  623. package/src/core/hooks/adapter/parse.ts +16 -0
  624. package/src/core/hooks/adapter/runtime-telemetry.ts +1200 -0
  625. package/src/core/hooks/cli.ts +342 -64
  626. package/src/core/hooks/effects/image-capture.ts +4 -1
  627. package/src/core/hooks/remediation-cap.ts +83 -0
  628. package/src/core/hooks/resolve/coord-root.ts +91 -11
  629. package/src/core/hooks/resolve/owner.ts +4 -0
  630. package/src/core/hooks/resolve/transcript.ts +55 -11
  631. package/src/core/inbox/contract.ts +81 -0
  632. package/src/core/inbox/index.ts +4 -0
  633. package/src/core/inbox/lifecycle.ts +104 -0
  634. package/src/core/inbox/service.ts +305 -0
  635. package/src/core/inbox/watcher.ts +36 -0
  636. package/src/core/presence/codec-digest.ts +15 -9
  637. package/src/core/presence/relay-client.ts +55 -7
  638. package/src/core/semantic/adapters.ts +452 -0
  639. package/src/core/semantic/contract.ts +430 -0
  640. package/src/core/semantic/evidence.ts +336 -0
  641. package/src/core/semantic/index.ts +201 -0
  642. package/src/core/semantic/once.ts +496 -0
  643. package/src/core/semantic/prompt.ts +96 -0
  644. package/src/core/semantic/review.ts +803 -0
  645. package/src/core/semantic/routes.ts +30 -0
  646. package/src/core/semantic/scheduler.ts +151 -0
  647. package/src/core/semantic/service-status.ts +212 -0
  648. package/src/core/semantic/service.ts +681 -0
  649. package/src/core/semantic/soak.ts +638 -0
  650. package/src/core/semantic/storage.ts +300 -0
  651. package/src/core/semantic/usage.ts +272 -0
  652. package/src/core/semantic/validate.ts +243 -0
  653. package/src/core/storage/buffer.ts +124 -0
  654. package/src/core/storage/builtins.ts +916 -0
  655. package/src/core/storage/catalog.ts +467 -0
  656. package/src/core/storage/config.ts +423 -0
  657. package/src/core/storage/contract.ts +342 -0
  658. package/src/core/storage/durable-history.ts +738 -0
  659. package/src/core/storage/health.ts +76 -0
  660. package/src/core/storage/index.ts +15 -0
  661. package/src/core/storage/inventory.ts +859 -0
  662. package/src/core/storage/jsonl.ts +213 -0
  663. package/src/core/storage/log-retention.ts +555 -0
  664. package/src/core/storage/logger.ts +546 -0
  665. package/src/core/storage/maintenance-providers.ts +200 -0
  666. package/src/core/storage/maintenance.ts +929 -0
  667. package/src/core/storage/metrics.ts +199 -0
  668. package/src/core/storage/policy.ts +141 -0
  669. package/src/core/storage/process-log.ts +203 -0
  670. package/src/core/storage/query.ts +360 -0
  671. package/src/core/storage/receipts.ts +162 -0
  672. package/src/core/storage/segments.ts +721 -0
  673. package/src/core/storage/sink-graph.ts +343 -0
  674. package/src/core/storage/storm-control.ts +91 -0
  675. package/src/core/work/state.ts +12 -21
  676. package/src/core/workflow/live-session-v3.ts +2 -4
  677. package/src/index.ts +2 -0
  678. package/src/lazy-commands.ts +294 -0
  679. package/src/lib/browser/client.ts +21 -0
  680. package/src/lib/browser/index.ts +4 -0
  681. package/src/lib/browser/standalone-html.ts +312 -0
  682. package/src/lib/docs-lint.ts +58 -77
  683. package/src/lib/docs-metadata-audit.ts +26 -21
  684. package/src/lib/docs-metadata-sync.ts +32 -9
  685. package/src/lib/docs-repository-view.ts +220 -0
  686. package/src/lib/http/client.ts +44 -8
  687. package/src/lib/http/index.ts +6 -1
  688. package/src/lib/indexer-exclusions.ts +173 -0
  689. package/src/lib/instructions/apply.ts +1 -0
  690. package/src/lib/instructions/templates.ts +154 -4
  691. package/src/lib/local-file-url.ts +31 -0
  692. package/src/lib/web-performance.ts +335 -0
@@ -9,10 +9,13 @@ import {
9
9
  openSync,
10
10
  readFileSync,
11
11
  renameSync,
12
+ statSync,
12
13
  writeFileSync,
13
14
  } from "node:fs";
15
+ import { hostname } from "node:os";
14
16
  import { dirname, join, resolve } from "node:path";
15
17
  import { fsyncParentDirectory } from "../../workflow/durable-record.ts";
18
+ import { acquireNoClobberLease } from "../../workflow/workspaces/leases.ts";
16
19
  import { canonicalJsonV3, sha256V3 } from "./canonical.ts";
17
20
  import { ADAPTER_CAPABILITY_PROFILES_V3 } from "./capabilities.ts";
18
21
  import {
@@ -23,11 +26,13 @@ import {
23
26
  EVENT_V3_GENESIS_MANIFEST,
24
27
  type EventV3ControlState,
25
28
  readEventV3ControlState,
26
- repairEventV3ControlPair,
27
29
  } from "./control.ts";
30
+ import { repairEventV3ControlPair } from "./control-writer.ts";
28
31
  import { loadOrCreateFingerprintKeyStoreV3 } from "./fingerprint-keys.ts";
29
32
  import { EVENT_V3_SCHEMA_DIGEST } from "./generated.ts";
30
- import { liveEventV3BuildId, livePlatformV3 } from "./live-routing.ts";
33
+ import { resolveEventLedgerRotateActiveBytesV3 } from "./rotation-config.ts";
34
+ import { currentHarneryRuntimeBuild, liveEventV3BuildId, livePlatformV3 } from "./runtime-build.ts";
35
+ import { drainReadyEventsV3 } from "./writer.ts";
31
36
 
32
37
  export interface InitializeEventLedgerV3Input {
33
38
  coordRoot: string;
@@ -47,6 +52,17 @@ export interface InitializeEventLedgerV3Result {
47
52
  control: Extract<EventV3ControlState, { state: "active" }>;
48
53
  }
49
54
 
55
+ export interface RefreshIncompatibleEventLedgerV3Result {
56
+ state: "current" | "refreshed";
57
+ archived_epoch?: string;
58
+ control: Extract<EventV3ControlState, { state: "active" }>;
59
+ }
60
+
61
+ const BOOTSTRAP_LEASE_RETRIES = 12;
62
+ const BOOTSTRAP_LEASE_RETRY_MS = 25;
63
+ const BOOTSTRAP_LEASE_STALE_MS = 10_000;
64
+ const bootstrapSleepCell = new Int32Array(new SharedArrayBuffer(4));
65
+
50
66
  /**
51
67
  * Ensure programmatic Harnery entry points have the same universal V3
52
68
  * boundary as `harn init`. Only a genuinely absent control pair is created;
@@ -79,6 +95,133 @@ export function ensureEventLedgerV3(
79
95
  */
80
96
  export function initializeEventLedgerV3(
81
97
  input: InitializeEventLedgerV3Input,
98
+ ): InitializeEventLedgerV3Result {
99
+ return withBootstrapLease(input.coordRoot, () => initializeEventLedgerV3Locked(input));
100
+ }
101
+
102
+ /**
103
+ * Replace only a runtime-incompatible epoch that the current code can name
104
+ * exactly. Corruption and ambiguous control failures remain closed for the
105
+ * explicit recovery command.
106
+ */
107
+ export function refreshIncompatibleEventLedgerV3(
108
+ coordRoot: string,
109
+ ): RefreshIncompatibleEventLedgerV3Result {
110
+ const root = resolve(coordRoot);
111
+ return withBootstrapLease(root, () => {
112
+ const current = readEventV3ControlState(root);
113
+ if (current.state === "active" && runtimeCapabilityProfileCurrent(current)) {
114
+ return { state: "current", control: current };
115
+ }
116
+ const refreshable =
117
+ (current.state === "invalid" && current.reason === "genesis_schema_digest_incompatible") ||
118
+ ((current.state === "candidate" || current.state === "active") &&
119
+ !runtimeCapabilityProfileCurrent(current));
120
+ if (!refreshable) {
121
+ const reason = "reason" in current ? `${current.state}:${current.reason}` : current.state;
122
+ throw new Error(`event_v3_runtime_refresh_refused:${reason}`);
123
+ }
124
+ const configPath = join(root, ".harnery", "config.jsonc");
125
+ const initialized = initializeEventLedgerV3Locked({
126
+ coordRoot: root,
127
+ harneryBuild: currentHarneryRuntimeBuild(),
128
+ hostBuild: repositoryBuild(root),
129
+ configDigest: sha256V3(
130
+ existsSync(configPath) ? readFileSync(configPath) : Buffer.from("{}\n"),
131
+ ),
132
+ approvalRecordId: "harnery-runtime-v3-auto-refresh",
133
+ forceNewEpoch: true,
134
+ });
135
+ return {
136
+ state: "refreshed",
137
+ ...(initialized.archived_epoch ? { archived_epoch: initialized.archived_epoch } : {}),
138
+ control: initialized.control,
139
+ };
140
+ });
141
+ }
142
+
143
+ export interface RotateOversizedEventLedgerV3Result {
144
+ state: "rotated" | "not_oversized" | "not_active" | "disabled";
145
+ active_bytes: number;
146
+ threshold_bytes: number;
147
+ archived_epoch?: string;
148
+ control?: Extract<EventV3ControlState, { state: "active" }>;
149
+ }
150
+
151
+ /**
152
+ * Archive a valid oversized epoch intact and start a fresh one.
153
+ *
154
+ * Every canonical read validates the complete epoch, and hook producers are
155
+ * one-shot processes, so an unbounded active segment makes every hook's cold
156
+ * read scale with all history. Rotation bounds that cost: the replaced epoch
157
+ * (events, spool, producer states, manifests) moves whole into the V3
158
+ * archive, live sessions re-onboard into the new epoch on their next signal,
159
+ * and the writer's epoch fence keeps in-flight producers of the old epoch
160
+ * from ever committing into the new one. Only a currently valid, active
161
+ * ledger rotates; integrity failures stay closed for the explicit recovery
162
+ * command. The threshold comes from the isolated Event V3 config resolver
163
+ * unless the caller pins one; a non-positive threshold disables rotation.
164
+ */
165
+ export function rotateOversizedEventLedgerV3(
166
+ coordRoot: string,
167
+ options: { thresholdBytes?: number } = {},
168
+ ): RotateOversizedEventLedgerV3Result {
169
+ const root = resolve(coordRoot);
170
+ const threshold = options.thresholdBytes ?? resolveEventLedgerRotateActiveBytesV3(root);
171
+ const activePath = join(root, ".harnery", "ledgers", "v3", "active.ndjson");
172
+ const measure = () => {
173
+ try {
174
+ return statSync(activePath).size;
175
+ } catch {
176
+ return 0;
177
+ }
178
+ };
179
+ if (threshold <= 0) {
180
+ return { state: "disabled", active_bytes: measure(), threshold_bytes: threshold };
181
+ }
182
+ if (measure() < threshold) {
183
+ return { state: "not_oversized", active_bytes: measure(), threshold_bytes: threshold };
184
+ }
185
+ return withBootstrapLease(root, () => {
186
+ const activeBytes = measure();
187
+ if (activeBytes < threshold) {
188
+ return { state: "not_oversized", active_bytes: activeBytes, threshold_bytes: threshold };
189
+ }
190
+ const current = readEventV3ControlState(root);
191
+ if (current.state !== "active") {
192
+ return { state: "not_active", active_bytes: activeBytes, threshold_bytes: threshold };
193
+ }
194
+ // Flush durable ready rows into the epoch they were produced for, so the
195
+ // archive carries them committed instead of stranded in its spool.
196
+ try {
197
+ drainReadyEventsV3(root);
198
+ } catch {
199
+ // A busy append lease only leaves rows in the archived spool; rotation
200
+ // itself stays safe.
201
+ }
202
+ const configPath = join(root, ".harnery", "config.jsonc");
203
+ const initialized = initializeEventLedgerV3Locked({
204
+ coordRoot: root,
205
+ harneryBuild: currentHarneryRuntimeBuild(),
206
+ hostBuild: repositoryBuild(root),
207
+ configDigest: sha256V3(
208
+ existsSync(configPath) ? readFileSync(configPath) : Buffer.from("{}\n"),
209
+ ),
210
+ approvalRecordId: "harnery-runtime-v3-size-rotation",
211
+ forceNewEpoch: true,
212
+ });
213
+ return {
214
+ state: "rotated",
215
+ active_bytes: activeBytes,
216
+ threshold_bytes: threshold,
217
+ ...(initialized.archived_epoch ? { archived_epoch: initialized.archived_epoch } : {}),
218
+ control: initialized.control,
219
+ };
220
+ });
221
+ }
222
+
223
+ function initializeEventLedgerV3Locked(
224
+ input: InitializeEventLedgerV3Input,
82
225
  ): InitializeEventLedgerV3Result {
83
226
  const root = resolve(input.coordRoot);
84
227
  let current = readEventV3ControlState(root);
@@ -147,6 +290,56 @@ export function initializeEventLedgerV3(
147
290
  };
148
291
  }
149
292
 
293
+ function runtimeCapabilityProfileCurrent(
294
+ control: Extract<EventV3ControlState, { state: "candidate" | "active" }>,
295
+ ): boolean {
296
+ const expected = Object.values(ADAPTER_CAPABILITY_PROFILES_V3).map((profile) =>
297
+ sha256V3(canonicalJsonV3(profile)),
298
+ );
299
+ const approved = control.genesis.profile.adapter_capability_profile_digests;
300
+ const expectedDigests = new Set<string>(expected);
301
+ return control.state === "candidate"
302
+ ? approved.some((digest) => expectedDigests.has(digest))
303
+ : expected.every((digest) => approved.includes(digest));
304
+ }
305
+
306
+ function withBootstrapLease<T>(coordRoot: string, operation: () => T): T {
307
+ const root = resolve(coordRoot);
308
+ const authority = createHash("sha256").update(root).digest("hex");
309
+ let lease: ReturnType<typeof acquireNoClobberLease> | undefined;
310
+ for (let attempt = 0; attempt < BOOTSTRAP_LEASE_RETRIES; attempt += 1) {
311
+ try {
312
+ lease = acquireNoClobberLease({
313
+ path: join(root, ".harnery", "private", "event-v3-bootstrap-lease"),
314
+ scope: "event-v3-bootstrap",
315
+ authoritySha256: authority,
316
+ staleAfterMs: BOOTSTRAP_LEASE_STALE_MS,
317
+ validateStaleOwner: (owner) => owner.host === hostname() && !pidIsAlive(owner.pid),
318
+ });
319
+ break;
320
+ } catch (error) {
321
+ if (attempt === BOOTSTRAP_LEASE_RETRIES - 1) throw error;
322
+ Atomics.wait(bootstrapSleepCell, 0, 0, BOOTSTRAP_LEASE_RETRY_MS);
323
+ }
324
+ }
325
+ if (!lease) throw new Error("event_v3_bootstrap_lease_busy");
326
+ try {
327
+ return operation();
328
+ } finally {
329
+ lease.release();
330
+ }
331
+ }
332
+
333
+ function pidIsAlive(pid: number): boolean {
334
+ if (!Number.isSafeInteger(pid) || pid < 1) return false;
335
+ try {
336
+ process.kill(pid, 0);
337
+ return true;
338
+ } catch (error) {
339
+ return (error as NodeJS.ErrnoException).code !== "ESRCH";
340
+ }
341
+ }
342
+
150
343
  function activateCandidateEpoch(
151
344
  root: string,
152
345
  candidate: CandidateGenesisManifestV3,
@@ -14,6 +14,21 @@ export type AdapterWaitKindV3 =
14
14
  | "rate_limit"
15
15
  | "unknown";
16
16
 
17
+ export const ADAPTER_WAIT_KINDS_V3: readonly AdapterWaitKindV3[] = [
18
+ "permission",
19
+ "needs_input",
20
+ "decision",
21
+ "approval",
22
+ "scheduled",
23
+ "rate_limit",
24
+ "unknown",
25
+ ] as const;
26
+
27
+ export interface WaitKindCapabilityV3 {
28
+ span_delivery: CapabilitySupportV3;
29
+ turn_completeness: CapabilitySupportV3;
30
+ }
31
+
17
32
  export type BaseAdapterSignalV3 =
18
33
  | "session_start"
19
34
  | "session_end"
@@ -69,7 +84,7 @@ const BASE_SIGNAL_SUPPORT: Record<Adapter, Record<BaseAdapterSignalV3, Capabilit
69
84
  turn_id: "conditional",
70
85
  permission: "native",
71
86
  post_compaction: "native",
72
- context_usage: "unsupported",
87
+ context_usage: "conditional",
73
88
  },
74
89
  codex: {
75
90
  ...SHARED_SIGNAL_SUPPORT,
@@ -77,7 +92,7 @@ const BASE_SIGNAL_SUPPORT: Record<Adapter, Record<BaseAdapterSignalV3, Capabilit
77
92
  turn_id: "native",
78
93
  permission: "native",
79
94
  post_compaction: "native",
80
- context_usage: "unsupported",
95
+ context_usage: "derived",
81
96
  },
82
97
  cursor: {
83
98
  ...SHARED_SIGNAL_SUPPORT,
@@ -91,7 +106,7 @@ const BASE_SIGNAL_SUPPORT: Record<Adapter, Record<BaseAdapterSignalV3, Capabilit
91
106
  shell: "conditional",
92
107
  permission: "conditional",
93
108
  post_compaction: "unsupported",
94
- context_usage: "unsupported",
109
+ context_usage: "conditional",
95
110
  },
96
111
  };
97
112
 
@@ -159,6 +174,25 @@ export function adapterTurnWaitCountSupportV3(_adapter: Adapter): CapabilitySupp
159
174
  return "unsupported";
160
175
  }
161
176
 
177
+ /**
178
+ * Per-kind wait matrix for native adapter turns. Span delivery and independent
179
+ * completed-turn completeness are deliberately separate: observing a span
180
+ * never proves that an absent span means zero.
181
+ */
182
+ export function adapterWaitCoverageMatrixV3(
183
+ adapter: Adapter,
184
+ ): Record<AdapterWaitKindV3, WaitKindCapabilityV3> {
185
+ return Object.fromEntries(
186
+ ADAPTER_WAIT_KINDS_V3.map((kind) => [
187
+ kind,
188
+ {
189
+ span_delivery: adapterWaitKindSupportV3(adapter, kind),
190
+ turn_completeness: adapterTurnWaitCountSupportV3(adapter),
191
+ },
192
+ ]),
193
+ ) as Record<AdapterWaitKindV3, WaitKindCapabilityV3>;
194
+ }
195
+
162
196
  /**
163
197
  * Local Cursor sessions expose the generic tool channel. Cloud/private-worker
164
198
  * sessions cannot guarantee whole-turn delivery because hooks may start only
@@ -0,0 +1,339 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import {
3
+ chmodSync,
4
+ closeSync,
5
+ existsSync,
6
+ fsyncSync,
7
+ openSync,
8
+ readFileSync,
9
+ renameSync,
10
+ unlinkSync,
11
+ writeFileSync,
12
+ } from "node:fs";
13
+ import { fsyncParentDirectory } from "../../workflow/durable-record.ts";
14
+ import { canonicalJsonV3, type FingerprintV3, fingerprintV3, sha256V3 } from "./canonical.ts";
15
+ import type { ActivationManifestV3, CandidateGenesisManifestV3 } from "./control.ts";
16
+ import { fingerprintContextV3 } from "./fingerprint-keys.ts";
17
+ import {
18
+ advanceEventV3AppendValidationCheckpointV3,
19
+ EVENT_V3_CONTROL_CHECKPOINT_RELATIVE_PATH,
20
+ EVENT_V3_CONTROL_WITNESS_RELATIVE_PATH,
21
+ type EventV3AppendValidationCheckpointV3,
22
+ type EventV3AuthorityStorageVersionV3,
23
+ eventV3AuthorityStorageVersionV3,
24
+ eventV3ControlCheckpointPathV3,
25
+ eventV3ControlWitnessPathV3,
26
+ parseEventV3AppendValidationCheckpointV3,
27
+ } from "./reader.ts";
28
+
29
+ export { EVENT_V3_CONTROL_CHECKPOINT_RELATIVE_PATH, EVENT_V3_CONTROL_WITNESS_RELATIVE_PATH };
30
+
31
+ interface EventV3ControlWitnessPayload {
32
+ format: "harnery-event-v3-control-witness";
33
+ format_version: 1;
34
+ genesis_id: `gex_${string}`;
35
+ activation_id: `act_${string}`;
36
+ genesis_event_id: `evt_${string}`;
37
+ activation_event_id: `evt_${string}`;
38
+ genesis_manifest_digest: `sha256:${string}`;
39
+ activation_manifest_digest: `sha256:${string}`;
40
+ candidate_manifest_digest: `sha256:${string}`;
41
+ privacy_key_epoch: `pep_${string}`;
42
+ root_id: `root_${string}`;
43
+ storage: EventV3AuthorityStorageVersionV3;
44
+ checkpoint_digest: `sha256:${string}`;
45
+ }
46
+
47
+ interface EventV3ControlWitness {
48
+ payload: EventV3ControlWitnessPayload;
49
+ authentication: FingerprintV3;
50
+ }
51
+
52
+ export interface ActiveControlWitnessBindingV3 {
53
+ genesis: CandidateGenesisManifestV3;
54
+ activation: ActivationManifestV3;
55
+ candidate_manifest_digest: `sha256:${string}`;
56
+ }
57
+
58
+ /** True only when one authenticated witness names this exact active control pair and storage. */
59
+ export function activeControlWitnessMatchesV3(
60
+ coordRoot: string,
61
+ binding: ActiveControlWitnessBindingV3,
62
+ ): boolean {
63
+ try {
64
+ const before = eventV3AuthorityStorageVersionV3(coordRoot);
65
+ const witness = readAuthenticatedWitnessV3(coordRoot);
66
+ if (!witness) return false;
67
+ const expected = witnessPayloadV3(binding, before, witness.payload.checkpoint_digest);
68
+ if (canonicalJsonV3(witness.payload) !== canonicalJsonV3(expected)) return false;
69
+ const after = eventV3AuthorityStorageVersionV3(coordRoot);
70
+ return sameStorageVersion(before, after);
71
+ } catch {
72
+ return false;
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Publish a witness only when the storage validated by the caller is still current.
78
+ * Failure is intentionally silent: the next read retains the canonical full-scan fallback.
79
+ */
80
+ export function publishActiveControlWitnessV3(
81
+ coordRoot: string,
82
+ binding: ActiveControlWitnessBindingV3,
83
+ validatedStorage: EventV3AuthorityStorageVersionV3,
84
+ checkpoint: EventV3AppendValidationCheckpointV3,
85
+ ): boolean {
86
+ try {
87
+ const current = eventV3AuthorityStorageVersionV3(coordRoot);
88
+ if (!sameStorageVersion(validatedStorage, current)) return false;
89
+ return publishWitnessV3(
90
+ coordRoot,
91
+ witnessPayloadV3(binding, current, checkpointDigestV3(checkpoint)),
92
+ checkpoint,
93
+ );
94
+ } catch {
95
+ return false;
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Capture a previously authenticated witness before the append lease mutates storage.
101
+ * The returned payload is safe to advance only while the caller continues to hold that lease.
102
+ */
103
+ export function readAdvanceableControlWitnessV3(coordRoot: string):
104
+ | {
105
+ payload: EventV3ControlWitnessPayload;
106
+ checkpoint: EventV3AppendValidationCheckpointV3;
107
+ }
108
+ | undefined {
109
+ try {
110
+ const storage = eventV3AuthorityStorageVersionV3(coordRoot);
111
+ const witness = readAuthenticatedWitnessV3(coordRoot);
112
+ if (!witness || !sameStorageVersion(witness.payload.storage, storage)) return undefined;
113
+ const checkpoint = readAuthenticatedCheckpointV3(coordRoot, witness.payload.checkpoint_digest);
114
+ return checkpoint && checkpoint.validated_active_bytes === storage.active_bytes
115
+ ? { payload: witness.payload, checkpoint }
116
+ : undefined;
117
+ } catch {
118
+ return undefined;
119
+ }
120
+ }
121
+
122
+ /** Advance a lease-held witness after durable appends without changing writer success semantics. */
123
+ export function advanceControlWitnessV3(
124
+ coordRoot: string,
125
+ prior: {
126
+ payload: EventV3ControlWitnessPayload;
127
+ checkpoint: EventV3AppendValidationCheckpointV3;
128
+ },
129
+ currentGenesisId: string | undefined,
130
+ ): boolean {
131
+ try {
132
+ if (currentGenesisId !== prior.payload.genesis_id) return false;
133
+ const storageBeforeValidation = eventV3AuthorityStorageVersionV3(coordRoot);
134
+ const checkpoint = advanceEventV3AppendValidationCheckpointV3(coordRoot, prior.checkpoint);
135
+ if (!checkpoint) return false;
136
+ const storage = eventV3AuthorityStorageVersionV3(coordRoot);
137
+ if (
138
+ storageBeforeValidation.fingerprint !== storage.fingerprint ||
139
+ prior.payload.storage.stable_fingerprint !== storage.stable_fingerprint ||
140
+ checkpoint.validated_active_bytes !== storage.active_bytes
141
+ ) {
142
+ return false;
143
+ }
144
+ return publishWitnessV3(
145
+ coordRoot,
146
+ {
147
+ ...prior.payload,
148
+ storage,
149
+ checkpoint_digest: checkpointDigestV3(checkpoint),
150
+ },
151
+ checkpoint,
152
+ );
153
+ } catch {
154
+ return false;
155
+ }
156
+ }
157
+
158
+ function witnessPayloadV3(
159
+ binding: ActiveControlWitnessBindingV3,
160
+ storage: EventV3AuthorityStorageVersionV3,
161
+ checkpointDigest: `sha256:${string}`,
162
+ ): EventV3ControlWitnessPayload {
163
+ const scope = binding.genesis.event.scope as { root_id: `root_${string}` };
164
+ return {
165
+ format: "harnery-event-v3-control-witness",
166
+ format_version: 1,
167
+ genesis_id: binding.genesis.event.payload.genesis_id as `gex_${string}`,
168
+ activation_id: binding.activation.activation_id,
169
+ genesis_event_id: binding.genesis.event.event_id as `evt_${string}`,
170
+ activation_event_id: binding.activation.event.event_id as `evt_${string}`,
171
+ genesis_manifest_digest: sha256V3(canonicalJsonV3(binding.genesis)),
172
+ activation_manifest_digest: sha256V3(canonicalJsonV3(binding.activation)),
173
+ candidate_manifest_digest: binding.candidate_manifest_digest,
174
+ privacy_key_epoch: binding.genesis.profile.privacy_key_epoch,
175
+ root_id: scope.root_id,
176
+ storage,
177
+ checkpoint_digest: checkpointDigest,
178
+ };
179
+ }
180
+
181
+ function readAuthenticatedWitnessV3(coordRoot: string): EventV3ControlWitness | undefined {
182
+ const path = eventV3ControlWitnessPathV3(coordRoot);
183
+ if (!existsSync(path)) return undefined;
184
+ const raw = readFileSync(path, "utf8");
185
+ const value: unknown = JSON.parse(raw);
186
+ const witness = parseWitnessV3(value);
187
+ if (`${canonicalJsonV3(witness)}\n` !== raw) return undefined;
188
+ const expected = authenticatePayloadV3(coordRoot, witness.payload);
189
+ return canonicalJsonV3(witness.authentication) === canonicalJsonV3(expected)
190
+ ? witness
191
+ : undefined;
192
+ }
193
+
194
+ function publishWitnessV3(
195
+ coordRoot: string,
196
+ payload: EventV3ControlWitnessPayload,
197
+ checkpoint: EventV3AppendValidationCheckpointV3,
198
+ ): boolean {
199
+ if (!publishCanonicalFileV3(eventV3ControlCheckpointPathV3(coordRoot), checkpoint)) return false;
200
+ const witness: EventV3ControlWitness = {
201
+ payload,
202
+ authentication: authenticatePayloadV3(coordRoot, payload),
203
+ };
204
+ return publishCanonicalFileV3(eventV3ControlWitnessPathV3(coordRoot), witness);
205
+ }
206
+
207
+ function publishCanonicalFileV3(path: string, value: unknown): boolean {
208
+ const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
209
+ let fd: number | undefined;
210
+ try {
211
+ fd = openSync(temporary, "wx", 0o600);
212
+ writeFileSync(fd, `${canonicalJsonV3(value)}\n`, "utf8");
213
+ fsyncSync(fd);
214
+ closeSync(fd);
215
+ fd = undefined;
216
+ chmodSync(temporary, 0o600);
217
+ renameSync(temporary, path);
218
+ fsyncParentDirectory(path);
219
+ return true;
220
+ } finally {
221
+ if (fd !== undefined) closeSync(fd);
222
+ if (existsSync(temporary)) unlinkSync(temporary);
223
+ }
224
+ }
225
+
226
+ function readAuthenticatedCheckpointV3(
227
+ coordRoot: string,
228
+ expectedDigest: `sha256:${string}`,
229
+ ): EventV3AppendValidationCheckpointV3 | undefined {
230
+ try {
231
+ const raw = readFileSync(eventV3ControlCheckpointPathV3(coordRoot), "utf8");
232
+ const value: unknown = JSON.parse(raw);
233
+ if (
234
+ `${canonicalJsonV3(value)}\n` !== raw ||
235
+ sha256V3(canonicalJsonV3(value)) !== expectedDigest
236
+ ) {
237
+ return undefined;
238
+ }
239
+ return parseEventV3AppendValidationCheckpointV3(value);
240
+ } catch {
241
+ return undefined;
242
+ }
243
+ }
244
+
245
+ function checkpointDigestV3(checkpoint: EventV3AppendValidationCheckpointV3): `sha256:${string}` {
246
+ return sha256V3(canonicalJsonV3(checkpoint));
247
+ }
248
+
249
+ function authenticatePayloadV3(
250
+ coordRoot: string,
251
+ payload: EventV3ControlWitnessPayload,
252
+ ): FingerprintV3 {
253
+ const context = fingerprintContextV3(
254
+ coordRoot,
255
+ payload.root_id,
256
+ undefined,
257
+ payload.privacy_key_epoch,
258
+ );
259
+ return fingerprintV3(context, "control-state-witness", payload, "root");
260
+ }
261
+
262
+ function parseWitnessV3(value: unknown): EventV3ControlWitness {
263
+ const envelope = object(value);
264
+ if (Object.keys(envelope).sort().join("\0") !== "authentication\0payload") {
265
+ throw new Error("control witness envelope is invalid");
266
+ }
267
+ const payload = object(envelope.payload);
268
+ const expectedPayloadKeys = [
269
+ "activation_event_id",
270
+ "activation_id",
271
+ "activation_manifest_digest",
272
+ "candidate_manifest_digest",
273
+ "checkpoint_digest",
274
+ "format",
275
+ "format_version",
276
+ "genesis_event_id",
277
+ "genesis_id",
278
+ "genesis_manifest_digest",
279
+ "privacy_key_epoch",
280
+ "root_id",
281
+ "storage",
282
+ ];
283
+ if (Object.keys(payload).sort().join("\0") !== expectedPayloadKeys.sort().join("\0")) {
284
+ throw new Error("control witness payload shape is invalid");
285
+ }
286
+ const storage = object(payload.storage);
287
+ if (Object.keys(storage).sort().join("\0") !== "active_bytes\0fingerprint\0stable_fingerprint") {
288
+ throw new Error("control witness storage shape is invalid");
289
+ }
290
+ if (
291
+ payload.format !== "harnery-event-v3-control-witness" ||
292
+ payload.format_version !== 1 ||
293
+ !token(payload.genesis_id, "gex_") ||
294
+ !token(payload.activation_id, "act_") ||
295
+ !token(payload.genesis_event_id, "evt_") ||
296
+ !token(payload.activation_event_id, "evt_") ||
297
+ !digest(payload.genesis_manifest_digest) ||
298
+ !digest(payload.activation_manifest_digest) ||
299
+ !digest(payload.candidate_manifest_digest) ||
300
+ !digest(payload.checkpoint_digest) ||
301
+ !token(payload.privacy_key_epoch, "pep_") ||
302
+ !token(payload.root_id, "root_") ||
303
+ !digest(storage.fingerprint) ||
304
+ !digest(storage.stable_fingerprint) ||
305
+ !Number.isSafeInteger(storage.active_bytes) ||
306
+ (storage.active_bytes as number) < 0
307
+ ) {
308
+ throw new Error("control witness payload is invalid");
309
+ }
310
+ const authentication = object(envelope.authentication);
311
+ return {
312
+ payload: payload as unknown as EventV3ControlWitnessPayload,
313
+ authentication: authentication as unknown as FingerprintV3,
314
+ };
315
+ }
316
+
317
+ function object(value: unknown): Record<string, unknown> {
318
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
319
+ throw new Error("control witness value is not an object");
320
+ }
321
+ return value as Record<string, unknown>;
322
+ }
323
+
324
+ function token(value: unknown, prefix: string): value is string {
325
+ return (
326
+ typeof value === "string" && value.startsWith(prefix) && /^[a-zA-Z0-9._-]{1,160}$/.test(value)
327
+ );
328
+ }
329
+
330
+ function digest(value: unknown): value is `sha256:${string}` {
331
+ return typeof value === "string" && /^sha256:[a-f0-9]{64}$/.test(value);
332
+ }
333
+
334
+ function sameStorageVersion(
335
+ left: EventV3AuthorityStorageVersionV3,
336
+ right: EventV3AuthorityStorageVersionV3,
337
+ ): boolean {
338
+ return left.fingerprint === right.fingerprint && left.active_bytes === right.active_bytes;
339
+ }
@@ -0,0 +1,16 @@
1
+ import { type EventV3ControlState, readEventV3ControlState } from "./control.ts";
2
+ import { writeEventV3 } from "./writer.ts";
3
+
4
+ /** Repair only a manifest-first crash by appending the exact pre-minted event. */
5
+ export function repairEventV3ControlPair(coordRoot: string): EventV3ControlState {
6
+ const control = readEventV3ControlState(coordRoot);
7
+ if (control.state !== "repairable") return control;
8
+ const event =
9
+ control.reason === "genesis_event_missing" ? control.genesis.event : control.activation?.event;
10
+ if (!event) return { state: "invalid", reason: "repair_event_unavailable" };
11
+ const result = writeEventV3(coordRoot, event);
12
+ if (result.state !== "committed") {
13
+ return { state: "invalid", reason: "control_event_repair_not_committed" };
14
+ }
15
+ return readEventV3ControlState(coordRoot);
16
+ }