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
@@ -97,6 +97,10 @@ const CLOSED_TURN_MEMORY_CAP = 16;
97
97
  const SPAN_SOFT_WATERMARK = 128;
98
98
  const PENDING_RUNTIME_CONTEXT_CAP = 4;
99
99
  const RUNTIME_CONTEXT_RETRY_LIMIT = 2;
100
+ /** Active turns pay for at most one bounded adapter telemetry read per interval. */
101
+ const ACTIVE_RUNTIME_CONTEXT_PROBE_INTERVAL_MS = 15_000;
102
+ /** Codex can flush the terminal row just after Stop; keep this grace bounded and off other hooks. */
103
+ const STOP_RUNTIME_CONTEXT_RETRY_DELAYS_MS = [75, 175] as const;
100
104
  /** Finalization is off the interactive hook path; briefly cover Codex's delayed transcript flush. */
101
105
  const APPROVED_END_RUNTIME_CONTEXT_RETRY_DELAYS_MS = [0, 250, 250] as const;
102
106
  /**
@@ -159,6 +163,12 @@ interface PendingRuntimeContextV3 extends TurnContextTargetV3 {
159
163
  attempts: number;
160
164
  }
161
165
 
166
+ interface ActiveRuntimeContextProbeV3 {
167
+ turn_id: `tid_${string}`;
168
+ attempted_at: string;
169
+ boundary?: "tool_completed";
170
+ }
171
+
162
172
  interface DelegationStateV3 extends OpenSpanStateV3 {
163
173
  source_id: `hid_${string}`;
164
174
  delegation_id: `del_${string}`;
@@ -177,6 +187,14 @@ export interface HookProducerStateV3 {
177
187
  capability_profile: `cap_${string}`;
178
188
  cursor_mode?: CursorExecutionModeV3;
179
189
  privacy_epoch_id: `pep_${string}`;
190
+ /**
191
+ * Genesis id of the ledger epoch this producer's boot chain lives in. The
192
+ * fingerprint key epoch survives ledger rotation, so this is the field that
193
+ * keeps a state file from being adopted across an epoch boundary (its
194
+ * sequences and causal links only validate inside their own epoch). A state
195
+ * without it predates the field and is never adopted.
196
+ */
197
+ epoch_genesis_id?: `gex_${string}`;
180
198
  boot_id: `boot_${string}`;
181
199
  clock_id: `clk_${string}`;
182
200
  next_sequence: number;
@@ -189,6 +207,9 @@ export interface HookProducerStateV3 {
189
207
  last_monotonic_ns?: string;
190
208
  last_observed_at?: string;
191
209
  started_event_id?: `evt_${string}`;
210
+ /** A derived lifecycle reopen is allowed to exist before the adapter's next
211
+ * native prompt. Retained owner-only until that prompt starts a real turn. */
212
+ session_start_derivation?: "approved_lifecycle_reopen" | "validated_current_session_heal";
192
213
  session_span: OpenSpanStateV3;
193
214
  current_turn_span?: OpenSpanStateV3;
194
215
  terminal: boolean;
@@ -201,6 +222,10 @@ export interface HookProducerStateV3 {
201
222
  turn_ordinal: number;
202
223
  pending?: PendingEventV3;
203
224
  pending_runtime_contexts?: PendingRuntimeContextV3[];
225
+ /** Last bounded active-turn probe; owner-only and used only for cadence. */
226
+ active_runtime_context_probe?: ActiveRuntimeContextProbeV3;
227
+ /** Last emitted runtime source witness; owner-only measurement deduplication. */
228
+ last_context_source_witness?: string;
204
229
  /** Verified adapter-native transcript path retained only in owner-only state. */
205
230
  runtime_transcript_path?: string;
206
231
  /** Tuning carried by the current attestation; {} means attested-none.
@@ -243,7 +268,7 @@ export interface RecordHookSignalV3Input {
243
268
  hook_duration_ms?: number;
244
269
  stop_remediation?: boolean;
245
270
  turn_ritual?: TurnRitualEvidenceV3;
246
- session_start_derivation?: "approved_lifecycle_reopen";
271
+ session_start_derivation?: "approved_lifecycle_reopen" | "validated_current_session_heal";
247
272
  delegated_child?: {
248
273
  generation_id: `gen_${string}`;
249
274
  parent_generation_id: `gen_${string}`;
@@ -607,8 +632,23 @@ function processHookSignalLocked(
607
632
  : control.activation.event.event_id;
608
633
  const rootFingerprintContext = fingerprintContextV3(input.coordRoot, rootId, undefined, epochId);
609
634
  const sessionId = `sid_${sessionHash.slice(4)}` as `sid_${string}`;
635
+ const genesisId = control.genesis.event.payload.genesis_id as `gex_${string}`;
636
+ // Every write below carries the epoch fence: an event produced for this
637
+ // epoch is refused (or quarantined from the spool) once the epoch has been
638
+ // replaced, instead of poisoning the successor's authority.
639
+ input = {
640
+ ...input,
641
+ writerOptions: { ...input.writerOptions, expectedGenesisId: genesisId },
642
+ };
610
643
  try {
611
644
  let state = existsSync(path) ? readProducerState(path) : undefined;
645
+ if (state && state.epoch_genesis_id !== genesisId) {
646
+ // A producer state from a replaced epoch (or one that predates the
647
+ // field) is never adopted: its boot sequences and causal links only
648
+ // validate inside the epoch that recorded them. The session re-onboards
649
+ // below exactly as it does after an automatic epoch refresh.
650
+ state = undefined;
651
+ }
612
652
  if (
613
653
  state &&
614
654
  (state.adapter !== input.adapter ||
@@ -634,7 +674,7 @@ function processHookSignalLocked(
634
674
  const pendingSource = state.pending.source_id;
635
675
  const incomingSource = sourceIdForSignal(input, rootFingerprintContext);
636
676
  const pendingEvent = state.pending.event;
637
- const durability = writeEventV3(input.coordRoot, pendingEvent);
677
+ const durability = writeEventV3(input.coordRoot, pendingEvent, input.writerOptions);
638
678
  applyCommittedEvent(state, pendingEvent);
639
679
  state.pending = undefined;
640
680
  publishProducerState(path, state);
@@ -648,10 +688,19 @@ function processHookSignalLocked(
648
688
  if (state && !state.terminal && state.started_event_id) {
649
689
  return { state: "already_started", event_id: state.started_event_id };
650
690
  }
651
- if (input.session_start_derivation && !state?.terminal) {
691
+ if (
692
+ (input.session_start_derivation === "approved_lifecycle_reopen" && !state?.terminal) ||
693
+ (input.session_start_derivation === "validated_current_session_heal" && state?.terminal)
694
+ ) {
652
695
  return { state: "missing_session_start" };
653
696
  }
654
- state = newProducerState(input, sessionId, epochId, boundaryEventId as `evt_${string}`);
697
+ state = newProducerState(
698
+ input,
699
+ sessionId,
700
+ epochId,
701
+ boundaryEventId as `evt_${string}`,
702
+ genesisId,
703
+ );
655
704
  } else if (!state || state.terminal) {
656
705
  // Mid-flight onboarding (ADR 0078): a live session with no producer
657
706
  // state in this epoch (fresh epoch, lost session-start hook) opens a
@@ -678,7 +727,13 @@ function processHookSignalLocked(
678
727
  });
679
728
  return { state: "missing_session_start" };
680
729
  }
681
- state = newProducerState(input, sessionId, epochId, boundaryEventId as `evt_${string}`);
730
+ state = newProducerState(
731
+ input,
732
+ sessionId,
733
+ epochId,
734
+ boundaryEventId as `evt_${string}`,
735
+ genesisId,
736
+ );
682
737
  const cursorPromptBootstrap = isCursorPromptBootstrap(input);
683
738
  const onboarding = buildMidFlightSessionStart(input, state, rootId, cursorPromptBootstrap);
684
739
  commitEventLocked(input, state, path, onboarding);
@@ -688,6 +743,7 @@ function processHookSignalLocked(
688
743
  instance_id: input.instance_id,
689
744
  signal: input.signal,
690
745
  session_hash: sessionHash,
746
+ ...(input.adapter === "codex" ? codexMidFlightDiagnosticContext(input.payload) : {}),
691
747
  });
692
748
  }
693
749
  }
@@ -1145,12 +1201,16 @@ function processHookSignalLocked(
1145
1201
  }
1146
1202
  if (
1147
1203
  input.signal === "session-start" &&
1148
- input.session_start_derivation === "approved_lifecycle_reopen" &&
1204
+ input.session_start_derivation &&
1149
1205
  event.event_type === "session.started"
1150
1206
  ) {
1207
+ const lifecycleReopen = input.session_start_derivation === "approved_lifecycle_reopen";
1208
+ const reason = lifecycleReopen
1209
+ ? "approved_lifecycle_reopen"
1210
+ : "validated_current_session_heal";
1151
1211
  event.provenance = {
1152
1212
  ...event.provenance,
1153
- source_event: `${input.adapter}.approved-lifecycle-reopen`,
1213
+ source_event: `${input.adapter}.${reason.replaceAll("_", "-")}`,
1154
1214
  attestation: "derived",
1155
1215
  confidence: "high",
1156
1216
  attribution: {
@@ -1161,7 +1221,7 @@ function processHookSignalLocked(
1161
1221
  };
1162
1222
  event.payload.resume = {
1163
1223
  state: "unknown",
1164
- reason: "approved_lifecycle_reopen",
1224
+ reason,
1165
1225
  };
1166
1226
  assertEventV3(event);
1167
1227
  }
@@ -1170,7 +1230,20 @@ function processHookSignalLocked(
1170
1230
  span.open_event_id = event.event_id as `evt_${string}`;
1171
1231
  stampSpanTurn(span, event, eventInput, state);
1172
1232
  }
1233
+ // A turn terminal clears current_native_turn_id when it commits. Retain the
1234
+ // native identity long enough to seed a delayed context retry afterward.
1235
+ const nativeTurnIdForContext = input.payload.turn_id ?? state.current_native_turn_id;
1173
1236
  const durability = commitEventLocked(input, state, path, event, sourceId);
1237
+ if (event.event_type === "context.compaction_started" && input.signal === "pre-compact") {
1238
+ maybeCommitNativeHookContextObservation(
1239
+ input,
1240
+ state,
1241
+ path,
1242
+ rootId,
1243
+ fingerprintContext,
1244
+ event,
1245
+ );
1246
+ }
1174
1247
  if (event.event_type === "tool.requested" && sourceId) {
1175
1248
  const explicitWait = explicitNativeWait(input);
1176
1249
  if (explicitWait) {
@@ -1183,9 +1256,25 @@ function processHookSignalLocked(
1183
1256
  if (progressKind) {
1184
1257
  commitProgressObservation(input, state, path, rootId, event, progressKind);
1185
1258
  }
1259
+ if (event.event_type === "tool.completed" && input.signal === "post-tool-use") {
1260
+ maybeCommitActiveRuntimeContextObservation(
1261
+ input,
1262
+ state,
1263
+ path,
1264
+ rootId,
1265
+ fingerprintContext,
1266
+ event,
1267
+ );
1268
+ }
1186
1269
  if (turnTelemetry) {
1187
1270
  const contextTarget = turnContextTarget(event);
1188
- queuePendingRuntimeContext(input, state, contextTarget, turnTelemetry.context);
1271
+ queuePendingRuntimeContext(
1272
+ input,
1273
+ state,
1274
+ contextTarget,
1275
+ turnTelemetry.context,
1276
+ nativeTurnIdForContext,
1277
+ );
1189
1278
  commitTurnContextObservation(
1190
1279
  input,
1191
1280
  state,
@@ -1652,6 +1741,53 @@ function commitTurnContextObservation(
1652
1741
  observedAt?: string,
1653
1742
  ): void {
1654
1743
  if (!target) return;
1744
+ commitContextObservation(
1745
+ input,
1746
+ state,
1747
+ path,
1748
+ rootId,
1749
+ fingerprintContext,
1750
+ {
1751
+ caused_by_event_id: target.terminal_event_id,
1752
+ observed_at: observedAt ?? target.terminal_observed_at,
1753
+ turn_id: target.turn_id,
1754
+ ...(target.run_id ? { run_id: target.run_id } : {}),
1755
+ ...(target.workflow_id ? { workflow_id: target.workflow_id } : {}),
1756
+ ...(target.workflow_agent_id ? { workflow_agent_id: target.workflow_agent_id } : {}),
1757
+ },
1758
+ measurement,
1759
+ contextProvenance,
1760
+ );
1761
+ }
1762
+
1763
+ function commitContextObservation(
1764
+ input: RecordHookSignalV3Input,
1765
+ state: HookProducerStateV3,
1766
+ path: string,
1767
+ rootId: `root_${string}`,
1768
+ fingerprintContext: ReturnType<typeof fingerprintContextV3>,
1769
+ target: {
1770
+ caused_by_event_id: `evt_${string}`;
1771
+ observed_at: string;
1772
+ turn_id: `tid_${string}`;
1773
+ run_id?: `run_${string}`;
1774
+ workflow_id?: `wf_${string}`;
1775
+ workflow_agent_id?: string;
1776
+ },
1777
+ measurement: TelemetryObservationV3<ContextMeasurementV3>,
1778
+ contextProvenance?: ContextTelemetryProvenanceV3,
1779
+ ): void {
1780
+ if (
1781
+ measurement.state === "observed" &&
1782
+ contextProvenance?.source_witness &&
1783
+ state.last_context_source_witness === contextProvenance.source_witness
1784
+ ) {
1785
+ publishProducerState(path, state);
1786
+ return;
1787
+ }
1788
+ if (measurement.state === "observed" && contextProvenance?.source_witness) {
1789
+ state.last_context_source_witness = contextProvenance.source_witness;
1790
+ }
1655
1791
  const event = buildEventV3("context.observed", {
1656
1792
  producer: {
1657
1793
  producer_id: input.producer_id,
@@ -1673,7 +1809,7 @@ function commitTurnContextObservation(
1673
1809
  ...(target.workflow_agent_id ? { workflow_agent_id: target.workflow_agent_id } : {}),
1674
1810
  },
1675
1811
  attestation_id: state.attestation_id,
1676
- links: { caused_by: [target.terminal_event_id] },
1812
+ links: { caused_by: [target.caused_by_event_id] },
1677
1813
  provenance: {
1678
1814
  source_event: safeRole(
1679
1815
  [
@@ -1700,10 +1836,10 @@ function commitTurnContextObservation(
1700
1836
  subject_instance_id: state.instance_id,
1701
1837
  },
1702
1838
  },
1703
- // The source sample may precede native task completion. The event itself
1704
- // is committed after turn.completed, while measurement.measured_at keeps
1705
- // the sample clock without creating a causal wall-clock regression.
1706
- observed_at: observedAt ?? target.terminal_observed_at,
1839
+ // The source sample may precede the hook boundary that admits it.
1840
+ // measurement.measured_at preserves the sample clock without creating a
1841
+ // causal wall-clock regression in the producer event chain.
1842
+ observed_at: target.observed_at,
1707
1843
  monotonic_ns: orderedEventMonotonic(state, input.monotonic_ns),
1708
1844
  clock_id: state.clock_id,
1709
1845
  payload: {
@@ -1714,6 +1850,198 @@ function commitTurnContextObservation(
1714
1850
  maybeAttestContextCapabilityChange(input, state, path, rootId, measurement, contextProvenance);
1715
1851
  }
1716
1852
 
1853
+ /**
1854
+ * Admit fresh adapter-native or bounded runtime context while a turn is open.
1855
+ * Tool completions are safe sampling boundaries. Persistent owner-only cadence
1856
+ * state prevents short-lived hook processes from reading on every request,
1857
+ * and the source witness prevents duplicate public events.
1858
+ */
1859
+ function maybeCommitActiveRuntimeContextObservation(
1860
+ input: RecordHookSignalV3Input,
1861
+ state: HookProducerStateV3,
1862
+ path: string,
1863
+ rootId: `root_${string}`,
1864
+ fingerprintContext: ReturnType<typeof fingerprintContextV3>,
1865
+ sourceEvent: EventV3,
1866
+ ): void {
1867
+ if (input.signal !== "post-tool-use" || state.terminal || !state.current_turn_id) {
1868
+ return;
1869
+ }
1870
+ const nativeSessionId = input.payload.session_id ?? input.payload.conversation_id;
1871
+ const nativeTurnId = input.payload.turn_id ?? state.current_native_turn_id;
1872
+ if (!nativeSessionId || (!nativeTurnId && input.adapter !== "cursor")) return;
1873
+
1874
+ const now = Date.now();
1875
+ const configuredInterval = input.runtimeTelemetryOptions?.activeContextProbeIntervalMs;
1876
+ const intervalMs =
1877
+ configuredInterval !== undefined && Number.isFinite(configuredInterval)
1878
+ ? Math.max(0, Math.floor(configuredInterval))
1879
+ : ACTIVE_RUNTIME_CONTEXT_PROBE_INTERVAL_MS;
1880
+ const prior = state.active_runtime_context_probe;
1881
+ const priorAttempt = prior ? Date.parse(prior.attempted_at) : Number.NaN;
1882
+ if (
1883
+ prior?.turn_id === state.current_turn_id &&
1884
+ prior.boundary === "tool_completed" &&
1885
+ Number.isFinite(priorAttempt) &&
1886
+ now - priorAttempt >= 0 &&
1887
+ now - priorAttempt < intervalMs
1888
+ ) {
1889
+ return;
1890
+ }
1891
+ state.active_runtime_context_probe = {
1892
+ turn_id: state.current_turn_id,
1893
+ attempted_at: new Date(now).toISOString(),
1894
+ boundary: "tool_completed",
1895
+ };
1896
+
1897
+ const native = extractTurnTelemetryV3(
1898
+ input.adapter,
1899
+ input.payload.raw,
1900
+ sourceEvent.time.observed_at,
1901
+ ).context;
1902
+ if (native.state === "observed") {
1903
+ commitActiveContextObservation(
1904
+ input,
1905
+ state,
1906
+ path,
1907
+ rootId,
1908
+ fingerprintContext,
1909
+ sourceEvent,
1910
+ native,
1911
+ nativeContextProvenance(input, state, native),
1912
+ );
1913
+ return;
1914
+ }
1915
+ if (input.adapter === "cursor" && state.cursor_mode === "cloud") {
1916
+ publishProducerState(path, state);
1917
+ return;
1918
+ }
1919
+
1920
+ const transcriptPath = runtimeTranscriptPath(input, state);
1921
+ if (!transcriptPath && input.adapter !== "cursor") {
1922
+ publishProducerState(path, state);
1923
+ return;
1924
+ }
1925
+ const runtime = readRuntimeContextTelemetry(
1926
+ {
1927
+ adapter: input.adapter,
1928
+ session_id: nativeSessionId,
1929
+ ...(nativeTurnId ? { turn_id: nativeTurnId } : {}),
1930
+ ...(state.current_turn_span?.opened_at
1931
+ ? { turn_started_at: state.current_turn_span.opened_at }
1932
+ : {}),
1933
+ transcript_path: transcriptPath,
1934
+ observed_at: sourceEvent.time.observed_at,
1935
+ mode: "active_turn",
1936
+ },
1937
+ input.runtimeTelemetryOptions,
1938
+ );
1939
+ if (runtime.bytes_read > 0) recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
1940
+ if (runtime.state !== "observed") {
1941
+ publishProducerState(path, state);
1942
+ return;
1943
+ }
1944
+
1945
+ commitActiveContextObservation(
1946
+ input,
1947
+ state,
1948
+ path,
1949
+ rootId,
1950
+ fingerprintContext,
1951
+ sourceEvent,
1952
+ runtimeContextObservation(runtime),
1953
+ {
1954
+ source_event: runtime.source_event,
1955
+ source_witness: runtime.source_witness,
1956
+ ...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
1957
+ attestation: runtime.attestation,
1958
+ confidence: runtime.confidence,
1959
+ },
1960
+ );
1961
+ }
1962
+
1963
+ function commitActiveContextObservation(
1964
+ input: RecordHookSignalV3Input,
1965
+ state: HookProducerStateV3,
1966
+ path: string,
1967
+ rootId: `root_${string}`,
1968
+ fingerprintContext: ReturnType<typeof fingerprintContextV3>,
1969
+ sourceEvent: EventV3,
1970
+ measurement: TelemetryObservationV3<ContextMeasurementV3>,
1971
+ provenance: ContextTelemetryProvenanceV3,
1972
+ ): void {
1973
+ if (!state.current_turn_id) return;
1974
+ const scope = sourceEvent.scope as {
1975
+ run_id?: `run_${string}`;
1976
+ workflow_id?: `wf_${string}`;
1977
+ workflow_agent_id?: string;
1978
+ };
1979
+ commitContextObservation(
1980
+ input,
1981
+ state,
1982
+ path,
1983
+ rootId,
1984
+ fingerprintContext,
1985
+ {
1986
+ caused_by_event_id: sourceEvent.event_id as `evt_${string}`,
1987
+ observed_at: sourceEvent.time.observed_at,
1988
+ turn_id: state.current_turn_id,
1989
+ ...(scope.run_id ? { run_id: scope.run_id } : {}),
1990
+ ...(scope.workflow_id ? { workflow_id: scope.workflow_id } : {}),
1991
+ ...(scope.workflow_agent_id ? { workflow_agent_id: scope.workflow_agent_id } : {}),
1992
+ },
1993
+ measurement,
1994
+ provenance,
1995
+ );
1996
+ }
1997
+
1998
+ function nativeContextProvenance(
1999
+ input: RecordHookSignalV3Input,
2000
+ state: HookProducerStateV3,
2001
+ measurement: Extract<TelemetryObservationV3<ContextMeasurementV3>, { state: "observed" }>,
2002
+ ): ContextTelemetryProvenanceV3 {
2003
+ const { measured_at: _measuredAt, ...stableValue } = measurement.value;
2004
+ const witness = canonicalJsonV3({
2005
+ adapter: input.adapter,
2006
+ session_id: state.session_id,
2007
+ turn_id: state.current_turn_id,
2008
+ value: stableValue,
2009
+ });
2010
+ return {
2011
+ source_event: `${input.adapter}.native_context`,
2012
+ source_witness: createHash("sha256").update(witness).digest("hex"),
2013
+ ...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
2014
+ attestation: measurement.attestation,
2015
+ confidence: measurement.confidence,
2016
+ };
2017
+ }
2018
+
2019
+ function maybeCommitNativeHookContextObservation(
2020
+ input: RecordHookSignalV3Input,
2021
+ state: HookProducerStateV3,
2022
+ path: string,
2023
+ rootId: `root_${string}`,
2024
+ fingerprintContext: ReturnType<typeof fingerprintContextV3>,
2025
+ sourceEvent: EventV3,
2026
+ ): void {
2027
+ const measurement = extractTurnTelemetryV3(
2028
+ input.adapter,
2029
+ input.payload.raw,
2030
+ sourceEvent.time.observed_at,
2031
+ ).context;
2032
+ if (measurement.state !== "observed") return;
2033
+ commitActiveContextObservation(
2034
+ input,
2035
+ state,
2036
+ path,
2037
+ rootId,
2038
+ fingerprintContext,
2039
+ sourceEvent,
2040
+ measurement,
2041
+ nativeContextProvenance(input, state, measurement),
2042
+ );
2043
+ }
2044
+
1717
2045
  function maybeAttestContextCapabilityChange(
1718
2046
  input: RecordHookSignalV3Input,
1719
2047
  state: HookProducerStateV3,
@@ -1729,6 +2057,12 @@ function maybeAttestContextCapabilityChange(
1729
2057
  source: provenance?.source_event ?? `${input.adapter}.turn_context`,
1730
2058
  attestation: provenance?.attestation ?? measurement.attestation,
1731
2059
  confidence: provenance?.confidence ?? measurement.confidence,
2060
+ completeness:
2061
+ "used_percent" in measurement.value
2062
+ ? ("percentage_only" as const)
2063
+ : (provenance?.attestation ?? measurement.attestation) === "inferred"
2064
+ ? ("inferred" as const)
2065
+ : ("exact" as const),
1732
2066
  }
1733
2067
  : measurement.state === "expected_but_missing"
1734
2068
  ? { state: "partial" as const, reason: measurement.reason }
@@ -1777,6 +2111,7 @@ function queuePendingRuntimeContext(
1777
2111
  state: HookProducerStateV3,
1778
2112
  target: TurnContextTargetV3 | undefined,
1779
2113
  measurement: TelemetryObservationV3<ContextMeasurementV3>,
2114
+ nativeTurnId: string | undefined,
1780
2115
  ): void {
1781
2116
  if (
1782
2117
  input.adapter !== "codex" ||
@@ -1787,7 +2122,6 @@ function queuePendingRuntimeContext(
1787
2122
  return;
1788
2123
  }
1789
2124
  const nativeSessionId = input.payload.session_id ?? input.payload.conversation_id;
1790
- const nativeTurnId = input.payload.turn_id;
1791
2125
  if (!nativeSessionId || !nativeTurnId) return;
1792
2126
  const pending: PendingRuntimeContextV3 = {
1793
2127
  ...target,
@@ -1925,19 +2259,36 @@ function turnTelemetryForTerminal(
1925
2259
  observedAt: string,
1926
2260
  ): TurnTelemetryV3 {
1927
2261
  const native = extractTurnTelemetryV3(input.adapter, input.payload.raw, observedAt);
1928
- if (native.context.state === "observed" || input.adapter === "cursor") return native;
2262
+ if (native.context.state === "observed") return native;
2263
+ if (input.adapter === "cursor" && state.cursor_mode === "cloud") {
2264
+ return {
2265
+ ...native,
2266
+ context: { state: "unsupported", capability: "context_usage" },
2267
+ };
2268
+ }
1929
2269
 
1930
- const runtime = readRuntimeContextTelemetry(
1931
- {
1932
- adapter: input.adapter,
1933
- session_id: input.payload.session_id ?? input.payload.conversation_id,
1934
- turn_id: input.payload.turn_id ?? state.current_native_turn_id,
1935
- transcript_path: runtimeTranscriptPath(input, state),
1936
- mode: "turn",
1937
- },
1938
- input.runtimeTelemetryOptions,
1939
- );
2270
+ const request = {
2271
+ adapter: input.adapter,
2272
+ session_id: input.payload.session_id ?? input.payload.conversation_id,
2273
+ turn_id: input.payload.turn_id ?? state.current_native_turn_id,
2274
+ transcript_path: runtimeTranscriptPath(input, state),
2275
+ observed_at: observedAt,
2276
+ mode: "turn" as const,
2277
+ };
2278
+ let runtime = readRuntimeContextTelemetry(request, input.runtimeTelemetryOptions);
1940
2279
  if (runtime.bytes_read > 0) recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
2280
+ if (
2281
+ input.adapter === "codex" &&
2282
+ runtime.state === "partial" &&
2283
+ retryableRuntimeContextReason(runtime.reason)
2284
+ ) {
2285
+ for (const delayMs of STOP_RUNTIME_CONTEXT_RETRY_DELAYS_MS) {
2286
+ sleepSync(delayMs);
2287
+ runtime = readRuntimeContextTelemetry(request, input.runtimeTelemetryOptions);
2288
+ if (runtime.bytes_read > 0) recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
2289
+ if (runtime.state !== "partial" || !retryableRuntimeContextReason(runtime.reason)) break;
2290
+ }
2291
+ }
1941
2292
  if (runtime.state === "unsupported") return native;
1942
2293
  return {
1943
2294
  ...native,
@@ -1947,8 +2298,8 @@ function turnTelemetryForTerminal(
1947
2298
  runtime.state === "observed" ? runtime.source_event : `${input.adapter}.runtime_context`,
1948
2299
  ...(runtime.state === "observed" ? { source_witness: runtime.source_witness } : {}),
1949
2300
  ...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
1950
- attestation: "derived",
1951
- confidence: runtime.state === "observed" ? "exact" : "high",
2301
+ attestation: runtime.state === "observed" ? runtime.attestation : "derived",
2302
+ confidence: runtime.state === "observed" ? runtime.confidence : "high",
1952
2303
  },
1953
2304
  };
1954
2305
  }
@@ -2001,6 +2352,19 @@ function runtimeContextObservation(
2001
2352
  runtime: RuntimeContextTelemetry,
2002
2353
  ): TelemetryObservationV3<ContextMeasurementV3> {
2003
2354
  if (runtime.state === "observed") {
2355
+ if ("used_percent" in runtime) {
2356
+ return {
2357
+ state: "observed",
2358
+ value: {
2359
+ used_percent: runtime.used_percent,
2360
+ remaining_percent: Math.max(0, 100 - runtime.used_percent),
2361
+ measured_at: runtime.measured_at,
2362
+ method: runtime.method,
2363
+ },
2364
+ attestation: runtime.attestation,
2365
+ confidence: runtime.confidence,
2366
+ };
2367
+ }
2004
2368
  return {
2005
2369
  state: "observed",
2006
2370
  value: {
@@ -2010,8 +2374,8 @@ function runtimeContextObservation(
2010
2374
  measured_at: runtime.measured_at,
2011
2375
  method: runtime.method,
2012
2376
  },
2013
- attestation: "derived",
2014
- confidence: "exact",
2377
+ attestation: runtime.attestation,
2378
+ confidence: runtime.confidence,
2015
2379
  };
2016
2380
  }
2017
2381
  return {
@@ -2176,8 +2540,8 @@ interface RuntimeAttestationChangeV3 {
2176
2540
  telemetry: RuntimeTelemetryCapabilitiesV3;
2177
2541
  reason: string;
2178
2542
  source_event: string;
2179
- attestation: "native" | "derived";
2180
- confidence: "exact" | "high";
2543
+ attestation: "native" | "derived" | "inferred";
2544
+ confidence: "exact" | "high" | "medium" | "low";
2181
2545
  }
2182
2546
 
2183
2547
  function commitRuntimeAttestationChange(
@@ -2527,6 +2891,40 @@ function isCursorPromptBootstrap(input: RecordHookSignalV3Input): boolean {
2527
2891
  );
2528
2892
  }
2529
2893
 
2894
+ /** Privacy-safe environment and recovery provenance for Codex mid-flight
2895
+ * onboarding. WSLENV values are never recorded, only normalized variable
2896
+ * names, and the native session identifier itself remains fingerprinted. */
2897
+ export function codexMidFlightDiagnosticContext(
2898
+ payload: ParsedPayload,
2899
+ env: NodeJS.ProcessEnv = process.env,
2900
+ ): Record<string, string | boolean> {
2901
+ const wslenv = env.WSLENV?.trim() ?? "";
2902
+ const wslenvNames = [
2903
+ ...new Set(
2904
+ wslenv
2905
+ .split(":")
2906
+ .map((entry) => entry.split("/", 1)[0]?.trim() ?? "")
2907
+ .filter((name) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(name)),
2908
+ ),
2909
+ ]
2910
+ .sort()
2911
+ .join(":")
2912
+ .slice(0, 512);
2913
+ const identityRecoverySource = payload.session_id
2914
+ ? "native_session_id"
2915
+ : payload.conversation_id
2916
+ ? "native_conversation_id"
2917
+ : payload.agent_id
2918
+ ? "native_agent_id"
2919
+ : "unavailable";
2920
+ return {
2921
+ thread_id_present: Boolean(env.CODEX_THREAD_ID?.trim()),
2922
+ wslenv_present: wslenv.length > 0,
2923
+ wslenv_names: wslenvNames,
2924
+ identity_recovery_source: identityRecoverySource,
2925
+ };
2926
+ }
2927
+
2530
2928
  function suppressClosedSpanSignal(
2531
2929
  input: RecordHookSignalV3Input,
2532
2930
  sessionHash: `hid_${string}`,
@@ -2555,6 +2953,13 @@ export function recordApprovedSessionEndV3(
2555
2953
  if (control.state !== input.mode) {
2556
2954
  return { state: "gate_closed", reason: control.state };
2557
2955
  }
2956
+ input = {
2957
+ ...input,
2958
+ writerOptions: {
2959
+ ...input.writerOptions,
2960
+ expectedGenesisId: control.genesis.event.payload.genesis_id as `gex_${string}`,
2961
+ },
2962
+ };
2558
2963
  const matches = listHookProducerStateRecordsV3(input.coordRoot, { includeTerminal: true }).filter(
2559
2964
  ({ state }) =>
2560
2965
  state.instance_id === input.instance_id && state.generation_id === input.generation_id,
@@ -2716,6 +3121,13 @@ export function salvageOpenSpansV3(input: SalvageOpenSpansV3Input): SalvageOpenS
2716
3121
  if (control.state !== input.mode) {
2717
3122
  return { state: "gate_closed", reason: control.state };
2718
3123
  }
3124
+ input = {
3125
+ ...input,
3126
+ writerOptions: {
3127
+ ...input.writerOptions,
3128
+ expectedGenesisId: control.genesis.event.payload.genesis_id as `gex_${string}`,
3129
+ },
3130
+ };
2719
3131
  const matches = listHookProducerStateRecordsV3(input.coordRoot).filter(
2720
3132
  ({ state }) =>
2721
3133
  state.instance_id === input.instance_id && state.generation_id === input.generation_id,
@@ -2824,6 +3236,9 @@ export function listHookProducerStateRecordsV3(
2824
3236
  )) {
2825
3237
  const path = join(directory, name);
2826
3238
  const state = readProducerState(path);
3239
+ // Skip authorities left behind by a replaced epoch: their sequences and
3240
+ // causal links belong to the archived ledger, not this one.
3241
+ if (state.epoch_genesis_id !== control.genesis.event.payload.genesis_id) continue;
2827
3242
  if (!options.includeTerminal && state.terminal) continue;
2828
3243
  records.push({ path, modified_at_ms: lstatSync(path).mtimeMs, state });
2829
3244
  }
@@ -2880,7 +3295,101 @@ export function readHookProducerStateV3(
2880
3295
  );
2881
3296
  const sessionHash = normalizeNativeIdV3(context, `${adapter}.session`, nativeSessionId);
2882
3297
  const path = producerStatePath(coordRoot, adapter, sessionHash);
2883
- return existsSync(path) ? readProducerState(path) : undefined;
3298
+ if (!existsSync(path)) return undefined;
3299
+ const state = readProducerState(path);
3300
+ // A state left behind by a replaced epoch is not this epoch's authority.
3301
+ return state.epoch_genesis_id === control.genesis.event.payload.genesis_id ? state : undefined;
3302
+ }
3303
+
3304
+ export interface ReconcilePendingRuntimeContextV3Input {
3305
+ coordRoot: string;
3306
+ mode: EventV3WriteMode;
3307
+ nativeSessionId: string;
3308
+ producer_id: `prd_${string}`;
3309
+ build_id: `build_${string}`;
3310
+ platform: "linux" | "windows" | "macos" | "unknown";
3311
+ finalAttempt?: boolean;
3312
+ runtimeTelemetryOptions?: RuntimeTelemetryOptions;
3313
+ writerOptions?: WriteEventV3Options;
3314
+ }
3315
+
3316
+ export type ReconcilePendingRuntimeContextV3Result =
3317
+ | { state: "gate_closed" }
3318
+ | { state: "missing" }
3319
+ | { state: "busy" }
3320
+ | { state: "not_pending" }
3321
+ | { state: "pending" }
3322
+ | { state: "settled" };
3323
+
3324
+ /**
3325
+ * Retry one Codex session's owner-only context join without replaying its Stop
3326
+ * signal. Codex appends `task_complete` only after the synchronous Stop hook
3327
+ * exits, so this is invoked by a bounded detached worker after that exit.
3328
+ */
3329
+ export function reconcilePendingRuntimeContextV3(
3330
+ input: ReconcilePendingRuntimeContextV3Input,
3331
+ ): ReconcilePendingRuntimeContextV3Result {
3332
+ const control = readEventV3ControlState(input.coordRoot);
3333
+ if (control.state !== input.mode) return { state: "gate_closed" };
3334
+ if (control.state !== "candidate" && control.state !== "active") {
3335
+ return { state: "gate_closed" };
3336
+ }
3337
+ const rootId = control.genesis.event.scope.root_id as `root_${string}`;
3338
+ const rootContext = fingerprintContextV3(
3339
+ input.coordRoot,
3340
+ rootId,
3341
+ undefined,
3342
+ control.genesis.profile.privacy_key_epoch,
3343
+ );
3344
+ const sessionHash = normalizeNativeIdV3(rootContext, "codex.session", input.nativeSessionId);
3345
+ const path = producerStatePath(input.coordRoot, "codex", sessionHash);
3346
+ if (!existsSync(path)) return { state: "missing" };
3347
+ const lease = acquireStateLeaseWithRetry(input.coordRoot, path, STATE_LEASE_RETRY_ATTEMPTS);
3348
+ if (!lease) return { state: "busy" };
3349
+ try {
3350
+ const state = readProducerState(path);
3351
+ if (state.epoch_genesis_id !== control.genesis.event.payload.genesis_id) {
3352
+ // The pending contexts belong to a replaced epoch; its archive already
3353
+ // holds everything this producer durably recorded.
3354
+ return { state: "missing" };
3355
+ }
3356
+ if (state.adapter !== "codex" || !state.pending_runtime_contexts?.length) {
3357
+ return { state: "not_pending" };
3358
+ }
3359
+ const context = fingerprintContextV3(
3360
+ input.coordRoot,
3361
+ rootId,
3362
+ state.generation_id,
3363
+ state.privacy_epoch_id,
3364
+ );
3365
+ reconcilePendingRuntimeContexts(
3366
+ {
3367
+ coordRoot: input.coordRoot,
3368
+ mode: input.mode,
3369
+ signal: "stop",
3370
+ payload: { raw: {}, session_id: input.nativeSessionId },
3371
+ adapter: "codex",
3372
+ instance_id: state.instance_id,
3373
+ producer_id: input.producer_id,
3374
+ build_id: input.build_id,
3375
+ platform: input.platform,
3376
+ observed_at: new Date().toISOString(),
3377
+ runtimeTelemetryOptions: input.runtimeTelemetryOptions,
3378
+ writerOptions: {
3379
+ ...input.writerOptions,
3380
+ expectedGenesisId: control.genesis.event.payload.genesis_id as `gex_${string}`,
3381
+ },
3382
+ },
3383
+ state,
3384
+ path,
3385
+ rootId,
3386
+ context,
3387
+ { deferRetryLimit: true, finalAttempt: input.finalAttempt },
3388
+ );
3389
+ return state.pending_runtime_contexts?.length ? { state: "pending" } : { state: "settled" };
3390
+ } finally {
3391
+ lease.release();
3392
+ }
2884
3393
  }
2885
3394
 
2886
3395
  /** Resolve one terminal producer only when native session and instance identity agree. */
@@ -2918,6 +3427,7 @@ export function readHookProducerStateByInstanceV3(
2918
3427
  /^hid_[a-f0-9]{64}\.json$/.test(entry),
2919
3428
  )) {
2920
3429
  const state = readProducerState(join(directory, name));
3430
+ if (state.epoch_genesis_id !== control.genesis.event.payload.genesis_id) continue;
2921
3431
  if (state.instance_id === instanceId && !state.terminal) matches.push(state);
2922
3432
  }
2923
3433
  }
@@ -2949,6 +3459,7 @@ function newProducerState(
2949
3459
  sessionId: `sid_${string}`,
2950
3460
  epochId: `pep_${string}`,
2951
3461
  boundaryEventId: `evt_${string}`,
3462
+ genesisId: `gex_${string}`,
2952
3463
  ): HookProducerStateV3 {
2953
3464
  const bootId = `boot_${randomUUID()}` as const;
2954
3465
  return {
@@ -2962,6 +3473,7 @@ function newProducerState(
2962
3473
  capability_profile: adapterCapabilityProfileDigestV3(input.adapter),
2963
3474
  cursor_mode: input.adapter === "cursor" ? (input.payload.cursor_mode ?? "unknown") : undefined,
2964
3475
  privacy_epoch_id: epochId,
3476
+ epoch_genesis_id: genesisId,
2965
3477
  boot_id: bootId,
2966
3478
  clock_id: clockIdV3(),
2967
3479
  next_sequence: 1,
@@ -2972,6 +3484,7 @@ function newProducerState(
2972
3484
  boot_id: bootId,
2973
3485
  clock: signalClock(input),
2974
3486
  }),
3487
+ session_start_derivation: input.session_start_derivation,
2975
3488
  terminal: false,
2976
3489
  spans: [],
2977
3490
  delegations: [],
@@ -3002,6 +3515,7 @@ function applyCommittedEvent(state: HookProducerStateV3, event: EventV3): void {
3002
3515
  if (event.event_type === "turn.started") {
3003
3516
  const nextTurnId = (event.scope as { turn_id: `tid_${string}` }).turn_id;
3004
3517
  state.current_turn_id = nextTurnId;
3518
+ state.session_start_derivation = undefined;
3005
3519
  if (state.tool_call_count_turn_id !== nextTurnId) {
3006
3520
  state.tool_call_count = 0;
3007
3521
  state.tool_call_count_turn_id = nextTurnId;
@@ -3378,6 +3892,7 @@ function readProducerState(path: string): HookProducerStateV3 {
3378
3892
  }
3379
3893
  if (state.adapter === "cursor") state.cursor_mode ??= "unknown";
3380
3894
  const allowedKeys = new Set([
3895
+ "active_runtime_context_probe",
3381
3896
  "adapter",
3382
3897
  "attestation_id",
3383
3898
  "boot_id",
@@ -3390,6 +3905,7 @@ function readProducerState(path: string): HookProducerStateV3 {
3390
3905
  "current_turn_span",
3391
3906
  "cursor_mode",
3392
3907
  "delegations",
3908
+ "epoch_genesis_id",
3393
3909
  "format",
3394
3910
  "format_version",
3395
3911
  "generation_id",
@@ -3399,6 +3915,7 @@ function readProducerState(path: string): HookProducerStateV3 {
3399
3915
  "last_attested_telemetry",
3400
3916
  "last_attested_tuning",
3401
3917
  "last_attested_tuning_observation",
3918
+ "last_context_source_witness",
3402
3919
  "tuning_probe_turn_id",
3403
3920
  "last_event_id",
3404
3921
  "last_monotonic_ns",
@@ -3409,6 +3926,7 @@ function readProducerState(path: string): HookProducerStateV3 {
3409
3926
  "runtime_transcript_path",
3410
3927
  "privacy_epoch_id",
3411
3928
  "session_id",
3929
+ "session_start_derivation",
3412
3930
  "session_span",
3413
3931
  "spans",
3414
3932
  "started_event_id",
@@ -3432,6 +3950,7 @@ function readProducerState(path: string): HookProducerStateV3 {
3432
3950
  !/^att_[0-9a-f-]{36}$/.test(state.attestation_id) ||
3433
3951
  !/^cap_[a-f0-9]{64}$/.test(state.capability_profile) ||
3434
3952
  !/^pep_[a-zA-Z0-9._-]+$/.test(state.privacy_epoch_id) ||
3953
+ (state.epoch_genesis_id !== undefined && !/^gex_[0-9a-f-]{36}$/.test(state.epoch_genesis_id)) ||
3435
3954
  !/^boot_[a-zA-Z0-9._-]+$/.test(state.boot_id) ||
3436
3955
  !/^clk_[0-9a-f-]{36}$/.test(state.clock_id) ||
3437
3956
  !Number.isSafeInteger(state.next_sequence) ||
@@ -3507,11 +4026,18 @@ function readProducerState(path: string): HookProducerStateV3 {
3507
4026
  (state.last_observed_at !== undefined &&
3508
4027
  !Number.isFinite(Date.parse(state.last_observed_at))) ||
3509
4028
  (state.started_event_id !== undefined && !/^evt_[0-9a-f-]{36}$/.test(state.started_event_id)) ||
4029
+ (state.session_start_derivation !== undefined &&
4030
+ state.session_start_derivation !== "approved_lifecycle_reopen" &&
4031
+ state.session_start_derivation !== "validated_current_session_heal") ||
3510
4032
  (state.pending_runtime_contexts !== undefined &&
3511
4033
  (!Array.isArray(state.pending_runtime_contexts) ||
3512
4034
  state.pending_runtime_contexts.length === 0 ||
3513
4035
  state.pending_runtime_contexts.length > PENDING_RUNTIME_CONTEXT_CAP ||
3514
4036
  state.pending_runtime_contexts.some((pending) => !validPendingRuntimeContext(pending)))) ||
4037
+ (state.active_runtime_context_probe !== undefined &&
4038
+ !validActiveRuntimeContextProbe(state.active_runtime_context_probe)) ||
4039
+ (state.last_context_source_witness !== undefined &&
4040
+ !/^[a-f0-9]{64}$/.test(state.last_context_source_witness)) ||
3515
4041
  (state.runtime_transcript_path !== undefined &&
3516
4042
  (typeof state.runtime_transcript_path !== "string" ||
3517
4043
  state.runtime_transcript_path.length === 0 ||
@@ -3629,6 +4155,18 @@ function validPendingRuntimeContext(value: unknown): value is PendingRuntimeCont
3629
4155
  );
3630
4156
  }
3631
4157
 
4158
+ function validActiveRuntimeContextProbe(value: unknown): value is ActiveRuntimeContextProbeV3 {
4159
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
4160
+ const probe = value as ActiveRuntimeContextProbeV3;
4161
+ return (
4162
+ typeof probe.turn_id === "string" &&
4163
+ /^tid_[a-f0-9]{64}$/.test(probe.turn_id) &&
4164
+ typeof probe.attempted_at === "string" &&
4165
+ Number.isFinite(Date.parse(probe.attempted_at)) &&
4166
+ (probe.boundary === undefined || probe.boundary === "tool_completed")
4167
+ );
4168
+ }
4169
+
3632
4170
  function pidIsAlive(pid: number): boolean {
3633
4171
  if (!Number.isSafeInteger(pid) || pid < 1) return false;
3634
4172
  try {