harnery 0.38.0 → 0.40.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 (378) hide show
  1. package/dist/commands/agents.d.ts.map +1 -1
  2. package/dist/commands/agents.js +32 -8
  3. package/dist/commands/artifacts.d.ts.map +1 -1
  4. package/dist/commands/artifacts.js +97 -6
  5. package/dist/commands/backup.d.ts +16 -0
  6. package/dist/commands/backup.d.ts.map +1 -1
  7. package/dist/commands/backup.js +239 -33
  8. package/dist/commands/browse.d.ts +8 -0
  9. package/dist/commands/browse.d.ts.map +1 -1
  10. package/dist/commands/browse.js +466 -231
  11. package/dist/commands/diagnostics.d.ts.map +1 -1
  12. package/dist/commands/diagnostics.js +6 -3
  13. package/dist/commands/ledger-v3.d.ts.map +1 -1
  14. package/dist/commands/ledger-v3.js +20 -4
  15. package/dist/commands/qa-run.d.ts.map +1 -1
  16. package/dist/commands/qa-run.js +26 -3
  17. package/dist/commands/qa-status.d.ts.map +1 -1
  18. package/dist/commands/qa-status.js +7 -2
  19. package/dist/commands/resources.d.ts.map +1 -1
  20. package/dist/commands/resources.js +23 -3
  21. package/dist/commands/review-pack.d.ts.map +1 -1
  22. package/dist/commands/review-pack.js +98 -23
  23. package/dist/commands/tunnel.d.ts.map +1 -1
  24. package/dist/commands/tunnel.js +2 -2
  25. package/dist/core/adapters/profiles.d.ts +1 -1
  26. package/dist/core/agents/canonical-emit.d.ts +3 -2
  27. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  28. package/dist/core/agents/canonical-emit.js +2 -0
  29. package/dist/core/agents/cli.js +13 -6
  30. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  31. package/dist/core/agents/live-authority-v3.js +5 -3
  32. package/dist/core/agents/live-lifecycle-v3.d.ts +2 -2
  33. package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
  34. package/dist/core/agents/render/prompt-context.d.ts +7 -5
  35. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  36. package/dist/core/agents/render/prompt-context.js +63 -8
  37. package/dist/core/agents/session-finalizer-v3.d.ts +2 -2
  38. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
  39. package/dist/core/agents/state/live-coordination-view.d.ts +3 -3
  40. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  41. package/dist/core/agents/state/live-coordination-view.js +2 -1
  42. package/dist/core/agents/state/names.d.ts +35 -2
  43. package/dist/core/agents/state/names.d.ts.map +1 -1
  44. package/dist/core/agents/state/names.js +80 -5
  45. package/dist/core/agents/state/stale-sweep.d.ts +2 -1
  46. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  47. package/dist/core/agents/state/stale-sweep.js +23 -6
  48. package/dist/core/agents/turn-elapsed.d.ts +51 -0
  49. package/dist/core/agents/turn-elapsed.d.ts.map +1 -0
  50. package/dist/core/agents/turn-elapsed.js +91 -0
  51. package/dist/core/artifacts/activity.d.ts +14 -0
  52. package/dist/core/artifacts/activity.d.ts.map +1 -0
  53. package/dist/core/artifacts/activity.js +52 -0
  54. package/dist/core/artifacts/delivery-card.d.ts +39 -0
  55. package/dist/core/artifacts/delivery-card.d.ts.map +1 -0
  56. package/dist/core/artifacts/delivery-card.js +282 -0
  57. package/dist/core/artifacts/index.d.ts +42 -7
  58. package/dist/core/artifacts/index.d.ts.map +1 -1
  59. package/dist/core/artifacts/index.js +288 -76
  60. package/dist/core/artifacts/mutation-lock.d.ts +2 -0
  61. package/dist/core/artifacts/mutation-lock.d.ts.map +1 -0
  62. package/dist/core/artifacts/mutation-lock.js +91 -0
  63. package/dist/core/backup/host-snapshot.d.ts +18 -0
  64. package/dist/core/backup/host-snapshot.d.ts.map +1 -0
  65. package/dist/core/backup/host-snapshot.js +64 -0
  66. package/dist/core/config.d.ts +20 -5
  67. package/dist/core/config.d.ts.map +1 -1
  68. package/dist/core/config.js +44 -10
  69. package/dist/core/diagnostics/advice.d.ts +38 -3
  70. package/dist/core/diagnostics/advice.d.ts.map +1 -1
  71. package/dist/core/diagnostics/advice.js +103 -99
  72. package/dist/core/diagnostics/bundle.d.ts.map +1 -1
  73. package/dist/core/diagnostics/bundle.js +111 -47
  74. package/dist/core/diagnostics/comparison.d.ts.map +1 -1
  75. package/dist/core/diagnostics/comparison.js +3 -2
  76. package/dist/core/diagnostics/contract.d.ts +15 -31
  77. package/dist/core/diagnostics/contract.d.ts.map +1 -1
  78. package/dist/core/diagnostics/contract.js +2 -5
  79. package/dist/core/diagnostics/index.d.ts +2 -0
  80. package/dist/core/diagnostics/index.d.ts.map +1 -1
  81. package/dist/core/diagnostics/index.js +2 -0
  82. package/dist/core/diagnostics/pressure-contract.d.ts +260 -0
  83. package/dist/core/diagnostics/pressure-contract.d.ts.map +1 -0
  84. package/dist/core/diagnostics/pressure-contract.js +70 -0
  85. package/dist/core/diagnostics/pressure.d.ts +25 -0
  86. package/dist/core/diagnostics/pressure.d.ts.map +1 -0
  87. package/dist/core/diagnostics/pressure.js +1138 -0
  88. package/dist/core/diagnostics/replay.d.ts.map +1 -1
  89. package/dist/core/diagnostics/replay.js +90 -10
  90. package/dist/core/events/v3/adapter-id.d.ts +6 -0
  91. package/dist/core/events/v3/adapter-id.d.ts.map +1 -0
  92. package/dist/core/events/v3/adapter-id.js +7 -0
  93. package/dist/core/events/v3/archive-retention.d.ts.map +1 -1
  94. package/dist/core/events/v3/archive-retention.js +3 -2
  95. package/dist/core/events/v3/bootstrap.d.ts +41 -4
  96. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  97. package/dist/core/events/v3/bootstrap.js +120 -17
  98. package/dist/core/events/v3/capabilities.d.ts +16 -9
  99. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  100. package/dist/core/events/v3/capabilities.js +37 -2
  101. package/dist/core/events/v3/capability-drift.d.ts +2 -2
  102. package/dist/core/events/v3/capability-drift.d.ts.map +1 -1
  103. package/dist/core/events/v3/control-witness.d.ts +48 -5
  104. package/dist/core/events/v3/control-witness.d.ts.map +1 -1
  105. package/dist/core/events/v3/control-witness.js +91 -36
  106. package/dist/core/events/v3/control.d.ts.map +1 -1
  107. package/dist/core/events/v3/control.js +22 -2
  108. package/dist/core/events/v3/index.d.ts +2 -1
  109. package/dist/core/events/v3/index.d.ts.map +1 -1
  110. package/dist/core/events/v3/index.js +2 -1
  111. package/dist/core/events/v3/live-feed.d.ts +7 -1
  112. package/dist/core/events/v3/live-feed.d.ts.map +1 -1
  113. package/dist/core/events/v3/live-feed.js +21 -3
  114. package/dist/core/events/v3/live-routing.d.ts.map +1 -1
  115. package/dist/core/events/v3/live-routing.js +10 -2
  116. package/dist/core/events/v3/producers/command-recorder.d.ts +2 -2
  117. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  118. package/dist/core/events/v3/producers/command-recorder.js +2 -1
  119. package/dist/core/events/v3/producers/coordination-recorder.d.ts +2 -2
  120. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  121. package/dist/core/events/v3/producers/coordination-recorder.js +2 -1
  122. package/dist/core/events/v3/producers/hook-base.d.ts +2 -2
  123. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  124. package/dist/core/events/v3/producers/hook-base.js +15 -5
  125. package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
  126. package/dist/core/events/v3/producers/hook.js +17 -4
  127. package/dist/core/events/v3/producers/intake.d.ts +4 -4
  128. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  129. package/dist/core/events/v3/producers/intake.js +3 -2
  130. package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -1
  131. package/dist/core/events/v3/producers/producer-state-observer.js +2 -1
  132. package/dist/core/events/v3/producers/recorder.d.ts +16 -5
  133. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  134. package/dist/core/events/v3/producers/recorder.js +31 -9
  135. package/dist/core/events/v3/reader.d.ts.map +1 -1
  136. package/dist/core/events/v3/reader.js +10 -13
  137. package/dist/core/events/v3/runtime-build.d.ts.map +1 -1
  138. package/dist/core/events/v3/runtime-build.js +3 -2
  139. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +2 -2
  140. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -1
  141. package/dist/core/events/v3/turn-telemetry.d.ts +2 -2
  142. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
  143. package/dist/core/hooks/adapter/output.d.ts +16 -14
  144. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  145. package/dist/core/hooks/adapter/output.js +36 -38
  146. package/dist/core/hooks/backup-schedule.d.ts +34 -0
  147. package/dist/core/hooks/backup-schedule.d.ts.map +1 -0
  148. package/dist/core/hooks/backup-schedule.js +114 -0
  149. package/dist/core/hooks/cli.js +61 -18
  150. package/dist/core/hooks/codex-wsl-bridge.d.ts +2 -0
  151. package/dist/core/hooks/codex-wsl-bridge.d.ts.map +1 -1
  152. package/dist/core/hooks/codex-wsl-bridge.js +18 -4
  153. package/dist/core/hooks/index.d.ts +1 -0
  154. package/dist/core/hooks/index.d.ts.map +1 -1
  155. package/dist/core/hooks/index.js +1 -0
  156. package/dist/core/hooks/prompt-context/contract.d.ts +61 -0
  157. package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -0
  158. package/dist/core/hooks/prompt-context/contract.js +102 -0
  159. package/dist/core/hooks/prompt-context/index.d.ts +5 -0
  160. package/dist/core/hooks/prompt-context/index.d.ts.map +1 -0
  161. package/dist/core/hooks/prompt-context/index.js +2 -0
  162. package/dist/core/hooks/prompt-context/runner.d.ts +24 -0
  163. package/dist/core/hooks/prompt-context/runner.d.ts.map +1 -0
  164. package/dist/core/hooks/prompt-context/runner.js +249 -0
  165. package/dist/core/qa-artifacts.d.ts +3 -0
  166. package/dist/core/qa-artifacts.d.ts.map +1 -1
  167. package/dist/core/qa-artifacts.js +25 -3
  168. package/dist/core/resources/contract.d.ts +69 -3
  169. package/dist/core/resources/contract.d.ts.map +1 -1
  170. package/dist/core/resources/contract.js +1 -1
  171. package/dist/core/resources/index.d.ts +1 -0
  172. package/dist/core/resources/index.d.ts.map +1 -1
  173. package/dist/core/resources/index.js +1 -0
  174. package/dist/core/resources/native.d.ts +36 -0
  175. package/dist/core/resources/native.d.ts.map +1 -0
  176. package/dist/core/resources/native.js +418 -0
  177. package/dist/core/resources/sampler.d.ts +2 -0
  178. package/dist/core/resources/sampler.d.ts.map +1 -1
  179. package/dist/core/resources/sampler.js +31 -1
  180. package/dist/core/resources/status.d.ts +61 -0
  181. package/dist/core/resources/status.d.ts.map +1 -0
  182. package/dist/core/resources/status.js +536 -0
  183. package/dist/core/resources/system.d.ts +27 -0
  184. package/dist/core/resources/system.d.ts.map +1 -0
  185. package/dist/core/resources/system.js +439 -0
  186. package/dist/core/semantic/contract.d.ts +13 -13
  187. package/dist/core/semantic/service.d.ts +2 -0
  188. package/dist/core/semantic/service.d.ts.map +1 -1
  189. package/dist/core/semantic/service.js +27 -4
  190. package/dist/core/storage/builtins.js +41 -0
  191. package/dist/core/supervisor/contract.d.ts +41 -3
  192. package/dist/core/supervisor/contract.d.ts.map +1 -1
  193. package/dist/core/supervisor/contract.js +3 -2
  194. package/dist/core/supervisor/findings.d.ts +3 -0
  195. package/dist/core/supervisor/findings.d.ts.map +1 -1
  196. package/dist/core/supervisor/findings.js +88 -0
  197. package/dist/core/supervisor/history.d.ts.map +1 -1
  198. package/dist/core/supervisor/history.js +14 -0
  199. package/dist/core/supervisor/ledger-state.d.ts +55 -0
  200. package/dist/core/supervisor/ledger-state.d.ts.map +1 -0
  201. package/dist/core/supervisor/ledger-state.js +0 -0
  202. package/dist/core/supervisor/service.d.ts.map +1 -1
  203. package/dist/core/supervisor/service.js +120 -7
  204. package/dist/core/supervisor/storage.d.ts +3 -1
  205. package/dist/core/supervisor/storage.d.ts.map +1 -1
  206. package/dist/core/supervisor/storage.js +4 -0
  207. package/dist/core/workflow/admission.d.ts +3 -0
  208. package/dist/core/workflow/admission.d.ts.map +1 -1
  209. package/dist/core/workflow/admission.js +28 -16
  210. package/dist/core/workflow/engine.js +2 -2
  211. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  212. package/dist/core/workflow/live-session-v3.js +6 -1
  213. package/dist/core/workflow/proof.d.ts.map +1 -1
  214. package/dist/core/workflow/proof.js +4 -3
  215. package/dist/lib/browser/capture-fidelity.d.ts +7 -0
  216. package/dist/lib/browser/capture-fidelity.d.ts.map +1 -1
  217. package/dist/lib/browser/capture-fidelity.js +17 -0
  218. package/dist/lib/browser/client.d.ts +9 -0
  219. package/dist/lib/browser/client.d.ts.map +1 -1
  220. package/dist/lib/browser/client.js +85 -37
  221. package/dist/lib/browser/index.d.ts +3 -1
  222. package/dist/lib/browser/index.d.ts.map +1 -1
  223. package/dist/lib/browser/index.js +2 -1
  224. package/dist/lib/browser/page-review-budget.d.ts +13 -0
  225. package/dist/lib/browser/page-review-budget.d.ts.map +1 -0
  226. package/dist/lib/browser/page-review-budget.js +251 -0
  227. package/dist/lib/browser/page-review-contracts.d.ts +127 -0
  228. package/dist/lib/browser/page-review-contracts.d.ts.map +1 -0
  229. package/dist/lib/browser/page-review-contracts.js +5 -0
  230. package/dist/lib/browser/page-review-evidence.d.ts +48 -0
  231. package/dist/lib/browser/page-review-evidence.d.ts.map +1 -0
  232. package/dist/lib/browser/page-review-evidence.js +340 -0
  233. package/dist/lib/browser/page-review-judge.d.ts +1 -1
  234. package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
  235. package/dist/lib/browser/page-review-judge.js +46 -38
  236. package/dist/lib/browser/page-review-pack.d.ts +44 -22
  237. package/dist/lib/browser/page-review-pack.d.ts.map +1 -1
  238. package/dist/lib/browser/page-review-pack.js +116 -36
  239. package/dist/lib/browser/page-review-source.d.ts +12 -0
  240. package/dist/lib/browser/page-review-source.d.ts.map +1 -0
  241. package/dist/lib/browser/page-review-source.js +22 -0
  242. package/dist/lib/browser/qa-run-contracts.d.ts +35 -9
  243. package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
  244. package/dist/lib/browser/qa-run-contracts.js +48 -14
  245. package/dist/lib/browser/qa-run.d.ts.map +1 -1
  246. package/dist/lib/browser/qa-run.js +215 -68
  247. package/dist/lib/browser/qa-snapshot.d.ts +6 -0
  248. package/dist/lib/browser/qa-snapshot.d.ts.map +1 -1
  249. package/dist/lib/browser/qa-snapshot.js +259 -48
  250. package/dist/lib/browser/review-capture-transaction.d.ts +13 -0
  251. package/dist/lib/browser/review-capture-transaction.d.ts.map +1 -0
  252. package/dist/lib/browser/review-capture-transaction.js +79 -0
  253. package/dist/lib/browser/standalone-html.d.ts.map +1 -1
  254. package/dist/lib/browser/standalone-html.js +4 -2
  255. package/dist/lib/browser/thumbnail-association.d.ts +34 -0
  256. package/dist/lib/browser/thumbnail-association.d.ts.map +1 -0
  257. package/dist/lib/browser/thumbnail-association.js +158 -0
  258. package/dist/lib/browser/tiling.d.ts +30 -0
  259. package/dist/lib/browser/tiling.d.ts.map +1 -1
  260. package/dist/lib/browser/tiling.js +38 -0
  261. package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
  262. package/dist/lib/docs-metadata-managed.js +4 -1
  263. package/dist/lib/identities/assume.d.ts.map +1 -1
  264. package/dist/lib/identities/assume.js +7 -1
  265. package/dist/lib/instructions/templates.d.ts.map +1 -1
  266. package/dist/lib/instructions/templates.js +1 -0
  267. package/dist/lib/local-file-url.d.ts +12 -0
  268. package/dist/lib/local-file-url.d.ts.map +1 -1
  269. package/dist/lib/local-file-url.js +16 -2
  270. package/dist/lib/tunnel/state.d.ts +19 -4
  271. package/dist/lib/tunnel/state.d.ts.map +1 -1
  272. package/dist/lib/tunnel/state.js +53 -13
  273. package/package.json +7 -4
  274. package/schemas/config.schema.json +69 -2
  275. package/src/commands/agents.ts +42 -9
  276. package/src/commands/artifacts.ts +130 -6
  277. package/src/commands/backup.ts +287 -34
  278. package/src/commands/browse.ts +564 -267
  279. package/src/commands/diagnostics.ts +6 -3
  280. package/src/commands/ledger-v3.ts +20 -3
  281. package/src/commands/qa-run.ts +37 -3
  282. package/src/commands/qa-status.ts +11 -2
  283. package/src/commands/resources.ts +23 -3
  284. package/src/commands/review-pack.ts +165 -62
  285. package/src/commands/tunnel.ts +2 -1
  286. package/src/core/agents/canonical-emit.ts +4 -2
  287. package/src/core/agents/cli.ts +14 -6
  288. package/src/core/agents/live-authority-v3.ts +7 -3
  289. package/src/core/agents/live-lifecycle-v3.ts +2 -2
  290. package/src/core/agents/render/prompt-context.ts +68 -14
  291. package/src/core/agents/session-finalizer-v3.ts +2 -2
  292. package/src/core/agents/state/live-coordination-view.ts +4 -4
  293. package/src/core/agents/state/names.ts +92 -7
  294. package/src/core/agents/state/stale-sweep.ts +22 -8
  295. package/src/core/agents/turn-elapsed.ts +135 -0
  296. package/src/core/artifacts/activity.ts +71 -0
  297. package/src/core/artifacts/delivery-card.ts +375 -0
  298. package/src/core/artifacts/index.ts +385 -91
  299. package/src/core/artifacts/mutation-lock.ts +106 -0
  300. package/src/core/backup/host-snapshot.ts +76 -0
  301. package/src/core/config.ts +66 -13
  302. package/src/core/diagnostics/advice.ts +148 -120
  303. package/src/core/diagnostics/bundle.ts +138 -52
  304. package/src/core/diagnostics/comparison.ts +6 -2
  305. package/src/core/diagnostics/contract.ts +39 -42
  306. package/src/core/diagnostics/index.ts +2 -0
  307. package/src/core/diagnostics/pressure-contract.ts +294 -0
  308. package/src/core/diagnostics/pressure.ts +1361 -0
  309. package/src/core/diagnostics/replay.ts +116 -11
  310. package/src/core/events/v3/adapter-id.ts +12 -0
  311. package/src/core/events/v3/archive-retention.ts +3 -6
  312. package/src/core/events/v3/bootstrap.ts +163 -16
  313. package/src/core/events/v3/capabilities.ts +75 -25
  314. package/src/core/events/v3/capability-drift.ts +2 -2
  315. package/src/core/events/v3/control-witness.ts +172 -41
  316. package/src/core/events/v3/control.ts +34 -2
  317. package/src/core/events/v3/index.ts +3 -0
  318. package/src/core/events/v3/live-feed.ts +23 -5
  319. package/src/core/events/v3/live-routing.ts +14 -2
  320. package/src/core/events/v3/producers/command-recorder.ts +4 -4
  321. package/src/core/events/v3/producers/coordination-recorder.ts +4 -4
  322. package/src/core/events/v3/producers/hook-base.ts +21 -16
  323. package/src/core/events/v3/producers/hook.ts +21 -4
  324. package/src/core/events/v3/producers/intake.ts +6 -6
  325. package/src/core/events/v3/producers/producer-state-observer.ts +2 -1
  326. package/src/core/events/v3/producers/recorder.ts +50 -21
  327. package/src/core/events/v3/reader.ts +14 -13
  328. package/src/core/events/v3/runtime-build.ts +3 -2
  329. package/src/core/events/v3/runtime-telemetry-capabilities.ts +3 -3
  330. package/src/core/events/v3/turn-telemetry.ts +4 -4
  331. package/src/core/hooks/adapter/output.ts +50 -36
  332. package/src/core/hooks/backup-schedule.ts +147 -0
  333. package/src/core/hooks/cli.ts +65 -14
  334. package/src/core/hooks/codex-wsl-bridge.ts +21 -5
  335. package/src/core/hooks/index.ts +1 -0
  336. package/src/core/hooks/prompt-context/contract.ts +177 -0
  337. package/src/core/hooks/prompt-context/index.ts +22 -0
  338. package/src/core/hooks/prompt-context/runner.ts +303 -0
  339. package/src/core/qa-artifacts.ts +29 -3
  340. package/src/core/resources/contract.ts +76 -3
  341. package/src/core/resources/index.ts +1 -0
  342. package/src/core/resources/native.ts +481 -0
  343. package/src/core/resources/sampler.ts +46 -1
  344. package/src/core/resources/status.ts +717 -0
  345. package/src/core/resources/system.ts +530 -0
  346. package/src/core/semantic/service.ts +37 -3
  347. package/src/core/storage/builtins.ts +41 -0
  348. package/src/core/supervisor/contract.ts +45 -3
  349. package/src/core/supervisor/findings.ts +159 -0
  350. package/src/core/supervisor/history.ts +15 -0
  351. package/src/core/supervisor/ledger-state.ts +0 -0
  352. package/src/core/supervisor/service.ts +133 -5
  353. package/src/core/supervisor/storage.ts +7 -0
  354. package/src/core/workflow/admission.ts +33 -17
  355. package/src/core/workflow/engine.ts +2 -2
  356. package/src/core/workflow/live-session-v3.ts +6 -8
  357. package/src/core/workflow/proof.ts +4 -3
  358. package/src/lib/browser/capture-fidelity.ts +23 -0
  359. package/src/lib/browser/client.ts +96 -44
  360. package/src/lib/browser/index.ts +15 -1
  361. package/src/lib/browser/page-review-budget.ts +309 -0
  362. package/src/lib/browser/page-review-contracts.ts +129 -0
  363. package/src/lib/browser/page-review-evidence.ts +465 -0
  364. package/src/lib/browser/page-review-judge.ts +56 -40
  365. package/src/lib/browser/page-review-pack.ts +181 -43
  366. package/src/lib/browser/page-review-source.ts +30 -0
  367. package/src/lib/browser/qa-run-contracts.ts +62 -18
  368. package/src/lib/browser/qa-run.ts +259 -71
  369. package/src/lib/browser/qa-snapshot.ts +289 -48
  370. package/src/lib/browser/review-capture-transaction.ts +106 -0
  371. package/src/lib/browser/standalone-html.ts +4 -2
  372. package/src/lib/browser/thumbnail-association.ts +190 -0
  373. package/src/lib/browser/tiling.ts +63 -0
  374. package/src/lib/docs-metadata-managed.ts +4 -1
  375. package/src/lib/identities/assume.ts +12 -4
  376. package/src/lib/instructions/templates.ts +1 -0
  377. package/src/lib/local-file-url.ts +17 -2
  378. package/src/lib/tunnel/state.ts +70 -13
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import { EVENT_ADAPTER_IDS_V3 } from "../events/v3/adapter-id.js";
2
3
  import { canonicalJsonV3, normalizeNativeIdV3, sha256V3 } from "../events/v3/canonical.js";
3
4
  import { readEventV3ControlState } from "../events/v3/control.js";
4
5
  import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from "../events/v3/coordination-view.js";
@@ -131,9 +132,7 @@ function readAuthoritySafeViewForBootstrap(coordRoot) {
131
132
  }
132
133
  function readSessionProducerStatesForBootstrap(coordRoot, nativeSessionId) {
133
134
  try {
134
- return ["claude-code", "codex", "cursor"]
135
- .map((adapter) => readHookProducerStateV3(coordRoot, adapter, nativeSessionId))
136
- .filter((state) => state !== undefined);
135
+ return EVENT_ADAPTER_IDS_V3.map((adapter) => readHookProducerStateV3(coordRoot, adapter, nativeSessionId)).filter((state) => state !== undefined);
137
136
  }
138
137
  catch {
139
138
  throw new LiveCoordinationAuthorityV3Error("producer_state_unsafe");
@@ -270,6 +269,9 @@ export function reopenLiveCoordinationGenerationV3(input) {
270
269
  if (!terminalView || terminalView.instance_id !== instanceId) {
271
270
  throw new LiveCoordinationAuthorityV3Error("terminal_generation_authority_missing");
272
271
  }
272
+ if (terminal.adapter === "openclaw") {
273
+ throw new LiveCoordinationAuthorityV3Error("lifecycle_not_human_facing");
274
+ }
273
275
  if (terminalView.parent_generation_id || terminalView.delegation_id || terminalView.workflow_id) {
274
276
  throw new LiveCoordinationAuthorityV3Error("lifecycle_not_human_facing");
275
277
  }
@@ -1,4 +1,4 @@
1
- import type { Adapter } from "../adapter.js";
1
+ import type { EventAdapterIdV3 } from "../events/v3/adapter-id.js";
2
2
  import type { EventV3 } from "../events/v3/contract.js";
3
3
  export type LiveLifecycleObservationV3Result = {
4
4
  state: "recorded";
@@ -8,7 +8,7 @@ interface LiveLifecycleObservationBaseV3 {
8
8
  coordRoot: string;
9
9
  owner: string;
10
10
  nativeSessionId: string;
11
- adapter: Adapter;
11
+ adapter: EventAdapterIdV3;
12
12
  observedAt?: string;
13
13
  }
14
14
  export declare function recordLiveSweepObservationV3(input: LiveLifecycleObservationBaseV3 & {
@@ -1 +1 @@
1
- {"version":3,"file":"live-lifecycle-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-lifecycle-v3.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAaxD,MAAM,MAAM,gCAAgC,GAAG;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAErF,UAAU,8BAA8B;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,8BAA8B,GAAG;IACtC,WAAW,EAAE,iBAAiB,GAAG,QAAQ,GAAG,uBAAuB,GAAG,mBAAmB,CAAC;IAC1F,KAAK,EAAE,MAAM,CAAC;CACf,GACA,gCAAgC,CAOlC;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,8BAA8B,GACpC,gCAAgC,CAQlC"}
1
+ {"version":3,"file":"live-lifecycle-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-lifecycle-v3.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAaxD,MAAM,MAAM,gCAAgC,GAAG;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAErF,UAAU,8BAA8B;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,8BAA8B,GAAG;IACtC,WAAW,EAAE,iBAAiB,GAAG,QAAQ,GAAG,uBAAuB,GAAG,mBAAmB,CAAC;IAC1F,KAAK,EAAE,MAAM,CAAC;CACf,GACA,gCAAgC,CAOlC;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,8BAA8B,GACpC,gCAAgC,CAQlC"}
@@ -49,11 +49,6 @@ export interface PromptContextOpts {
49
49
  /** When true, append the non-deduplicated Codex status-footer reminder.
50
50
  * The caller enables this only for human-facing Codex sessions. */
51
51
  statusFooterNudge?: boolean;
52
- /** Adapter id this prompt is being rendered for. Gates the mailbox drain:
53
- * an adapter that cannot receive UserPromptSubmit context must not consume
54
- * messages here, or they are removed from the queue and never shown. When
55
- * omitted, delivery is attempted (the default route can receive). */
56
- adapter?: string;
57
52
  /** Adapter id whose Stop hook ENFORCES the end-of-turn ritual (task_set +
58
53
  * status check). When set, append a fresh per-prompt reminder of that
59
54
  * contract so the model satisfies it before ending the turn instead of
@@ -70,4 +65,11 @@ export interface PromptContextOpts {
70
65
  * councils are pending, matching the bash behavior).
71
66
  */
72
67
  export declare function renderPromptContext(opts: PromptContextOpts): string;
68
+ /**
69
+ * Prompts receive the published assessment, and only when it changes in a way
70
+ * that changes what an agent should do. The dedupe key is scope, state, and
71
+ * recommended action, so a moving number or a different contributor does not
72
+ * re-emit the same advice.
73
+ */
74
+ export declare function resourceWarningIfChanged(coordRoot: string, instanceId: string): string;
73
75
  //# sourceMappingURL=prompt-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/prompt-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AA+CH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;8EAC0E;IAC1E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;kFAC8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;kFAC8E;IAC9E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;uEACmE;IACnE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;yEAGqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;wBAIoB;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAqFnE"}
1
+ {"version":3,"file":"prompt-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/prompt-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAgDH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;8EAC0E;IAC1E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;kFAC8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;kFAC8E;IAC9E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;uEACmE;IACnE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;wBAIoB;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAkFnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CA6CtF"}
@@ -37,10 +37,11 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, w
37
37
  import { join } from "node:path";
38
38
  import { coordEnv } from "../../../lib/env.js";
39
39
  import { endOfTurnStatusCommand, hostPromptReminder, resolveBinName } from "../../config.js";
40
- import { canReceiveContext } from "../../hooks/adapter/output.js";
41
40
  import { readRemoteMachines } from "../../presence/index.js";
41
+ import { readResourceStatus } from "../../resources/status.js";
42
42
  import { drainMailbox, formatMailboxDelivery } from "../mailbox.js";
43
43
  import { sessionNameDisplayBlock, sessionNameDisplayPending } from "../session-name-display.js";
44
+ import { heartbeatPath } from "../state/heartbeat-reader.js";
44
45
  import { readLiveCoordinationRow, readLiveCoordinationRows, } from "../state/live-coordination-view.js";
45
46
  import { formatPendingCouncils, recordDeliveredMessages } from "./session-context.js";
46
47
  /**
@@ -52,7 +53,7 @@ import { formatPendingCouncils, recordDeliveredMessages } from "./session-contex
52
53
  * councils are pending, matching the bash behavior).
53
54
  */
54
55
  export function renderPromptContext(opts) {
55
- const { coordRoot, instanceId, sessionId, agentName, sessionNameNudge, taskNudge, hostPromptReminder: promptReminderEnabled, statusFooterNudge, turnRitualNudge, adapter, } = opts;
56
+ const { coordRoot, instanceId, sessionId, agentName, sessionNameNudge, taskNudge, hostPromptReminder: promptReminderEnabled, statusFooterNudge, turnRitualNudge, } = opts;
56
57
  const sections = [];
57
58
  // The hook route does not pass --name, so resolve it from the heartbeat.
58
59
  // Every name-addressed section below (messages, councils) is silently
@@ -62,12 +63,7 @@ export function renderPromptContext(opts) {
62
63
  // exactly once, and it is the one section here that carries new information
63
64
  // from another agent rather than a reminder.
64
65
  //
65
- // Draining is gated on the adapter being able to receive this event's
66
- // context. Cursor cannot, so draining there would empty the queue into output
67
- // that is discarded; those sessions get their messages at SessionStart, which
68
- // Cursor does deliver.
69
- const canDeliverHere = !adapter || canReceiveContext(adapter, "UserPromptSubmit");
70
- if (resolvedName && canDeliverHere) {
66
+ if (resolvedName) {
71
67
  const delivered = drainMailbox(coordRoot, resolvedName);
72
68
  if (delivered.length > 0) {
73
69
  recordDeliveredMessages(instanceId, delivered);
@@ -78,6 +74,9 @@ export function renderPromptContext(opts) {
78
74
  const peerTable = computePeerTableIfChanged(coordRoot, instanceId, sessionId);
79
75
  if (peerTable)
80
76
  sections.push(peerTable);
77
+ const resources = resourceWarningIfChanged(coordRoot, instanceId);
78
+ if (resources)
79
+ sections.push(resources);
81
80
  // 3. Council pending with hash dedup.
82
81
  if (resolvedName) {
83
82
  const councilMsg = computeCouncilPendingIfChanged(coordRoot, instanceId, resolvedName);
@@ -123,6 +122,62 @@ export function renderPromptContext(opts) {
123
122
  }
124
123
  return sections.join("\n\n");
125
124
  }
125
+ /**
126
+ * Prompts receive the published assessment, and only when it changes in a way
127
+ * that changes what an agent should do. The dedupe key is scope, state, and
128
+ * recommended action, so a moving number or a different contributor does not
129
+ * re-emit the same advice.
130
+ */
131
+ export function resourceWarningIfChanged(coordRoot, instanceId) {
132
+ try {
133
+ heartbeatPath(coordRoot, instanceId);
134
+ const status = readResourceStatus(coordRoot);
135
+ const assessment = status.assessment;
136
+ const hashFile = join(coordRoot, ".harnery", `.last-resource-hash.${instanceId}`);
137
+ const previous = safeRead(hashFile);
138
+ // Existing users without an observer should retain ordinary coordination.
139
+ if (status.assessment_capability.reason_code === "pressure_record_missing" && !previous) {
140
+ return "";
141
+ }
142
+ const key = `${assessment.scope}:${assessment.state}:${assessment.recommended_action}`;
143
+ if (previous === key)
144
+ return "";
145
+ writeHashFile(hashFile, key);
146
+ const warning = assessment.state === "elevated" || assessment.state === "critical";
147
+ const wasWarning = !!previous && (previous.includes(":elevated:") || previous.includes(":critical:"));
148
+ if (!warning && !wasWarning)
149
+ return "";
150
+ const lines = [`Resource update: ${assessment.summary}`];
151
+ if (assessment.state === "unknown") {
152
+ lines.push("Resource headroom cannot be measured right now, so continue normal coordination and judge heavy work yourself.");
153
+ }
154
+ else if (!warning && wasWarning) {
155
+ lines.push("The previously reported resource warning has cleared.");
156
+ }
157
+ for (const item of assessment.guidance) {
158
+ lines.push(`${WORKLOAD_LABEL[item.workload_class]}: ${item.summary}`);
159
+ }
160
+ const owners = assessment.contributors
161
+ .filter((row) => row.attribution_confidence === "exact" && row.owner_id)
162
+ .slice(0, 3)
163
+ .map((row) => `${row.owner_kind ?? "owner"} ${row.owner_id}`);
164
+ if (owners.length) {
165
+ lines.push(`Measured owners of the contended resource: ${owners.join(", ")}. That says who is holding it, not what the machine as a whole can take.`);
166
+ }
167
+ lines.push(`Read \`${resolveBinName(coordRoot)} resources status --json\` for the evidence behind this.`);
168
+ return lines.join("\n");
169
+ }
170
+ catch {
171
+ return "";
172
+ }
173
+ }
174
+ /** How an agent recognizes the work each guidance entry is about. */
175
+ const WORKLOAD_LABEL = {
176
+ lightweight: "Reads and small edits",
177
+ "cpu-heavy": "Builds and test runs",
178
+ "memory-heavy": "Browser captures and page QA",
179
+ "storage-heavy": "Large writes and exports",
180
+ };
126
181
  function renderHostPromptReminder(coordRoot, selfInstanceId) {
127
182
  const hb = readLiveCoordinationRow(coordRoot, selfInstanceId);
128
183
  if (!hb || hb.kind === "subagent" || hb.kind === "transient" || hb.workflow_run_id)
@@ -1,9 +1,9 @@
1
- import type { Adapter } from "../adapter.js";
1
+ import type { EventAdapterIdV3 } from "../events/v3/adapter-id.js";
2
2
  import type { EventV3 } from "../events/v3/contract.js";
3
3
  import { type SessionFinalizationRequestV3 } from "./session-finalization-state-v3.js";
4
4
  export { listSessionFinalizationRequestsV3, type SessionFinalizationRequestV3, type SessionFinalizationTriggerV3, } from "./session-finalization-state-v3.js";
5
5
  export interface SessionArchiveObservationV3 {
6
- adapter: Adapter;
6
+ adapter: EventAdapterIdV3;
7
7
  native_session_id: string;
8
8
  archived: boolean;
9
9
  observed_at: string;
@@ -1 +1 @@
1
- {"version":3,"file":"session-finalizer-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-finalizer-v3.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAmBxD,OAAO,EAIL,KAAK,4BAA4B,EAIlC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,iCAAiC,EACjC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,GAClC,MAAM,oCAAoC,CAAC;AAK5C,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qCAAqC;IACpD,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,oBAAoB,CAAC,EAAE,SAAS,2BAA2B,EAAE,CAAC;CAC/D;AAED,MAAM,WAAW,oCAAoC;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC;IAC9B,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,4BAA4B,CAAC,SAAS,CAAC,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,gCAAiC,SAAQ,yBAAyB;CAAG;AAEtF,MAAM,MAAM,iCAAiC,GACzC,UAAU,CAAC,OAAO,oBAAoB,CAAC,GACvC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,wBAAwB,CAAA;CAAE,GACnC;IAAE,KAAK,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,4BAA4B,CAAA;CAAE,GAC1D;IACE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,OAAO,EAAE,4BAA4B,CAAC;IACtC,oIAAoI;IACpI,OAAO,EAAE;QACP,aAAa,EAAE,QAAQ,MAAM,EAAE,EAAE,CAAC;QAClC,iBAAiB,EAAE,OAAO,CAAC;QAC3B,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,CAAC;AAEN,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC;IAC9B,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB;;;;;;;;;;;;;;;;;EA6BpE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gCAAgC,GACtC,iCAAiC,CA8DnC;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAIzE;AAED,qFAAqF;AACrF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B;;;;;;;;;;;;;;;;;;;;EAiC5E;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,qCAA0C,GAClD,oCAAoC,CAmOtC"}
1
+ {"version":3,"file":"session-finalizer-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-finalizer-v3.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAmBxD,OAAO,EAIL,KAAK,4BAA4B,EAIlC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,iCAAiC,EACjC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,GAClC,MAAM,oCAAoC,CAAC;AAK5C,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qCAAqC;IACpD,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,oBAAoB,CAAC,EAAE,SAAS,2BAA2B,EAAE,CAAC;CAC/D;AAED,MAAM,WAAW,oCAAoC;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC;IAC9B,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,4BAA4B,CAAC,SAAS,CAAC,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,gCAAiC,SAAQ,yBAAyB;CAAG;AAEtF,MAAM,MAAM,iCAAiC,GACzC,UAAU,CAAC,OAAO,oBAAoB,CAAC,GACvC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,wBAAwB,CAAA;CAAE,GACnC;IAAE,KAAK,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,4BAA4B,CAAA;CAAE,GAC1D;IACE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,OAAO,EAAE,4BAA4B,CAAC;IACtC,oIAAoI;IACpI,OAAO,EAAE;QACP,aAAa,EAAE,QAAQ,MAAM,EAAE,EAAE,CAAC;QAClC,iBAAiB,EAAE,OAAO,CAAC;QAC3B,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,CAAC;AAEN,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC;IAC9B,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB;;;;;;;;;;;;;;;;;EA6BpE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gCAAgC,GACtC,iCAAiC,CA8DnC;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAIzE;AAED,qFAAqF;AACrF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B;;;;;;;;;;;;;;;;;;;;EAiC5E;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,qCAA0C,GAClD,oCAAoC,CAmOtC"}
@@ -1,4 +1,4 @@
1
- import type { Adapter } from "../../adapter.js";
1
+ import { type EventAdapterIdV3 } from "../../events/v3/adapter-id.js";
2
2
  import { type CoordinationGenerationViewV3 } from "../../events/v3/coordination-view.js";
3
3
  import { type Heartbeat } from "./heartbeat-reader.js";
4
4
  /**
@@ -21,9 +21,9 @@ export declare function readLiveCoordinationRow(coordRoot: string, nativeInstanc
21
21
  * V3 generation is stronger evidence than a missing or stale heartbeat, so
22
22
  * callers must never substitute another adapter when this function succeeds.
23
23
  */
24
- export declare function liveCoordinationAdapterV3(coordRoot: string, nativeInstanceId: string): Adapter | null;
24
+ export declare function liveCoordinationAdapterV3(coordRoot: string, nativeInstanceId: string): EventAdapterIdV3 | null;
25
25
  export declare function isCurrentV3HeartbeatCache(cache: Heartbeat | null | undefined, generation: CoordinationGenerationViewV3): cache is Heartbeat;
26
26
  export declare function projectHeartbeatV3(coordRoot: string, generation: CoordinationGenerationViewV3, cache: Heartbeat | undefined, nativeInstanceId: string | undefined, parent?: CoordinationGenerationViewV3): V3HeartbeatMaterialization;
27
27
  export declare function observedAdapterV3(generation: CoordinationGenerationViewV3): string | undefined;
28
- export declare function isAdapterV3(value: string | undefined): value is Adapter;
28
+ export declare function isAdapterV3(value: string | undefined): value is EventAdapterIdV3;
29
29
  //# sourceMappingURL=live-coordination-view.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EACL,KAAK,4BAA4B,EAIlC,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAGtE;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,SAAS;IAC3D,cAAc,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CA2BxF;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,0BAA0B,GAAG,IAAI,CAuBnC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,OAAO,GAAG,IAAI,CAWhB;AA8BD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,UAAU,EAAE,4BAA4B,GACvC,KAAK,IAAI,SAAS,CAMpB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,4BAA4B,EACxC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,MAAM,CAAC,EAAE,4BAA4B,GACpC,0BAA0B,CAsD5B;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,4BAA4B,GAAG,MAAM,GAAG,SAAS,CAG9F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,OAAO,CAEvE"}
1
+ {"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EACL,KAAK,4BAA4B,EAIlC,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAGtE;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,SAAS;IAC3D,cAAc,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CA2BxF;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,0BAA0B,GAAG,IAAI,CAuBnC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,gBAAgB,GAAG,IAAI,CAWzB;AA8BD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,UAAU,EAAE,4BAA4B,GACvC,KAAK,IAAI,SAAS,CAMpB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,4BAA4B,EACxC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,MAAM,CAAC,EAAE,4BAA4B,GACpC,0BAA0B,CAsD5B;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,4BAA4B,GAAG,MAAM,GAAG,SAAS,CAG9F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAEhF"}
@@ -1,5 +1,6 @@
1
1
  import { existsSync, readdirSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { EVENT_ADAPTER_IDS_V3 } from "../../events/v3/adapter-id.js";
3
4
  import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from "../../events/v3/coordination-view.js";
4
5
  import { liveInstanceIdV3, nativeInstanceIdV3, observeLiveEventLedgerRouteV3, } from "../../events/v3/live-route-observer.js";
5
6
  import { readHeartbeat } from "./heartbeat-reader.js";
@@ -148,7 +149,7 @@ export function observedAdapterV3(generation) {
148
149
  return observation.state === "observed" ? observation.value.id : undefined;
149
150
  }
150
151
  export function isAdapterV3(value) {
151
- return value === "claude-code" || value === "cursor" || value === "codex";
152
+ return EVENT_ADAPTER_IDS_V3.includes(value ?? "");
152
153
  }
153
154
  function observedModel(generation) {
154
155
  const observation = generation.runtime_attestation.model;
@@ -25,10 +25,17 @@
25
25
  * new binding instead of rewriting history; readers therefore resolve from the
26
26
  * end of the file. Older one-row histories retain their original behavior.
27
27
  * 3. Else: new assignment, consume a counter slot.
28
+ *
29
+ * Live-name skip: the pool holds 260 names and a busy repo consumes ~100 a
30
+ * day, so the counter wraps roughly every three days while sessions that
31
+ * resume under a stable instance_id keep a name for far longer. A counter-only
32
+ * pick therefore hands a live agent's name to a new one (observed 2026-09-06:
33
+ * two concurrent "Maya" agents, their pool slots exactly 520 apart). Assignment
34
+ * now probes forward past any name a fresh heartbeat still holds.
28
35
  */
29
36
  /** All 260 names. */
30
37
  export declare const COORD_NAMES: readonly ["Anna", "Bob", "Carmen", "Dorian", "Erika", "Fred", "Gemma", "Hank", "Imelda", "Jerry", "Karen", "Lorenzo", "Mindy", "Nate", "Odette", "Peter", "Quinn", "Rafael", "Sara", "Tony", "Ursula", "Vinson", "Whitney", "Xander", "Yara", "Zane", "Alex", "Bertha", "Carlos", "Dalia", "Ernesto", "Francine", "Gordon", "Helene", "Isaias", "Joyce", "Kirk", "Lucia", "Milton", "Nadine", "Oscar", "Patty", "Quentin", "Rebekah", "Sean", "Tammy", "Ulrik", "Valerie", "Wallace", "Xanthe", "Yusuf", "Zara", "Adelaide", "Bruno", "Cora", "Damon", "Edna", "Felix", "Greta", "Hugo", "Ines", "Jasper", "Kaia", "Larry", "Maxine", "Nicholas", "Olive", "Paxton", "Querida", "Roman", "Stella", "Tobias", "Una", "Virgil", "Willow", "Xavier", "Yolanda", "Zephyr", "Aaron", "Beatrice", "Cyrus", "Delia", "Elias", "Florence", "Galileo", "Hester", "Ian", "Jenna", "Klaus", "Linda", "Marco", "Nora", "Otto", "Paulette", "Quill", "Renee", "Sebastian", "Theresa", "Umberto", "Vera", "Walter", "Xena", "Yves", "Zoe", "Anita", "Beau", "Celeste", "Dexter", "Edith", "Fitz", "Gloria", "Hadley", "Iris", "Jude", "Kira", "Leo", "Maya", "Nash", "Olga", "Phillip", "Quetzal", "Royce", "Sage", "Trent", "Uma", "Vincent", "Wynne", "Xerxes", "Yvette", "Zoltan", "Andre", "Bonnie", "Caleb", "Daphne", "Ezra", "Fiona", "Gibson", "Holly", "Ivan", "Juno", "Knox", "Lila", "Mason", "Nila", "Owen", "Petra", "Quincy", "Rosa", "Sterling", "Talia", "Uri", "Violet", "Wesley", "Ximena", "Yuri", "Zelda", "Astrid", "Boris", "Cassidy", "Davis", "Esme", "Forrest", "Genevieve", "Henry", "Imogen", "Joaquin", "Kestrel", "Luther", "Margot", "Nigel", "Ophelia", "Percy", "Quenby", "Reagan", "Sienna", "Truman", "Undine", "Voss", "Wren", "Xan", "Yael", "Zia", "Arthur", "Bianca", "Cody", "Dahlia", "Evander", "Fern", "Gustavo", "Harriet", "Ira", "Josephine", "Kendrick", "Lainey", "Miles", "Naomi", "Orion", "Pearl", "Quark", "Rylie", "Saul", "Tessa", "Ulysses", "Vesper", "Wyatt", "Xiomara", "Yancy", "Zinnia", "Amelia", "Barnaby", "Calliope", "Drake", "Estelle", "Foster", "Greer", "Hollis", "Irene", "Jericho", "Klara", "Logan", "Mavis", "Nico", "Oakley", "Pascal", "Quito", "Rhett", "Scout", "Theron", "Unity", "Vance", "Winifred", "Xola", "Yvonne", "Zev", "Atticus", "Brenda", "Crispin", "Dolores", "Eustace", "Felicity", "Granger", "Hazel", "Idris", "Jovi", "Kasper", "Lyric", "Magnus", "Noor", "Otis", "Phoebe", "Querubin", "Rosalind", "Silas", "Tatum", "Upton", "Vivian", "Wendell", "Xuxa", "Yann", "Zora"];
31
- export type NameKind = "session" | "subagent" | "transient";
38
+ export type NameKind = "session" | "subagent" | "transient" | "workflow-child";
32
39
  export interface NameHistoryRow {
33
40
  instance_id: string;
34
41
  name: string;
@@ -74,12 +81,38 @@ export interface NameAssumptionResult {
74
81
  * this auditable and retry-safe without mutating prior assignment history.
75
82
  */
76
83
  export declare function recordNameAssumption(coordRoot: string, instanceId: string, name: string, agentId: string, kind?: NameKind): NameAssumptionResult;
84
+ /**
85
+ * Names a live agent currently holds, read from the generation-bound heartbeat
86
+ * cache (`.harnery/active/<instance>.json`).
87
+ *
88
+ * Deliberately reads the cache directly rather than the V3 coordination view:
89
+ * that view imports `resolveName` from this module, so depending on it here
90
+ * would build an import cycle. The cache is the same set the view materializes
91
+ * from and is pruned as sessions end, so it answers "is this name taken right
92
+ * now" without one.
93
+ *
94
+ * Both error directions are safe for the caller. A stale row that slips past
95
+ * the freshness window costs one skipped pool slot; a live agent missing from
96
+ * the cache just restores the old counter-only behavior for that assignment.
97
+ */
98
+ export declare function readLiveNames(coordRoot: string, opts: {
99
+ freshnessSecs: number;
100
+ nowMs?: number;
101
+ }): Set<string>;
77
102
  /**
78
103
  * Assign a name to <instanceId> with the given <kind>. Counter-consuming when
79
104
  * the owner is new. Idempotent: returns existing name on resume.
105
+ *
106
+ * Slot choice probes forward from the counter and takes the first name no live
107
+ * agent holds, then advances the counter past every slot it skipped so the skip
108
+ * is durable rather than re-probed on the next assignment. A full lap without a
109
+ * free name means all 260 are genuinely live, so the raw counter slot is used:
110
+ * a duplicate name beats refusing to name an agent at all.
80
111
  */
81
- export declare function assignName(coordRoot: string, instanceId: string, kind: NameKind, opts?: {
112
+ export declare function assignName(coordRoot: string, instanceId: string, kind: NameKind, opts: {
113
+ freshnessSecs: number;
82
114
  forkedFrom?: string;
115
+ nowMs?: number;
83
116
  }): string;
84
117
  /** One step of recorded fork lineage: the latest row for <instanceId> that
85
118
  * carries `forked_from` (latest-row-wins, matching resolveName). */
@@ -1 +1 @@
1
- {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAKH,qBAAqB;AACrB,eAAO,MAAM,WAAW,85EA+Qd,CAAC;AAMX,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;2DAEuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAsCD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4B5D;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,QAAoB,GACzB,oBAAoB,CAoBtB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,QAAQ,EACd,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7B,MAAM,CA0BR;AAED;oEACoE;AACpE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAUrD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAYrD"}
1
+ {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAYH,qBAAqB;AACrB,eAAO,MAAM,WAAW,85EA+Qd,CAAC;AAMX,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAE/E,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;2DAEuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAsCD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4B5D;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,QAAoB,GACzB,oBAAoB,CAoBtB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,GAAG,CAAC,MAAM,CAAC,CA4Bb;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACnE,MAAM,CA4CR;AAED;oEACoE;AACpE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAUrD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAYrD"}
@@ -25,8 +25,15 @@
25
25
  * new binding instead of rewriting history; readers therefore resolve from the
26
26
  * end of the file. Older one-row histories retain their original behavior.
27
27
  * 3. Else: new assignment, consume a counter slot.
28
+ *
29
+ * Live-name skip: the pool holds 260 names and a busy repo consumes ~100 a
30
+ * day, so the counter wraps roughly every three days while sessions that
31
+ * resume under a stable instance_id keep a name for far longer. A counter-only
32
+ * pick therefore hands a live agent's name to a new one (observed 2026-09-06:
33
+ * two concurrent "Maya" agents, their pool slots exactly 520 apart). Assignment
34
+ * now probes forward past any name a fresh heartbeat still holds.
28
35
  */
29
- import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
36
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
30
37
  import { dirname, join } from "node:path";
31
38
  /** All 260 names. */
32
39
  export const COORD_NAMES = [
@@ -393,9 +400,62 @@ export function recordNameAssumption(coordRoot, instanceId, name, agentId, kind
393
400
  });
394
401
  return { changed: true, previous, current };
395
402
  }
403
+ /**
404
+ * Names a live agent currently holds, read from the generation-bound heartbeat
405
+ * cache (`.harnery/active/<instance>.json`).
406
+ *
407
+ * Deliberately reads the cache directly rather than the V3 coordination view:
408
+ * that view imports `resolveName` from this module, so depending on it here
409
+ * would build an import cycle. The cache is the same set the view materializes
410
+ * from and is pruned as sessions end, so it answers "is this name taken right
411
+ * now" without one.
412
+ *
413
+ * Both error directions are safe for the caller. A stale row that slips past
414
+ * the freshness window costs one skipped pool slot; a live agent missing from
415
+ * the cache just restores the old counter-only behavior for that assignment.
416
+ */
417
+ export function readLiveNames(coordRoot, opts) {
418
+ const live = new Set();
419
+ const dir = join(coordRoot, ".harnery", "active");
420
+ let entries;
421
+ try {
422
+ entries = readdirSync(dir);
423
+ }
424
+ catch {
425
+ return live; // No cache yet (fresh checkout) → nothing is live.
426
+ }
427
+ const nowMs = opts.nowMs ?? Date.now();
428
+ const cutoffMs = nowMs - opts.freshnessSecs * 1000;
429
+ for (const entry of entries) {
430
+ if (!entry.endsWith(".json"))
431
+ continue;
432
+ let row;
433
+ try {
434
+ row = JSON.parse(readFileSync(join(dir, entry), "utf8"));
435
+ }
436
+ catch {
437
+ continue; // A torn or half-written row cannot prove a name is held.
438
+ }
439
+ if (typeof row.name !== "string" || row.name.length === 0)
440
+ continue;
441
+ if (typeof row.last_heartbeat !== "string")
442
+ continue;
443
+ const beatMs = Date.parse(row.last_heartbeat);
444
+ if (!Number.isFinite(beatMs) || beatMs < cutoffMs)
445
+ continue;
446
+ live.add(row.name);
447
+ }
448
+ return live;
449
+ }
396
450
  /**
397
451
  * Assign a name to <instanceId> with the given <kind>. Counter-consuming when
398
452
  * the owner is new. Idempotent: returns existing name on resume.
453
+ *
454
+ * Slot choice probes forward from the counter and takes the first name no live
455
+ * agent holds, then advances the counter past every slot it skipped so the skip
456
+ * is durable rather than re-probed on the next assignment. A full lap without a
457
+ * free name means all 260 are genuinely live, so the raw counter slot is used:
458
+ * a duplicate name beats refusing to name an agent at all.
399
459
  */
400
460
  export function assignName(coordRoot, instanceId, kind, opts) {
401
461
  // Check 1: existing history row → original name. A resume re-enters here,
@@ -404,7 +464,14 @@ export function assignName(coordRoot, instanceId, kind, opts) {
404
464
  const existing = resolveName(coordRoot, instanceId);
405
465
  if (existing)
406
466
  return existing.name;
407
- // New owner: consume a counter slot.
467
+ // New owner: consume a counter slot. The live set is gathered BEFORE the
468
+ // counter read on purpose. Counter read-modify-write is already unlocked, so
469
+ // concurrent assignments can collide on one slot; doing the directory scan
470
+ // first keeps that window exactly as narrow as it was before the skip existed.
471
+ const live = readLiveNames(coordRoot, {
472
+ freshnessSecs: opts.freshnessSecs,
473
+ ...(opts.nowMs !== undefined ? { nowMs: opts.nowMs } : {}),
474
+ });
408
475
  const cPath = counterPath(coordRoot);
409
476
  let counter = 0;
410
477
  if (existsSync(cPath)) {
@@ -412,9 +479,17 @@ export function assignName(coordRoot, instanceId, kind, opts) {
412
479
  if (/^\d+$/.test(raw))
413
480
  counter = Number.parseInt(raw, 10);
414
481
  }
415
- const name = COORD_NAMES[counter % 260];
416
- atomicWrite(cPath, String(counter + 1));
417
- const forkedFrom = opts?.forkedFrom;
482
+ let chosen = counter;
483
+ for (let probe = 0; probe < 260; probe++) {
484
+ const candidate = COORD_NAMES[(counter + probe) % 260];
485
+ if (!live.has(candidate)) {
486
+ chosen = counter + probe;
487
+ break;
488
+ }
489
+ }
490
+ const name = COORD_NAMES[chosen % 260];
491
+ atomicWrite(cPath, String(chosen + 1));
492
+ const forkedFrom = opts.forkedFrom;
418
493
  appendHistory(coordRoot, {
419
494
  instance_id: instanceId,
420
495
  name,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Stale-sweep: prune dead heartbeats + orphaned pid-map + .last-peer-hash
2
+ * Stale-sweep: prune dead heartbeats + orphaned pid-map + prompt hash
3
3
  * files.
4
4
  *
5
5
  * Runs after session.started to clean up crashed-peer detritus before the new
@@ -13,5 +13,6 @@ export declare function staleSweep(coordRoot: string): {
13
13
  heartbeatsRemoved: string[];
14
14
  pidmapsRemoved: number;
15
15
  peerHashesRemoved: number;
16
+ resourceHashesRemoved: number;
16
17
  };
17
18
  //# sourceMappingURL=stale-sweep.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stale-sweep.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/stale-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAuEH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG;IAC7C,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CA8IA"}
1
+ {"version":3,"file":"stale-sweep.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/stale-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAyEH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG;IAC7C,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAyJA"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Stale-sweep: prune dead heartbeats + orphaned pid-map + .last-peer-hash
2
+ * Stale-sweep: prune dead heartbeats + orphaned pid-map + prompt hash
3
3
  * files.
4
4
  *
5
5
  * Runs after session.started to clean up crashed-peer detritus before the new
@@ -20,6 +20,8 @@ function adapterFromPlatform(platform) {
20
20
  return "cursor";
21
21
  if (platform === "codex")
22
22
  return "codex";
23
+ if (platform === "openclaw")
24
+ return "openclaw";
23
25
  return "claude-code";
24
26
  }
25
27
  /**
@@ -72,6 +74,7 @@ export function staleSweep(coordRoot) {
72
74
  const heartbeatsRemoved = [];
73
75
  let pidmapsRemoved = 0;
74
76
  let peerHashesRemoved = 0;
77
+ let resourceHashesRemoved = 0;
75
78
  const freshness = coordFreshnessSeconds(coordRoot);
76
79
  const nowSec = Math.floor(Date.now() / 1000);
77
80
  const cutoff = nowSec - freshness;
@@ -173,17 +176,31 @@ export function staleSweep(coordRoot) {
173
176
  }
174
177
  }
175
178
  }
176
- // 3. Prune .last-peer-hash files for dead owners.
179
+ // 3. Prune prompt hashes for dead owners. Resource hashes retain their own
180
+ // count so existing peer-hash telemetry keeps its original meaning.
177
181
  const agentsDir = join(coordRoot, ".harnery");
178
182
  if (existsSync(agentsDir)) {
179
183
  for (const f of readdirSync(agentsDir)) {
180
- if (!f.startsWith(".last-peer-hash."))
184
+ const resourceHash = f.startsWith(".last-resource-hash.");
185
+ const prefix = resourceHash ? ".last-resource-hash." : ".last-peer-hash.";
186
+ if (!f.startsWith(prefix))
181
187
  continue;
182
- const owner = f.slice(".last-peer-hash.".length);
188
+ const owner = f.slice(prefix.length);
189
+ if (resourceHash) {
190
+ // Ignore atomic-write temporary files and preserve hashes when a
191
+ // retained heartbeat's liveness could not be determined safely.
192
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(owner))
193
+ continue;
194
+ if (existsSync(join(d, `${owner}.json`)))
195
+ continue;
196
+ }
183
197
  if (!liveInstanceIds.has(owner)) {
184
198
  try {
185
199
  unlinkSync(join(agentsDir, f));
186
- peerHashesRemoved += 1;
200
+ if (resourceHash)
201
+ resourceHashesRemoved += 1;
202
+ else
203
+ peerHashesRemoved += 1;
187
204
  }
188
205
  catch {
189
206
  /* swallow */
@@ -191,5 +208,5 @@ export function staleSweep(coordRoot) {
191
208
  }
192
209
  }
193
210
  }
194
- return { heartbeatsRemoved, pidmapsRemoved, peerHashesRemoved };
211
+ return { heartbeatsRemoved, pidmapsRemoved, peerHashesRemoved, resourceHashesRemoved };
195
212
  }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * How long the current turn has been running, for the closing status box.
3
+ *
4
+ * The box already reports `session`, which is cumulative and says nothing
5
+ * about the work just done: a 9-minute session hides whether this turn took
6
+ * twelve seconds or eight minutes. `turn` measures from the operator's prompt
7
+ * (`turn.started`) to the moment the box renders, so the operator reads the
8
+ * cost of the turn they are about to be handed.
9
+ *
10
+ * Every read here is best-effort by contract. A missing ledger, an
11
+ * unvalidated one, or no `turn.started` for this owner renders no row rather
12
+ * than failing the status command.
13
+ */
14
+ import type { EventV3 } from "../events/v3/contract.js";
15
+ export interface TurnElapsed {
16
+ /** Seconds from the turn's start to its terminal, or to `now` while open. */
17
+ secs: number;
18
+ /** True once a `turn.completed` closed the turn this measures. */
19
+ complete: boolean;
20
+ /** Stop-hook restarts folded into this measurement. */
21
+ remediation_restarts: number;
22
+ }
23
+ /**
24
+ * Measure the newest turn for `instanceId` from an already-read event stream.
25
+ *
26
+ * A Stop-hook bounce ends one `turn.started` and opens another carrying
27
+ * `stop_remediation`. The operator experiences those as one turn, so the walk
28
+ * back over remediation restarts reports elapsed time since their prompt, not
29
+ * since the last retry. The walk stays inside one generation: a resumed
30
+ * session must not absorb the previous generation's turn into its own.
31
+ */
32
+ export declare function resolveTurnElapsed(events: readonly EventV3[], instanceId: string, now?: number): TurnElapsed | null;
33
+ /**
34
+ * Render a turn duration for the box. Seconds stay visible below an hour
35
+ * because most turns land there and a bare `4m` cannot be compared with the
36
+ * turn before it.
37
+ */
38
+ export declare function formatTurnElapsed(secs: number): string;
39
+ export interface TurnElapsedTarget {
40
+ coordRoot: string;
41
+ instanceId: string;
42
+ }
43
+ /**
44
+ * The whole status-box contribution in one best-effort call: read the ledger
45
+ * and render this session's `turn` row. Null means render no row.
46
+ */
47
+ export declare function turnElapsedStatusRow(target: TurnElapsedTarget, now?: number): {
48
+ value: string;
49
+ elapsed: TurnElapsed;
50
+ } | null;
51
+ //# sourceMappingURL=turn-elapsed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-elapsed.d.ts","sourceRoot":"","sources":["../../../src/core/agents/turn-elapsed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAOxD,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,QAAQ,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAWD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,MAAmB,GACvB,WAAW,GAAG,IAAI,CA0CpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,EACzB,GAAG,GAAE,MAAmB,GACvB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG,IAAI,CAchD"}