jg-agent-hq 1.0.0 → 2.0.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 (390) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +58 -16
  3. package/api/README.md +365 -73
  4. package/dist/accounts/accounts.d.ts +21 -0
  5. package/dist/accounts/accounts.js +37 -0
  6. package/dist/accounts/index.d.ts +1 -0
  7. package/dist/accounts/index.js +2 -0
  8. package/dist/actions/actions.d.ts +59 -6
  9. package/dist/actions/actions.js +558 -372
  10. package/dist/actions/live/live.d.ts +2 -0
  11. package/dist/actions/live/live.js +11 -1
  12. package/dist/actions/reads.d.ts +6 -1
  13. package/dist/actions/reads.js +33 -2
  14. package/dist/agent-tools/agent-tools.d.ts +6 -0
  15. package/dist/agent-tools/agent-tools.js +181 -0
  16. package/dist/agent-tools/constants.d.ts +7 -0
  17. package/dist/agent-tools/constants.js +45 -0
  18. package/dist/agent-tools/index.d.ts +4 -0
  19. package/dist/agent-tools/index.js +4 -0
  20. package/dist/agent-tools/mcp/index.d.ts +1 -0
  21. package/dist/agent-tools/mcp/index.js +2 -0
  22. package/dist/agent-tools/mcp/mcp.d.ts +7 -0
  23. package/dist/agent-tools/mcp/mcp.js +50 -0
  24. package/dist/agent-tools/types.d.ts +64 -0
  25. package/dist/agent-tools/types.js +1 -0
  26. package/dist/agent-tools/utilities.d.ts +13 -0
  27. package/dist/agent-tools/utilities.js +37 -0
  28. package/dist/cli/cli.js +36 -41
  29. package/dist/collaboration/collaboration.d.ts +7 -0
  30. package/dist/collaboration/collaboration.js +119 -0
  31. package/dist/collaboration/constants.d.ts +2 -0
  32. package/dist/collaboration/constants.js +3 -0
  33. package/dist/collaboration/dispatch/dispatch.d.ts +12 -0
  34. package/dist/collaboration/dispatch/dispatch.js +148 -0
  35. package/dist/collaboration/dispatch/index.d.ts +3 -0
  36. package/dist/collaboration/dispatch/index.js +4 -0
  37. package/dist/collaboration/dispatch/types.d.ts +632 -0
  38. package/dist/collaboration/dispatch/types.js +44 -0
  39. package/dist/collaboration/grants/grants.d.ts +45 -0
  40. package/dist/collaboration/grants/grants.js +131 -0
  41. package/dist/collaboration/grants/index.d.ts +1 -0
  42. package/dist/collaboration/grants/index.js +2 -0
  43. package/dist/collaboration/identity/credentials.d.ts +17 -0
  44. package/dist/collaboration/identity/credentials.js +182 -0
  45. package/dist/collaboration/identity/index.d.ts +4 -0
  46. package/dist/collaboration/identity/index.js +4 -0
  47. package/dist/collaboration/identity/types.d.ts +171 -0
  48. package/dist/collaboration/identity/types.js +87 -0
  49. package/dist/collaboration/index.d.ts +3 -0
  50. package/dist/collaboration/index.js +3 -0
  51. package/dist/collaboration/types.d.ts +25 -0
  52. package/dist/collaboration/types.js +1 -0
  53. package/dist/contracts/accounts/index.d.ts +4 -0
  54. package/dist/contracts/accounts/index.js +3 -0
  55. package/dist/contracts/accounts/types.d.ts +66 -0
  56. package/dist/contracts/accounts/types.js +57 -0
  57. package/dist/contracts/actions/index.d.ts +2 -2
  58. package/dist/contracts/actions/index.js +1 -1
  59. package/dist/contracts/actions/types.d.ts +536 -60
  60. package/dist/contracts/actions/types.js +99 -19
  61. package/dist/contracts/agent-tools/index.d.ts +2 -0
  62. package/dist/contracts/agent-tools/index.js +2 -0
  63. package/dist/contracts/agent-tools/types.d.ts +695 -0
  64. package/dist/contracts/agent-tools/types.js +125 -0
  65. package/dist/contracts/browser/types.d.ts +507 -187
  66. package/dist/contracts/browser/types.js +0 -3
  67. package/dist/contracts/collaboration/index.d.ts +4 -0
  68. package/dist/contracts/collaboration/index.js +4 -0
  69. package/dist/contracts/collaboration/reports/constants.d.ts +1 -0
  70. package/dist/contracts/collaboration/reports/constants.js +2 -0
  71. package/dist/contracts/collaboration/reports/index.d.ts +3 -0
  72. package/dist/contracts/collaboration/reports/index.js +3 -0
  73. package/dist/contracts/collaboration/reports/types.d.ts +69 -0
  74. package/dist/contracts/collaboration/reports/types.js +53 -0
  75. package/dist/contracts/collaboration/types.d.ts +6734 -0
  76. package/dist/contracts/collaboration/types.js +696 -0
  77. package/dist/contracts/configuration/index.d.ts +2 -0
  78. package/dist/contracts/configuration/index.js +2 -0
  79. package/dist/contracts/configuration/types.d.ts +69 -0
  80. package/dist/contracts/configuration/types.js +56 -0
  81. package/dist/contracts/evidence/index.d.ts +2 -0
  82. package/dist/contracts/evidence/index.js +2 -0
  83. package/dist/contracts/evidence/types.d.ts +160 -0
  84. package/dist/contracts/evidence/types.js +74 -0
  85. package/dist/contracts/extensions/index.d.ts +4 -0
  86. package/dist/contracts/extensions/index.js +3 -0
  87. package/dist/contracts/extensions/types.d.ts +150 -0
  88. package/dist/contracts/extensions/types.js +93 -0
  89. package/dist/contracts/identities/index.d.ts +2 -1
  90. package/dist/contracts/identities/index.js +1 -1
  91. package/dist/contracts/identities/types.d.ts +7 -0
  92. package/dist/contracts/identities/types.js +8 -0
  93. package/dist/contracts/index.d.ts +29 -4
  94. package/dist/contracts/index.js +25 -3
  95. package/dist/contracts/inputs/index.d.ts +2 -0
  96. package/dist/contracts/inputs/index.js +2 -0
  97. package/dist/contracts/inputs/types.d.ts +30 -0
  98. package/dist/contracts/inputs/types.js +21 -0
  99. package/dist/contracts/models/index.d.ts +2 -0
  100. package/dist/contracts/models/index.js +2 -0
  101. package/dist/contracts/models/types.d.ts +34 -0
  102. package/dist/contracts/models/types.js +28 -0
  103. package/dist/contracts/plans/types.d.ts +37 -17
  104. package/dist/contracts/plans/types.js +6 -2
  105. package/dist/contracts/providers/index.d.ts +2 -0
  106. package/dist/contracts/providers/index.js +2 -0
  107. package/dist/contracts/providers/types.d.ts +1276 -0
  108. package/dist/contracts/providers/types.js +79 -0
  109. package/dist/contracts/results/index.d.ts +2 -0
  110. package/dist/contracts/results/index.js +2 -0
  111. package/dist/contracts/results/types.d.ts +44 -0
  112. package/dist/contracts/results/types.js +55 -0
  113. package/dist/contracts/skills/types.d.ts +25 -3
  114. package/dist/contracts/skills/types.js +7 -1
  115. package/dist/contracts/types.d.ts +11037 -2516
  116. package/dist/contracts/types.js +75 -22
  117. package/dist/extensions/extensions.d.ts +25 -0
  118. package/dist/extensions/extensions.js +176 -0
  119. package/dist/extensions/index.d.ts +1 -0
  120. package/dist/extensions/index.js +2 -0
  121. package/dist/index.d.ts +11 -0
  122. package/dist/index.js +2 -0
  123. package/dist/ipc/client.d.ts +1 -1
  124. package/dist/ipc/client.js +16 -1
  125. package/dist/locks/locks.js +82 -52
  126. package/dist/plans/admission.d.ts +136 -23
  127. package/dist/plans/admission.js +250 -100
  128. package/dist/plans/authority.js +5 -1
  129. package/dist/plans/documents.d.ts +77 -0
  130. package/dist/plans/documents.js +272 -0
  131. package/dist/plans/files.d.ts +18 -3
  132. package/dist/plans/files.js +97 -52
  133. package/dist/plans/finalization.d.ts +1 -1
  134. package/dist/plans/finalization.js +4 -12
  135. package/dist/plans/plans.d.ts +110 -23
  136. package/dist/plans/plans.js +215 -42
  137. package/dist/plans/reconciliation.d.ts +1 -1
  138. package/dist/plans/reconciliation.js +20 -19
  139. package/dist/plans/types.d.ts +15 -4
  140. package/dist/plans/types.js +11 -3
  141. package/dist/plans/utilities.d.ts +16 -7
  142. package/dist/plans/utilities.js +38 -174
  143. package/dist/providers/claude/accounts/accounts.d.ts +6 -0
  144. package/dist/providers/claude/accounts/accounts.js +41 -0
  145. package/dist/providers/claude/accounts/index.d.ts +1 -0
  146. package/dist/providers/claude/accounts/index.js +2 -0
  147. package/dist/providers/claude/adapter.d.ts +7 -0
  148. package/dist/providers/claude/adapter.js +313 -0
  149. package/dist/providers/claude/authentication/authentication.d.ts +23 -0
  150. package/dist/providers/claude/authentication/authentication.js +67 -0
  151. package/dist/providers/claude/authentication/index.d.ts +1 -0
  152. package/dist/providers/claude/authentication/index.js +2 -0
  153. package/dist/providers/claude/claude.d.ts +82 -2
  154. package/dist/providers/claude/claude.js +110 -14
  155. package/dist/providers/claude/configuration/configuration.d.ts +16 -0
  156. package/dist/providers/claude/configuration/configuration.js +94 -0
  157. package/dist/providers/claude/configuration/index.d.ts +1 -0
  158. package/dist/providers/claude/configuration/index.js +2 -0
  159. package/dist/providers/claude/control/control.d.ts +147 -5
  160. package/dist/providers/claude/control/control.js +310 -60
  161. package/dist/providers/claude/control/permissions.d.ts +1 -1
  162. package/dist/providers/claude/control/permissions.js +86 -3
  163. package/dist/providers/claude/control/stream.js +78 -4
  164. package/dist/providers/claude/control/types.d.ts +14 -5
  165. package/dist/providers/claude/extensions/extensions.d.ts +18 -0
  166. package/dist/providers/claude/extensions/extensions.js +168 -0
  167. package/dist/providers/claude/extensions/index.d.ts +1 -0
  168. package/dist/providers/claude/extensions/index.js +2 -0
  169. package/dist/providers/claude/history/history.model.d.ts +2 -0
  170. package/dist/providers/claude/history/history.model.js +110 -69
  171. package/dist/providers/claude/history/types.d.ts +3604 -370
  172. package/dist/providers/claude/history/types.js +10 -2
  173. package/dist/providers/claude/history/utilities.d.ts +1 -1
  174. package/dist/providers/claude/history/utilities.js +32 -3
  175. package/dist/providers/claude/index.d.ts +1 -0
  176. package/dist/providers/claude/index.js +1 -0
  177. package/dist/providers/claude/models/index.d.ts +1 -0
  178. package/dist/providers/claude/models/index.js +2 -0
  179. package/dist/providers/claude/models/models.d.ts +9 -0
  180. package/dist/providers/claude/models/models.js +67 -0
  181. package/dist/providers/claude/models/types.d.ts +14 -0
  182. package/dist/providers/claude/models/types.js +22 -0
  183. package/dist/providers/claude/rpc.d.ts +15 -3
  184. package/dist/providers/claude/rpc.js +38 -7
  185. package/dist/providers/claude/types.d.ts +4 -11
  186. package/dist/providers/claude/types.js +5 -8
  187. package/dist/providers/codex/accounts/accounts.d.ts +10 -0
  188. package/dist/providers/codex/accounts/accounts.js +48 -0
  189. package/dist/providers/codex/accounts/index.d.ts +1 -0
  190. package/dist/providers/codex/accounts/index.js +2 -0
  191. package/dist/providers/codex/adapter.d.ts +6 -0
  192. package/dist/providers/codex/adapter.js +273 -0
  193. package/dist/providers/codex/approvals/types.d.ts +21 -0
  194. package/dist/providers/codex/approvals/types.js +23 -0
  195. package/dist/providers/codex/approvals/utilities.d.ts +2 -2
  196. package/dist/providers/codex/approvals/utilities.js +53 -30
  197. package/dist/providers/codex/authentication/authentication.d.ts +37 -0
  198. package/dist/providers/codex/authentication/authentication.js +242 -0
  199. package/dist/providers/codex/authentication/index.d.ts +1 -0
  200. package/dist/providers/codex/authentication/index.js +2 -0
  201. package/dist/providers/codex/codex.d.ts +2 -1
  202. package/dist/providers/codex/codex.js +327 -43
  203. package/dist/providers/codex/configuration/configuration.d.ts +44 -0
  204. package/dist/providers/codex/configuration/configuration.js +137 -0
  205. package/dist/providers/codex/configuration/index.d.ts +1 -0
  206. package/dist/providers/codex/configuration/index.js +2 -0
  207. package/dist/providers/codex/events.d.ts +9 -0
  208. package/dist/providers/codex/events.js +214 -0
  209. package/dist/providers/codex/extensions/extensions.d.ts +14 -0
  210. package/dist/providers/codex/extensions/extensions.js +213 -0
  211. package/dist/providers/codex/extensions/index.d.ts +1 -0
  212. package/dist/providers/codex/extensions/index.js +2 -0
  213. package/dist/providers/codex/index.d.ts +1 -0
  214. package/dist/providers/codex/index.js +1 -0
  215. package/dist/providers/codex/models/index.d.ts +1 -0
  216. package/dist/providers/codex/models/index.js +2 -0
  217. package/dist/providers/codex/models/models.d.ts +11 -0
  218. package/dist/providers/codex/models/models.js +23 -0
  219. package/dist/providers/codex/models/types.d.ts +15 -0
  220. package/dist/providers/codex/models/types.js +19 -0
  221. package/dist/providers/codex/rpc.d.ts +1 -1
  222. package/dist/providers/codex/rpc.js +4 -2
  223. package/dist/providers/codex/transformers.d.ts +4 -2
  224. package/dist/providers/codex/transformers.js +28 -2
  225. package/dist/providers/codex/types.d.ts +86 -10
  226. package/dist/providers/codex/types.js +3 -0
  227. package/dist/providers/configuration/configuration.d.ts +16 -0
  228. package/dist/providers/configuration/configuration.js +50 -0
  229. package/dist/providers/configuration/index.d.ts +1 -0
  230. package/dist/providers/configuration/index.js +2 -0
  231. package/dist/providers/constants.d.ts +7 -0
  232. package/dist/providers/constants.js +11 -0
  233. package/dist/providers/elicitation/elicitation.d.ts +16 -0
  234. package/dist/providers/elicitation/elicitation.js +39 -0
  235. package/dist/providers/elicitation/index.d.ts +1 -0
  236. package/dist/providers/elicitation/index.js +2 -0
  237. package/dist/providers/extensions/index.d.ts +2 -0
  238. package/dist/providers/extensions/index.js +2 -0
  239. package/dist/providers/extensions/types.d.ts +66 -0
  240. package/dist/providers/extensions/types.js +16 -0
  241. package/dist/providers/index.d.ts +10 -3
  242. package/dist/providers/index.js +9 -2
  243. package/dist/providers/inputs/index.d.ts +2 -0
  244. package/dist/providers/inputs/index.js +2 -0
  245. package/dist/providers/inputs/inputs.d.ts +13 -0
  246. package/dist/providers/inputs/inputs.js +108 -0
  247. package/dist/providers/lineage/index.d.ts +1 -0
  248. package/dist/providers/lineage/index.js +2 -0
  249. package/dist/providers/lineage/lineage.d.ts +8 -0
  250. package/dist/providers/lineage/lineage.js +24 -0
  251. package/dist/providers/process/index.d.ts +1 -0
  252. package/dist/providers/process/index.js +2 -0
  253. package/dist/providers/process/ownership.d.ts +11 -0
  254. package/dist/providers/process/ownership.js +63 -0
  255. package/dist/providers/process.js +5 -56
  256. package/dist/providers/registry/index.d.ts +3 -0
  257. package/dist/providers/registry/index.js +4 -0
  258. package/dist/providers/registry/registry.d.ts +43 -0
  259. package/dist/providers/registry/registry.js +594 -0
  260. package/dist/providers/registry/types.d.ts +13 -0
  261. package/dist/providers/registry/types.js +1 -0
  262. package/dist/providers/registry/utilities.d.ts +12 -0
  263. package/dist/providers/registry/utilities.js +45 -0
  264. package/dist/providers/registry/validations.d.ts +30 -0
  265. package/dist/providers/registry/validations.js +131 -0
  266. package/dist/providers/results/index.d.ts +1 -0
  267. package/dist/providers/results/index.js +2 -0
  268. package/dist/providers/results/results.d.ts +6 -0
  269. package/dist/providers/results/results.js +48 -0
  270. package/dist/providers/types.d.ts +204 -7
  271. package/dist/providers/types.js +19 -1
  272. package/dist/runtime/runtime.d.ts +2 -2
  273. package/dist/runtime/runtime.js +137 -82
  274. package/dist/runtime/types.d.ts +24 -2
  275. package/dist/runtime/types.js +8 -0
  276. package/dist/sessions/evidence/index.d.ts +3 -0
  277. package/dist/sessions/evidence/index.js +4 -0
  278. package/dist/sessions/evidence/types.d.ts +18 -0
  279. package/dist/sessions/evidence/types.js +24 -0
  280. package/dist/sessions/evidence/utilities.d.ts +41 -0
  281. package/dist/sessions/evidence/utilities.js +181 -0
  282. package/dist/sessions/sessions.d.ts +10 -3
  283. package/dist/sessions/sessions.js +107 -66
  284. package/dist/sessions/types.d.ts +1 -1
  285. package/dist/sessions/utilities.js +1 -1
  286. package/dist/skills/skills.d.ts +15 -3
  287. package/dist/skills/skills.js +28 -13
  288. package/dist/snapshots/artifacts.d.ts +7 -0
  289. package/dist/snapshots/artifacts.js +50 -0
  290. package/dist/snapshots/constants.d.ts +5 -0
  291. package/dist/snapshots/constants.js +11 -0
  292. package/dist/snapshots/database.d.ts +18 -0
  293. package/dist/snapshots/database.js +298 -0
  294. package/dist/snapshots/files.d.ts +45 -0
  295. package/dist/snapshots/files.js +196 -0
  296. package/dist/snapshots/index.d.ts +2 -0
  297. package/dist/snapshots/index.js +2 -0
  298. package/dist/snapshots/snapshots.d.ts +33 -0
  299. package/dist/snapshots/snapshots.js +272 -0
  300. package/dist/snapshots/snapshots.worker.d.ts +1 -0
  301. package/dist/snapshots/snapshots.worker.js +31 -0
  302. package/dist/snapshots/types.d.ts +165 -0
  303. package/dist/snapshots/types.js +66 -0
  304. package/dist/storage/constants.d.ts +6 -0
  305. package/dist/storage/constants.js +7 -0
  306. package/dist/storage/index.d.ts +4 -0
  307. package/dist/storage/index.js +6 -0
  308. package/dist/storage/storage.d.ts +13 -0
  309. package/dist/storage/storage.js +98 -0
  310. package/dist/storage/types.d.ts +19 -0
  311. package/dist/storage/types.js +20 -0
  312. package/dist/store/browser/browser.model.js +15 -7
  313. package/dist/store/collaboration/authority.d.ts +228 -0
  314. package/dist/store/collaboration/authority.js +128 -0
  315. package/dist/store/collaboration/collaboration.model.d.ts +412 -0
  316. package/dist/store/collaboration/collaboration.model.js +254 -0
  317. package/dist/store/collaboration/constants.d.ts +13 -0
  318. package/dist/store/collaboration/constants.js +14 -0
  319. package/dist/store/collaboration/dispatch.d.ts +19 -0
  320. package/dist/store/collaboration/dispatch.js +197 -0
  321. package/dist/store/collaboration/identity.d.ts +21 -0
  322. package/dist/store/collaboration/identity.js +146 -0
  323. package/dist/store/collaboration/index.d.ts +3 -0
  324. package/dist/store/collaboration/index.js +5 -0
  325. package/dist/store/collaboration/invocation.d.ts +21 -0
  326. package/dist/store/collaboration/invocation.js +162 -0
  327. package/dist/store/collaboration/messages.d.ts +54 -0
  328. package/dist/store/collaboration/messages.js +157 -0
  329. package/dist/store/collaboration/outcomes.d.ts +11 -0
  330. package/dist/store/collaboration/outcomes.js +216 -0
  331. package/dist/store/collaboration/queries.d.ts +23 -0
  332. package/dist/store/collaboration/queries.js +259 -0
  333. package/dist/store/collaboration/reports.d.ts +37 -0
  334. package/dist/store/collaboration/reports.js +117 -0
  335. package/dist/store/collaboration/requests.d.ts +22 -0
  336. package/dist/store/collaboration/requests.js +111 -0
  337. package/dist/store/collaboration/search.d.ts +13 -0
  338. package/dist/store/collaboration/search.js +58 -0
  339. package/dist/store/collaboration/spawn.d.ts +33 -0
  340. package/dist/store/collaboration/spawn.js +96 -0
  341. package/dist/store/collaboration/streams.d.ts +13 -0
  342. package/dist/store/collaboration/streams.js +100 -0
  343. package/dist/store/collaboration/tasks.d.ts +20 -0
  344. package/dist/store/collaboration/tasks.js +169 -0
  345. package/dist/store/collaboration/transformers.d.ts +56 -0
  346. package/dist/store/collaboration/transformers.js +179 -0
  347. package/dist/store/collaboration/types.d.ts +25 -0
  348. package/dist/store/collaboration/types.js +8 -0
  349. package/dist/store/collaboration/utilities.d.ts +23 -0
  350. package/dist/store/collaboration/utilities.js +77 -0
  351. package/dist/store/collaboration/waits.d.ts +26 -0
  352. package/dist/store/collaboration/waits.js +114 -0
  353. package/dist/store/control/constants.d.ts +3 -3
  354. package/dist/store/control/constants.js +3 -3
  355. package/dist/store/control/control.model.d.ts +20 -3
  356. package/dist/store/control/control.model.js +456 -129
  357. package/dist/store/control/index.d.ts +4 -2
  358. package/dist/store/control/index.js +4 -1
  359. package/dist/store/control/transformers.d.ts +2 -2
  360. package/dist/store/control/transformers.js +12 -5
  361. package/dist/store/control/types.d.ts +602 -126
  362. package/dist/store/control/types.js +48 -8
  363. package/dist/store/plans/plans.model.js +24 -21
  364. package/dist/store/schema.d.ts +13 -0
  365. package/dist/store/schema.js +102 -0
  366. package/dist/store/schema.sql +429 -96
  367. package/dist/store/store.d.ts +2 -0
  368. package/dist/store/store.js +66 -19
  369. package/dist/store/store.worker.js +239 -166
  370. package/dist/store/types.d.ts +4663 -1407
  371. package/dist/store/types.js +48 -18
  372. package/docs/recovery.md +23 -0
  373. package/errors/README.md +54 -27
  374. package/package.json +8 -2
  375. package/dist/contracts/handoffs/index.d.ts +0 -2
  376. package/dist/contracts/handoffs/index.js +0 -2
  377. package/dist/contracts/handoffs/types.d.ts +0 -585
  378. package/dist/contracts/handoffs/types.js +0 -112
  379. package/dist/handoffs/handoffs.d.ts +0 -43
  380. package/dist/handoffs/handoffs.js +0 -465
  381. package/dist/handoffs/index.d.ts +0 -4
  382. package/dist/handoffs/index.js +0 -6
  383. package/dist/handoffs/types.d.ts +0 -492
  384. package/dist/handoffs/types.js +0 -29
  385. package/dist/handoffs/utilities.d.ts +0 -11
  386. package/dist/handoffs/utilities.js +0 -24
  387. package/dist/store/handoffs/handoffs.model.d.ts +0 -37
  388. package/dist/store/handoffs/handoffs.model.js +0 -150
  389. package/dist/store/handoffs/index.d.ts +0 -1
  390. package/dist/store/handoffs/index.js +0 -2
package/api/README.md CHANGED
@@ -6,7 +6,7 @@ Intentional Node API failures use `Exception` from `jg-exception`. The [error re
6
6
 
7
7
  ## Lock lifecycle
8
8
 
9
- - `acquireHqLock(root, command, options?)` acquires `.runtime/hq.lock` and returns an asynchronous release function. The caller owns the trusted state root and supplies a non-empty, single-line operation label. Surrounding whitespace is trimmed. The returned release function is idempotent and refuses a replaced owner.
9
+ - `acquireHqLock(root, command, options?)` acquires `.runtime/hq.lock` and returns an asynchronous release function. The caller owns the trusted state root and supplies a non-empty, single-line operation label. Surrounding whitespace is trimmed. The returned release function is idempotent and refuses a replaced owner. Acquisitions in one process queue by their normalized lock path, so later status polling cannot overtake a waiting checkpoint. Cross-process exclusion still uses the same file and exact owner; no cross-process ordering is promised. Timed-out or failed waiters leave the local queue.
10
10
  - `withHqLock(root, command, operation, options?)` runs an asynchronous operation under the lock. It releases on success or failure; operation failures propagate unchanged. If cleanup also fails, the original operation error stays primary and cleanup failure is reported on stderr.
11
11
  - `readHqLockState(root, now?)` reports free, held or unreadable without acquiring or reclaiming the lock. Held state includes the owner, liveness and age.
12
12
  - `getOwnerLiveness(pid)` reports alive, dead or unknown. An unverifiable owner is not evidence that recovery is safe.
@@ -18,47 +18,204 @@ Intentional Node API failures use `Exception` from `jg-exception`. The [error re
18
18
 
19
19
  All operations may expose the relevant intentional contracts in [errors](../errors/README.md). Filesystem failures outside those classifications propagate to the trusted Node caller. The returned acquisition release function can expose the ownership-changed contract.
20
20
 
21
+ ## Shared storage
22
+
23
+ `hq.storage` returns an independent `IStorageDescriptor` containing the canonical `databasePath`, `schemaHash`, `reservedPrefix` (`hq_`), and required `connectionSettings`: `foreignKeys` true, `busyTimeoutMs` 5000, `journalMode` wal, and `synchronous` full. Exported Node types are `IStorageDescriptor` and `IStorageMaintenanceOperation<T>`. No database handle, storage callback, raw SQL command or storage path is exposed by browser contracts or IPC.
24
+
25
+ For node:sqlite, open the host connection with `new DatabaseSync(storage.databasePath, { timeout: storage.connectionSettings.busyTimeoutMs, enableForeignKeyConstraints: storage.connectionSettings.foreignKeys })`. These options enable foreign keys and a 5,000 ms busy timeout; the descriptor itself is not a DatabaseSync options object. See the [Node 24 SQLite API](https://nodejs.org/download/release/v24.15.0/docs/api/sqlite.html#new-databasesyncpath-options). Keep WAL mode and FULL synchronization; do not change database-wide settings while HQ is running. Hosts own their table prefix, definitions, connection lifetime and user_version. HQ-owned tables and indexes are reserved. A nonempty database requires the matching singleton hq_schema stamp; otherwise startup throws JG_AGENT_HQ_STORAGE_INVALID without changing the database. The stamp also binds the SHA-256 fingerprint of action.key; a different valid-length key fails with JG_AGENT_HQ_ACTION_KEY_UNAVAILABLE before a writer opens. Fresh initialization is transactional.
26
+
27
+ `await hq.withStorageMaintenance(operation)` passes the storage descriptor to the async operation and returns its result. It closes admission before draining accepted HQ operations, allows their awaited nested calls and required native evidence to finish, and checks for active native execution or prepared plan writes before invoking the callback. Concurrent maintenance, new HQ requests, browser host effects and shutdown conflict while maintenance is held. During the callback, native event persistence waits in its existing bounded lane, and an already accepted scheduled stop waits for release. The callback must not call HQ, start native work or leave transactions open. Its errors propagate unchanged; it owns rollback and reconciliation for its SQL effects. After success or failure, HQ admission resumes. Calls after shutdown use JG_AGENT_HQ_RUNTIME_NOT_RUNNING.
28
+
29
+ The host must coordinate every application connection that can write during maintenance. A shared file gives SQLite transaction isolation, not an atomic transaction spanning host SQL and HQ API calls. HQ does not expose its worker connection. Snapshot scheduling and remote backup operations belong to the host application.
30
+
31
+ ## Snapshot and restore
32
+
33
+ Import createHqSnapshot, inspectHqSnapshot and restoreHqSnapshot from jg-agent-hq in a trusted Node host. They are absent from browser contracts, IPC and agent tools. The exported types are IHqSnapshotInspection, IHqRestoreOptions and IHqRestoreResult.
34
+
35
+ | Operation | Contract |
36
+ | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
37
+ | `createHqSnapshot(hq, destination)` | Pause all host writers, then capture a quiescent running runtime into an absent absolute destination under an existing canonical parent. Returns IHqSnapshotInspection. |
38
+ | `inspectHqSnapshot(directory)` | Validate the complete private snapshot without changing it. Returns IHqSnapshotInspection. |
39
+ | `restoreHqSnapshot({ snapshotDirectory, destination })` | Validate before creating an absent recovery destination, copy and validate staged files, then expose state and plan recovery directories. Returns IHqRestoreResult. All proposed destination connections must be stopped. |
40
+
41
+ Capture holds exclusive HQ maintenance admission and the coordination metadata lock, then takes each registered plan's shared document locks in the existing order. Active native turns, unresolved native ownership or in-flight native mutations use ACTION_CONFLICT, without interruption. Concurrent maintenance and locked documents also conflict. Snapshot capture retains prepared document write intents and source mismatches; ordinary host schema maintenance continues to reject prepared writes. Host connections must stop writing for the complete capture; quiesce native background jobs and independent document writers as well. Uncoordinated writes, attached databases and external files are outside this coherence contract.
42
+
43
+ SQLite's worker-owned backup API includes committed WAL data and every table in the main database, including application tables and exact hq_report payloads. The resulting database needs no WAL sidecar. The snapshot also contains the private 32-byte action.key and every present registered plan.md, milestones.md and coordination.json. Capture binds the original canonical state root and checks the key against its startup hash, rejecting a key replaced while the runtime is open. The indexed hq_plan_registration records durable references from plans, task/grant scope and requests. Enumeration uses directory seek pages of 128; file copy and SHA-256 use 65,536-byte buffers. There is no repository scan, transcript copy or artifact cache.
44
+
45
+ The one inventory format is manifest.jsonl: header, database, action-key and ordered plan records. Each plan's generated directory is `plans/<SHA-256 of source directory>`. Records retain exact source directory, observed plan ID/revision, companion byte counts/hashes and bounded diagnostics. Missing source plans, parser observations and corrupt coordination remain visible evidence; capture does not repair them or require checker conformance. Registered plans outside the runtime's current allowed roots retain an unavailable record without reading their files. A final complete.json binds the complete manifest hash and record count. Directories are private (0700), files are private (0600), and destinations are created exclusively. Runtime sockets, owner records, process IDs, bridge credentials and provider authentication are excluded.
46
+
47
+ Inspection streams the inventory, verifies each listed regular file and every expected/absent companion, rejects links and unsafe paths, checks the current HQ schema stamp and database/key pairing, SQLite integrity/foreign keys, exact report hashes and complete registered-plan coverage. It rechecks captured plan identities and diagnostics. Full database verification runs in a dedicated worker. Inspection returns bounded directory/header/hash/count metadata; it does not load a growing inventory into memory. Hashes detect corruption and bind content; they do not authenticate a snapshot supplied by an untrusted party.
48
+
49
+ Restore leaves every existing destination untouched, including an empty directory, repository or live state root. Use a new directory. It validates the source before reserving that directory and validates the staged copy independently against the initially inspected manifest hash before changing recovery authority. On success, stateRoot points to destination/state, recoveryRoot to destination/plans, recovery.jsonl retains the source inventory and recovered.json records completion. Caught failures remove only the operation's newly created output. A crash can leave incomplete output; do not open it as a recovered runtime.
50
+
51
+ Restored task and agent lifecycles are paused unless already stopped, automatic dispatch is disabled, all skill grants are revoked, live approvals expire and queued input loses readiness. Submitted actions retain uncertainty. Managed native identities become uncertain and require explicit ownership reconciliation. IDs, stored reports, waiting child sets/continuation reservations, delivery links, historical receipts and exact prepared document intents remain intact. No native operation runs during restore.
52
+
53
+ Call createAgentHq with the returned stateRoot and an explicitly selected allowedRoots array. Runtime construction never imports source root permissions from the snapshot and always assigns a new epoch; stored execution and revision leases cannot authorize work in it. Native source workspace paths and plan bindings remain evidence and are not rewritten. Recover repository/native files separately. Inspect recovery.jsonl and copy selected companions into explicitly chosen plan locations only after comparing current files; restore never overwrites a source repository. Rebind task plan references and obtain fresh plan/execution authority where needed, reconcile pending document writes using their exact IDs/baselines, and make explicit current-revision lifecycle/native ownership decisions before enabling dispatch. Source paths outside the newly selected roots remain unavailable.
54
+
55
+ These exports use SNAPSHOT_INVALID for incomplete, corrupt, unsafe or occupied snapshot/recovery selections and SNAPSHOT_FAILED for operational copy, backup, lock-release, worker or cleanup failures. Capture additionally exposes ACTION_CONFLICT for a busy checkpoint. Operational messages retain private diagnostic causes; no snapshot exception is exposed through public RPC.
56
+
57
+ Snapshots are plaintext local state. The host owns encryption/key recovery, scheduling, uploads, retention and last-success status. A disk failure can lose every change after the last successful off-machine backup. A local snapshot alone provides no remote durability. See the [recovery workflow](../docs/recovery.md).
58
+
59
+ Native snapshot qualification on 2026-10-23 used Codex 0.164.0 (gpt-6.1-sol) and Claude Code 2.1.309 (claude-opus-5-5). Both produced exact HQ reports from controlled native sessions. Quiescent capture, offline restore and explicit root selection retained their report bytes/hashes, changed the runtime epoch, paused task dispatch and left both providers idle on the recovered runtime. Claude read-tool permissions received exact explicit replies. These observations do not establish a native version admission rule.
60
+
21
61
  ## Runtime lifecycle
22
62
 
23
- `createAgentHq({ stateRoot, allowedRoots })` starts one controller and returns `IAgentHq`: its canonical `stateRoot`, a `closed` lifetime promise, `request(command)` and idempotent `close()`. Paths must be absolute. Allowed roots must exist and are canonicalized at startup. A client-selected workspace must resolve inside an allowed root. State is a real directory owned by the current OS user with no group/other access. The controller creates it privately when absent.
63
+ `createAgentHq({ stateRoot, allowedRoots })` starts one controller and returns `IAgentHq`: its canonical `stateRoot`, a `closed` lifetime promise, `request(command)`, idempotent `close()`, a trusted Node-only `storage` descriptor and `withStorageMaintenance(callback)`. Paths must be absolute. Allowed roots must exist and are canonicalized at startup. A client-selected workspace must resolve inside an allowed root. State is a real directory owned by the current OS user with no group/other access. The controller creates it privately when absent.
24
64
 
25
65
  The controller exclusively creates `hq-owner.json`. A live, inactive, incomplete or unverifiable existing owner prevents another controller from starting. There is no automatic takeover. Before deliberate recovery, establish that the inspected host, its worker and native process group have stopped. Runtime shutdown sends interruption requests across the bounded session cohort concurrently, then closes IPC connections, SQLite and owned native processes before removing the exact owner. Failed cleanup preserves ownership evidence. A new runtime receives a new epoch.
26
66
 
27
- `requestAgentHq(stateRoot, command)` is a one-command IPC client. It verifies the private owner and socket, binds the command to the runtime epoch and checks the matching response. Closing a client does not close the host. `stop` accepts a shutdown request; the SDK caller must await `runtime.closed` when it owns the runtime. The CLI confirms owner removal before reporting `state: stopped`.
67
+ `requestAgentHq(stateRoot, command, signal?)` is a one-command IPC client. It verifies the private owner and socket, binds the command to the runtime epoch and checks the matching response. Cancellation closes that client's socket and reports transport failure; it never undoes an admitted action. Closing a client does not close the host. `stop` accepts a shutdown request; the SDK caller must await `runtime.closed` when it owns the runtime. The CLI confirms owner removal before reporting `state: stopped`.
28
68
 
29
69
  The socket accepts at most 32 simultaneous connections. Requests are bounded to 65,536 UTF-8 bytes; native and IPC response frames to 8,388,608 bytes. Structured transports reject malformed UTF-8/JSON, oversized frames and incomplete tails. Each native connection has at most 32 pending calls with a 30-second response deadline. IPC connections have a 35-second deadline. The SQLite worker bounds its queue to 128 commands, accommodating client reads, native lifecycle observations and action dispatch; collection operations remain limited to one page. Database work runs off the host event loop. The state directory is a same-user trust boundary, not a sandbox against other code running as that user.
30
70
 
31
- ## Read commands
71
+ ## Provider adapters and capabilities
72
+
73
+ `createAgentHq` accepts optional `providerFactories`, an array of additional trusted `IAgentProviderFactory` objects. The built-in `codex` and `claude` registrations remain available. Each factory has a validated `id` and asynchronous `create(context)`; duplicate IDs or invalid registrations use JG_AGENT_HQ_REQUEST_INVALID. Registration is construction-time Node code. Browser and IPC clients cannot supply factories, executable paths or modules.
74
+
75
+ Factories receive canonical allowed roots, the runtime epoch, a cancellation signal and runtime-owned event callbacks. They return `IAgentProvider`, which owns native protocol validation, processes, authentication, capabilities, history, skill invocation spelling and concrete session controls. Each operation receives a bounded `IProviderCall.signal`. Factories must clean up partial initialization before rejecting; `close()` must be idempotent and confirm that owned resources stopped. HQ retains ownership evidence when cleanup cannot be confirmed. Failed construction is not automatically replayed.
32
76
 
33
- Import `HqRequestSchema`, `HqResponseSchema` and their inferred types from `jg-agent-hq/contracts`. Requests are closed contracts. Responses tolerate additive fields. Read providers are `codex` and `claude`. Both providers support explicit thread control. Status reports Codex steering as available and Claude steering as unavailable.
77
+ `IAgentProviderEvents` carries normalized observations, items, deltas, prompts, outcomes and connection loss. `validateInput` rejects unsupported media/output options before admission and again at dispatch. `startTurn` receives content-bound `IProviderInputFile` bytes read by HQ. A turn-completed observation may carry a validated complete result whose state must match that observation. Registration binds provider identity. Echo each supplied request ID unchanged; HQ derives its action identity and verifies the exact receipt, runtime, provider, native session and workspace. A late create/fork/resume/unarchive/revert outcome also supplies verified native session metadata. Unknown control states cannot establish success or idle ownership. Callback metadata may grow additively; known identity and state fields remain validated. Native permission requests keep their exact reply channel and validation. An unsupported request is denied rather than approved.
34
78
 
35
- | Command | Required fields | Result |
36
- | --------- | --------------------------------------- | ------------------------------------------------------------------------------------------ |
37
- | `status` | None | Runtime epoch, host PID, start time, worker availability and native transport availability |
38
- | `stop` | None | Accepted shutdown and runtime epoch |
39
- | `threads` | `provider`, `workspaceRoot` | Paged native discovery; optional `search` |
40
- | `thread` | `provider`, `workspaceRoot`, `nativeId` | One native thread's metadata |
41
- | `turns` | Same target fields | Paged native turn metadata without hydrating items |
42
- | `items` | Same target fields | Paged persisted native items; optional `turnId` |
43
- | `usage` | `provider` | Actual subscription observations |
79
+ `{ kind: 'capabilities', provider, threadId? }` returns `IProviderCapabilities`. The optional managed thread must belong to that provider and an allowed workspace. The response includes provider/session scope, observation time, concrete operation support, and supported HQ input/configuration schemas. Each operation is `supported`, `unsupported`, `unavailable` or `unknown`, with a structured reason when support cannot be established. Supported settings describe whether a change is live or requires an idle restart. Configuration schemas describe typed session and turn settings, their live or idle-restart change mode, and native permission/sandbox choices. Model and effort values come from the native model catalog. Capabilities are observations, not permission grants or execution authority.
80
+
81
+ The current built-in surfaces map to these native entry points:
82
+
83
+ | HQ surface | Codex | Claude |
84
+ | ------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
85
+ | Create/adopt/resume | `thread/start`, `thread/read`, `thread/resume` | Structured session creation/resume and idle/session-ID fences |
86
+ | Rename | `thread/name/set` | `rename_session` control request |
87
+ | Message/queue | `turn/start` with explicit native input | Structured user messages with matching acknowledgements |
88
+ | Steer | `turn/steer` for the exact active turn | Explicitly unsupported by the structured interface |
89
+ | Interrupt | `turn/interrupt` | `interrupt` control request; completion remains separate |
90
+ | Close/recover | Native background-terminal cleanup/verification and `thread/unsubscribe` | Confirmed process-group shutdown and explicit session release/resume |
91
+ | History | `thread/list`, `thread/read`, `thread/turns/list`, `thread/items/list` | Bounded worker-owned indexing of native transcripts |
92
+ | Skills | `skills/list` and native skill input | Initialization command metadata and native invocation text |
93
+ | Fork | `thread/fork` with verified source lineage | Native `--resume`, `--fork-session` and distinct `--session-id` |
94
+ | Archive/unarchive | Native archive/unarchive, with explicit resume afterward | Explicitly unsupported |
95
+ | Compact | `thread/compact/start`, correlated with native turn events | Native `/compact`, correlated with input and result events |
96
+ | Revert | `thread/revert` before an exact turn, without undoing files | Explicitly unsupported |
97
+ | Models/settings | `model/list`, `config/read`, native startup and next-turn parameters | `list_models`, `get_settings`, native startup flags and `apply_flag_settings` |
98
+ | Usage | `account/rateLimits/read` | `get_usage` control request, with explicit unavailable observations |
99
+ | Account | `account/read`, ChatGPT login start/cancel and native logout | Initialization account metadata and native `auth logout`; interactive login is unavailable |
100
+ | Skill reload | `skills/list` with native `forceReload` | `reload_skills`, followed by complete initialization command metadata |
101
+ | MCP inventory | `mcpServerStatus/list`, including tools and resources | `mcp_status`; tool input schemas and resource catalogs are unavailable |
102
+ | MCP controls | `config/mcpServer/reload`, server OAuth login | `mcp_reconnect`, `mcp_toggle`; structured server login is unavailable |
103
+ | Plugin reload | Under-development native plugin management is unavailable | `reload_plugins` for existing native configuration, retaining held outcomes |
104
+
105
+ Availability depends on the selected native connection and, for session metadata, that session's initialization. Native settings, hooks, plugins and authentication remain with the harness. Codex protocol details are in the [official app-server reference](https://learn.chatgpt.com/docs/app-server); Claude flags and programmatic behavior are in the [CLI reference](https://code.claude.com/docs/en/cli-reference) and [programmatic guide](https://code.claude.com/docs/en/headless). Public-API integration tests exercise both native boundaries and a third provider through real HQ persistence and IPC, including compatible version labels, missing-provider isolation, duplicate registration and malformed evidence.
106
+
107
+ Local qualification on 2026-10-23 used Codex 0.163.0 and Claude Code 2.1.309 with native settings and authentication in a disposable workspace. Both created and named sessions with selected models and startup instructions, acknowledged a text message, reported native completion, exposed live presentation and completed compaction. Both resumed the same native identity after runtime restart, applied next-turn model/effort selections with native readback, and forked stored history through the public HQ action API. Codex also completed public history revert and archive/unarchive, leaving the unarchived child inactive. Claude resumed its compacted transcript after HQ excluded native API diagnostic blobs from conversation indexing. Both also accepted a PNG and UTF-8 document through the HQ file-reference path and returned a validated structured READY result with per-turn token observations (Codex gpt-6.1-sol; Claude claude-haiku-4-5-20251001). Owned controllers and runtimes shut down cleanly. This checks those controls on this host; other controls and platforms require their own qualification.
108
+
109
+ Third-party adapter failures use JG_AGENT_HQ_PROVIDER_FAILED, retaining safe diagnostic causes. Canonical request/access/state errors and JG_AGENT_HQ_CAPABILITY_UNAVAILABLE retain their meaning. An explicit native rejection may carry `nativeRejection: true`; use it only when native rejection is proven. Timeouts and lost responses remain uncertain and are not retried with a new identity. Capability reads normally return availability data; an unusable descriptor does not disable unrelated session controls. Quota reads return an unavailable observation when no trustworthy measurement can be obtained. Essential malformed control data quarantines the affected provider. Lifecycle queues are bounded per provider; overflow marks that provider uncertain and stops it while other providers remain usable. SQLite failures still affect the shared store.
110
+
111
+ ## Read commands
112
+
113
+ Import `HqRequestSchema`, `HqResponseSchema` and their inferred types from `jg-agent-hq/contracts`. Requests are closed contracts. Responses tolerate additive fields. Provider fields use `ProviderIdSchema`, a bounded lowercase identifier. `codex` and `claude` are built in; trusted Node factories can add providers. Status returns a bounded `providers` array of `{ provider, state, version }`, where state is `idle`, `ready` or `unavailable`. Reading status does not start a provider. The diagnostic version/user-agent string may be null and never decides compatibility.
114
+
115
+ | Command | Required fields | Result |
116
+ | ----------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
117
+ | `status` | None | Runtime epoch, host PID, start time, worker availability and native transport availability |
118
+ | `capabilities` | `provider`; optional managed `threadId` | Provider/session-scoped support, input/configuration schemas and unavailable reasons |
119
+ | `models` | `provider` | Paged native model identities, effort choices and defaults when observed |
120
+ | `configuration` | `provider`, `workspaceRoot`; optional managed `threadId` | Known effective native settings and paged agent/profile choices |
121
+ | `stop` | None | Accepted shutdown and runtime epoch |
122
+ | `threads` | `provider`, `workspaceRoot` | Paged native discovery; optional `search` |
123
+ | `sessions` | `provider`, `workspaceRoot` | Byte-bounded discovery with exact IDs; optional `search` |
124
+ | `thread` | `provider`, `workspaceRoot`, `nativeId` | One native thread's metadata |
125
+ | `turns` | Same target fields | Paged native turn metadata without hydrating items |
126
+ | `items` | Same target fields | Paged persisted native items; optional `turnId` |
127
+ | `session-evidence` | Same target fields | Newest-first bounded evidence, exact references and full normalized text continuation |
128
+ | `account` | `provider` | Safe native account metadata with explicit unavailable observations |
129
+ | `mcp-servers` | Managed `threadId` | Paged configured native MCP server identity, connection and auth metadata |
130
+ | `mcp-tools` / `mcp-resources` | Managed `threadId`, `serverName` | Paged native descriptions; no resource content is fetched |
131
+ | `provider-actions` | `provider` | Paged global action metadata, including authentication receipts |
132
+ | `login` | `actionId` | Live authentication presentation or known terminal state |
133
+ | `usage` | `provider` | Actual subscription observations |
44
134
 
45
135
  Paged commands accept `limit` (default 32, maximum 128) and an opaque `cursor`. Continue with exactly the same command, target, filters and limit. The cursor binds those fields to the provider continuation. Codex requests descending creation order for threads, descending turns and ascending items. Claude orders discovery by creation time/native UUID descending and history by native chain position ascending. Workspace authorization is rechecked for each request, independently of cursor validation, before selected-thread items are fetched.
46
136
 
47
137
  Threads expose native state, `historyState` (`available` or `unavailable`), ownership (`external`, `managed` or `uncertain`) and nullable `managedId`. A managed thread uses its HQ name; an external thread retains its nullable native name. Timestamps use Unix milliseconds. Discovery projections are not authoritative transcript history and never cache a conversation body. Repeated Codex history reads go to its native APIs so a completed turn whose items have not flushed can be read again later. There is no resume-to-read behavior or Codex transcript-file parser.
48
138
 
139
+ ## Bounded session evidence
140
+
141
+ `sessions` and `session-evidence` enforce a 65,536-byte total serialized response budget, including the IPC envelope. Both accept `limit` (default 32, maximum 128) and an opaque `cursor`. A request inspects at most eight source items, so it may return fewer than its limit. Continue until `nextCursor` is null, including when a filtered page is empty. Discovery preserves every matching identity rather than selecting an agent by an ambiguous native label. Native display names are limited to 1,024 UTF-8 bytes with `isNameTruncated`; exact managed/native IDs remain unchanged.
142
+
143
+ `session-evidence` selects `provider`, `workspaceRoot`, `nativeId`, and optional `turnId`, `nativeItemId` and `kinds` (the history item kinds). Items arrive newest first. Each fragment has `reference: { provider, nativeId, turnId, itemId, sha256 }`, `text`, `offsetBytes`, `totalBytes`, `isComplete`, `contentState`, native type, kind and provenance. The hash identifies the complete normalized UTF-8 text, not the fragment or raw transcript record. Non-text native blocks retain explicit labels; this API does not return raw provider payloads or binary attachments. `isComplete` is true only on the final fragment of supported, untruncated normalized text. `contentState` distinguishes available content, unsupported native content and a provider preview. Concatenate fragments for one exact reference in byte-offset order and verify its total length and hash. Empty native history returns an empty terminal page; missing or unverifiable history reports its provider's unavailable error.
144
+
145
+ Text chunks contain at most 32,768 UTF-8 bytes and shrink when escaping or metadata consumes the response budget. Cursors bind all query fields and the content of a partially consumed native page. Changed content, changed query scope or a changed Claude chain revision uses CURSOR_INVALID; start a fresh read rather than joining different evidence. New native pages use the provider's continuation, not an immutable transcript snapshot. Newly arriving or removed history may therefore require a fresh discovery/evidence read. Authorization is rechecked on every request before content access, and no alternate raw-file path bypasses a denial.
146
+
147
+ `HistoryItemSchema` and evidence fragments expose `provenance: { origin, source, nativeInputId, actionId, contentBoundary: 'untrusted', grantsAuthority: false }`. Origins are operator, agent, tool, system or unknown. Native assistant/tool kinds establish only their observed category. A native user role, quoted operator text or an imported message cannot establish an operator. HQ correlates a submitted input only when its exact native message/client identity, thread/turn and complete normalized text hash match the acknowledged action ledger. Programmatic host submissions have source `host-action` and unknown actor. An authenticated browser submission additionally requires the same selected thread and text fingerprint, yielding `authenticated-host-action` and operator provenance. Unverifiable, modified, attachment-expanded or skill-expanded content stays unknown. Provenance remains historical evidence and grants no current approval, execution authority or tool permission; quotations remain inside its untrusted content boundary.
148
+
149
+ Codex uses its native descending item API with unloaded thread metadata. It never reads Codex transcript files. Claude uses indexed current-chain byte locations, exact UUID lookups and separate bounded seeks per selected kind. Its cold index retains the existing 4 MiB batches and 30-second operation budget; selected evidence reads parse at most 4 MiB of records. Continuation revalidates and rereads one bounded native page to detect content changes rather than caching transcript bodies. Work and memory per read are bounded independently of history growth; reconstructing a large body may reread that source page. No conversation-body cache is maintained.
150
+
151
+ ## Native accounts and extensions
152
+
153
+ `account` reads only native account metadata: `provider`, `state`, nullable `accountType`, `email`, `organization`, `subscription`, `isAuthenticationRequired`, `observedAt`, and `source: 'native'`. This describes configured authentication; it is not a network-validity guarantee. Codex uses `account/read` without token refresh. Claude reads fresh initialization account metadata in an owned read process. Missing optional metadata yields `unavailable` without disabling session control. Configuration files, environment values, headers and credentials are never returned.
154
+
155
+ `mcp-servers`, `mcp-tools` and `mcp-resources` require the exact managed session and an authorized workspace. They return `provider`, `state` (`available`, `partial`, `unavailable`, `unsupported`), `observedAt`, `unavailableCount`, `data` and `nextCursor`. Default and maximum page sizes are 32 and 128. Native leaf inventories are bounded to 4096 entries and 1 MiB before paging; malformed optional entries are counted without inventing metadata. Claude server and all leaf continuation use a content revision and stable identity, so catalog changes invalidate continuation. Codex retains its native server cursor. Query binding is checked before native retrieval. Unknown server metadata remains null. Claude's native status surface omits tool input schemas and does not enumerate resources; HQ reports null schemas and an unsupported resource catalog. Metadata reads never fetch resource contents or call tools.
156
+
157
+ Concrete action commands use the existing `{ kind: 'action', action: { id, runtimeEpoch, command } }` envelope:
158
+
159
+ - `skills-reload`, `mcp-reload` and `plugins-reload` take `threadId`.
160
+ - `mcp-reconnect` and `mcp-login` also take `serverName`.
161
+ - `mcp-set-enabled` takes `threadId`, `serverName` and `isEnabled`.
162
+ - `account-login` and `account-logout` take `provider` and nonempty `operatorConfirmation`; `account-login-cancel` additionally takes the initiating `loginActionId`.
163
+
164
+ Capabilities distinguish each operation. Extension changes require an idle owned session and cannot bypass a permission wait. Codex MCP reload queues a native refresh for all loaded sessions, so HQ requires those sessions to be idle and fences new execution until its outcome is known. Claude reconnect and enable/disable target one session server. Skill reload uses the runtime-authorized managed workspace and retains explicit-only native commands. Plugin reload preserves native configuration and reports `held` when the native interface defers the change. A reload applied with native plugin errors retains `controlState: 'applied'` and `completion: 'failed'`. HQ does not install plugins, forward arbitrary RPC, replace MCP configuration, disable normal hooks or inject global settings.
165
+
166
+ Receipts include nullable `provider` and `controlState` (`accepted`, `applied`, `held`). Native login initiation is acknowledged as `accepted`, with null `completion`; it does not claim authentication succeeded. Exact native completion sets `completed`, `failed` or `interrupted`. A matching cancellation acknowledgement records interruption even when its failure notification arrives first. OAuth completion matches the exact native login ID and, for MCP, the server and session as well. Unknown completion identities do not resolve another action. Native permission approval and plan authority remain separate.
167
+
168
+ `login` returns `state` (`pending`, `completed`, `failed`, `canceled`, `unavailable`), nullable `authorizationUrl`, `canCancel` and nullable `observedAt`. URLs are sensitive live presentation: HQ never opens them automatically or persists them, login IDs or tokens. Codex exposes its native ChatGPT browser login and cancellation, logout and configured MCP OAuth. Claude's interactive login and MCP OAuth commands have no qualified structured challenge surface and remain explicitly unsupported. Claude logout uses the native CLI, discards human-oriented output, confirms process-group shutdown and invalidates account-derived observations. Unconfirmed logout cleanup remains owned by the provider and prevents HQ from releasing runtime ownership.
169
+
170
+ Close the selected provider's managed sessions before changing its account. Pending or uncertain provider-wide changes fence new execution in that runtime; the other provider remains usable. `status` reports lazy native connection health without starting a provider; ready transport does not prove credentials are valid. `provider-actions` pages global receipt metadata in descending creation time/UUID order; thread-scoped controls remain in `actions`. Inspect selected receipts after interrupted requests instead of resending them. Restart retains receipts, loses sensitive login presentation, and never restarts authentication or inference. Native account reads cannot prove an interrupted sign-out's exact effect. A new account action requires fresh explicit operator intent after runtime ownership recovery.
171
+
172
+ Catalog observations are coalesced only while a read is in flight, with no retained performance cache. Native changes invalidate those joins; subsequent reads obtain fresh metadata. Native rejection is recorded as failed, while timeouts and lost responses remain uncertain until exact late evidence arrives. A late acknowledgement clears only its own pending control and does not resume queued work or grant authority.
173
+
174
+ Native qualification on 2026-10-23 used Codex 0.163.0 and Claude Code 2.1.309. Both exposed account metadata, configured MCP servers/tools and explicit-only skills after native reload. Codex exposed resource/template metadata and completed native MCP reload; Claude completed reconnect, disable/enable and plugin reload without inference. Disposable native account configuration verified Codex browser-login initiation/cancellation and both providers' logout. An owned loopback OAuth server verified Codex MCP challenge initiation and exact terminal denial through its native callback. User credential storage was not altered. These observations qualify the listed operations on this host; they do not establish other platforms or remote authentication success.
175
+
176
+ ## Native configuration
177
+
178
+ `models` returns native model IDs, display metadata, nullable effort choices/defaults and bounded continuation. Model/effort names are not fixed to a CLI release. Codex retains its native cursor; Claude uses an inventory revision and stable model key. Changed catalogs invalidate continuation.
179
+
180
+ `configuration` accepts `provider`, authorized `workspaceRoot`, optional managed `threadId`, `limit` and `cursor`. Session selection must match both provider and workspace. The result includes `nativeId`, `workingDirectory`, known `effective` settings, bounded `instructionSources` with `isComplete`, and one page of native `choices` (`agent` or `profile`). Null means unknown or unavailable, never a fabricated default. A null `choices` value means the optional native inventory is unavailable; an empty array means a known empty inventory. Effective settings remain readable when Claude omits its optional agent catalog. Native inventory is bounded to 4096 entries; choice continuation binds the query and inventory revision. Instruction source paths are metadata only; HQ does not load those files through this operation. Claude uses an owned session's settings or a disposable workspace-scoped read process with no user prompt. At most four workspace read processes run concurrently; cancellation and runtime shutdown confirm their exit, including reads still initializing. Unconfirmed cleanup retains runtime ownership. Whole configuration documents, source layers and credentials are not returned.
181
+
182
+ `thread-create` and `thread-resume` accept optional `settings`: `model`, `effort`, `outputSchema`, `permissionMode`, `systemInstructions`, `developerInstructions`, plus Codex `sandbox` or Claude `nativeAgent`. The workspace is the native working directory. Codex system/developer instructions map to native base/developer overrides. Claude system instructions use `--system-prompt`, and developer instructions use `--append-system-prompt`. Omitted fields keep native defaults. These are explicit native settings, separate from HQ plan authority and native tool approvals. The action envelope byte limit still applies.
183
+
184
+ Startup settings require an idle restart, using close followed by explicit resume; they cannot be attached to active input. Codex may retain a loaded idle thread after unsubscribe and ignores resume overrides there. HQ rejects startup overrides on such a thread; restart the HQ runtime's native connection before applying them. It never acknowledges an ignored model change. Claude opens a new native process for explicit resume, preserving the exact native session ID. Native profile selection and Codex native agent selection are not exposed as startup overrides; discovery does not imply a supported setting change.
185
+
186
+ A `message` or `queue` accepts optional `settings: { model?, effort?, outputSchema? }`, applied at delivery. Codex accepts an output schema per turn; Claude requires it to match the process schema, except that HQ can install its shared directed-request envelope through an idle restart of the same native session. Codex uses native turn parameters; Claude acknowledges a native flag-layer update before sending that input. Startup instructions, permission settings and agent selection are excluded from this live path. Queue entries retain explicit settings; omitted options inherit native settings at delivery. Native rejection, partial control failure or lost acknowledgement never causes automatic input replay. Ordinary settings are not written to native configuration files. Confirmed startup instruction selections stay in the owned controller's memory; settings unavailable from native observation after reconnect are null.
187
+
188
+ Managed threads expose `nativeLineage: { sessionId, parentThreadId, forkedFromId } | null`, nullable `forkedFromThreadId`, and `isArchived`. Native IDs are kept exactly as observed; a session ID can differ from the thread ID. Unknown later fields never erase confirmed immutable lineage. A contradiction uses JG_AGENT_HQ_PROVIDER_FAILED. Native Claude history omits the fork source, so confirmed HQ fork metadata enriches that read. A fork whose creation is uncertain is never automatically created again; explicit replacement recovery uses the recorded source. Attaching an uncertain fork requires native evidence of its source relationship.
189
+
190
+ ## File inputs and complete results
191
+
192
+ Text and native skill inputs accept optional `files: [{ path, mediaType }]`. Paths may be absolute or relative to the managed workspace and must resolve inside an operator-authorized root. HQ opens a checked regular-file descriptor, validates UTF-8 or the declared format signature, and binds the canonical path, byte count and SHA-256 before admission. It rereads and verifies that binding immediately before native delivery. Missing, changed or escaping queued files fail without sending input. Symlinks cannot redirect delivery outside the trusted roots. URLs are never fetched.
193
+
194
+ The fixed limits are 8 references, 2,097,152 aggregate file bytes and 65,536 bytes per UTF-8 text file. Empty files, NUL-containing or invalid UTF-8 text, wrong signatures, unsupported media and oversized input are rejected. The 32,768-byte action envelope contains references, never base64. File bytes are encoded only inside the native 8 MiB frame; the file limits leave room even for worst-case JSON escaping.
195
+
196
+ Codex supports PNG, JPEG, WebP and UTF-8 text. Images use native `image` data inputs; text files become complete text inputs labeled with their canonical path and hash. Claude supports those formats plus GIF and PDF, using native image/document blocks. Media signatures establish the declared format, not complete image/PDF validity; native decoder or model rejection remains a provider failure. `capabilities.inputSchema` includes `supportedMediaTypes`, `maxFiles`, `maxFileBytes` and `maxTextFileBytes`. Native model-specific media limitations remain native errors.
197
+
198
+ Select a bounded JSON `outputSchema` in session settings or, for Codex, on a message/queue entry. Schemas are limited to 8,192 serialized UTF-8 bytes, 16 levels and 1,024 visited nodes, and must be supported by the installed Zod JSON Schema validator. External references are rejected and no remote schema is retrieved. Codex sends the selected schema as `turn/start.outputSchema`. Claude starts its owned structured process with `--json-schema`; a different schema requires close and explicit resume of the same native session. Its capability descriptor marks this as `idle-restart`.
199
+
200
+ Selected action receipts expose nullable `result: { state, format, text, structuredOutput, isComplete, failure, usage }`. Results come from the complete native final message/result, independently of the 65,536-character history/live preview. The serialized result budget is 8,257,536 UTF-8 bytes, leaving 128 KiB of the 8 MiB IPC frame for action, plan and transport metadata. Structured results retain the complete parsed value with `text: null`, avoiding a second escaped copy of the same JSON. This admits a 1 MiB UTF-8 report even when JSON escaping expands its content. HQ validates native structured output against the requested schema without stripping fields. Invalid or missing schema output fails the turn; oversized capture fails explicitly with no saved excerpt. Invalid but bounded JSON remains untrusted evidence in `structuredOutput`. The result is saved with native turn completion, survives a runtime restart and is omitted from action-list reads.
201
+
202
+ `failure` is null or `native-error`, `invalid-structured-output`, `result-too-large`, or `missing-result`. A native turn can complete without a final assistant message; without a requested schema, that remains completed with `isComplete: false` and `missing-result`. It cannot supply a complete report. Interrupted native execution remains interrupted unless capture itself exceeds the result budget. None of these outcomes causes automatic replay.
203
+
204
+ `usage` is nullable and contains known `inputTokens`, `outputTokens`, `cachedInputTokens` and accounting `scope`. Built-in adapters expose per-turn observations, not billable counters; missing or malformed optional usage is unavailable without invalidating essential completion evidence. Native MCP/dynamic tool calls and Claude tool blocks appear as bounded `tool` items. Truncation and live gaps remain explicit. Complete final results are authoritative retained records, not a parallel conversation cache.
205
+
49
206
  ## Claude history
50
207
 
51
208
  Claude connects on its first read through `claude --print --input-format stream-json --output-format stream-json --verbose`. No user prompt, bare mode, permission bypass or SDK dependency is used. Runtime status reports this adapter as `idle`, `ready` or `unavailable`, with its observed CLI version. An unavailable native lane requires restarting the host after resolving the native problem.
52
209
 
53
- The qualified CLI interface has no session-history listing operation. The Claude-owned reader therefore uses direct UUID JSONL files in the native project's directory beneath `CLAUDE_CONFIG_DIR`, or the normal `.claude` directory. The running CLI must match 2.1.304 or 2.1.306. Transcript records may independently use the qualified formats 2.1.296, 2.1.299, 2.1.304 and 2.1.306, including multiple qualified formats within one session. Qualifying a stored record format does not qualify that executable version. Other formats, encoded project keys longer than 200 characters, directory/file links, malformed records and records larger than 1 MiB report unavailable. Discovery never recurses into subdirectories, including excluded directories. Unsupported discovered sessions have `historyState: unavailable`; they do not prevent supported sessions from being listed.
210
+ The structured CLI interface has no session-history listing operation. The Claude-owned reader therefore uses direct UUID JSONL files in the native project's directory beneath `CLAUDE_CONFIG_DIR`, or the normal `.claude` directory. CLI and transcript version labels do not gate reads. Required session identity, workspace, parent links, timestamps and message roles are validated, while additive fields and mixed version labels are tolerated. Encoded project keys longer than 200 characters, directory/file links, malformed required fields and records larger than 1 MiB report unavailable. Discovery never recurses into subdirectories, including excluded directories. Unsupported discovered sessions have `historyState: unavailable`; they do not prevent supported sessions from being listed.
54
211
 
55
212
  Discovery verifies the workspace recorded inside each transcript before returning its identity or title. A matching native directory name alone is insufficient because punctuation replacement can produce colliding directory keys. Native working directories may be the selected workspace or its subdirectories, including removed subdirectories. The nearest existing path ancestor must resolve inside the workspace without excluded segments; sibling paths and symlink escapes are rejected. Foreign workspaces are omitted. If a file's workspace cannot be established, discovery reports unavailable rather than inventing an empty result.
56
213
 
57
- The existing SQLite worker incrementally records file identity, complete-line offsets, message identities and parent links. It does not save message bodies. File identity includes the reader projection revision and qualified record formats, so a reader capability change refreshes rejected or obsolete projections from native files. Each worker batch inspects at most 128 directory entries and reads at most 4 MiB of new transcript bytes, one file at a time. The adapter continues batches with a host-event-loop yield between them, within a 30-second operation budget. If that budget is reached, the read reports unavailable and subsequent reads continue indexing. At most four incomplete discovery iterators remain open. Shutdown closes them. Discovery continuations use that projection without starting another directory scan; start a fresh first page to refresh discovery. Removed files are discarded from the projection after a complete refresh. No additional cache infrastructure or browser cache is used.
214
+ The existing SQLite worker incrementally records file identity, complete-line offsets, message identities and parent links. It does not save message bodies. File identity includes the current reader projection revision and a native prefix hash, so source changes invalidate the derived projection. Each worker batch inspects at most 128 directory entries and reads at most 4 MiB of new transcript bytes, one file at a time. The adapter continues batches with a host-event-loop yield between them, within a 30-second operation budget. If that budget is reached, the read reports unavailable and subsequent reads continue indexing. At most four incomplete discovery iterators remain open. Shutdown closes them. Discovery continuations use that projection without starting another directory scan; start a fresh first page to refresh discovery. Removed files are discarded from the projection after a complete refresh. No additional cache infrastructure or browser cache is used.
58
215
 
59
216
  Current-chain membership and turn starts are indexed as metadata. Ordinary item and turn continuations seek those indexes; they do not walk the full chain per page. A changed branch rebuilds membership before exposing that revision. Repeated native message identities can replace content while retaining their parent; a changed parent for the same identity is an unsupported format.
60
217
 
61
- Selected history reads refresh only that file, retain incomplete tails, and detect truncation or replaced identity. Changed branch/file revisions invalidate item and turn continuations. Only the current parent-linked conversation chain is returned. Text is reread from the native file for the selected page and normalized as plain text. Non-text content has explicit native block labels. Each selected page reads at most 4 MiB of record bytes and returns at most 4 MiB of serialized item presentation, so a large-text page can contain fewer rows than its requested limit.
218
+ Selected history reads refresh only that file, retain incomplete tails, and detect truncation or replaced identity. Changed branch/file revisions invalidate item and turn continuations. Only the current parent-linked conversation chain is returned. Text is reread from the native file for the selected page and normalized as plain text. Tool calls show their native name and input; tool results have kind `tool`. Other non-text content has explicit native block labels. An unknown record containing content is returned as an `unsupported` item when its identity and chain are trustworthy; it cannot imply an agent response, idle state or completion. Each selected page reads at most 4 MiB of record bytes and returns at most 4 MiB of serialized item presentation, so a large-text page can contain fewer rows than its requested limit.
62
219
 
63
220
  File timestamps and records do not prove that a native process is idle or a turn completed. Claude file-backed thread and turn states are therefore `unknown`, with no invented completion timestamp. Explicit native custom titles are preserved; a missing title remains null. File-backed grouping follows native user records and parent links, including generated user-record markers; it is not an authoritative execution boundary.
64
221
 
@@ -66,21 +223,26 @@ File timestamps and records do not prove that a native process is idle or a turn
66
223
 
67
224
  Send `{ kind: 'action', action: { id, runtimeEpoch, command } }`. Generate one UUID per user intent, take the epoch from `status`, and retain the complete envelope until its receipt can be read. The validated envelope is limited to 32,768 UTF-8 bytes. It is recorded before native writes. Reusing the UUID with the identical envelope returns the saved receipt without dispatch; a changed envelope conflicts. This check also works for an original request read after restart. A new UUID with an expired epoch cannot execute.
68
225
 
69
- | Action | Fields and behavior |
70
- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
71
- | `thread-create` | `provider` (`codex` or `claude`), `workspaceRoot`, `name`. Creates an empty native thread and sets its readable name before reporting acknowledgement. |
72
- | `thread-adopt` | The same fields plus `nativeId`, `operatorConfirmation`. Explicitly transfers an external thread after confirmed inactive ownership. Codex must report it unloaded; Claude requires qualified workspace history and the native idle/session-identity checks. |
73
- | `thread-resume` | `threadId`, `operatorConfirmation`. Resumes an inactive managed thread; HQ does not fetch its complete conversation bodies. |
74
- | `thread-recover` | `threadId`, `operatorConfirmation`, `recovery`. The recovery is `{ kind: 'resume' }` for a known native identity, `{ kind: 'attach', nativeId }` for an inspected identity after uncertain creation, or `{ kind: 'create' }` to explicitly create a fresh empty thread when no native identity was recorded. The latter can leave an empty orphan from the uncertain creation; it never repeats a message. |
75
- | `thread-rename` | `threadId`, `name`. Changes the name only after the matching native acknowledgement. |
76
- | `thread-close` | `threadId`. Requires an idle thread and pauses its queue. Codex cleans and verifies its native terminal list before unsubscribe. Claude closes the owned CLI and proves process-group exit before releasing control. |
77
- | `message` | `threadId`, `input`. Starts a turn only while idle. |
78
- | `steer` | `threadId`, `expectedTurnId`, `text`. Codex uses native `turn/steer`. Claude rejects this operation; it never substitutes interruption. A finished or changed turn cannot become a new turn. |
79
- | `queue` | `threadId`, `expectedTurnId`, `input`. Saves an explicit next-turn message or skill invocation, never a permission or question answer. |
80
- | `queue-send` | `queuedActionId`. Explicitly authorizes a still-undelivered queue entry, including a queue paused by restart or interruption. |
81
- | `queue-cancel` | `queuedActionId`. Cancels only an undelivered queue entry and clears its saved body. |
82
- | `interrupt` | `threadId`, `expectedTurnId`. A native request acknowledgement leaves the thread stopping until native completion evidence arrives. |
83
- | `native-reply` | `threadId`, `expectedTurnId`, `approvalId`, `response`. Answers one exact current native request; cannot consume queue text. |
226
+ | Action | Fields and behavior |
227
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
228
+ | `thread-fork` | Source `threadId`, child `name`. Requires an idle owned source or an inactive managed source. Creates a distinct native session and retains `forkedFromThreadId` and exact native lineage without inheriting plan authority. |
229
+ | `thread-archive` | Idle owned `threadId`. Confirms native background cleanup, archives natively and releases control. |
230
+ | `thread-unarchive` | Inactive archived `threadId`. Unarchives the exact native session and leaves it inactive. |
231
+ | `thread-compact` | Idle owned `threadId`. Records native admission separately from its correlated turn completion. Clears the live presentation and requires a fresh history read. |
232
+ | `thread-revert` | Idle owned `threadId`, exact `beforeTurnId`. Removes that native turn and later history; files and historical HQ receipts remain unchanged. Clears the live presentation and requires a fresh history read. |
233
+ | `thread-create` | `provider` (a registered provider ID), `workspaceRoot`, `name`. Creates an empty native thread and sets its readable name before reporting acknowledgement. |
234
+ | `thread-adopt` | The same fields plus `nativeId`, `operatorConfirmation`. Explicitly transfers an external thread after confirmed inactive ownership. Codex must report it unloaded; Claude requires qualified workspace history and the native idle/session-identity checks. |
235
+ | `thread-resume` | `threadId`, `operatorConfirmation`. Resumes an inactive managed thread; HQ does not fetch its complete conversation bodies. |
236
+ | `thread-recover` | `threadId`, `operatorConfirmation`, `recovery`. The recovery is `{ kind: 'resume' }` for a known native identity, `{ kind: 'attach', nativeId }` for an inspected identity after uncertain creation, or `{ kind: 'create' }` to explicitly create a fresh empty thread when no native identity was recorded. The latter can leave an empty orphan from the uncertain creation; it never repeats a message. |
237
+ | `thread-rename` | `threadId`, `name`. Changes the name only after the matching native acknowledgement. |
238
+ | `thread-close` | `threadId`. Requires an idle thread and pauses its queue. Codex cleans and verifies its native terminal list before unsubscribe. Claude closes the owned CLI and proves process-group exit before releasing control. |
239
+ | `message` | `threadId`, `input`. Starts a turn only while idle. |
240
+ | `steer` | `threadId`, `expectedTurnId`, `text`. Codex uses native `turn/steer`. Claude rejects this operation; it never substitutes interruption. A finished or changed turn cannot become a new turn. |
241
+ | `queue` | `threadId`, `expectedTurnId`, `input`. Saves an explicit next-turn message or skill invocation, never a permission or question answer. |
242
+ | `queue-send` | `queuedActionId`. Explicitly authorizes a still-undelivered queue entry, including a queue paused by restart or interruption. |
243
+ | `queue-cancel` | `queuedActionId`. Cancels only an undelivered queue entry and clears its saved body. |
244
+ | `interrupt` | `threadId`, `expectedTurnId`. A native request acknowledgement leaves the thread stopping until native completion evidence arrives. |
245
+ | `native-reply` | `threadId`, `expectedTurnId`, `approvalId`, `response`. Answers one exact current native request; cannot consume queue text. |
84
246
 
85
247
  Message and queue input is a closed union: `{ kind: 'text', text }` or `{ kind: 'skill', skillId, arguments }`. Text is nonempty and at most 65,536 characters; skill arguments may be empty and cap at 16,384 characters. The envelope's UTF-8 limit still applies. A selected skill is resolved through the target thread's current native catalog before admission. Unavailable, missing or disabled selections cannot dispatch. Normal text needs no catalog read. Steering retains its `text` field and exact active-turn target.
86
248
 
@@ -88,7 +250,7 @@ Names use lowercase ASCII letters, digits and hyphens, start with a letter or di
88
250
 
89
251
  Codex may keep an idle native thread loaded after `thread/unsubscribe`. An explicitly confirmed resume may reacquire that thread only when its known HQ control is inactive and managed. Active native threads, uncertain HQ ownership and already controlled idle sessions remain blocked. Other adoption and recovery checks are unchanged.
90
252
 
91
- Receipts separate `delivery` (`queued`, `submitted`, `acknowledged`, `uncertain`, `failed`, `canceled`) from nullable native turn `completion` (`completed`, `failed`, `interrupted`). Acknowledgement means the exact native request was accepted, not that the turn or tool completed. Permission replies remain submitted after a pipe write and become acknowledged only when Codex resolves the exact native request or Claude returns a tool-result block for the exact tool-use identity. Claude cancellation expires the prompt and leaves an unacknowledged written reply uncertain. Resolution does not prove a tool ran. The receipt includes HQ/native identity, request phase, digest, timestamps, safe failure classification and optional related action. Only selected receipts expose undelivered `queuedText` and `queuedSkill`; collection reads omit both. Queued native skill selections contain a native name and nullable source path, never skill content. Both are cleared after delivery acknowledgement or cancellation.
253
+ Receipts separate `delivery` (`queued`, `submitted`, `acknowledged`, `uncertain`, `failed`, `canceled`) from nullable native turn `completion` (`completed`, `failed`, `interrupted`). Acknowledgement means the exact native request was accepted, not that the turn or tool completed. Permission replies remain submitted after a pipe write and become acknowledged only when Codex resolves the exact native request or Claude returns a tool-result block for the exact tool-use identity. Claude cancellation expires the prompt and leaves an unacknowledged written reply uncertain. Resolution does not prove a tool ran. The receipt includes HQ/native identity, request phase, digest, timestamps, safe failure classification and optional related action. Only selected receipts expose undelivered `queuedInput` and the nullable complete native `result`; collection reads omit both. Queued input retains prepared text, native skill identity, content-bound file references and explicit turn settings, never file bytes or skill content. It is cleared after delivery acknowledgement or cancellation.
92
254
 
93
255
  A missing acknowledgement never triggers an automatic resend. Exact late responses reconcile delivery, including completion that arrived first. Native output loss marks the affected provider controls and submitted work uncertain. A Claude process failure affects its own session; a Codex transport failure affects its Codex cohort. Restart quarantines controls from an interrupted runtime; explicit recovery preserves the HQ identity and name. Successful shutdown proves native process-group exit before marking controls inactive. Unknown creation without a native identity remains uncertain.
94
256
 
@@ -99,18 +261,23 @@ Native replies use one of these closed response forms:
99
261
  - `{ kind: 'decision', decision: 'accept' | 'acceptForSession' | 'decline' | 'cancel' }` for command/file approval, restricted to the choices Codex offers.
100
262
  - `{ kind: 'permission', decision: 'accept' | 'decline', scope: 'turn' | 'session' }` for additional permissions. Acceptance copies only the complete displayed native scope. Unknown permission fields cannot be approved.
101
263
  - `{ kind: 'answers', answers: { [questionId]: [answer] } }` for native questions. Every requested question must have an answer; `allowsMultiple` indicates whether several answers are allowed. Codex questions accept one answer, and predefined choices are enforced when free text is unavailable.
264
+ - `{ kind: 'elicitation', action: 'accept' | 'decline' | 'cancel', content }` for MCP forms and URL requests. Accepted forms require an object matching the exact native JSON Schema. URL acceptance, decline and cancellation require `content: null`. Responses never open a URL or fetch a schema.
265
+
266
+ Approval records expose `replyActionId` as soon as a reply is admitted, so reconnecting clients can read its receipt and avoid offering another answer while native resolution is pending. `approvals` accepts `threadId`, optional `state`, `limit` (default 32, maximum 128) and a query-bound `cursor`; it returns `{ data, nextCursor }` in descending `(createdAt, id)` order. Indexed seek reads do not load the complete history. State filters are live views, so refresh the first page to observe new records or transitions above a continuation position.
102
267
 
103
- Prompts expose `replyActionId` as soon as a reply is admitted, so reconnecting clients can read its receipt and avoid offering another answer while native resolution is pending. Prompts and answers remain in memory. SQLite retains only native request identities, scope fingerprints and reply receipts. Fingerprints use a per-store HMAC key in the private 32-byte `action.key`. Keep that file with the database; a missing or invalid key on a nonempty store fails closed. Ordinary message bodies are not saved by HQ. Undelivered queued messages are saved until dispatch or cancellation.
268
+ Each record contains identity, `kind`, `isBlocking`, `state`, `replyActionId`, timestamps and nullable `presentation`. Presentation contains the complete native title, detail, decisions, questions and optional elicitation metadata. It is available only for a matching live pending request. Resolved or expired records retain metadata after reconnect and restart, with `presentation: null`. Restart and native disconnect expire pending requests; they never recreate response authority. `expired` means the request is no longer answerable, not that a submitted response was rejected. Prompt bodies and answers remain in memory. SQLite retains only native request identities scoped to their managed thread, scope fingerprints and reply receipts. Fingerprints use a per-store HMAC key in the private 32-byte `action.key`. Keep that file with the database; a missing, invalid or mismatched key on a nonempty store fails closed. Ordinary input bodies are not saved by HQ. Undelivered queued inputs are saved until acknowledgement or cancellation. Complete native final results are retained on the selected action receipt; streamed token and tool-output bodies remain native.
104
269
 
105
270
  ### Claude native control
106
271
 
107
- Each controlled session has one persistent native `claude` process in the authorized workspace. HQ adds structured input/output, replayed user-message acknowledgements, partial-message output and `--permission-prompt-tool=stdio`. It does not set a model, replace instructions/settings, disable session persistence, bypass permissions or enable a bare mode. Native skills remain available. Control was exercised against CLI 2.1.304 and 2.1.306. Native idle initialization, session identity and matching acknowledgements establish capability; a changed version label alone does not disable compatible controls. File history retains its separate qualified-version check.
272
+ Each controlled session has one persistent native `claude` process in the authorized workspace. HQ adds structured input/output, replayed user-message acknowledgements, partial-message output and `--permission-prompt-tool=stdio`. It applies only explicitly selected startup options, including model, instructions or an output schema. It preserves normal native settings, session persistence and permission handling. Native skills remain available. Native idle initialization, session identity and matching acknowledgements establish capability. Version labels and missing diagnostic version metadata do not disable compatible controls or file history.
108
273
 
109
274
  Creation chooses a native UUID without inference, then names that exact session. Resume uses native `--resume` and verifies the session-id fence on the name control before marking the session idle. The operator's handoff confirmation establishes that another CLI controller is closed; file timestamps and file-backed unknown states do not establish this. Independently running CLIs are outside HQ's state-directory coordination boundary.
110
275
 
111
276
  An ordinary message is submitted only while idle. Its native UUID becomes the turn identity. A matching native replay or result acknowledges delivery, and the native result establishes completion. A request-success envelope can acknowledge a name change or interruption without a response body. HQ never writes queued follow-up input into Claude's own busy queue; the shared HQ queue dispatches it only after the previous result. Interruption acknowledgement alone does not establish a stop. An error result is classified as interrupted only when the qualified native interruption marker was observed for an explicitly interrupted input. Other terminal errors remain failed.
112
277
 
113
- Claude questions use exact question text as their answer identity and expose whether multiple selections are supported. Tool permissions offer `accept` or `decline` for the displayed input only. Session-wide permission changes are unavailable; HQ does not apply native permission suggestions automatically. A reply is written through the separate control channel and acknowledged only by the matching tool result. Tool execution can still fail after that acknowledgement. Reused raw request IDs in different CLI processes have distinct controller scopes. Prompt bodies and replies remain out of SQLite.
278
+ Claude questions use exact question text as their answer identity and expose whether multiple selections are supported. Claude can_use_tool permissions use response `{ kind: 'decision', decision: 'accept' | 'decline' }`; question replies use `{ kind: 'answers', answers }`. The response kind `permission` with a turn/session scope belongs to Codex additional permissions. Tool permissions offer `accept` or `decline` for the displayed input only. Complete request details include native policy hints and reasons as untrusted display data; none authorizes a response. Unsupported permission fields or interaction surfaces receive an unsupported-request error. Requests requiring a native interaction card cannot be answered with generic approval; supported `AskUserQuestion` cards use their typed answer contract. Session-wide permission changes are unavailable; HQ does not apply native permission suggestions automatically. A reply is written through the separate control channel and acknowledged only by the matching tool result. Tool execution can still fail after that acknowledgement. Reused raw request IDs in different CLI processes have distinct controller scopes. Prompt bodies and replies remain out of SQLite.
279
+
280
+ Both providers support turn-correlated MCP `form` and `url` elicitation. Forms use bounded local JSON Schema validation (8 KiB, 16 levels, 1,024 nodes); responses stay within the action envelope’s 32 KiB budget. Unknown modes, unsupported schemas and Codex requests without a native turn are denied. Elicitation URLs are HTTP(S) links without embedded credentials; applications decide how to display or open them. Never render native strings as HTML or terminal instructions, and never infer a permission decision from model output or form metadata. Codex acknowledges an elicitation reply through its exact native request-resolution event. Claude supplies no equivalent form-reply acknowledgement: a successful write stays submitted, and terminal completion or cancellation expires the request and makes its unresolved reply uncertain. Retrying that same action returns its receipt without sending again.
114
281
 
115
282
  Partial text uses temporary live identities until the final native message UUID arrives; that replacement shares the existing global live-item budget. Native thinking content is not copied into text presentation. Persisted history reconciles matching final items through the same content normalizer. Closing the session proves owned process-group exit, including native background children, before HQ releases control.
116
283
 
@@ -137,12 +304,12 @@ Trusted runtime construction also accepts `codexExtraSkillRoots?: string[]` and
137
304
  | `receipt` | `actionId` | One receipt or null. |
138
305
  | `actions` | `threadId`, optional `limit`, `cursor` | Creation/UUID seek page of action metadata without queued bodies. |
139
306
  | `events` | `threadId`, optional `after` (default 0), `limit` | Ascending durable sequence page and `hasMore`; continue after the final sequence. |
140
- | `approvals` | `threadId` | Current in-memory native prompts, including exact scope and question metadata. |
307
+ | `approvals` | `threadId`, optional `state`, `limit`, `cursor` | Durable approval metadata pages with nullable live presentation. |
141
308
  | `live-items` | `threadId` | Active/awaiting-flush item window, `hasGap`, `revision` and `unchanged`. Optional `afterRevision` omits bodies for an unchanged window. |
142
309
 
143
310
  The installed CLI exposes `managed-thread-name --name <name>` and `suggest-thread-name --topic <topic>`. Suggestions normalize punctuation to hyphens, keep at most 32 characters, and use `session` when the topic contains no ASCII letters or digits. Creation checks availability again inside its admission transaction. All action targets, histories and relationships continue to use immutable HQ/native identities. Name lookup never adopts, resumes or starts a native session.
144
311
 
145
- Control pages default to 32 and cap at 128. Seek cursors are bound to their complete query and ordering. Reads recheck allowed workspaces. Rejected controls retain their known thread association, and native availability failures appear in each affected thread's replay. Lifecycle replay contains metadata, not token or tool output. The native lifecycle backlog is bounded to 128 operations; an overflow stops native control and marks its state uncertain rather than losing events silently.
312
+ Control pages default to 32 and cap at 128. Seek cursors are bound to their complete query and ordering. Reads recheck allowed workspaces. Rejected controls retain their known thread association, and native availability failures appear in each affected thread's replay. Lifecycle replay contains metadata, not token or tool output. Each provider has a bounded native lifecycle backlog; overflow stops that source and marks its state uncertain rather than losing events silently. Other providers retain their independent connection and admission state.
146
313
 
147
314
  Live item presentation is bounded to 128 items per cached thread, 32 windows and 4 MiB of serialized presentation across the runtime, including escaped text and identifiers. This leaves room inside the IPC response limit. Display text uses the same truncation contract as native history. Eviction, an unavailable window or missing chunks sets `hasGap`. Completed items remain `awaiting-flush` after thread closure until a native history page contains exactly matching normalized content or the bounded cache evicts them. Read persisted history and the live window together after reconnect; a process restart cannot reconstruct unflushed in-memory content.
148
315
 
@@ -168,13 +335,17 @@ Output is one JSON line with `schemaVersion: 1`. Read output includes the comman
168
335
 
169
336
  ## Plan coordination
170
337
 
171
- `computePlanRevision({ body, metadata, milestones })` is the pure Node API for execution identity. `metadata` contains `scope`, `repositories` and `errorReservations`. Reservation entries contain `repository`, `namespace`, inclusive `start`/`end`, `registryPath` and `purpose`; this API hashes them and does not allocate codes. Repository and reservation order is canonicalized. Plan bodies normalize line endings only. Private coordinators supply the body after parsing their own frontmatter; ordinary planning directories use the entire plan file.
338
+ `computePlanRevision({ body, metadata, milestones })` is the pure Node API for execution identity. `metadata` contains `scope`, `repositories`, `errorReservations` and JSON-safe `extensions`. Reservation entries contain `repository`, `namespace`, inclusive `start`/`end`, `registryPath` and `purpose`; this API hashes them and does not allocate codes. Repository and reservation order is canonicalized; object keys use strict deterministic JSON. The exact parsed body, including its line endings, is contractual.
339
+
340
+ Send `{ kind: 'plan', command }` through the existing local request API. Every command selects `target: { directory }`, an absolute directory inside an allowed workspace. The default profile uses jg-plans observations: absent HQ fields default to local scope and empty repository/reservation lists; unknown fields, including plan `id`, remain in `extensions`. Only `created_at`, `updated_at`, `revision` and `status` are administrative. Malformed, non-mapping or non-JSON metadata fails closed. No preferred-document conformance gate is imposed.
172
341
 
173
- Send `{ kind: 'plan', command }` through the existing local request API. Every command selects `target: { directory }`, an absolute directory inside an allowed workspace. A private host supplies `parsePlanContract({ directory, content })` when constructing the runtime. It returns the exact body after frontmatter and its contract metadata from the current file. The core validates that exclusion boundary and metadata while leaving private frontmatter policy with its owner. With no parser, the whole ordinary plan is contractual. The private server resolves operator identity itself and never forwards browser-supplied roots, contract exclusions or metadata.
342
+ A trusted private host may supply `parsePlanContract({ directory, content })`. It must return exactly the body observed by jg-plans and valid HQ metadata. That host owns its alternative metadata profile and must put its contractual extension fields in `extensions`. It cannot exclude body prose. The private server resolves operator identity itself and never forwards browser-supplied roots, contract exclusions or metadata.
343
+
344
+ Milestone contracts retain every requirement byte outside observed status/identity lines, plus preamble and all intervening/trailing shared sections. Only recognized Overview table spans and the three valid `jg_skills` binding fields are excluded; other milestone metadata remains contractual. HQ does not regenerate Overview tables. Statuses must be exactly pending, in progress or done, and milestone IDs/order participate in sequence identity. Ordinal renumbering alone does not change a milestone's identity. Missing IDs are assigned explicitly by jg-plans and saved before application. When present, a skills binding must match the current plan id, revision and fingerprint excluding exactly the four administrative keys. A matching binding never grants HQ approval or execution permission.
174
345
 
175
346
  | Command kind | Required fields and result |
176
347
  | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
177
- | `status` | `target`. Returns current execution revisions, full inspection hashes, approval state and a bounded coordination summary and retained-evidence counts. |
348
+ | `status` | `target`. Returns current execution revisions, full inspection hashes, `skillsBinding` (`absent`, `current` or `stale`), approval state and a bounded coordination summary and retained-evidence counts. |
178
349
  | `milestones` | `target`, optional `limit` (default 32, maximum 128) and `cursor`. Returns a bounded ordered seek page. |
179
350
  | `finalize` | `target`, `action`, `expected`. Assigns initial UUIDs or reconciles a checkpoint. Returns the complete canonical file, or a saved proposal needing one confirmation. Optional `confirmation: { proposalId, decisions }` resolves every unmatched source. |
180
351
  | `begin-revision` | `target`, `action`, `expected`, `intent: 'plan' \| 'breakdown'`, `threadIds`, `checkouts`. Closes execution admission and starts owned interruption/checkpoint work. |
@@ -190,13 +361,23 @@ Send `{ kind: 'plan', command }` through the existing local request API. Every c
190
361
 
191
362
  Milestones are optional. Finalizing a plan with no milestone file returns `content: null` and does not create a file. That unit needs plan approval and explicit execution authorization, with `milestoneIds: []`; execution checks, completion and native execution scopes select it with `milestoneId: null`. A real breakdown requires a nonempty selection of its stable IDs and its separate sequence approval. Null cannot select a milestone or bypass sequence approval. Whole-plan completion retains its exact plan contract/digest, actual check references and checkout evidence, with null shared-sequence digest. Completed work cannot be authorized again under that unchanged contract.
192
363
 
193
- A first-use sequence has one `**Milestone ID:** <uuid>` immediately below each `**Status:**` line. Blank lines may separate the heading from its status; no intervening requirement prose is allowed. The initial finalizer rejects duplicate, malformed or misplaced IDs and inconsistent framing. It refreshes existing Overview status rows and returns the complete canonical file for presentation before approval. A changed finalized contract goes through checkpoint reconciliation. A raw or changed sequence cannot inherit finalized status or sequence authority. A done marker remains visible but blocks execution without completion evidence.
364
+ Skills bindings are optional for generic HQ plans. When present, their syntax must be valid and their plan ID, revision and structural fingerprint must match before finalization or execution. A valid but stale binding remains visible in status: plan approval and explicit revision invocations remain available so jg-plan can retain the old sequence until jg-breakdown refreshes its coverage. Malformed bindings fail as invalid artifacts. A stale binding never supplies sequence approval or completion, even when semantic execution digests are unchanged.
365
+
366
+ A first-use sequence has one `**Milestone ID:** <uuid>` immediately below each `**Status:**` line. Blank lines may separate the heading from its status; no intervening requirement prose is allowed. The initial finalizer rejects duplicate, malformed or misplaced IDs and inconsistent framing. It preserves existing Overview text and returns the complete canonical file for presentation before approval. A changed finalized contract goes through checkpoint reconciliation. A raw or changed sequence cannot inherit finalized status or sequence authority. A done marker remains visible but blocks execution without completion evidence.
194
367
 
195
- The milestone contract includes its stable UUID, title without its ordinal, all requirement prose, shared sequence requirements and the approval statement. Status and identity marker lines are excluded from the prose; only the derived Overview table is excluded from shared text. Prose next to that table remains contractual. Sequence order is significant. Renumbering preserves execution identity; changed requirements, dependencies, scope, reservations or order require applicable approval. Full-file hashes preserve exact UTF-8 bytes and are distinct from normalized execution revisions. Administrative frontmatter excluded by the trusted contract parser, session labels, status advancement and coordination receipts do not change execution digests.
368
+ The milestone contract includes its stable UUID, title without its ordinal, all requirement prose, shared sequence requirements and the approval statement. Status and identity marker lines are excluded from the prose; only the derived Overview table is excluded from shared text. Prose next to that table remains contractual. Sequence order is significant. Renumbering preserves execution identity; changed requirements, dependencies, scope, reservations or order require applicable approval. Full-file hashes preserve exact UTF-8 bytes and are distinct from semantic execution revisions. Administrative frontmatter excluded by the trusted contract parser, session labels, status advancement and coordination receipts do not change execution digests.
196
369
 
197
370
  Plan and milestone artifacts are bounded to 1 MiB each; coordination evidence is bounded to 8 MiB and a sequence to 1,024 milestones. Reads do not scan planning trees. Milestone pages use ordinal seek ordering with unique ascending ordinals. Cursors bind the selected directory, page size, execution revisions and exact milestone inspection hash. Any changed artifact requires a fresh page; renumbering or status-only edits still preserve approval. A SQLite projection is rebuilt only when the selected milestone file's full hash changes. Every read verifies its source file; the projection is replaceable and never grants authority.
198
371
 
199
- Mutations hold the shared metadata lock at `<coordinationRoot>/.runtime/hq.lock` (`coordinationRoot` defaults to `stateRoot`), retain a durable action identity and intended write before changing files, sync temporary files and atomically replace each artifact. Use `serve --coordination-root <directory>` when the canonical coordination lock is separate from runtime storage. Repeating an action UUID with the identical payload never reapproves revoked work. A changed payload conflicts. An interrupted write remains blocked and can be retried with its original action only when files match the recorded baseline or exact intended output. Conflicting edits are preserved. Completed write bodies are removed from SQLite while replay identity remains. The current finalization receipt retains the operator event, execution revision, nullable canonical file hash and timestamp independently of write recovery bodies. Status reads expose `pendingActionId` for unresolved writes; they never approve or resume work.
372
+ Mutations acquire the HQ metadata lock at `<coordinationRoot>/.runtime/hq.lock` (`coordinationRoot` defaults to `stateRoot`), then the public jg-plans document locks in plan-before-milestones order. Use `serve --coordination-root <directory>` when coordination ownership is separate from runtime storage. Locks cover bounded observation, preparation, journaling and file application; no model turn or native stop wait holds them. A busy document lock becomes `JG_AGENT_HQ_ACTION_CONFLICT` with the safe `document-locked` reason. There is no automatic stale-lock takeover.
373
+
374
+ SQLite persists exact prepared plan/milestone sources, assigned IDs and timestamps before application. A plan source of null means keep; milestone operations are explicitly keep, write with source, or remove. A null recorded before-plan hash permits only coordination work. Replay accepts only each recorded baseline or its exact desired state. Markdown is applied before coordination. Every HQ replacement uses jg-fs checked atomic writes with explicit 0600; absent targets are created exclusively and privately before content is written. Strict bounded, same-handle, single-link reads remain in HQ. Inspection alone never changes file permissions.
375
+
376
+ After file durability succeeds, document locks must release successfully before SQLite marks the intent completed and clears its write bodies; HQ metadata ownership remains held through completion. A write, sync or release failure retains the prepared payload and closes admission. A crash after release and before completion is replayable. A failed completion acknowledgement is reconciled against the durable ledger: confirmed completion succeeds, an uncommitted intent stays pending, and an unknown outcome remains closed. Retry only the same original action and payload after inspection; changed files or payloads conflict. Nonparticipating writers still have a final comparison-to-replacement/removal race; these operations are not a multi-file transaction.
377
+
378
+ Accepted implementation input prepares aggregate and selected pending milestone progress before native admission. Message, queue and steering requests record accepted implementation scope; an in-progress marker does not assert that a provider has started or completed a turn. Progress is journaled and released before current authority is checked again for native admission. A retry of the same native action can finish its retained progress intent without regenerating timestamps; it still needs current runtime/authorization checks. Native control and permission actions do not advance progress.
379
+
380
+ Only accepted completion evidence advances a milestone to done. Aggregate done requires the complete current execution contract, applicable current approval/finalization and verified completion; administrative done markers alone do not provide them. Progress-only plan changes preserve revision and set updated_at once in the saved prepared source. An unchanged plan preserves its timestamp. The current finalization receipt retains the operator event, semantic revision, nullable canonical file hash and timestamp independently of write recovery bodies. Status reads expose pendingActionId for unresolved writes and never approve or resume work.
200
381
 
201
382
  `coordination.json` includes required `comparisons`, an array bounded to 1,024 records validated by `PlanComparisonSchema`. Each record binds `sourceRevision`, `targetDirectory`, `targetRevision`, a `compatible` or `contradiction` verdict, `reason`, `reviewedAt` and reviewer provenance (`provider`, `cliVersion`, nullable observed `model`, and native message `reference`). A trusted coordinator writes these records while holding the same metadata lock. Core operations preserve them; status exposes only `comparisonCount`. They never change execution digests or grant authority. The coordinator owns relevance, freshness, semantic judgments, bounded review reads and any execution gate, including contradictions. The standalone core does not assess compatibility.
202
383
 
@@ -208,7 +389,7 @@ Begin revision before invoking a planning skill. Execution admission closes unde
208
389
 
209
390
  The local host supplies checkout evidence as `{ repository, directory, claimReference, paths }`. Paths are exact relative task paths. The core streams their contents, records link targets without following them, includes missing paths as deletions, and captures the current Git branch/HEAD. It does not stage or reset files and rejects traversal, parent-link escapes, `.git` and excluded archive/backup directories. Check commands and references are trusted operator evidence; this primitive does not execute arbitrary submitted commands or treat an imported agent claim as verification.
210
391
 
211
- After native `jg-plan` revises the contract and an explicitly requested `jg-breakdown` regenerates a needed sequence, close the planning controller before finalization. Only unique exact normalized title and complete-contract matches retain identity automatically. Every unmatched checkpoint source, including done and partial work, appears in one saved proposal. Confirmation decisions use `sourceIds`, `targetIds`, `relation` (`equivalent`, `requirements-changed`, `omitted`, `reopened`) and explicit one-to-one `retainedPairs`. One source ID cannot be assigned to multiple targets. Grouped decisions retain split/merged evidence. A complete equivalent mapping preserves verified completion or partial status; rewording does not create new checks. A changed requirement gets fresh pending identity. Explicit reopening preserves evidence while invalidating its completion credit. Unverified done markers cannot become verified through an equivalent mapping.
392
+ After native `jg-plan` revises the contract and an explicitly requested `jg-breakdown` regenerates a needed sequence, close the planning controller before finalization. Only unique exact title and complete-contract matches retain identity automatically. Every unmatched checkpoint source, including done and partial work, appears in one saved proposal. Status exposes its nullable `coordination.revision.proposalId`; clients use the paged reconciliation reads to present correspondence and confirm that exact saved identity. Confirmation decisions use `sourceIds`, `targetIds`, `relation` (`equivalent`, `requirements-changed`, `omitted`, `reopened`) and explicit one-to-one `retainedPairs`. One source ID cannot be assigned to multiple targets. Grouped decisions retain split/merged evidence. A complete equivalent mapping preserves verified completion or partial status; rewording does not create new checks. A changed requirement gets fresh pending identity. Explicit reopening preserves evidence while invalidating its completion credit. Unverified done markers cannot become verified through an equivalent mapping.
212
393
 
213
394
  A whole-plan checkpoint retains null milestones and an empty milestone inventory. If a revision removes a sequence because the remaining scope no longer needs one, every unmatched checkpoint milestone still requires explicit omission confirmation. Its verified evidence remains available; absence alone never resets progress or authorizes whole-plan execution.
214
395
 
@@ -220,58 +401,169 @@ Selected status/admission/queue observations detect external contract edits or m
220
401
 
221
402
  Retained evidence pages bind their collection, page size and exact coordination hash. Reads do not load complete collections into the client; SQLite rebuilds the replaceable projection only when its selected authoritative file changes. The file has a hard size/record bound and rejects growth beyond it without discarding evidence.
222
403
 
223
- ## Cross-provider handoffs
404
+ ## Task collaboration
405
+
406
+ Use `{ kind: 'collaboration', actor, command }` through `hq.request`, `requestAgentHq`, or the CLI's JSON `request` command. The response is `{ kind: 'collaboration', result }`. These are trusted same-user host/IPC operations. Applications authenticate operators and supply `{ kind: 'host', operatorRef }`; HQ compares that reference with the task owner. A host acting for a managed agent supplies `{ kind: 'agent', agentId }`. This actor field is not an authentication mechanism for an untrusted client. Agent IDs are immutable managed-thread UUIDs, separate from provider/native IDs and display names.
407
+
408
+ Every mutation has an `id` UUID. Creation uses that same UUID for the new task, stream, grant or message/request. Mutations return `{ kind: 'operation', operation }`, retaining the normalized command digest, actor, task, command kind and exact original result. Repeating the same identity and command returns that receipt; changing its payload conflicts. `operation-read` selects a receipt without replaying the effect. Reads return their selected result directly. Current membership/owner checks apply to replays and selected reads.
409
+
410
+ `task-create` requires `workspaceRoot`, `title`, `policy` and nullable `plan`. The policy specifies `providers`, `workspaceRoots`, `effects`, `canSpawn`, `canManagePeerSubscriptions`, `canExecuteRequests`, `automaticDispatch`, positive `concurrencyLimit`, nonnegative `spawnLimit` and `automaticTurnLimit`. No execution limits are inferred from a role. The policy must include the task workspace. Workspace roots and plan directories resolve through the runtime's allowed roots; metadata path prefixes are normalized relative paths, with `''` selecting a whole workspace. References identify evidence and do not grant filesystem access.
411
+
412
+ Commands scoped to an existing task require `taskId`:
413
+
414
+ | Commands | Additional fields and behavior |
415
+ | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
416
+ | `task-read`, `task-policy-set`, `task-plan-set`, `task-state-set` | Setters are owner-only and require `expectedRevision` plus `policy`, nullable `plan`, or `state`. Policy/plan share `policyRevision`; lifecycle uses `lifecycleRevision`. Active, paused and stopped states remain separate from native session state. |
417
+ | `tasks-list` | Uses `workspaceRoot` instead of `taskId`; returns only the host owner's tasks. |
418
+ | `agent-add`, `agent-read`, `agents-list`, `agent-policy-set`, `agent-state-set`, `agent-revoke` | Membership changes are owner-only. Add selects an existing `agentId`, nullable `parentAgentId`, nullable `role`, and `permissions`. Provider/workspace come from the managed thread. Set/revoke require current `expectedRevision`; reinstating a revoked membership also requires it. Child permissions cannot exceed their parent's current effective permissions when added or changed. |
419
+ | `grant-issue`, `grant-read`, `grants-list`, `grant-revoke` | Owner-only issue/revoke; read selects `grantId`, revoke also requires `expectedRevision`. Issue fields are nullable `eligibleAgentIds` (null means task-wide), exact `skills: [{name, mode}]`, `effects`, `scopes: [{workspaceRoot, pathPrefixes}]` and nullable `plan`. Grants start at revision 1; revocation increments revision. |
420
+ | `stream-create`, `stream-read`, `streams-list`, `stream-archive` | Create supplies `title`/`purpose`. Read/archive select `streamId`; archive supplies `isArchived` and requires the host owner or creating agent. List optionally filters `isArchived` or the calling agent's `subscribed: true` streams. Archiving preserves history and outstanding requests. |
421
+ | `subscription-set`, `subscription-read`, `subscription-advance` | Set/read select `streamId` and `agentId`. Set supplies `isActive`, `notify`, and optional `historyLimit` from 1 to 128 when joining. Agents manage themselves or peers only with current peer-management permission; the host owner can manage either. New subscriptions start at the stream's current boundary. Explicit historical notification is bounded. Advance selects `streamId` and monotonic `throughSequence` for the calling agent. Unsubscribe preserves existing assignments and delivery records. |
422
+ | `message-publish`, `messages-list`, `messages-search`, `message-read`, `message-ack` | Publication fields are described below. List/search optionally select `streamId`; search requires a literal nonempty `query`. Selected read/ack use `messageId`. Only a delivery recipient can acknowledge. |
423
+ | `request-read`, `requests-list`, `request-claim`, `request-resolve`, `request-cancel`, `request-reassign` | Selected operations use `requestId`. List optionally filters `agentId` (target or assignee) and `state`. Claim requires an eligible active agent; claimable work additionally requires an active stream subscription. Resolve requires an assigned, non-dispatched request, `outcome: 'completed' \| 'failed'` and 1–16 evidence `references`. Cancellation is available to the requester, assignee or owner. Reassign is requester/owner-only and requires `expectedAssigneeAgentId` plus `targetAgentId`; it requires no active or uncertain dispatch. Canceling dispatched work retains its binding until terminal collection and requests interruption of the exact native turn. |
424
+ | `deliveries-list`, `status`, `fanout-recover`, `operation-read` | Delivery list optionally selects `recipientAgentId` and `state: 'unacknowledged' \| 'undelivered' \| 'all'`, defaulting to unacknowledged; agents can read only their own deliveries. Status reports capped counts and `hasMore`, including undelivered and unacknowledged counts, current revisions and background fan-out/dispatch failure. Owner-only recovery schedules another bounded pass. Receipt read selects `operationId`, returning null when absent. |
425
+
426
+ List commands accept `limit` (default 32, maximum 128) and `cursor`. Pages return summaries with `nextCursor`; they omit message bodies, grant scopes, member permissions and request arguments. Cursors bind the exact actor and filters and preserve a fixed high-water boundary. Lists are newest-first by record sequence; subscribed-stream discovery follows subscription sequence. Searches match a literal phrase in summary/body or stored reports through task/stream-scoped FTS5, rather than accepting FTS operators from the caller. No automatic retention deletion or message summarization runs.
224
427
 
225
- Use the existing JSON client, `jg-agent-hq request --state-root <directory>`, or `runtime.request({ kind: 'handoff', command })`. All commands are closed contracts exported through `jg-agent-hq/contracts`.
428
+ `message-publish` requires `streamId`, `messageKind: 'information' | 'request' | 'reply' | 'status'`, `summary`, `body`, `references`, nullable `replyToMessageId` and nullable `request`. HQ derives the author from the trusted actor. Summaries are at most 1,024 UTF-8 bytes, bodies at most 8,192 UTF-8 bytes, and references at most 16. Reply publications require their same-task message link. Archived streams accept linked replies to outstanding requests, but reject ordinary new traffic. Message content remains immutable.
226
429
 
227
- | Command | Required fields | Result |
228
- | --------- | ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
229
- | `create` | `id` (UUID), `runtimeEpoch`, `sourceThreadId`, `purpose` (`challenge` or `review`); optional `commit` (exact current Git HEAD) | Saved handoff and opposite-provider thread creation receipt. |
230
- | `show` | `id` | Selected handoff, retained findings and separate creation/review/feedback delivery. |
231
- | `preview` | `id`, `phase` (`review` or `feedback`) | Exact native invocation, immutable target ID and preview digest; no native input. |
232
- | `send` | `id`, `phase`, `expectedPreviewDigest` | Explicit delivery through the existing action ledger. |
233
- | `collect` | `id`, `turnId`, `itemId`; optional `limit`/`cursor` for the selected native history page | One immutable completed reviewer message, with its hash and native references. |
234
- | `list` | `workspaceRoot`; optional `sourceThreadId`, `limit`, `cursor` | Seek page of summaries, without finding bodies. |
430
+ A request publication supplies exactly one assignment mode: a `targetAgentId` with `claimable: false`, or null with `claimable: true`. Its other fields are nullable `skill: {name, mode}`, nullable `grantId`/`grantRevision`, bounded `arguments`, `effects`, `scopes`, nullable `plan`, `targetReferences` and optional `returnStreamId`. A selected skill requires an exact unrevoked grant revision. Publication and claim check current policy and scopes; claim also checks the receiving agent's eligibility. Requests without a skill require no invented skill grant. `jg-execute` auto requests must explicitly cover commit and push effects. Grants do not replace workflow approval, native permissions or actual dispatch admission.
235
431
 
236
- Example creation request:
432
+ Artifact references select a report ID/hash, repository path with commit/hash and optional line range, native provider/session/turn/item/hash, or exact plan revision/milestone. Selected `message-read` returns the exact body and a bounded reference page, with byte/reference offsets and optional continuation. Collaboration responses fit within 65,536 serialized bytes; commands leave room inside the existing 65,536-byte IPC request envelope. Oversized input fails without partial publication.
237
433
 
238
- ```json
434
+ Broadcast notifications do not assign each subscriber work. Notification intent, native delivery (`nativeActionId`/`deliveredAt`), explicit `acknowledgedAt`, subscription read position, request claim and resolution remain independent. Information, reads and acknowledgements do not submit native input. Authorized directed request intent can wake the separate dispatcher. Directed intent persists even for an unsubscribed recipient. Subscriber fan-out runs in batches of at most 32 with transactionally retained progress; restart resumes it. A failed batch leaves durable intent and exposes `JG_AGENT_HQ_STORE_FAILED` in `status.fanoutFailure` until explicit recovery or runtime restart. The host owner can inspect all task metadata; revoked members cannot read or replay operations. Paused participants retain historical reads, while fresh claims require active task/member state.
435
+
436
+ Authorization failures use `JG_AGENT_HQ_COLLABORATION_FORBIDDEN`; conflicting command identities, assignments, lifecycle revisions and terminal transitions use `JG_AGENT_HQ_COLLABORATION_CONFLICT`. IPC maps these to the existing safe access-denied/state-conflict errors. Native execution and plan approval remain separate contracts.
437
+
438
+ ### Directed requests and exact reports
439
+
440
+ An idle directed recipient runs when `policy.automaticDispatch` is enabled, or when the owner commits `request-dispatch` with `requestId`. A claimed request is eligible through its one assignee. Busy requests retain `pendingActionId` and a visible `dispatchBlockedReason`; HQ submits at a safe native boundary. Admission atomically reserves one active dispatch per agent across tasks, task concurrency and one cumulative `automaticTurnCount` for an automatic attempt. Explicit host dispatch/input/resumption does not consume that automatic budget. Already admitted failed or uncertain attempts retain their consumed count. No timer or model turn polls for work.
441
+
442
+ Each dispatch uses the existing native action ledger and an immutable selected invocation context. `currentActionId` stays held through terminal outcome collection, so ordinary queued input cannot run ahead of it. `lastActionId`, `lastReportId`, `dispatchCount`, `requiredAuthority`, `failureReason` and blocked reasons remain inspectable on the request. Known ownership, exact assignment, current task/member policy, selected grant revision and plan authority are checked again before native submission. Read-only plan assessment verifies the selected ID/revision without replacing the recipient's implementation binding. Writable planned work requires the existing exact approved native plan scope. Requests do not approve a plan or answer native permissions.
443
+
444
+ The native response is a closed object:
445
+
446
+ ```ts
239
447
  {
240
- "kind": "handoff",
241
- "command": {
242
- "kind": "create",
243
- "id": "72dbce82-598b-4aa5-8c5b-2b79157adbcc",
244
- "runtimeEpoch": "512c7c32-6aaf-417d-89ae-9cd792f65e11",
245
- "sourceThreadId": "eaa4c6e3-199f-4f70-b683-0e5aa29c4c74",
246
- "purpose": "challenge"
247
- }
448
+ requestId: string | null;
449
+ outcome: 'completed' | 'waiting-children' | 'needs-input' | 'paused' | 'failed';
450
+ childRequestIds: string[];
451
+ report: string;
452
+ requiredAuthority: 'requester' | 'operator' | null;
248
453
  }
249
454
  ```
250
455
 
251
- Use the current runtime epoch and actual managed source ID from the runtime reads. Creation verifies source access through the provider's authoritative history interface, records native/source/repository/revision references, and saves the intent before admitting reviewer creation. `challenge` resolves the installed `jg-challenge-session`; `review` resolves `jg-review-session`. Reviewer input contains exact source references, not a copied transcript. Missing, disabled or ambiguous native skills remain unavailable. No skill-file parser, copied workflow or global installation is added.
456
+ Delegated work uses the exact request UUID. Only needs-input specifies `requiredAuthority`; other outcomes use null. Only waiting-children specifies a nonempty unique `childRequestIds` array; other outcomes use an empty array. The normal Markdown report stays inside `report`. HQ validates the envelope against the exact native action, assignee, provider, session and turn, without another model. Completed means the assignee claims completion. It is not approval or acceptance. Failed assignee reports remain exact evidence. Missing, malformed, wrongly bound or oversized output produces a labeled runtime failure, never a manufactured agent report. Native interruption retains interrupted state; uncertain native delivery retains the unresolved binding and never automatically resends.
457
+
458
+ The shared native schema omits an external dialect reference because the qualified Claude CLI rejects that reference during initialization. Codex selects this schema per turn. Claude installs it through one confirmed idle process restart, retaining native identity, instructions, permission settings, model and effort. An empty session reuses its same session ID; a session with input resumes its existing history. No global native configuration changes. Subsequent ordinary Claude conversations return `requestId: null` and HQ unwraps their report into the normal text result. Explicit unrelated output schemas retain their normal native selection contract.
252
459
 
253
- Creation may still be pending when its response arrives. Read `show` until its creation is delivered, then request a preview. Preview states are `ready`, `missing-skill`, `skill-unavailable`, `target-unavailable`, `source-changed` and `findings-unavailable`. Preview saves no input and grants no native permission. Sending requires the exact ready preview digest. IDs and immutable phase intents make identical retries return the same action receipt; a changed payload or preview with the same identity conflicts. An unavailable or uncertain target is never replaced or resumed by a read or retry. If an intent was saved before native admission and the host restarted, retain it for inspection and create a new handoff only after establishing that no native input was admitted.
460
+ | Command | Required selection and behavior |
461
+ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
462
+ | `request-dispatch` | Owner-only `requestId`; explicitly schedules eligible pending work even when automatic dispatch is disabled. |
463
+ | `request-input` | `requestId`, exact `expectedActionId` and bounded `body`. Only the owner or the recorded requester may answer a requester checkpoint; operator checkpoints require the owner. The linked immutable input message reserves one next action. Agent answers require active membership and normal automatic policy/limits. |
464
+ | `request-resume` | Owner-only `requestId`, `expectedActionId`, current `expectedAgentRevision`, current `expectedTaskRevision` and `body`. Resumes interrupted work or reactivates a paused parent wait under current authority, preserving its continuation reservation; a paused task must first be activated explicitly. |
465
+ | `request-authorize` | Owner-only `requestId`, nullable exact `expectedActionId`, nullable `grantId`/`grantRevision` and nullable `plan`. Refreshes the selected authority at an input/interruption/child-wait checkpoint, or before the first queued attempt. Null action selects work with no prior attempt. Skill, mode, effects, arguments and scopes stay selected; this command grants no plan approval. |
466
+ | `request-collect` | Owner-only `requestId` and `actionId`; selects already saved native evidence. Returns the immutable collection or null while evidence is unsettled. It accepts no model-provided completion text and never submits input. |
467
+ | `invocation-read` | Agent-only `taskId`; returns the one active verified invocation or null. It includes selected request scope, action/turn binding, compact grant issuer/revision, immutable parent/return route, bounded child-wait state, continuation generation/result references and linked input identity/author. Read request and input message bodies separately. |
468
+ | `report-read` | `reportId` and optional `cursor`, scoped by `taskId`. Returns metadata, exact UTF-8 `text`, `offsetBytes`, `isComplete` and `nextCursor`. |
254
469
 
255
- Collection reads exactly the requested native page through the provider adapter and accepts only one non-truncated agent message from the handoff's completed reviewer turn. Finding bodies are limited to 8 KiB UTF-8, never silently shortened. To select a later page, use the same `limit`, turn filter and preceding cursor as the native items read. A different message or changed body cannot overwrite collected findings. Full histories remain with the native CLIs. Persisted reviewer references retain the exact native session, turn and item identities.
470
+ Collection atomically commits the request transition, exact report, bounded reply, return delivery intent and immutable receipt. Repeated collection returns the original receipt. A canceled request keeps its canceled state if terminal evidence arrives later. Explicit idle ownership recovery or reattachment (`thread-recover` or `thread-resume`) may close canceled uncertain work, recording `recoveryActionId`; the native receipt remains uncertain. Reports and replies remain readable after task pause or grant revocation, subject to current task visibility. Runtime diagnostics use a runtime author. Native input acceptance sets `nativeActionId`/`deliveredAt`; it neither acknowledges a message nor resolves its request.
256
471
 
257
- Feedback resolves installed `jg-feedback` in the author thread and carries the selected findings with exact source, reviewer, item, revision and commit references. Source contract or selected Git HEAD changes invalidate an unsent preview. The action's optional `expectedPlan` guards the author's captured revision under the existing plan lock; explicit `null` requires an unbound thread. This guard applies only to `message` and `queue`, grants no execution scope, and cannot answer tool permissions. An explicitly selected native `jg-feedback` skill with a matching `expectedPlan` uses a neutral revision guard, so assessment remains available after execution is revoked or completed. It preserves the thread's existing implementation binding; ordinary input still requires valid execution authority. Queued assessment keeps that same revision guard at automatic or explicit dispatch. Known native identities cannot be reassigned; existing control admission preserves the exact author for queued feedback. Existing revision gates pause stale queued feedback. Neither handoff delivery nor a completed assessment turn means recommendations were accepted or implementation was authorized.
472
+ Reports have a fixed 1,048,576 UTF-8 byte ceiling. HQ rejects malformed UTF-16 or oversize output rather than replacing characters or storing a truncated report. Metadata records immutable report/request/action/reply IDs, server-derived agent author, native provenance, byte count and SHA-256. Replies carry a labeled excerpt and report ID/hash. `report-read` uses bounded database substring reads with an actor/task/report/hash-bound cursor, keeping the entire response within 65,536 serialized bytes. Native history availability does not affect these reads.
258
473
 
259
- Delivery is `prepared`, `queued`, `submitted`, `delivered`, `uncertain`, `failed` or `canceled`; native `completion` is separately null, `completed`, `failed` or `interrupted`. Acknowledgement alone becomes `delivered`. Busy destinations use native next-turn queues, including while waiting for permissions; feedback is never written as a permission answer. Pending native permissions remain explicit actions on their own channels. No automatic feedback, response loop, approval or publication follows collection.
474
+ `messages-search` merges bounded message and report FTS5 seeks in deterministic message sequence order. A report hit returns its associated reply and optional `reportMatch: {reportId, sha256, excerpt}`. Searches do not load full report bodies into Node or scan all reports; SQLite generates excerpts only for selected fixed-capacity indexed hits. There is no report cache, transcript mirror or general artifact subsystem. `status.dispatchFailure` exposes a failed recovery pass; owner `fanout-recover` also schedules dispatch recovery.
260
475
 
261
- Lists use indexed `createdAt DESC, id DESC` seek ordering, default 32/max 128, and cursors bound to the workspace, source filter and page size. Concurrent newer inserts do not reappear on continuation; deleted unseen records disappear. Summaries do not transfer retained finding bodies through the worker. SQLite owns the small private `handoff` and `handoff_dispatch` records alongside existing actions. No database migration or transcript mirror is required. Reads are fresh and bounded; no separate cache is used.
476
+ ### Parent waits and continuations
477
+
478
+ A delegated `message-publish` supplies `parentRequestId` matching the publishing agent's active assigned invocation in the same task. HQ records that parent and its exact native action immutably. Child effects, paths and plan scope cannot exceed the active parent selection; recipient task permissions and selected skill grants are checked separately. Root publications omit this field. A host or an unrelated invocation cannot forge a child relationship.
479
+
480
+ A waiting-children envelope names 1–32 unique direct children and retains every still-incomplete child from the recorded wait. HQ stores `childRequestIds`, an incremented `waitGeneration` and one `continuationActionId` on the parent. It releases native-turn capacity while preserving the assignee, incomplete request and plan binding. Registering a wait and collecting a child result check readiness in the same SQLite transaction. An early result cannot be lost. Resolved success, resolved failure and cancellation satisfy terminal waits; interruption and input questions do not. Reporting completed while a direct child remains unfinished produces `children-pending`, with a failed runtime outcome rather than parent completion. Invalid wait relationships produce `invalid-child-wait`.
481
+
482
+ All terminal children, or an unconsumed requester clarification from a named child, can reserve one next native action for that generation. The existing action ledger owns admission, busy queueing, uncertainty and replay. Continuation packets carry bounded child states, action/report IDs and hashes, and short excerpts; full payloads use `hq_report_read`. Native acceptance marks only the included report deliveries and clarification triggers as delivered/consumed. Later questions remain pending for the next wait generation. An agent may answer its direct child's requester checkpoint with `hq_request_input` and yield again. Operator-only questions require the host and never wake a parent to supply approval.
483
+
484
+ The parent retains its scope and rechecks current lifecycle, grants, plan revision and resource limits at admission. Paused, interrupted, revoked, canceled or resolved parents do not restart from child traffic. Current host authorization/resumption may unblock a saved wait; it does not replace an uncertain action. Restart recovers recorded wait conditions and reservations without starting a native controller. Explicit native reattachment remains necessary after shutdown. Ending a parent does not cancel its children, and late reports remain readable. Continuation acceptance, acknowledgement and replies never become new child-result triggers. `hq_identity.waiting` returns at most 32 authorized wait summaries plus `hasMore`; use bounded `hq_requests_list` for further inspection.
485
+
486
+ Native qualification on 2026-10-23 exercised complete Codex-to-Claude, Claude-to-Codex and Codex-to-Codex parent/child journeys without skills. Each child completed once; each parent yielded and completed on its second turn. Reports were checked byte-for-byte and by SHA-256. Native tool permissions were answered only for the selected HQ task operations.
487
+
488
+ ## Agent tools
489
+
490
+ Controlled sessions receive the same closed tools through provider-bound Codex dynamic callbacks or Claude's session-specific stdio MCP configuration. `operations.agentTools` reports availability separately from other controls. Codex dynamic tools are experimental. New HQ-created sessions declare them at `thread/start`; the native resume/fork interfaces retain their own tool configuration. An adopted or reconnected Codex session without observed registration reports unknown support until a native callback establishes it. No version label controls this decision. Claude adds one server using `--mcp-config`, preserving normal settings and other configured servers. Native permission prompts still require explicit replies.
491
+
492
+ `hq_identity({taskId?, limit?, cursor?})` returns `{identity, pending}`. Identity contains the immutable managed `agentId`, provider/native ID, runtime epoch, workspace, bounded task summaries, selected task, membership (including parent/role), child purpose and effective permissions. The compact `invocation` identifies active assigned work and its blocked reason. Active invocation selects its task by default; otherwise identity selects an unambiguous single membership; otherwise the caller selects an authorized `taskId`. The selector grants nothing. Pending work uses the task status counts. Identity is reconstructed from current durable records after compaction and explicit resume, without injecting stream history.
493
+
494
+ | Tools | Inputs and results |
495
+ | --------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
496
+ | `hq_agents_list`, `hq_streams_list`, `hq_stream_create`, `hq_subscription_set` | The corresponding collaboration command fields without `kind` or an actor. |
497
+ | `hq_messages_list`, `hq_messages_search`, `hq_message_read`, `hq_message_publish`, `hq_message_ack` | The corresponding bounded collaboration command fields; HQ supplies the author. |
498
+ | `hq_request_read`, `hq_requests_list`, `hq_request_claim`, `hq_request_resolve` | Current request relationships/waits and explicit non-dispatched resolution. |
499
+ | `hq_invocation_read`, `hq_report_read`, `hq_request_input` | Verified invocation, exact report chunks and linked requester input through the corresponding collaboration commands. |
500
+ | `hq_deliveries_list` | `taskId`, optional `limit` and `cursor`; returns only the calling agent's unacknowledged inbox. |
501
+ | `hq_sessions_list`, `hq_session_evidence_read` | The corresponding native read fields plus `taskId`, checked against effective read/provider/workspace permissions. |
502
+ | `hq_agent_spawn` | `id`, `taskId`, explicit `provider`, `workspaceRoot` and a nonempty bounded `purpose`; returns `{taskId, agentId, receipt}` from the native action ledger. |
503
+
504
+ Native connection identity or an opaque bridge credential supplies the sender. No tool accepts an authoritative actor, runtime epoch or sender ID, issues host grants, approves a plan, expands directories or changes native permissions. Each call checks current membership and policy. During an active dispatch, non-identity tools also recheck its selected grant and scope. Session reads and spawning cannot expand its selected workspace access. Tool arguments are closed schemas; safe results contain one text block with exact bounded JSON and `isError`. Core payloads fit within 65,536 serialized bytes, and native text wrappers account separately for JSON escaping. Calls are bounded to 32 outstanding operations and a 30-second gateway deadline; cancellation never proves an admitted native effect failed.
505
+
506
+ Spawn capacity is reserved transactionally with the new managed thread, parent link and copied effective task permissions, narrowed to the parent's active invocation when present. The task's `spawnCount` is cumulative and cannot exceed `policy.spawnLimit`. A rejected admission consumes no slot; an admitted failed or uncertain native creation retains its reservation. Reuse the same `id` and arguments to inspect that receipt. HQ never resends an uncertain creation. A new child has a distinct managed ID and no inherited plan approval or exact-agent skill eligibility. Either provider may create either provider. Native subagent calls resolve to their owner unless native lineage proves an independent managed binding; a shared MCP credential cannot distinguish native children.
507
+
508
+ The stdio entry is `jg-agent-hq agent-bridge`. Its only credential input is `JG_AGENT_HQ_BRIDGE_FILE`, a private short-lived file path supplied in the session MCP environment. The opaque token stays out of argv, prompts, SQLite, native configuration and snapshots. Files are 0600 under an owned 0700 system temporary directory, revoked and removed when their session closes, and rotated on reconnect/runtime restart. Runtime shutdown drains tool calls and removes its files/directory. The installed `@modelcontextprotocol/server` owns stdio framing, cancellation and negotiation. Stdout is protocol-only. Trusted factory contexts receive `IProviderAgentTools`, with JSON descriptors, a provider-bound callback and a revocable MCP lease; the Node package exports its descriptor/lease types.
509
+
510
+ Native qualification on 2026-10-23 used Codex 0.164.0 and Claude Code 2.1.309. Each called `hq_identity` and created an authorized child with the other provider through `hq_agent_spawn`; HQ confirmed the native creation receipts and parent memberships. Both then resumed their same managed/native identities after runtime restart, compacted, and called `hq_identity` again with the new runtime epoch, confirmed through native tool evidence. Claude's tool permissions received explicit per-call replies. Owned controllers, bridges and credential files shut down cleanly. These observations qualify those paths on this host; version labels remain diagnostics.
511
+
512
+ Directed-request qualification on 2026-10-23 used Codex 0.164.0 and Claude Code 2.1.309. Each called `hq_invocation_read` under its selected request, completed in one native turn, and returned an exact report retained by HQ. Native tool evidence confirmed the request/action binding; Claude's read-only MCP permission received an explicit reply. Report reads survived controller shutdown/restart without another model turn. The shared envelope uses no external schema-dialect reference; native version labels remain diagnostic.
513
+
514
+ ## Native skill delegation
515
+
516
+ A directed request may select an installed native skill by exact name, mode and current host-issued grant. HQ reads the recipient's native catalog and formats the invocation through that provider. Codex receives its native skill name/path selection; Claude receives its native slash invocation. Missing, disabled, ambiguous or unreadable metadata produces a retained skill-unavailable dispatch reason without sending plain text instead. Reload or repair the native catalog, then explicitly retry dispatch or allow an authorized recovery event. HQ never reads or rewrites skill instructions.
517
+
518
+ The immutable action command binds the coordination packet, while private preparation adds native skill presentation. Full arguments and mode come from the verified request, rather than being copied into each continuation. The session-bound hq_invocation_read returns the exact task, request, assignee, action, selected grant and current scope/plan/lifecycle. Verify it before acting. Native user-role framing, environment variables, quoted feedback and pasted grant IDs prove no operator authority.
519
+
520
+ | Workflow need | HQ mapping |
521
+ | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
522
+ | Verify delegated entry and mode | hq_invocation_read; use request.specification and the selected grant, not packet claims. |
523
+ | Read exact session evidence | hq_sessions_list and hq_session_evidence_read with authorized references, bounded pages/chunks and provenance. Denial never permits raw-history fallback. |
524
+ | Read review findings | hq_message_read or hq_report_read for the exact authorized reference; report hashes bind content. |
525
+ | Finish a read-only assessment | Return the native structured envelope. HQ stores/transports the report without a mutating tool or another inference turn. |
526
+ | Wait for child work | Return waiting-children with unique direct childRequestIds; continuation carries bounded states and report references. |
527
+ | Require selection/approval | Return needs-input with requiredAuthority operator; requester is for ordinary clarification only. |
528
+ | Pause/resume | Return paused under a pause grant. The host explicitly resumes against current lifecycle revisions; child results and earlier grants cannot resume it. |
529
+
530
+ Only the outermost delegated workflow wraps its normal report. Nested workflows, including jg-execute auto's review/push steps, retain their reports and require their selected effects. A workflow entry grant approves no new plan or later command selection. Both vendors may implement, review, challenge or assess work; same-vendor requests are supported. Skills are optional, and standalone skills retain native-history lookup and manual feedback handoff without an HQ dependency.
531
+
532
+ For ordinary explicit native skill messages, optional expectedPlan guards the captured revision under the plan lock; explicit null requires an unbound thread. It applies only to message/queue, grants no execution scope and answers no native permissions. A selected jg-feedback assessment with matching expectedPlan retains a neutral revision guard after execution is revoked or completed, preserving the existing implementation binding. Queued assessment keeps the same guard and native target; revision gates pause stale input. Read-only collaboration requests use their selected plan reference without inheriting implementation authority. Delivery or a completed assessment never means findings were accepted.
533
+
534
+ The public examples/review-handoff.ts helper uses an existing task/stream and selected memberships/grants with automaticDispatch false. Present each exact review/feedback specification through confirmRequest. The reviewer report returns as an immutable ID/hash reference for a separately confirmed author assessment. The helper waits through bounded host reads for up to 30 seconds; timeout never publishes a replacement request. Inspect the retained IDs after a timeout or checkpoint. No provider pairing, implicit feedback invocation or permission approval is built in.
535
+
536
+ Native qualification on 2026-10-23 exercised all fourteen explicit workflows in Codex 0.164.0 (gpt-6.1-sol) and Claude Code 2.1.309 (claude-opus-5-5), with recorded native configuration. Both providers preserved planning/selection checkpoints, read-only report returns, standalone feedback, denied managed-evidence boundaries and explicit pause/resume. Skill-based parent/child journeys ran in both directions with two parent turns and one child turn, checking exact report hashes. Claude also exercised auto review and signed publication against a disposable local bare remote. Codex’s workspace sandbox kept Git metadata read-only, so its publication attempt reported the native restriction without bypassing it. These are qualification observations, not version admission rules.
262
537
 
263
538
  ## Browser host integration
264
539
 
265
540
  `jg-agent-hq/contracts` exports closed `BrowserActionSchema`, `BrowserCommandSchema` and `BrowserReceiptSchema` contracts, plus browser session, repository and bounded plan read models. These schemas contain generic identities, not a deployment registry or private handler implementation. They do not expose native RPC, executables or provider configuration. Standalone IPC continues to support only its existing owned commands.
266
541
 
267
- A trusted Node host calls `runtime.performBrowserAction(request, operatorId, execute)` after validating its signed operator identity. The host supplies one dispatcher function in process. It must validate every target against its registry, check operation-specific revisions/turns, and normalize approval provenance to that authenticated operator. Never accept a callback, operator identity or handler name from HTTP input. The request has a stable UUID, current runtime epoch and one closed command: native, plan, handoff, priority, error-reservation or publication-retry. The complete serialized request is limited to 2 MiB; nested native commands retain their tighter limits.
542
+ A trusted Node host calls `runtime.performBrowserAction(request, operatorId, execute)` after validating its signed operator identity. The host supplies one dispatcher function in process. It must validate every target against its registry, check operation-specific revisions/turns, and normalize approval provenance to that authenticated operator. Never accept a callback, operator identity or handler name from HTTP input. The request has a stable UUID, current runtime epoch and one closed command: native, plan, priority, error-reservation or publication-retry. The complete serialized request is limited to 2 MiB; nested native commands retain their tighter limits.
268
543
 
269
544
  SQLite records an HMAC digest and receipt before invoking the dispatcher. The same UUID and identical normalized request returns the stored receipt without invoking it again. Changed payloads or operators conflict. New requests require the current epoch. Replaying a saved request after restart reconciles it without granting execution authority. Submitted receipts from another runtime become uncertain. Dispatcher failure also leaves the receipt uncertain because its effects may already have committed. This state never automatically resends an effect.
270
545
 
271
- The dispatcher receives a server-owned `nativeActionId`; use this ID for a native child action, preserving the validated runtime and command. `readBrowserAction(id, operatorId)` returns only that operator's receipt and joins its exact native receipt. Host acknowledgement means the handler completed, not that a native turn completed. An unknown or differently owned ID returns null. Receipts retain metadata rather than message bodies or arbitrary handler output. Subsequent domain reads provide the result. At most 32 host jobs are admitted concurrently. Runtime close rejects new host work and waits for admitted work before closing its worker.
546
+ The dispatcher receives a server-owned `nativeActionId`; use this ID for a native child action, preserving the validated runtime and command. `readBrowserAction(id, operatorId)` returns only that operator's receipt and joins its exact native receipt. Host acknowledgement means the handler completed, not that a native turn completed. An unknown or differently owned ID returns null. Host receipts retain admission metadata rather than arbitrary handler output. The selected joined native receipt includes its queued input and complete bounded final result; paged domain reads omit those bodies. At most 32 host jobs are admitted concurrently. Runtime close rejects new host work and waits for admitted work before closing its worker.
272
547
 
273
548
  `PublicationStatusSchema` is a browser-safe observation supplied by the host, independent of native execution and quota states. It contains the receipt UUID, state/reason, due/attempt/success timestamps, nullable pending and published commit hashes, and bounded queued/selected file counts. It contains no artifact bodies, paths, credentials or deployment configuration. `publication-retry` requires `publicationId` and `expectedCommit` (null before a commit exists). The host must compare both against its current receipt before acting and reconcile or retry only its recorded verified commit. The public runtime supplies no Git publisher, service installer or publication storage.
274
549
 
275
550
  Live reads accept `afterRevision`. A matching revision returns `unchanged: true` with an empty data array; retain the displayed window. A changed revision returns the complete bounded window. Revisions belong to one runtime. After reconnect to a new runtime, discard the revision and refresh native history. Token bodies stay in the existing bounded memory window and are never copied into lifecycle or browser-action tables.
276
551
 
277
552
  `thread-plan` accepts a managed `threadId` and returns its nullable `ActionPlanContextSchema`. The host verifies the thread's registered checkout before exposing it. It is read-only and grants no execution authority.
553
+
554
+ ## Qualification
555
+
556
+ The operation matrix describes the implemented native interfaces and their explicit unavailable surfaces. Executed qualification is narrower than every possible model, configuration and account state. Native versions below are observations, never admission rules.
557
+
558
+ | Area | Executed evidence | Boundary |
559
+ | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
560
+ | Provider integration | Public contract tests route a third provider, isolate unavailable providers and tolerate additive fields and future version labels. Native lifecycle, configuration, files, account and extension checks are listed in their sections above. | Each additional adapter needs its own native qualification. |
561
+ | Directed collaboration | Codex 0.164.0 and Claude Code 2.1.309 completed both vendor directions. A parent yielded before its child started, then finished on its second turn. Same-vendor delegation answered a child clarification and finished with three parent turns and two child turns. | Reading, subscription and information messages grant no execution authority. |
562
+ | Identity and native interaction | Both providers retained managed/native identities after compaction and reconnect with a fresh runtime epoch. Codex interruption and continuation passed. Claude AskUserQuestion and scoped MCP permission replies used exact native identities. | A timed-out compaction retained uncertain delivery even when completion later arrived; it was not resent. Explicit resume followed confirmed controller shutdown. |
563
+ | Reports and recovery | Six final reports matched complete native outcomes byte for byte. A 46,464-byte report was found through indexed search and read in two chunks. After removing all eight qualification transcripts, offline recovery retained those reports and the host preference; tasks were paused and providers stayed idle. | Native transcripts, repository files and authentication remain separate recovery responsibilities. |
564
+ | Optional skills | All fourteen explicit workflows ran in both providers, including verified delegation and standalone use. Skill-based parent returns ran in both directions. An unissued grant was rejected without creating its request. | Later approvals remain required. Claude signed publication used a disposable bare remote; the qualified Codex sandbox denied Git metadata writes. |
565
+ | Host coverage | Linux x86_64 package checks passed on Node 24.15.0 and 24.22.1. Integrated delegation ran on the floor; identity, native interaction and recovery also ran on 24.22.1. | No macOS host was available for this run. Windows is outside the declared host contract. |
566
+
567
+ The integrated delegation, identity and recovery checks used gpt-6.1-sol with medium effort and claude-opus-5-5 with medium effort in disposable workspaces on 2026-10-23. The [Node release index](https://nodejs.org/dist/index.json) identified 24.22.1 as the current LTS patch at qualification time. Local checks do not establish a published npm release or a deployed website.
568
+
569
+ Native model/output budgets also bound structured results. A generation that ends with incomplete JSON remains failed and creates no successful report; its bounded native result stays on the action receipt. The report byte limit does not increase the native model's output budget. Claude output schemas belong to session startup or explicit idle resume, as described in the configuration contract. Its unavailable steering, archive/revert, resource catalog and interactive authentication surfaces remain explicit in the operation matrix.