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
@@ -3,17 +3,19 @@ import { chmodSync, closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, open
3
3
  import { hostname } from "node:os";
4
4
  import { basename, join, resolve } from "node:path";
5
5
  import { extractBashCommand } from "../../../hooks/adapter/parse.js";
6
+ import { discoverCodexSessionTranscript, readRuntimeContextTelemetry, readRuntimeTuning, } from "../../../hooks/adapter/runtime-telemetry.js";
6
7
  import { fsyncParentDirectory } from "../../../workflow/durable-record.js";
7
8
  import { acquireNoClobberLease } from "../../../workflow/workspaces/leases.js";
8
9
  import { buildEventV3 } from "../builder.js";
9
- import { fingerprintV3, normalizeNativeIdV3 } from "../canonical.js";
10
+ import { canonicalJsonV3, fingerprintV3, normalizeNativeIdV3 } from "../canonical.js";
10
11
  import { adapterCapabilityProfileDigestV3, adapterSignalSupportV3, cursorToolChannelSupportV3, } from "../capabilities.js";
11
12
  import { capabilityDriftPayloadsV3 } from "../capability-drift.js";
12
13
  import { markObservedClockRegressionV3 } from "../clock-order.js";
13
14
  import { readEventV3ControlState } from "../control.js";
14
15
  import { fingerprintContextV3 } from "../fingerprint-keys.js";
15
- import { attestationIdV3, clockIdV3, delegationIdV3, generationIdV3, spanIdV3 } from "../ids.js";
16
+ import { attestationIdV3, clockIdV3, delegationIdV3, eventIdV3, generationIdV3, spanIdV3, } from "../ids.js";
16
17
  import { readLedgerV3 } from "../reader.js";
18
+ import { effectiveRuntimeTelemetryCapabilitiesV3, } from "../runtime-telemetry-capabilities.js";
17
19
  import { closeSpanStateV3, openSpanStateV3, recoverSpanUpperBoundV3, } from "../span-state.js";
18
20
  import { extractTurnTelemetryV3, } from "../turn-telemetry.js";
19
21
  import { assertEventV3, validateEventV3 } from "../validate.js";
@@ -27,6 +29,14 @@ const CLOSED_SPAN_TURN_RETENTION = 2;
27
29
  const CLOSED_SPAN_MEMORY_CAP = 512;
28
30
  const CLOSED_TURN_MEMORY_CAP = 16;
29
31
  const SPAN_SOFT_WATERMARK = 128;
32
+ const PENDING_RUNTIME_CONTEXT_CAP = 4;
33
+ const RUNTIME_CONTEXT_RETRY_LIMIT = 2;
34
+ /** Active turns pay for at most one bounded adapter telemetry read per interval. */
35
+ const ACTIVE_RUNTIME_CONTEXT_PROBE_INTERVAL_MS = 15_000;
36
+ /** Codex can flush the terminal row just after Stop; keep this grace bounded and off other hooks. */
37
+ const STOP_RUNTIME_CONTEXT_RETRY_DELAYS_MS = [75, 175];
38
+ /** Finalization is off the interactive hook path; briefly cover Codex's delayed transcript flush. */
39
+ const APPROVED_END_RUNTIME_CONTEXT_RETRY_DELAYS_MS = [0, 250, 250];
30
40
  /**
31
41
  * Adapters whose turn-boundary recovery and mid-flight onboarding are enabled.
32
42
  * Kept in code, outside the digested capability profiles, so tuning recovery
@@ -88,7 +98,14 @@ function hookSignalGate(control, adapter, signal) {
88
98
  return undefined;
89
99
  }
90
100
  function sessionHashForSignal(input, context) {
91
- const nativeSession = input.payload.session_id ?? input.payload.conversation_id ?? input.payload.agent_id;
101
+ const nativeChild = input.payload.subagent_id ?? input.payload.agent_id;
102
+ const childOwnsSignal = input.signal !== "sub-agent-start" &&
103
+ input.signal !== "sub-agent-stop" &&
104
+ nativeChild !== undefined &&
105
+ input.instance_id === asLiveInstanceId(nativeChild);
106
+ const nativeSession = childOwnsSignal
107
+ ? nativeChild
108
+ : (input.payload.session_id ?? input.payload.conversation_id ?? input.payload.agent_id);
92
109
  if (nativeSession !== undefined) {
93
110
  return normalizeNativeIdV3(context, `${input.adapter}.session`, nativeSession);
94
111
  }
@@ -130,6 +147,7 @@ function intakeRecord(input) {
130
147
  : {}),
131
148
  ...(input.stop_remediation !== undefined ? { stop_remediation: input.stop_remediation } : {}),
132
149
  ...(input.turn_ritual ? { turn_ritual: input.turn_ritual } : {}),
150
+ ...(input.delegated_child ? { delegated_child: input.delegated_child } : {}),
133
151
  };
134
152
  }
135
153
  function inputForIntakeRecord(coordRoot, record) {
@@ -152,6 +170,7 @@ function inputForIntakeRecord(coordRoot, record) {
152
170
  ...(record.hook_duration_ms !== undefined ? { hook_duration_ms: record.hook_duration_ms } : {}),
153
171
  ...(record.stop_remediation !== undefined ? { stop_remediation: record.stop_remediation } : {}),
154
172
  ...(record.turn_ritual ? { turn_ritual: record.turn_ritual } : {}),
173
+ ...(record.delegated_child ? { delegated_child: record.delegated_child } : {}),
155
174
  };
156
175
  }
157
176
  /**
@@ -268,8 +287,23 @@ function processHookSignalLocked(control, input, sessionHash, path) {
268
287
  : control.activation.event.event_id;
269
288
  const rootFingerprintContext = fingerprintContextV3(input.coordRoot, rootId, undefined, epochId);
270
289
  const sessionId = `sid_${sessionHash.slice(4)}`;
290
+ const genesisId = control.genesis.event.payload.genesis_id;
291
+ // Every write below carries the epoch fence: an event produced for this
292
+ // epoch is refused (or quarantined from the spool) once the epoch has been
293
+ // replaced, instead of poisoning the successor's authority.
294
+ input = {
295
+ ...input,
296
+ writerOptions: { ...input.writerOptions, expectedGenesisId: genesisId },
297
+ };
271
298
  try {
272
299
  let state = existsSync(path) ? readProducerState(path) : undefined;
300
+ if (state && state.epoch_genesis_id !== genesisId) {
301
+ // A producer state from a replaced epoch (or one that predates the
302
+ // field) is never adopted: its boot sequences and causal links only
303
+ // validate inside the epoch that recorded them. The session re-onboards
304
+ // below exactly as it does after an automatic epoch refresh.
305
+ state = undefined;
306
+ }
273
307
  if (state &&
274
308
  (state.adapter !== input.adapter ||
275
309
  state.session_id !== sessionId ||
@@ -292,7 +326,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
292
326
  const pendingSource = state.pending.source_id;
293
327
  const incomingSource = sourceIdForSignal(input, rootFingerprintContext);
294
328
  const pendingEvent = state.pending.event;
295
- const durability = writeEventV3(input.coordRoot, pendingEvent);
329
+ const durability = writeEventV3(input.coordRoot, pendingEvent, input.writerOptions);
296
330
  applyCommittedEvent(state, pendingEvent);
297
331
  state.pending = undefined;
298
332
  publishProducerState(path, state);
@@ -306,10 +340,11 @@ function processHookSignalLocked(control, input, sessionHash, path) {
306
340
  if (state && !state.terminal && state.started_event_id) {
307
341
  return { state: "already_started", event_id: state.started_event_id };
308
342
  }
309
- if (input.session_start_derivation && !state?.terminal) {
343
+ if ((input.session_start_derivation === "approved_lifecycle_reopen" && !state?.terminal) ||
344
+ (input.session_start_derivation === "validated_current_session_heal" && state?.terminal)) {
310
345
  return { state: "missing_session_start" };
311
346
  }
312
- state = newProducerState(input, sessionId, epochId, boundaryEventId);
347
+ state = newProducerState(input, sessionId, epochId, boundaryEventId, genesisId);
313
348
  }
314
349
  else if (!state || state.terminal) {
315
350
  // Mid-flight onboarding (ADR 0078): a live session with no producer
@@ -335,7 +370,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
335
370
  });
336
371
  return { state: "missing_session_start" };
337
372
  }
338
- state = newProducerState(input, sessionId, epochId, boundaryEventId);
373
+ state = newProducerState(input, sessionId, epochId, boundaryEventId, genesisId);
339
374
  const cursorPromptBootstrap = isCursorPromptBootstrap(input);
340
375
  const onboarding = buildMidFlightSessionStart(input, state, rootId, cursorPromptBootstrap);
341
376
  commitEventLocked(input, state, path, onboarding);
@@ -345,6 +380,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
345
380
  instance_id: input.instance_id,
346
381
  signal: input.signal,
347
382
  session_hash: sessionHash,
383
+ ...(input.adapter === "codex" ? codexMidFlightDiagnosticContext(input.payload) : {}),
348
384
  });
349
385
  }
350
386
  }
@@ -386,6 +422,9 @@ function processHookSignalLocked(control, input, sessionHash, path) {
386
422
  (cursorPromptWithinOpenTurn ||
387
423
  (nativeTid !== undefined && state.current_turn_id === nativeTid));
388
424
  recordTurnHarnessTiming(state, input, !duplicateOpenTurnStart);
425
+ reconcilePendingRuntimeContexts(input, state, path, rootId, fingerprintContext, {
426
+ finalAttempt: input.signal === "session-end",
427
+ });
389
428
  closeResolvedWaits(input, state, path, rootId, fingerprintContext, nativeTid);
390
429
  if (input.signal === "permission-request") {
391
430
  const waitId = waitIdForInput(input, fingerprintContext);
@@ -435,6 +474,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
435
474
  boot_id: state.boot_id,
436
475
  clock: eventClock,
437
476
  });
477
+ state.current_native_turn_id = input.payload.turn_id;
438
478
  }
439
479
  let sourceId = sourceIdForSignal(input, rootFingerprintContext);
440
480
  const semanticKey = cursorShellSemanticKey(input, rootFingerprintContext);
@@ -628,7 +668,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
628
668
  })
629
669
  : undefined;
630
670
  const turnTelemetry = input.signal === "stop" || input.signal === "stop-failure"
631
- ? extractTurnTelemetryV3(input.adapter, input.payload.raw, eventClock.observed_at)
671
+ ? turnTelemetryForTerminal(input, state, eventClock.observed_at)
632
672
  : undefined;
633
673
  const cursorToolChannelSupport = input.adapter === "cursor"
634
674
  ? cursorToolChannelSupportV3(state.cursor_mode ?? "unknown")
@@ -642,6 +682,9 @@ function processHookSignalLocked(control, input, sessionHash, path) {
642
682
  }
643
683
  const toolCallCountScopeMismatch = (input.signal === "stop" || input.signal === "stop-failure") &&
644
684
  (!state.current_turn_id || state.tool_call_count_turn_id !== state.current_turn_id);
685
+ // Before the signal's own event: the tool call or turn that carries the
686
+ // new effort already ran under it, so it must ride the new attestation.
687
+ maybeAttestTuningChange(input, state, path, rootId);
645
688
  const event = normalizeHookEventV3(input.signal, eventInput.payload, {
646
689
  coordRoot: input.coordRoot,
647
690
  adapter: input.adapter,
@@ -665,6 +708,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
665
708
  platform: input.platform,
666
709
  bridge: input.bridge,
667
710
  capability_profile: state.capability_profile,
711
+ cursor_mode: state.cursor_mode,
668
712
  fingerprintContext,
669
713
  turn_id: state.current_turn_id,
670
714
  span_id: openingSpan?.span_id ?? closingSpan?.span_id,
@@ -703,11 +747,53 @@ function processHookSignalLocked(control, input, sessionHash, path) {
703
747
  if (!event)
704
748
  return { state: "ignored" };
705
749
  if (input.signal === "session-start" &&
706
- input.session_start_derivation === "approved_lifecycle_reopen" &&
750
+ input.delegated_child &&
707
751
  event.event_type === "session.started") {
752
+ event.links = {
753
+ caused_by: [input.delegated_child.caused_by_event_id],
754
+ parent_generation_id: input.delegated_child.parent_generation_id,
755
+ delegation_id: input.delegated_child.delegation_id,
756
+ };
757
+ event.provenance = {
758
+ ...event.provenance,
759
+ source_event: `${input.adapter}.subagent-start.child-generation`,
760
+ attestation: "derived",
761
+ confidence: "high",
762
+ attribution: {
763
+ method: "native_payload",
764
+ state: "verified",
765
+ subject_instance_id: state.instance_id,
766
+ },
767
+ };
768
+ assertEventV3(event);
769
+ }
770
+ if (input.signal === "user-prompt-submit" &&
771
+ input.delegated_child &&
772
+ event.event_type === "turn.started") {
773
+ event.links = { caused_by: [input.delegated_child.caused_by_event_id] };
708
774
  event.provenance = {
709
775
  ...event.provenance,
710
- source_event: `${input.adapter}.approved-lifecycle-reopen`,
776
+ source_event: `${input.adapter}.subagent-start.child-turn`,
777
+ attestation: "derived",
778
+ confidence: "high",
779
+ attribution: {
780
+ method: "native_payload",
781
+ state: "verified",
782
+ subject_instance_id: state.instance_id,
783
+ },
784
+ };
785
+ assertEventV3(event);
786
+ }
787
+ if (input.signal === "session-start" &&
788
+ input.session_start_derivation &&
789
+ event.event_type === "session.started") {
790
+ const lifecycleReopen = input.session_start_derivation === "approved_lifecycle_reopen";
791
+ const reason = lifecycleReopen
792
+ ? "approved_lifecycle_reopen"
793
+ : "validated_current_session_heal";
794
+ event.provenance = {
795
+ ...event.provenance,
796
+ source_event: `${input.adapter}.${reason.replaceAll("_", "-")}`,
711
797
  attestation: "derived",
712
798
  confidence: "high",
713
799
  attribution: {
@@ -718,7 +804,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
718
804
  };
719
805
  event.payload.resume = {
720
806
  state: "unknown",
721
- reason: "approved_lifecycle_reopen",
807
+ reason,
722
808
  };
723
809
  assertEventV3(event);
724
810
  }
@@ -727,7 +813,13 @@ function processHookSignalLocked(control, input, sessionHash, path) {
727
813
  span.open_event_id = event.event_id;
728
814
  stampSpanTurn(span, event, eventInput, state);
729
815
  }
816
+ // A turn terminal clears current_native_turn_id when it commits. Retain the
817
+ // native identity long enough to seed a delayed context retry afterward.
818
+ const nativeTurnIdForContext = input.payload.turn_id ?? state.current_native_turn_id;
730
819
  const durability = commitEventLocked(input, state, path, event, sourceId);
820
+ if (event.event_type === "context.compaction_started" && input.signal === "pre-compact") {
821
+ maybeCommitNativeHookContextObservation(input, state, path, rootId, fingerprintContext, event);
822
+ }
731
823
  if (event.event_type === "tool.requested" && sourceId) {
732
824
  const explicitWait = explicitNativeWait(input);
733
825
  if (explicitWait) {
@@ -741,8 +833,13 @@ function processHookSignalLocked(control, input, sessionHash, path) {
741
833
  if (progressKind) {
742
834
  commitProgressObservation(input, state, path, rootId, event, progressKind);
743
835
  }
836
+ if (event.event_type === "tool.completed" && input.signal === "post-tool-use") {
837
+ maybeCommitActiveRuntimeContextObservation(input, state, path, rootId, fingerprintContext, event);
838
+ }
744
839
  if (turnTelemetry) {
745
- commitTurnContextObservation(input, state, path, rootId, event, turnTelemetry.context);
840
+ const contextTarget = turnContextTarget(event);
841
+ queuePendingRuntimeContext(input, state, contextTarget, turnTelemetry.context, nativeTurnIdForContext);
842
+ commitTurnContextObservation(input, state, path, rootId, fingerprintContext, contextTarget, turnTelemetry.context, turnTelemetry.context_provenance);
746
843
  }
747
844
  if (event.event_type === "session.ended") {
748
845
  commitCapabilityDriftEvents(input, state, path, rootId);
@@ -1101,9 +1198,28 @@ function commitEventLocked(input, state, path, event, sourceId) {
1101
1198
  publishProducerState(path, state);
1102
1199
  return durability;
1103
1200
  }
1104
- function commitTurnContextObservation(input, state, path, rootId, turnTerminal, measurement) {
1105
- if (turnTerminal.event_type !== "turn.completed")
1201
+ function commitTurnContextObservation(input, state, path, rootId, fingerprintContext, target, measurement, contextProvenance, observedAt) {
1202
+ if (!target)
1106
1203
  return;
1204
+ commitContextObservation(input, state, path, rootId, fingerprintContext, {
1205
+ caused_by_event_id: target.terminal_event_id,
1206
+ observed_at: observedAt ?? target.terminal_observed_at,
1207
+ turn_id: target.turn_id,
1208
+ ...(target.run_id ? { run_id: target.run_id } : {}),
1209
+ ...(target.workflow_id ? { workflow_id: target.workflow_id } : {}),
1210
+ ...(target.workflow_agent_id ? { workflow_agent_id: target.workflow_agent_id } : {}),
1211
+ }, measurement, contextProvenance);
1212
+ }
1213
+ function commitContextObservation(input, state, path, rootId, fingerprintContext, target, measurement, contextProvenance) {
1214
+ if (measurement.state === "observed" &&
1215
+ contextProvenance?.source_witness &&
1216
+ state.last_context_source_witness === contextProvenance.source_witness) {
1217
+ publishProducerState(path, state);
1218
+ return;
1219
+ }
1220
+ if (measurement.state === "observed" && contextProvenance?.source_witness) {
1221
+ state.last_context_source_witness = contextProvenance.source_witness;
1222
+ }
1107
1223
  const event = buildEventV3("context.observed", {
1108
1224
  producer: {
1109
1225
  producer_id: input.producer_id,
@@ -1119,34 +1235,667 @@ function commitTurnContextObservation(input, state, path, rootId, turnTerminal,
1119
1235
  instance_id: state.instance_id,
1120
1236
  session_id: state.session_id,
1121
1237
  generation_id: state.generation_id,
1122
- turn_id: turnTerminal.scope.turn_id,
1123
- ...(input.run_id ? { run_id: input.run_id } : {}),
1124
- ...(input.workflow_id ? { workflow_id: input.workflow_id } : {}),
1125
- ...(input.workflow_agent_id ? { workflow_agent_id: input.workflow_agent_id } : {}),
1238
+ turn_id: target.turn_id,
1239
+ ...(target.run_id ? { run_id: target.run_id } : {}),
1240
+ ...(target.workflow_id ? { workflow_id: target.workflow_id } : {}),
1241
+ ...(target.workflow_agent_id ? { workflow_agent_id: target.workflow_agent_id } : {}),
1126
1242
  },
1127
1243
  attestation_id: state.attestation_id,
1128
- links: { caused_by: [turnTerminal.event_id] },
1244
+ links: { caused_by: [target.caused_by_event_id] },
1129
1245
  provenance: {
1130
- source_event: `${input.adapter}.turn-context`,
1246
+ source_event: safeRole([
1247
+ contextProvenance?.source_event ?? `${input.adapter}.turn-context`,
1248
+ contextProvenance?.runtime_version,
1249
+ ]
1250
+ .filter(Boolean)
1251
+ .join(".")),
1252
+ attestation: contextProvenance?.attestation ?? "native",
1253
+ confidence: contextProvenance?.confidence ?? "exact",
1254
+ ...(contextProvenance?.source_witness
1255
+ ? {
1256
+ source_record_id: normalizeNativeIdV3(fingerprintContext, `${input.adapter}.runtime-context`, contextProvenance.source_witness),
1257
+ }
1258
+ : {}),
1259
+ attribution: {
1260
+ method: "native_payload",
1261
+ state: "verified",
1262
+ subject_instance_id: state.instance_id,
1263
+ },
1264
+ },
1265
+ // The source sample may precede the hook boundary that admits it.
1266
+ // measurement.measured_at preserves the sample clock without creating a
1267
+ // causal wall-clock regression in the producer event chain.
1268
+ observed_at: target.observed_at,
1269
+ monotonic_ns: orderedEventMonotonic(state, input.monotonic_ns),
1270
+ clock_id: state.clock_id,
1271
+ payload: {
1272
+ measurement,
1273
+ },
1274
+ });
1275
+ commitEventLocked(input, state, path, event);
1276
+ maybeAttestContextCapabilityChange(input, state, path, rootId, measurement, contextProvenance);
1277
+ }
1278
+ /**
1279
+ * Admit fresh adapter-native or bounded runtime context while a turn is open.
1280
+ * Tool completions are safe sampling boundaries. Persistent owner-only cadence
1281
+ * state prevents short-lived hook processes from reading on every request,
1282
+ * and the source witness prevents duplicate public events.
1283
+ */
1284
+ function maybeCommitActiveRuntimeContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent) {
1285
+ if (input.signal !== "post-tool-use" || state.terminal || !state.current_turn_id) {
1286
+ return;
1287
+ }
1288
+ const nativeSessionId = input.payload.session_id ?? input.payload.conversation_id;
1289
+ const nativeTurnId = input.payload.turn_id ?? state.current_native_turn_id;
1290
+ if (!nativeSessionId || (!nativeTurnId && input.adapter !== "cursor"))
1291
+ return;
1292
+ const now = Date.now();
1293
+ const configuredInterval = input.runtimeTelemetryOptions?.activeContextProbeIntervalMs;
1294
+ const intervalMs = configuredInterval !== undefined && Number.isFinite(configuredInterval)
1295
+ ? Math.max(0, Math.floor(configuredInterval))
1296
+ : ACTIVE_RUNTIME_CONTEXT_PROBE_INTERVAL_MS;
1297
+ const prior = state.active_runtime_context_probe;
1298
+ const priorAttempt = prior ? Date.parse(prior.attempted_at) : Number.NaN;
1299
+ if (prior?.turn_id === state.current_turn_id &&
1300
+ prior.boundary === "tool_completed" &&
1301
+ Number.isFinite(priorAttempt) &&
1302
+ now - priorAttempt >= 0 &&
1303
+ now - priorAttempt < intervalMs) {
1304
+ return;
1305
+ }
1306
+ state.active_runtime_context_probe = {
1307
+ turn_id: state.current_turn_id,
1308
+ attempted_at: new Date(now).toISOString(),
1309
+ boundary: "tool_completed",
1310
+ };
1311
+ const native = extractTurnTelemetryV3(input.adapter, input.payload.raw, sourceEvent.time.observed_at).context;
1312
+ if (native.state === "observed") {
1313
+ commitActiveContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent, native, nativeContextProvenance(input, state, native));
1314
+ return;
1315
+ }
1316
+ if (input.adapter === "cursor" && state.cursor_mode === "cloud") {
1317
+ publishProducerState(path, state);
1318
+ return;
1319
+ }
1320
+ const transcriptPath = runtimeTranscriptPath(input, state);
1321
+ if (!transcriptPath && input.adapter !== "cursor") {
1322
+ publishProducerState(path, state);
1323
+ return;
1324
+ }
1325
+ const runtime = readRuntimeContextTelemetry({
1326
+ adapter: input.adapter,
1327
+ session_id: nativeSessionId,
1328
+ ...(nativeTurnId ? { turn_id: nativeTurnId } : {}),
1329
+ ...(state.current_turn_span?.opened_at
1330
+ ? { turn_started_at: state.current_turn_span.opened_at }
1331
+ : {}),
1332
+ transcript_path: transcriptPath,
1333
+ observed_at: sourceEvent.time.observed_at,
1334
+ mode: "active_turn",
1335
+ }, input.runtimeTelemetryOptions);
1336
+ if (runtime.bytes_read > 0)
1337
+ recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
1338
+ if (runtime.state !== "observed") {
1339
+ publishProducerState(path, state);
1340
+ return;
1341
+ }
1342
+ commitActiveContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent, runtimeContextObservation(runtime), {
1343
+ source_event: runtime.source_event,
1344
+ source_witness: runtime.source_witness,
1345
+ ...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
1346
+ attestation: runtime.attestation,
1347
+ confidence: runtime.confidence,
1348
+ });
1349
+ }
1350
+ function commitActiveContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent, measurement, provenance) {
1351
+ if (!state.current_turn_id)
1352
+ return;
1353
+ const scope = sourceEvent.scope;
1354
+ commitContextObservation(input, state, path, rootId, fingerprintContext, {
1355
+ caused_by_event_id: sourceEvent.event_id,
1356
+ observed_at: sourceEvent.time.observed_at,
1357
+ turn_id: state.current_turn_id,
1358
+ ...(scope.run_id ? { run_id: scope.run_id } : {}),
1359
+ ...(scope.workflow_id ? { workflow_id: scope.workflow_id } : {}),
1360
+ ...(scope.workflow_agent_id ? { workflow_agent_id: scope.workflow_agent_id } : {}),
1361
+ }, measurement, provenance);
1362
+ }
1363
+ function nativeContextProvenance(input, state, measurement) {
1364
+ const { measured_at: _measuredAt, ...stableValue } = measurement.value;
1365
+ const witness = canonicalJsonV3({
1366
+ adapter: input.adapter,
1367
+ session_id: state.session_id,
1368
+ turn_id: state.current_turn_id,
1369
+ value: stableValue,
1370
+ });
1371
+ return {
1372
+ source_event: `${input.adapter}.native_context`,
1373
+ source_witness: createHash("sha256").update(witness).digest("hex"),
1374
+ ...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
1375
+ attestation: measurement.attestation,
1376
+ confidence: measurement.confidence,
1377
+ };
1378
+ }
1379
+ function maybeCommitNativeHookContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent) {
1380
+ const measurement = extractTurnTelemetryV3(input.adapter, input.payload.raw, sourceEvent.time.observed_at).context;
1381
+ if (measurement.state !== "observed")
1382
+ return;
1383
+ commitActiveContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent, measurement, nativeContextProvenance(input, state, measurement));
1384
+ }
1385
+ function maybeAttestContextCapabilityChange(input, state, path, rootId, measurement, provenance) {
1386
+ const context = measurement.state === "observed"
1387
+ ? {
1388
+ state: "observed",
1389
+ source: provenance?.source_event ?? `${input.adapter}.turn_context`,
1390
+ attestation: provenance?.attestation ?? measurement.attestation,
1391
+ confidence: provenance?.confidence ?? measurement.confidence,
1392
+ completeness: "used_percent" in measurement.value
1393
+ ? "percentage_only"
1394
+ : (provenance?.attestation ?? measurement.attestation) === "inferred"
1395
+ ? "inferred"
1396
+ : "exact",
1397
+ }
1398
+ : measurement.state === "expected_but_missing"
1399
+ ? { state: "partial", reason: measurement.reason }
1400
+ : { state: "unsupported" };
1401
+ const telemetry = effectiveRuntimeTelemetryCapabilitiesV3({
1402
+ adapter: input.adapter,
1403
+ ...(state.cursor_mode ? { cursor_mode: state.cursor_mode } : {}),
1404
+ context,
1405
+ canonical_turn_boundaries: true,
1406
+ });
1407
+ if (!state.last_attested_telemetry)
1408
+ return;
1409
+ if (canonicalJsonV3(telemetry) === canonicalJsonV3(state.last_attested_telemetry))
1410
+ return;
1411
+ if (!state.last_attested_model_observation || !state.last_attested_tuning_observation)
1412
+ return;
1413
+ commitRuntimeAttestationChange(input, state, path, rootId, {
1414
+ model: state.last_attested_model_observation,
1415
+ tuning: state.last_attested_tuning_observation,
1416
+ telemetry,
1417
+ reason: "runtime_telemetry_changed",
1418
+ source_event: provenance?.source_event ?? `${input.adapter}.turn_context`,
1419
+ attestation: provenance?.attestation ?? "derived",
1420
+ confidence: provenance?.confidence ?? (measurement.state === "observed" ? "exact" : "high"),
1421
+ });
1422
+ }
1423
+ function turnContextTarget(turnTerminal) {
1424
+ if (turnTerminal.event_type !== "turn.completed")
1425
+ return undefined;
1426
+ const scope = turnTerminal.scope;
1427
+ return {
1428
+ terminal_event_id: turnTerminal.event_id,
1429
+ terminal_observed_at: turnTerminal.time.observed_at,
1430
+ turn_id: scope.turn_id,
1431
+ ...(scope.run_id ? { run_id: scope.run_id } : {}),
1432
+ ...(scope.workflow_id ? { workflow_id: scope.workflow_id } : {}),
1433
+ ...(scope.workflow_agent_id ? { workflow_agent_id: scope.workflow_agent_id } : {}),
1434
+ };
1435
+ }
1436
+ function queuePendingRuntimeContext(input, state, target, measurement, nativeTurnId) {
1437
+ if (input.adapter !== "codex" ||
1438
+ !target ||
1439
+ measurement.state !== "expected_but_missing" ||
1440
+ !retryableRuntimeContextReason(measurement.reason)) {
1441
+ return;
1442
+ }
1443
+ const nativeSessionId = input.payload.session_id ?? input.payload.conversation_id;
1444
+ if (!nativeSessionId || !nativeTurnId)
1445
+ return;
1446
+ const pending = {
1447
+ ...target,
1448
+ native_session_id: nativeSessionId,
1449
+ native_turn_id: nativeTurnId,
1450
+ ...((input.payload.transcript_path ?? state.runtime_transcript_path)
1451
+ ? { transcript_path: input.payload.transcript_path ?? state.runtime_transcript_path }
1452
+ : {}),
1453
+ ...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
1454
+ attempts: 0,
1455
+ };
1456
+ state.pending_runtime_contexts = [
1457
+ ...(state.pending_runtime_contexts ?? []).filter((candidate) => candidate.turn_id !== target.turn_id),
1458
+ pending,
1459
+ ].slice(-PENDING_RUNTIME_CONTEXT_CAP);
1460
+ }
1461
+ function reconcilePendingRuntimeContexts(input, state, path, rootId, fingerprintContext, options = {}) {
1462
+ if (state.adapter !== "codex" || !state.pending_runtime_contexts?.length)
1463
+ return;
1464
+ for (const pending of [...state.pending_runtime_contexts]) {
1465
+ const runtime = readRuntimeContextTelemetry({
1466
+ adapter: "codex",
1467
+ session_id: pending.native_session_id,
1468
+ turn_id: pending.native_turn_id,
1469
+ transcript_path: pending.transcript_path,
1470
+ mode: "turn",
1471
+ }, input.runtimeTelemetryOptions);
1472
+ if (runtime.bytes_read > 0)
1473
+ recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
1474
+ const queue = state.pending_runtime_contexts;
1475
+ if (!queue)
1476
+ break;
1477
+ const index = queue.findIndex((candidate) => candidate.turn_id === pending.turn_id);
1478
+ if (index < 0)
1479
+ continue;
1480
+ if (runtime.state === "observed") {
1481
+ queue.splice(index, 1);
1482
+ if (queue.length === 0) {
1483
+ state.pending_runtime_contexts = undefined;
1484
+ }
1485
+ commitTurnContextObservation(input, state, path, rootId, fingerprintContext, pending, runtimeContextObservation(runtime), {
1486
+ source_event: runtime.source_event,
1487
+ source_witness: runtime.source_witness,
1488
+ ...(pending.runtime_version ? { runtime_version: pending.runtime_version } : {}),
1489
+ attestation: "derived",
1490
+ confidence: "exact",
1491
+ }, signalClock(input).observed_at);
1492
+ continue;
1493
+ }
1494
+ const attempts = pending.attempts + 1;
1495
+ if (options.finalAttempt ||
1496
+ runtime.state === "unsupported" ||
1497
+ !retryableRuntimeContextReason(runtime.reason) ||
1498
+ (!options.deferRetryLimit && attempts >= RUNTIME_CONTEXT_RETRY_LIMIT)) {
1499
+ queue.splice(index, 1);
1500
+ }
1501
+ else {
1502
+ queue[index] = { ...pending, attempts };
1503
+ }
1504
+ }
1505
+ if (state.pending_runtime_contexts?.length === 0) {
1506
+ state.pending_runtime_contexts = undefined;
1507
+ }
1508
+ publishProducerState(path, state);
1509
+ }
1510
+ function reconcilePendingRuntimeContextsBeforeApprovedEnd(input, state, path, rootId, fingerprintContext) {
1511
+ if (state.adapter !== "codex" || !state.pending_runtime_contexts?.length)
1512
+ return;
1513
+ for (const [index, delayMs] of APPROVED_END_RUNTIME_CONTEXT_RETRY_DELAYS_MS.entries()) {
1514
+ if (delayMs > 0)
1515
+ sleepSync(delayMs);
1516
+ reconcilePendingRuntimeContexts({
1517
+ coordRoot: input.coordRoot,
1518
+ mode: input.mode,
1519
+ signal: "session-end",
1520
+ payload: { raw: {} },
1521
+ adapter: state.adapter,
1522
+ instance_id: state.instance_id,
1523
+ producer_id: "prd_agent-finalizer",
1524
+ build_id: input.build_id,
1525
+ platform: input.platform,
1526
+ observed_at: new Date().toISOString(),
1527
+ writerOptions: input.writerOptions,
1528
+ }, state, path, rootId, fingerprintContext, {
1529
+ deferRetryLimit: true,
1530
+ finalAttempt: index === APPROVED_END_RUNTIME_CONTEXT_RETRY_DELAYS_MS.length - 1,
1531
+ });
1532
+ if (!state.pending_runtime_contexts?.length)
1533
+ return;
1534
+ }
1535
+ }
1536
+ function retryableRuntimeContextReason(reason) {
1537
+ return (reason === "codex_transcript_turn_not_found" ||
1538
+ reason === "codex_transcript_turn_not_terminal" ||
1539
+ reason === "codex_transcript_token_count_missing");
1540
+ }
1541
+ function turnTelemetryForTerminal(input, state, observedAt) {
1542
+ const native = extractTurnTelemetryV3(input.adapter, input.payload.raw, observedAt);
1543
+ if (native.context.state === "observed")
1544
+ return native;
1545
+ if (input.adapter === "cursor" && state.cursor_mode === "cloud") {
1546
+ return {
1547
+ ...native,
1548
+ context: { state: "unsupported", capability: "context_usage" },
1549
+ };
1550
+ }
1551
+ const request = {
1552
+ adapter: input.adapter,
1553
+ session_id: input.payload.session_id ?? input.payload.conversation_id,
1554
+ turn_id: input.payload.turn_id ?? state.current_native_turn_id,
1555
+ transcript_path: runtimeTranscriptPath(input, state),
1556
+ observed_at: observedAt,
1557
+ mode: "turn",
1558
+ };
1559
+ let runtime = readRuntimeContextTelemetry(request, input.runtimeTelemetryOptions);
1560
+ if (runtime.bytes_read > 0)
1561
+ recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
1562
+ if (input.adapter === "codex" &&
1563
+ runtime.state === "partial" &&
1564
+ retryableRuntimeContextReason(runtime.reason)) {
1565
+ for (const delayMs of STOP_RUNTIME_CONTEXT_RETRY_DELAYS_MS) {
1566
+ sleepSync(delayMs);
1567
+ runtime = readRuntimeContextTelemetry(request, input.runtimeTelemetryOptions);
1568
+ if (runtime.bytes_read > 0)
1569
+ recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
1570
+ if (runtime.state !== "partial" || !retryableRuntimeContextReason(runtime.reason))
1571
+ break;
1572
+ }
1573
+ }
1574
+ if (runtime.state === "unsupported")
1575
+ return native;
1576
+ return {
1577
+ ...native,
1578
+ context: runtimeContextObservation(runtime),
1579
+ context_provenance: {
1580
+ source_event: runtime.state === "observed" ? runtime.source_event : `${input.adapter}.runtime_context`,
1581
+ ...(runtime.state === "observed" ? { source_witness: runtime.source_witness } : {}),
1582
+ ...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
1583
+ attestation: runtime.state === "observed" ? runtime.attestation : "derived",
1584
+ confidence: runtime.state === "observed" ? runtime.confidence : "high",
1585
+ },
1586
+ };
1587
+ }
1588
+ /**
1589
+ * Resolve Codex's rollout once, retain it in owner-only producer state, and
1590
+ * verify the cached path against the native session before every reuse. Public
1591
+ * events receive only numeric telemetry and an opaque source witness.
1592
+ */
1593
+ function runtimeTranscriptPath(input, state) {
1594
+ if (input.adapter !== "codex")
1595
+ return input.payload.transcript_path;
1596
+ const nativeSessionId = input.payload.session_id ?? input.payload.conversation_id;
1597
+ if (!nativeSessionId)
1598
+ return input.payload.transcript_path;
1599
+ const supplied = input.payload.transcript_path;
1600
+ if (supplied) {
1601
+ const verified = discoverCodexSessionTranscript(nativeSessionId, supplied, input.runtimeTelemetryOptions);
1602
+ if (verified)
1603
+ state.runtime_transcript_path = verified;
1604
+ // Preserve a supplied mismatch so the typed reader reports it honestly.
1605
+ return verified ?? supplied;
1606
+ }
1607
+ if (state.runtime_transcript_path) {
1608
+ const verified = discoverCodexSessionTranscript(nativeSessionId, state.runtime_transcript_path, input.runtimeTelemetryOptions);
1609
+ if (verified)
1610
+ return verified;
1611
+ state.runtime_transcript_path = undefined;
1612
+ }
1613
+ const discovered = discoverCodexSessionTranscript(nativeSessionId, undefined, input.runtimeTelemetryOptions);
1614
+ if (discovered)
1615
+ state.runtime_transcript_path = discovered;
1616
+ return discovered;
1617
+ }
1618
+ function runtimeContextObservation(runtime) {
1619
+ if (runtime.state === "observed") {
1620
+ if ("used_percent" in runtime) {
1621
+ return {
1622
+ state: "observed",
1623
+ value: {
1624
+ used_percent: runtime.used_percent,
1625
+ remaining_percent: Math.max(0, 100 - runtime.used_percent),
1626
+ measured_at: runtime.measured_at,
1627
+ method: runtime.method,
1628
+ },
1629
+ attestation: runtime.attestation,
1630
+ confidence: runtime.confidence,
1631
+ };
1632
+ }
1633
+ return {
1634
+ state: "observed",
1635
+ value: {
1636
+ used_tokens: runtime.used_tokens,
1637
+ limit_tokens: runtime.limit_tokens,
1638
+ remaining_tokens: Math.max(0, runtime.limit_tokens - runtime.used_tokens),
1639
+ measured_at: runtime.measured_at,
1640
+ method: runtime.method,
1641
+ },
1642
+ attestation: runtime.attestation,
1643
+ confidence: runtime.confidence,
1644
+ };
1645
+ }
1646
+ return {
1647
+ state: "expected_but_missing",
1648
+ capability: "context_usage",
1649
+ reason: runtime.reason,
1650
+ };
1651
+ }
1652
+ /** Seed the change-detection baseline from a committed session.started. */
1653
+ function seedAttestedTuning(state, event) {
1654
+ const attestation = event.payload
1655
+ .runtime_attestation;
1656
+ if (!attestation)
1657
+ return;
1658
+ const tuning = attestation.tuning;
1659
+ state.last_attested_tuning =
1660
+ tuning?.state === "observed"
1661
+ ? {
1662
+ ...(tuning.value?.effort ? { effort: tuning.value.effort } : {}),
1663
+ ...(tuning.value?.speed ? { speed: tuning.value.speed } : {}),
1664
+ }
1665
+ : {};
1666
+ const model = attestation.model;
1667
+ if (model.state === "observed") {
1668
+ state.last_attested_model = { provider: model.value.provider, id: model.value.id };
1669
+ }
1670
+ state.last_attested_model_observation = model;
1671
+ state.last_attested_tuning_observation = tuning;
1672
+ state.last_attested_telemetry = attestation.telemetry;
1673
+ }
1674
+ /**
1675
+ * Emit `session.attestation_changed` when the observed tuning moves.
1676
+ *
1677
+ * Detection channels are deliberately cheap: CC stamps `effort.level` on
1678
+ * every tool hook and Stop (zero I/O), and Codex tuning is read from the
1679
+ * rollout only at turn terminals, where the context enrichment already pays
1680
+ * for a bounded tail read. A pre-upgrade state file (no baseline) seeds
1681
+ * silently so existing sessions do not fire a spurious change on their next
1682
+ * tool event; a fresh session's baseline comes from its session.started.
1683
+ */
1684
+ function maybeAttestTuningChange(input, state, path, rootId) {
1685
+ if (input.signal !== "pre-tool-use" &&
1686
+ input.signal !== "post-tool-use" &&
1687
+ input.signal !== "stop") {
1688
+ return;
1689
+ }
1690
+ if (state.terminal)
1691
+ return;
1692
+ let candidate;
1693
+ let attestationSource = "native";
1694
+ let sourceEvent = `${input.adapter}.effort-payload`;
1695
+ if (input.adapter === "claude-code" || input.adapter === "cursor") {
1696
+ if (!input.payload.effort)
1697
+ return;
1698
+ candidate = { effort: input.payload.effort };
1699
+ }
1700
+ else if (input.adapter === "codex" &&
1701
+ (input.signal === "stop" ||
1702
+ // Early probe: without it, a Codex card shows no effort until the first
1703
+ // turn terminal. One rollout read per turn while effort is unknown.
1704
+ (input.signal === "post-tool-use" &&
1705
+ !state.last_attested_tuning?.effort &&
1706
+ state.current_turn_id !== undefined &&
1707
+ state.tuning_probe_turn_id !== state.current_turn_id))) {
1708
+ if (input.signal === "post-tool-use")
1709
+ state.tuning_probe_turn_id = state.current_turn_id;
1710
+ const runtime = readRuntimeTuning({
1711
+ adapter: "codex",
1712
+ session_id: input.payload.session_id ?? input.payload.conversation_id,
1713
+ transcript_path: runtimeTranscriptPath(input, state),
1714
+ }, input.runtimeTelemetryOptions);
1715
+ if (runtime.bytes_read > 0)
1716
+ recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
1717
+ if (runtime.state !== "observed")
1718
+ return;
1719
+ candidate = {
1720
+ ...(runtime.effort ? { effort: runtime.effort } : {}),
1721
+ ...(runtime.speed ? { speed: runtime.speed } : {}),
1722
+ ...(runtime.model ? { model: runtime.model } : {}),
1723
+ };
1724
+ attestationSource = "derived";
1725
+ sourceEvent = runtime.source_event;
1726
+ }
1727
+ else {
1728
+ return;
1729
+ }
1730
+ const baseline = state.last_attested_tuning;
1731
+ const next = { effort: candidate.effort, speed: candidate.speed ?? baseline?.speed };
1732
+ if (baseline === undefined || state.last_attested_telemetry === undefined) {
1733
+ // Pre-upgrade state: adopt without emitting; there is no attested prior.
1734
+ state.last_attested_tuning = { ...(next.effort ? { effort: next.effort } : {}) };
1735
+ if (next.speed)
1736
+ state.last_attested_tuning.speed = next.speed;
1737
+ return;
1738
+ }
1739
+ if (baseline.effort === next.effort && (candidate.speed ?? baseline.speed) === baseline.speed) {
1740
+ return;
1741
+ }
1742
+ // CC change detection rides the payload; the paired transcript row also
1743
+ // carries speed and the (possibly swapped) model, so refresh from it.
1744
+ if (input.adapter === "claude-code") {
1745
+ const runtime = readRuntimeTuning({
1746
+ adapter: "claude-code",
1747
+ transcript_path: input.payload.transcript_path,
1748
+ });
1749
+ if (runtime.bytes_read > 0)
1750
+ recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
1751
+ if (runtime.state === "observed" && runtime.effort === candidate.effort) {
1752
+ if (runtime.speed)
1753
+ candidate.speed = runtime.speed;
1754
+ if (runtime.model)
1755
+ candidate.model = runtime.model;
1756
+ }
1757
+ }
1758
+ const model = candidate.model
1759
+ ? {
1760
+ state: "observed",
1761
+ value: { provider: modelProviderFor(input.adapter), id: safeRole(candidate.model) },
1762
+ attestation: "derived",
1763
+ confidence: "high",
1764
+ }
1765
+ : state.last_attested_model
1766
+ ? {
1767
+ state: "observed",
1768
+ value: state.last_attested_model,
1769
+ attestation: "derived",
1770
+ confidence: "high",
1771
+ }
1772
+ : { state: "expected_but_missing", capability: "model_identity", reason: "not_reported" };
1773
+ const tuning = candidate.effort || candidate.speed
1774
+ ? {
1775
+ state: "observed",
1776
+ value: {
1777
+ ...(candidate.effort ? { effort: candidate.effort } : {}),
1778
+ ...(candidate.speed ? { speed: candidate.speed } : {}),
1779
+ },
1780
+ attestation: attestationSource,
1781
+ confidence: "exact",
1782
+ }
1783
+ : { state: "unsupported", capability: "effort_selection" };
1784
+ commitRuntimeAttestationChange(input, state, path, rootId, {
1785
+ model,
1786
+ tuning,
1787
+ telemetry: state.last_attested_telemetry,
1788
+ reason: "runtime_tuning_changed",
1789
+ source_event: sourceEvent,
1790
+ attestation: attestationSource,
1791
+ confidence: attestationSource === "native" ? "exact" : "high",
1792
+ });
1793
+ }
1794
+ function commitRuntimeAttestationChange(input, state, path, rootId, change) {
1795
+ const priorAttestationId = state.attestation_id;
1796
+ const nextAttestationId = attestationIdV3();
1797
+ const eventId = eventIdV3();
1798
+ const runtimeAttestation = {
1799
+ attestation_id: nextAttestationId,
1800
+ generation_id: state.generation_id,
1801
+ adapter: {
1802
+ state: "observed",
1803
+ value: {
1804
+ id: input.adapter,
1805
+ ...(input.adapterVersion ? { version: input.adapterVersion } : {}),
1806
+ },
1131
1807
  attestation: "native",
1132
1808
  confidence: "exact",
1809
+ },
1810
+ harness: {
1811
+ state: "observed",
1812
+ value: {
1813
+ id: input.adapter,
1814
+ ...(input.harnessVersion ? { version: input.harnessVersion } : {}),
1815
+ },
1816
+ attestation: "native",
1817
+ confidence: "exact",
1818
+ },
1819
+ model: change.model,
1820
+ tuning: change.tuning,
1821
+ telemetry: change.telemetry,
1822
+ capability_profile: state.capability_profile,
1823
+ declared_by_event_id: eventId,
1824
+ };
1825
+ const event = buildEventV3("session.attestation_changed", {
1826
+ event_id: eventId,
1827
+ producer: {
1828
+ producer_id: input.producer_id,
1829
+ boot_id: state.boot_id,
1830
+ sequence: state.next_sequence,
1831
+ component: "agent-hook",
1832
+ build_id: input.build_id,
1833
+ platform: input.platform,
1834
+ ...(input.bridge ? { bridge: input.bridge } : {}),
1835
+ },
1836
+ scope: {
1837
+ root_id: rootId,
1838
+ instance_id: state.instance_id,
1839
+ session_id: state.session_id,
1840
+ generation_id: state.generation_id,
1841
+ ...(input.run_id ? { run_id: input.run_id } : {}),
1842
+ ...(input.workflow_id ? { workflow_id: input.workflow_id } : {}),
1843
+ ...(input.workflow_agent_id ? { workflow_agent_id: input.workflow_agent_id } : {}),
1844
+ },
1845
+ attestation_id: nextAttestationId,
1846
+ links: { caused_by: state.last_event_id ? [state.last_event_id] : [] },
1847
+ provenance: {
1848
+ source_event: safeRole(change.source_event),
1849
+ attestation: change.attestation,
1850
+ confidence: change.confidence,
1133
1851
  attribution: {
1134
1852
  method: "native_payload",
1135
1853
  state: "verified",
1136
1854
  subject_instance_id: state.instance_id,
1137
1855
  },
1138
1856
  },
1139
- observed_at: measurement.state === "observed"
1140
- ? measurement.value.measured_at
1141
- : turnTerminal.time.observed_at,
1857
+ observed_at: input.observed_at ?? new Date().toISOString(),
1142
1858
  monotonic_ns: orderedEventMonotonic(state, input.monotonic_ns),
1143
1859
  clock_id: state.clock_id,
1144
1860
  payload: {
1145
- measurement,
1861
+ prior_attestation_id: priorAttestationId,
1862
+ runtime_attestation: runtimeAttestation,
1863
+ reason: change.reason,
1146
1864
  },
1147
1865
  });
1866
+ // Mutate BEFORE the commit: commitEventLocked publishes the state file, so
1867
+ // post-commit mutations would be dropped by the next signal's fresh read.
1868
+ // A crash between publishes replays the pending event against a state that
1869
+ // already carries the new attestation id, which is the id the event declares.
1870
+ state.attestation_id = nextAttestationId;
1871
+ state.last_attested_model_observation = change.model;
1872
+ state.last_attested_tuning_observation = change.tuning;
1873
+ state.last_attested_telemetry = change.telemetry;
1874
+ state.last_attested_model =
1875
+ change.model.state === "observed" ? { ...change.model.value } : undefined;
1876
+ state.last_attested_tuning = change.tuning.state === "observed" ? { ...change.tuning.value } : {};
1148
1877
  commitEventLocked(input, state, path, event);
1149
1878
  }
1879
+ function modelProviderFor(adapter) {
1880
+ if (adapter === "claude-code")
1881
+ return "anthropic";
1882
+ if (adapter === "codex")
1883
+ return "openai";
1884
+ return "cursor";
1885
+ }
1886
+ function recordRuntimeTelemetryTiming(state, durationMs) {
1887
+ const duration = Math.max(0, Math.ceil(durationMs));
1888
+ if (!Number.isSafeInteger(duration))
1889
+ return;
1890
+ state.turn_harness = {
1891
+ hook_time_ms: state.turn_harness.hook_time_ms + duration,
1892
+ hook_count: state.turn_harness.hook_count + 1,
1893
+ slowest_hook: duration >= state.turn_harness.slowest_hook_ms
1894
+ ? "runtime-context"
1895
+ : state.turn_harness.slowest_hook,
1896
+ slowest_hook_ms: Math.max(duration, state.turn_harness.slowest_hook_ms),
1897
+ };
1898
+ }
1150
1899
  function commitCapabilityDriftEvents(input, state, path, rootId) {
1151
1900
  const read = readLedgerV3(input.coordRoot);
1152
1901
  if (!read.complete)
@@ -1336,6 +2085,34 @@ function isCursorPromptBootstrap(input) {
1336
2085
  (input.payload.conversation_id !== undefined || input.payload.session_id !== undefined) &&
1337
2086
  input.payload.turn_id !== undefined);
1338
2087
  }
2088
+ /** Privacy-safe environment and recovery provenance for Codex mid-flight
2089
+ * onboarding. WSLENV values are never recorded, only normalized variable
2090
+ * names, and the native session identifier itself remains fingerprinted. */
2091
+ export function codexMidFlightDiagnosticContext(payload, env = process.env) {
2092
+ const wslenv = env.WSLENV?.trim() ?? "";
2093
+ const wslenvNames = [
2094
+ ...new Set(wslenv
2095
+ .split(":")
2096
+ .map((entry) => entry.split("/", 1)[0]?.trim() ?? "")
2097
+ .filter((name) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(name))),
2098
+ ]
2099
+ .sort()
2100
+ .join(":")
2101
+ .slice(0, 512);
2102
+ const identityRecoverySource = payload.session_id
2103
+ ? "native_session_id"
2104
+ : payload.conversation_id
2105
+ ? "native_conversation_id"
2106
+ : payload.agent_id
2107
+ ? "native_agent_id"
2108
+ : "unavailable";
2109
+ return {
2110
+ thread_id_present: Boolean(env.CODEX_THREAD_ID?.trim()),
2111
+ wslenv_present: wslenv.length > 0,
2112
+ wslenv_names: wslenvNames,
2113
+ identity_recovery_source: identityRecoverySource,
2114
+ };
2115
+ }
1339
2116
  function suppressClosedSpanSignal(input, sessionHash, category) {
1340
2117
  writeProducerDiagnosticV3(input.coordRoot, category, {
1341
2118
  adapter: input.adapter,
@@ -1357,6 +2134,13 @@ export function recordApprovedSessionEndV3(input) {
1357
2134
  if (control.state !== input.mode) {
1358
2135
  return { state: "gate_closed", reason: control.state };
1359
2136
  }
2137
+ input = {
2138
+ ...input,
2139
+ writerOptions: {
2140
+ ...input.writerOptions,
2141
+ expectedGenesisId: control.genesis.event.payload.genesis_id,
2142
+ },
2143
+ };
1360
2144
  const matches = listHookProducerStateRecordsV3(input.coordRoot, { includeTerminal: true }).filter(({ state }) => state.instance_id === input.instance_id && state.generation_id === input.generation_id);
1361
2145
  if (matches.length !== 1) {
1362
2146
  return {
@@ -1390,6 +2174,7 @@ export function recordApprovedSessionEndV3(input) {
1390
2174
  }
1391
2175
  const rootId = control.genesis.event.scope.root_id;
1392
2176
  const context = fingerprintContextV3(input.coordRoot, rootId, state.generation_id, state.privacy_epoch_id);
2177
+ reconcilePendingRuntimeContextsBeforeApprovedEnd(input, state, record.path, rootId, context);
1393
2178
  const expected = [
1394
2179
  "session_started",
1395
2180
  "turn_closed",
@@ -1482,6 +2267,13 @@ export function salvageOpenSpansV3(input) {
1482
2267
  if (control.state !== input.mode) {
1483
2268
  return { state: "gate_closed", reason: control.state };
1484
2269
  }
2270
+ input = {
2271
+ ...input,
2272
+ writerOptions: {
2273
+ ...input.writerOptions,
2274
+ expectedGenesisId: control.genesis.event.payload.genesis_id,
2275
+ },
2276
+ };
1485
2277
  const matches = listHookProducerStateRecordsV3(input.coordRoot).filter(({ state }) => state.instance_id === input.instance_id && state.generation_id === input.generation_id);
1486
2278
  if (matches.length !== 1) {
1487
2279
  return {
@@ -1568,6 +2360,10 @@ export function listHookProducerStateRecordsV3(coordRoot, options = {}) {
1568
2360
  for (const name of readdirSync(directory).filter((entry) => /^hid_[a-f0-9]{64}\.json$/.test(entry))) {
1569
2361
  const path = join(directory, name);
1570
2362
  const state = readProducerState(path);
2363
+ // Skip authorities left behind by a replaced epoch: their sequences and
2364
+ // causal links belong to the archived ledger, not this one.
2365
+ if (state.epoch_genesis_id !== control.genesis.event.payload.genesis_id)
2366
+ continue;
1571
2367
  if (!options.includeTerminal && state.terminal)
1572
2368
  continue;
1573
2369
  records.push({ path, modified_at_ms: lstatSync(path).mtimeMs, state });
@@ -1612,7 +2408,66 @@ export function readHookProducerStateV3(coordRoot, adapter, nativeSessionId) {
1612
2408
  const context = fingerprintContextV3(coordRoot, rootId, undefined, control.genesis.profile.privacy_key_epoch);
1613
2409
  const sessionHash = normalizeNativeIdV3(context, `${adapter}.session`, nativeSessionId);
1614
2410
  const path = producerStatePath(coordRoot, adapter, sessionHash);
1615
- return existsSync(path) ? readProducerState(path) : undefined;
2411
+ if (!existsSync(path))
2412
+ return undefined;
2413
+ const state = readProducerState(path);
2414
+ // A state left behind by a replaced epoch is not this epoch's authority.
2415
+ return state.epoch_genesis_id === control.genesis.event.payload.genesis_id ? state : undefined;
2416
+ }
2417
+ /**
2418
+ * Retry one Codex session's owner-only context join without replaying its Stop
2419
+ * signal. Codex appends `task_complete` only after the synchronous Stop hook
2420
+ * exits, so this is invoked by a bounded detached worker after that exit.
2421
+ */
2422
+ export function reconcilePendingRuntimeContextV3(input) {
2423
+ const control = readEventV3ControlState(input.coordRoot);
2424
+ if (control.state !== input.mode)
2425
+ return { state: "gate_closed" };
2426
+ if (control.state !== "candidate" && control.state !== "active") {
2427
+ return { state: "gate_closed" };
2428
+ }
2429
+ const rootId = control.genesis.event.scope.root_id;
2430
+ const rootContext = fingerprintContextV3(input.coordRoot, rootId, undefined, control.genesis.profile.privacy_key_epoch);
2431
+ const sessionHash = normalizeNativeIdV3(rootContext, "codex.session", input.nativeSessionId);
2432
+ const path = producerStatePath(input.coordRoot, "codex", sessionHash);
2433
+ if (!existsSync(path))
2434
+ return { state: "missing" };
2435
+ const lease = acquireStateLeaseWithRetry(input.coordRoot, path, STATE_LEASE_RETRY_ATTEMPTS);
2436
+ if (!lease)
2437
+ return { state: "busy" };
2438
+ try {
2439
+ const state = readProducerState(path);
2440
+ if (state.epoch_genesis_id !== control.genesis.event.payload.genesis_id) {
2441
+ // The pending contexts belong to a replaced epoch; its archive already
2442
+ // holds everything this producer durably recorded.
2443
+ return { state: "missing" };
2444
+ }
2445
+ if (state.adapter !== "codex" || !state.pending_runtime_contexts?.length) {
2446
+ return { state: "not_pending" };
2447
+ }
2448
+ const context = fingerprintContextV3(input.coordRoot, rootId, state.generation_id, state.privacy_epoch_id);
2449
+ reconcilePendingRuntimeContexts({
2450
+ coordRoot: input.coordRoot,
2451
+ mode: input.mode,
2452
+ signal: "stop",
2453
+ payload: { raw: {}, session_id: input.nativeSessionId },
2454
+ adapter: "codex",
2455
+ instance_id: state.instance_id,
2456
+ producer_id: input.producer_id,
2457
+ build_id: input.build_id,
2458
+ platform: input.platform,
2459
+ observed_at: new Date().toISOString(),
2460
+ runtimeTelemetryOptions: input.runtimeTelemetryOptions,
2461
+ writerOptions: {
2462
+ ...input.writerOptions,
2463
+ expectedGenesisId: control.genesis.event.payload.genesis_id,
2464
+ },
2465
+ }, state, path, rootId, context, { deferRetryLimit: true, finalAttempt: input.finalAttempt });
2466
+ return state.pending_runtime_contexts?.length ? { state: "pending" } : { state: "settled" };
2467
+ }
2468
+ finally {
2469
+ lease.release();
2470
+ }
1616
2471
  }
1617
2472
  /** Resolve one terminal producer only when native session and instance identity agree. */
1618
2473
  export function readTerminalHookProducerStateV3(coordRoot, nativeSessionId, instanceId) {
@@ -1639,13 +2494,30 @@ export function readHookProducerStateByInstanceV3(coordRoot, instanceId) {
1639
2494
  }
1640
2495
  for (const name of readdirSync(directory).filter((entry) => /^hid_[a-f0-9]{64}\.json$/.test(entry))) {
1641
2496
  const state = readProducerState(join(directory, name));
2497
+ if (state.epoch_genesis_id !== control.genesis.event.payload.genesis_id)
2498
+ continue;
1642
2499
  if (state.instance_id === instanceId && !state.terminal)
1643
2500
  matches.push(state);
1644
2501
  }
1645
2502
  }
1646
2503
  return matches.length === 1 ? matches[0] : undefined;
1647
2504
  }
1648
- function newProducerState(input, sessionId, epochId, boundaryEventId) {
2505
+ /**
2506
+ * Join a coordination actor to its hook producer.
2507
+ *
2508
+ * Native subagent commands can retain the parent's session id even after the
2509
+ * child has its own canonical generation. Prefer the native session join, but
2510
+ * when that points at a different instance accept only one exact live
2511
+ * instance match for the same adapter.
2512
+ */
2513
+ export function readJoinableHookProducerStateV3(coordRoot, adapter, nativeSessionId, instanceId) {
2514
+ const direct = readHookProducerStateV3(coordRoot, adapter, nativeSessionId);
2515
+ if (direct?.instance_id === instanceId && !direct.terminal)
2516
+ return direct;
2517
+ const byInstance = readHookProducerStateByInstanceV3(coordRoot, instanceId);
2518
+ return byInstance?.adapter === adapter && !byInstance.terminal ? byInstance : undefined;
2519
+ }
2520
+ function newProducerState(input, sessionId, epochId, boundaryEventId, genesisId) {
1649
2521
  const bootId = `boot_${randomUUID()}`;
1650
2522
  return {
1651
2523
  format: STATE_FORMAT,
@@ -1653,11 +2525,12 @@ function newProducerState(input, sessionId, epochId, boundaryEventId) {
1653
2525
  adapter: input.adapter,
1654
2526
  instance_id: input.instance_id,
1655
2527
  session_id: sessionId,
1656
- generation_id: generationIdV3(),
2528
+ generation_id: input.delegated_child?.generation_id ?? generationIdV3(),
1657
2529
  attestation_id: attestationIdV3(),
1658
2530
  capability_profile: adapterCapabilityProfileDigestV3(input.adapter),
1659
2531
  cursor_mode: input.adapter === "cursor" ? (input.payload.cursor_mode ?? "unknown") : undefined,
1660
2532
  privacy_epoch_id: epochId,
2533
+ epoch_genesis_id: genesisId,
1661
2534
  boot_id: bootId,
1662
2535
  clock_id: clockIdV3(),
1663
2536
  next_sequence: 1,
@@ -1668,6 +2541,7 @@ function newProducerState(input, sessionId, epochId, boundaryEventId) {
1668
2541
  boot_id: bootId,
1669
2542
  clock: signalClock(input),
1670
2543
  }),
2544
+ session_start_derivation: input.session_start_derivation,
1671
2545
  terminal: false,
1672
2546
  spans: [],
1673
2547
  delegations: [],
@@ -1694,10 +2568,12 @@ function applyCommittedEvent(state, event) {
1694
2568
  if (event.event_type === "session.started") {
1695
2569
  state.started_event_id = event.event_id;
1696
2570
  state.session_span.open_event_id = event.event_id;
2571
+ seedAttestedTuning(state, event);
1697
2572
  }
1698
2573
  if (event.event_type === "turn.started") {
1699
2574
  const nextTurnId = event.scope.turn_id;
1700
2575
  state.current_turn_id = nextTurnId;
2576
+ state.session_start_derivation = undefined;
1701
2577
  if (state.tool_call_count_turn_id !== nextTurnId) {
1702
2578
  state.tool_call_count = 0;
1703
2579
  state.tool_call_count_turn_id = nextTurnId;
@@ -1773,6 +2649,7 @@ function applyCommittedEvent(state, event) {
1773
2649
  }
1774
2650
  }
1775
2651
  state.current_turn_id = undefined;
2652
+ state.current_native_turn_id = undefined;
1776
2653
  state.current_turn_span = undefined;
1777
2654
  state.tool_call_count = 0;
1778
2655
  state.tool_call_count_turn_id = undefined;
@@ -1918,6 +2795,14 @@ function safeRole(value) {
1918
2795
  .slice(0, 128);
1919
2796
  return /^[a-zA-Z0-9]/.test(normalized) ? normalized : "agent";
1920
2797
  }
2798
+ function asLiveInstanceId(nativeInstanceId) {
2799
+ if (/^inst_[a-zA-Z0-9._-]{1,128}$/.test(nativeInstanceId)) {
2800
+ return nativeInstanceId;
2801
+ }
2802
+ if (/^[a-zA-Z0-9._-]{1,128}$/.test(nativeInstanceId))
2803
+ return `inst_${nativeInstanceId}`;
2804
+ return `inst_${createHash("sha256").update(nativeInstanceId.normalize("NFC")).digest("hex")}`;
2805
+ }
1921
2806
  function safeTokenOrUndefined(value) {
1922
2807
  if (typeof value !== "string")
1923
2808
  return undefined;
@@ -1996,9 +2881,14 @@ function readProducerState(path) {
1996
2881
  state.waits ??= [];
1997
2882
  state.closed_turn_ids ??= [];
1998
2883
  state.turn_harness ??= emptyTurnHarnessTiming();
2884
+ if (Array.isArray(state.pending_runtime_contexts) &&
2885
+ state.pending_runtime_contexts.length === 0) {
2886
+ state.pending_runtime_contexts = undefined;
2887
+ }
1999
2888
  if (state.adapter === "cursor")
2000
2889
  state.cursor_mode ??= "unknown";
2001
2890
  const allowedKeys = new Set([
2891
+ "active_runtime_context_probe",
2002
2892
  "adapter",
2003
2893
  "attestation_id",
2004
2894
  "boot_id",
@@ -2007,20 +2897,32 @@ function readProducerState(path) {
2007
2897
  "closed_spans",
2008
2898
  "closed_turn_ids",
2009
2899
  "current_turn_id",
2900
+ "current_native_turn_id",
2010
2901
  "current_turn_span",
2011
2902
  "cursor_mode",
2012
2903
  "delegations",
2904
+ "epoch_genesis_id",
2013
2905
  "format",
2014
2906
  "format_version",
2015
2907
  "generation_id",
2016
2908
  "instance_id",
2909
+ "last_attested_model",
2910
+ "last_attested_model_observation",
2911
+ "last_attested_telemetry",
2912
+ "last_attested_tuning",
2913
+ "last_attested_tuning_observation",
2914
+ "last_context_source_witness",
2915
+ "tuning_probe_turn_id",
2017
2916
  "last_event_id",
2018
2917
  "last_monotonic_ns",
2019
2918
  "last_observed_at",
2020
2919
  "next_sequence",
2021
2920
  "pending",
2921
+ "pending_runtime_contexts",
2922
+ "runtime_transcript_path",
2022
2923
  "privacy_epoch_id",
2023
2924
  "session_id",
2925
+ "session_start_derivation",
2024
2926
  "session_span",
2025
2927
  "spans",
2026
2928
  "started_event_id",
@@ -2043,6 +2945,7 @@ function readProducerState(path) {
2043
2945
  !/^att_[0-9a-f-]{36}$/.test(state.attestation_id) ||
2044
2946
  !/^cap_[a-f0-9]{64}$/.test(state.capability_profile) ||
2045
2947
  !/^pep_[a-zA-Z0-9._-]+$/.test(state.privacy_epoch_id) ||
2948
+ (state.epoch_genesis_id !== undefined && !/^gex_[0-9a-f-]{36}$/.test(state.epoch_genesis_id)) ||
2046
2949
  !/^boot_[a-zA-Z0-9._-]+$/.test(state.boot_id) ||
2047
2950
  !/^clk_[0-9a-f-]{36}$/.test(state.clock_id) ||
2048
2951
  !Number.isSafeInteger(state.next_sequence) ||
@@ -2097,11 +3000,32 @@ function readProducerState(path) {
2097
3000
  !Number.isSafeInteger(state.turn_ordinal) ||
2098
3001
  state.turn_ordinal < 0 ||
2099
3002
  (state.current_turn_id !== undefined && !/^tid_[a-f0-9]{64}$/.test(state.current_turn_id)) ||
3003
+ (state.current_native_turn_id !== undefined &&
3004
+ (typeof state.current_native_turn_id !== "string" ||
3005
+ state.current_native_turn_id.length === 0 ||
3006
+ state.current_native_turn_id.length > 512)) ||
2100
3007
  (state.last_event_id !== undefined && !/^evt_[0-9a-f-]{36}$/.test(state.last_event_id)) ||
2101
3008
  (state.last_monotonic_ns !== undefined && !/^\d+$/.test(state.last_monotonic_ns)) ||
2102
3009
  (state.last_observed_at !== undefined &&
2103
3010
  !Number.isFinite(Date.parse(state.last_observed_at))) ||
2104
3011
  (state.started_event_id !== undefined && !/^evt_[0-9a-f-]{36}$/.test(state.started_event_id)) ||
3012
+ (state.session_start_derivation !== undefined &&
3013
+ state.session_start_derivation !== "approved_lifecycle_reopen" &&
3014
+ state.session_start_derivation !== "validated_current_session_heal") ||
3015
+ (state.pending_runtime_contexts !== undefined &&
3016
+ (!Array.isArray(state.pending_runtime_contexts) ||
3017
+ state.pending_runtime_contexts.length === 0 ||
3018
+ state.pending_runtime_contexts.length > PENDING_RUNTIME_CONTEXT_CAP ||
3019
+ state.pending_runtime_contexts.some((pending) => !validPendingRuntimeContext(pending)))) ||
3020
+ (state.active_runtime_context_probe !== undefined &&
3021
+ !validActiveRuntimeContextProbe(state.active_runtime_context_probe)) ||
3022
+ (state.last_context_source_witness !== undefined &&
3023
+ !/^[a-f0-9]{64}$/.test(state.last_context_source_witness)) ||
3024
+ (state.runtime_transcript_path !== undefined &&
3025
+ (typeof state.runtime_transcript_path !== "string" ||
3026
+ state.runtime_transcript_path.length === 0 ||
3027
+ state.runtime_transcript_path.length > 4096 ||
3028
+ state.runtime_transcript_path.includes("\0"))) ||
2105
3029
  (state.pending?.source_id !== undefined &&
2106
3030
  !/^hid_[a-f0-9]{64}$/.test(state.pending.source_id)) ||
2107
3031
  (state.pending && !validateEventV3(state.pending.event).ok)) {
@@ -2163,6 +3087,47 @@ function validTurnHarnessTiming(value) {
2163
3087
  (value.slowest_hook === undefined ||
2164
3088
  /^[a-zA-Z0-9][a-zA-Z0-9._:/+-]{0,127}$/.test(value.slowest_hook)));
2165
3089
  }
3090
+ function validPendingRuntimeContext(value) {
3091
+ if (!value || typeof value !== "object" || Array.isArray(value))
3092
+ return false;
3093
+ const pending = value;
3094
+ return (typeof pending.terminal_event_id === "string" &&
3095
+ /^evt_[0-9a-f-]{36}$/.test(pending.terminal_event_id) &&
3096
+ typeof pending.terminal_observed_at === "string" &&
3097
+ Number.isFinite(Date.parse(pending.terminal_observed_at)) &&
3098
+ typeof pending.turn_id === "string" &&
3099
+ /^tid_[a-f0-9]{64}$/.test(pending.turn_id) &&
3100
+ (pending.run_id === undefined || /^run_[0-9a-f-]{36}$/.test(pending.run_id)) &&
3101
+ (pending.workflow_id === undefined || /^wf_[0-9a-f-]{36}$/.test(pending.workflow_id)) &&
3102
+ (pending.workflow_agent_id === undefined ||
3103
+ /^[a-zA-Z0-9][a-zA-Z0-9._:/+-]{0,127}$/.test(pending.workflow_agent_id)) &&
3104
+ typeof pending.native_session_id === "string" &&
3105
+ pending.native_session_id.length > 0 &&
3106
+ pending.native_session_id.length <= 512 &&
3107
+ typeof pending.native_turn_id === "string" &&
3108
+ pending.native_turn_id.length > 0 &&
3109
+ pending.native_turn_id.length <= 512 &&
3110
+ (pending.transcript_path === undefined ||
3111
+ (typeof pending.transcript_path === "string" &&
3112
+ pending.transcript_path.length > 0 &&
3113
+ pending.transcript_path.length <= 4096)) &&
3114
+ (pending.runtime_version === undefined ||
3115
+ (typeof pending.runtime_version === "string" &&
3116
+ /^[a-zA-Z0-9][a-zA-Z0-9._:/+-]{0,127}$/.test(pending.runtime_version))) &&
3117
+ Number.isSafeInteger(pending.attempts) &&
3118
+ pending.attempts >= 0 &&
3119
+ pending.attempts < RUNTIME_CONTEXT_RETRY_LIMIT);
3120
+ }
3121
+ function validActiveRuntimeContextProbe(value) {
3122
+ if (!value || typeof value !== "object" || Array.isArray(value))
3123
+ return false;
3124
+ const probe = value;
3125
+ return (typeof probe.turn_id === "string" &&
3126
+ /^tid_[a-f0-9]{64}$/.test(probe.turn_id) &&
3127
+ typeof probe.attempted_at === "string" &&
3128
+ Number.isFinite(Date.parse(probe.attempted_at)) &&
3129
+ (probe.boundary === undefined || probe.boundary === "tool_completed"));
3130
+ }
2166
3131
  function pidIsAlive(pid) {
2167
3132
  if (!Number.isSafeInteger(pid) || pid < 1)
2168
3133
  return false;