oh-my-codex 0.20.2 → 0.20.5

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 (805) hide show
  1. package/Cargo.lock +36 -18
  2. package/Cargo.toml +1 -1
  3. package/README.md +28 -2
  4. package/crates/omx-runtime/Cargo.toml +4 -0
  5. package/crates/omx-runtime/src/main.rs +415 -2
  6. package/crates/omx-runtime/tests/execution.rs +483 -0
  7. package/crates/omx-runtime-core/src/dispatch.rs +96 -10
  8. package/crates/omx-runtime-core/src/engine.rs +839 -29
  9. package/crates/omx-runtime-core/src/lib.rs +8 -0
  10. package/dist/adapt/__tests__/herdr-target.test.d.ts +2 -0
  11. package/dist/adapt/__tests__/herdr-target.test.d.ts.map +1 -0
  12. package/dist/adapt/__tests__/herdr-target.test.js +72 -0
  13. package/dist/adapt/__tests__/herdr-target.test.js.map +1 -0
  14. package/dist/adapt/contracts.d.ts +1 -1
  15. package/dist/adapt/contracts.d.ts.map +1 -1
  16. package/dist/adapt/contracts.js +1 -1
  17. package/dist/adapt/contracts.js.map +1 -1
  18. package/dist/adapt/herdr/__tests__/authority.test.d.ts +2 -0
  19. package/dist/adapt/herdr/__tests__/authority.test.d.ts.map +1 -0
  20. package/dist/adapt/herdr/__tests__/authority.test.js +49 -0
  21. package/dist/adapt/herdr/__tests__/authority.test.js.map +1 -0
  22. package/dist/adapt/herdr/__tests__/bridge.test.d.ts +2 -0
  23. package/dist/adapt/herdr/__tests__/bridge.test.d.ts.map +1 -0
  24. package/dist/adapt/herdr/__tests__/bridge.test.js +176 -0
  25. package/dist/adapt/herdr/__tests__/bridge.test.js.map +1 -0
  26. package/dist/adapt/herdr/__tests__/sanitize.test.d.ts +2 -0
  27. package/dist/adapt/herdr/__tests__/sanitize.test.d.ts.map +1 -0
  28. package/dist/adapt/herdr/__tests__/sanitize.test.js +45 -0
  29. package/dist/adapt/herdr/__tests__/sanitize.test.js.map +1 -0
  30. package/dist/adapt/herdr/__tests__/semantic.test.d.ts +2 -0
  31. package/dist/adapt/herdr/__tests__/semantic.test.d.ts.map +1 -0
  32. package/dist/adapt/herdr/__tests__/semantic.test.js +130 -0
  33. package/dist/adapt/herdr/__tests__/semantic.test.js.map +1 -0
  34. package/dist/adapt/herdr/__tests__/seq-store.test.d.ts +2 -0
  35. package/dist/adapt/herdr/__tests__/seq-store.test.d.ts.map +1 -0
  36. package/dist/adapt/herdr/__tests__/seq-store.test.js +54 -0
  37. package/dist/adapt/herdr/__tests__/seq-store.test.js.map +1 -0
  38. package/dist/adapt/herdr/__tests__/socket-live.test.d.ts +2 -0
  39. package/dist/adapt/herdr/__tests__/socket-live.test.d.ts.map +1 -0
  40. package/dist/adapt/herdr/__tests__/socket-live.test.js +104 -0
  41. package/dist/adapt/herdr/__tests__/socket-live.test.js.map +1 -0
  42. package/dist/adapt/herdr/__tests__/team-map.test.d.ts +2 -0
  43. package/dist/adapt/herdr/__tests__/team-map.test.d.ts.map +1 -0
  44. package/dist/adapt/herdr/__tests__/team-map.test.js +46 -0
  45. package/dist/adapt/herdr/__tests__/team-map.test.js.map +1 -0
  46. package/dist/adapt/herdr/__tests__/transport.test.d.ts +2 -0
  47. package/dist/adapt/herdr/__tests__/transport.test.d.ts.map +1 -0
  48. package/dist/adapt/herdr/__tests__/transport.test.js +160 -0
  49. package/dist/adapt/herdr/__tests__/transport.test.js.map +1 -0
  50. package/dist/adapt/herdr/__tests__/wiring.test.d.ts +2 -0
  51. package/dist/adapt/herdr/__tests__/wiring.test.d.ts.map +1 -0
  52. package/dist/adapt/herdr/__tests__/wiring.test.js +118 -0
  53. package/dist/adapt/herdr/__tests__/wiring.test.js.map +1 -0
  54. package/dist/adapt/herdr/authority.d.ts +34 -0
  55. package/dist/adapt/herdr/authority.d.ts.map +1 -0
  56. package/dist/adapt/herdr/authority.js +71 -0
  57. package/dist/adapt/herdr/authority.js.map +1 -0
  58. package/dist/adapt/herdr/bridge.d.ts +84 -0
  59. package/dist/adapt/herdr/bridge.d.ts.map +1 -0
  60. package/dist/adapt/herdr/bridge.js +222 -0
  61. package/dist/adapt/herdr/bridge.js.map +1 -0
  62. package/dist/adapt/herdr/sanitize.d.ts +20 -0
  63. package/dist/adapt/herdr/sanitize.d.ts.map +1 -0
  64. package/dist/adapt/herdr/sanitize.js +70 -0
  65. package/dist/adapt/herdr/sanitize.js.map +1 -0
  66. package/dist/adapt/herdr/semantic.d.ts +67 -0
  67. package/dist/adapt/herdr/semantic.d.ts.map +1 -0
  68. package/dist/adapt/herdr/semantic.js +170 -0
  69. package/dist/adapt/herdr/semantic.js.map +1 -0
  70. package/dist/adapt/herdr/seq-store.d.ts +32 -0
  71. package/dist/adapt/herdr/seq-store.d.ts.map +1 -0
  72. package/dist/adapt/herdr/seq-store.js +126 -0
  73. package/dist/adapt/herdr/seq-store.js.map +1 -0
  74. package/dist/adapt/herdr/team-map.d.ts +30 -0
  75. package/dist/adapt/herdr/team-map.d.ts.map +1 -0
  76. package/dist/adapt/herdr/team-map.js +37 -0
  77. package/dist/adapt/herdr/team-map.js.map +1 -0
  78. package/dist/adapt/herdr/transport.d.ts +115 -0
  79. package/dist/adapt/herdr/transport.d.ts.map +1 -0
  80. package/dist/adapt/herdr/transport.js +260 -0
  81. package/dist/adapt/herdr/transport.js.map +1 -0
  82. package/dist/adapt/herdr/wiring.d.ts +24 -0
  83. package/dist/adapt/herdr/wiring.d.ts.map +1 -0
  84. package/dist/adapt/herdr/wiring.js +62 -0
  85. package/dist/adapt/herdr/wiring.js.map +1 -0
  86. package/dist/adapt/herdr.d.ts +19 -0
  87. package/dist/adapt/herdr.d.ts.map +1 -0
  88. package/dist/adapt/herdr.js +115 -0
  89. package/dist/adapt/herdr.js.map +1 -0
  90. package/dist/adapt/index.d.ts +4 -0
  91. package/dist/adapt/index.d.ts.map +1 -1
  92. package/dist/adapt/index.js +48 -0
  93. package/dist/adapt/index.js.map +1 -1
  94. package/dist/adapt/registry.d.ts.map +1 -1
  95. package/dist/adapt/registry.js +11 -0
  96. package/dist/adapt/registry.js.map +1 -1
  97. package/dist/agents/__tests__/definitions.test.js +81 -0
  98. package/dist/agents/__tests__/definitions.test.js.map +1 -1
  99. package/dist/agents/__tests__/native-config.test.js +25 -0
  100. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  101. package/dist/agents/native-config.d.ts +2 -1
  102. package/dist/agents/native-config.d.ts.map +1 -1
  103. package/dist/agents/native-config.js.map +1 -1
  104. package/dist/auth/__tests__/hotswap.test.js +60 -1
  105. package/dist/auth/__tests__/hotswap.test.js.map +1 -1
  106. package/dist/auth/__tests__/storage.test.js +33 -1
  107. package/dist/auth/__tests__/storage.test.js.map +1 -1
  108. package/dist/auth/hotswap.d.ts +22 -2
  109. package/dist/auth/hotswap.d.ts.map +1 -1
  110. package/dist/auth/hotswap.js +107 -22
  111. package/dist/auth/hotswap.js.map +1 -1
  112. package/dist/auth/storage.js +1 -1
  113. package/dist/auth/storage.js.map +1 -1
  114. package/dist/autopilot/__tests__/ralplan-gate.test.js +86 -1333
  115. package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
  116. package/dist/autopilot/ralplan-gate.d.ts.map +1 -1
  117. package/dist/autopilot/ralplan-gate.js +7 -6
  118. package/dist/autopilot/ralplan-gate.js.map +1 -1
  119. package/dist/cli/__tests__/agents-init.test.js +4 -23
  120. package/dist/cli/__tests__/agents-init.test.js.map +1 -1
  121. package/dist/cli/__tests__/api.test.js +61 -24
  122. package/dist/cli/__tests__/api.test.js.map +1 -1
  123. package/dist/cli/__tests__/auth.test.js +63 -7
  124. package/dist/cli/__tests__/auth.test.js.map +1 -1
  125. package/dist/cli/__tests__/codex-feature-probe.test.js +66 -1
  126. package/dist/cli/__tests__/codex-feature-probe.test.js.map +1 -1
  127. package/dist/cli/__tests__/codex-plugin-layout.test.js +150 -2
  128. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  129. package/dist/cli/__tests__/detached-leader-teardown.test.d.ts +2 -0
  130. package/dist/cli/__tests__/detached-leader-teardown.test.d.ts.map +1 -0
  131. package/dist/cli/__tests__/detached-leader-teardown.test.js +473 -0
  132. package/dist/cli/__tests__/detached-leader-teardown.test.js.map +1 -0
  133. package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts +2 -0
  134. package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts.map +1 -0
  135. package/dist/cli/__tests__/doctor-process-identity-readiness.test.js +103 -0
  136. package/dist/cli/__tests__/doctor-process-identity-readiness.test.js.map +1 -0
  137. package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts +2 -0
  138. package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts.map +1 -0
  139. package/dist/cli/__tests__/doctor-state-root-binding.test.js +139 -0
  140. package/dist/cli/__tests__/doctor-state-root-binding.test.js.map +1 -0
  141. package/dist/cli/__tests__/doctor-warning-copy.test.js +135 -1
  142. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  143. package/dist/cli/__tests__/exec.test.js +211 -0
  144. package/dist/cli/__tests__/exec.test.js.map +1 -1
  145. package/dist/cli/__tests__/index.test.js +878 -463
  146. package/dist/cli/__tests__/index.test.js.map +1 -1
  147. package/dist/cli/__tests__/launch-fallback.test.js +1290 -127
  148. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  149. package/dist/cli/__tests__/mcp-parity.test.js +8 -4
  150. package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
  151. package/dist/cli/__tests__/native-assets.test.js +398 -16
  152. package/dist/cli/__tests__/native-assets.test.js.map +1 -1
  153. package/dist/cli/__tests__/native-hook-claim-journal.test.js +132 -6
  154. package/dist/cli/__tests__/native-hook-claim-journal.test.js.map +1 -1
  155. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +3 -3
  156. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
  157. package/dist/cli/__tests__/ralph.test.js +3 -3
  158. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  159. package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js +49 -164
  160. package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js.map +1 -1
  161. package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts +2 -0
  162. package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts.map +1 -0
  163. package/dist/cli/__tests__/ralplan-child-binding-3212.test.js +56 -0
  164. package/dist/cli/__tests__/ralplan-child-binding-3212.test.js.map +1 -0
  165. package/dist/cli/__tests__/ralplan.test.js +107 -109
  166. package/dist/cli/__tests__/ralplan.test.js.map +1 -1
  167. package/dist/cli/__tests__/resume.test.js +11 -10
  168. package/dist/cli/__tests__/resume.test.js.map +1 -1
  169. package/dist/cli/__tests__/session-scoped-runtime.test.js +1118 -43
  170. package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
  171. package/dist/cli/__tests__/session-search-help.test.js +25 -1
  172. package/dist/cli/__tests__/session-search-help.test.js.map +1 -1
  173. package/dist/cli/__tests__/setup-agents-overwrite.test.js +8 -55
  174. package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
  175. package/dist/cli/__tests__/setup-install-mode.test.js +224 -7
  176. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  177. package/dist/cli/__tests__/sparkshell-cli.test.js +93 -41
  178. package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
  179. package/dist/cli/__tests__/team.test.js +150 -8
  180. package/dist/cli/__tests__/team.test.js.map +1 -1
  181. package/dist/cli/__tests__/ultragoal.test.js +117 -2
  182. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  183. package/dist/cli/__tests__/uninstall.test.js +95 -4
  184. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  185. package/dist/cli/__tests__/update.test.js +669 -177
  186. package/dist/cli/__tests__/update.test.js.map +1 -1
  187. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +33 -2
  188. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
  189. package/dist/cli/api.d.ts.map +1 -1
  190. package/dist/cli/api.js +9 -10
  191. package/dist/cli/api.js.map +1 -1
  192. package/dist/cli/codex-feature-probe.d.ts +16 -0
  193. package/dist/cli/codex-feature-probe.d.ts.map +1 -1
  194. package/dist/cli/codex-feature-probe.js +44 -0
  195. package/dist/cli/codex-feature-probe.js.map +1 -1
  196. package/dist/cli/codex-home.d.ts.map +1 -1
  197. package/dist/cli/codex-home.js +7 -4
  198. package/dist/cli/codex-home.js.map +1 -1
  199. package/dist/cli/doctor.d.ts +20 -0
  200. package/dist/cli/doctor.d.ts.map +1 -1
  201. package/dist/cli/doctor.js +290 -3
  202. package/dist/cli/doctor.js.map +1 -1
  203. package/dist/cli/index.d.ts +234 -12
  204. package/dist/cli/index.d.ts.map +1 -1
  205. package/dist/cli/index.js +2409 -746
  206. package/dist/cli/index.js.map +1 -1
  207. package/dist/cli/mcp-parity.js +2 -2
  208. package/dist/cli/mcp-parity.js.map +1 -1
  209. package/dist/cli/native-assets.d.ts +25 -0
  210. package/dist/cli/native-assets.d.ts.map +1 -1
  211. package/dist/cli/native-assets.js +448 -51
  212. package/dist/cli/native-assets.js.map +1 -1
  213. package/dist/cli/native-hook-claim-journal.d.ts +20 -5
  214. package/dist/cli/native-hook-claim-journal.d.ts.map +1 -1
  215. package/dist/cli/native-hook-claim-journal.js +67 -32
  216. package/dist/cli/native-hook-claim-journal.js.map +1 -1
  217. package/dist/cli/package-manager-ownership.d.ts +63 -0
  218. package/dist/cli/package-manager-ownership.d.ts.map +1 -0
  219. package/dist/cli/package-manager-ownership.js +323 -0
  220. package/dist/cli/package-manager-ownership.js.map +1 -0
  221. package/dist/cli/ralph.js +2 -2
  222. package/dist/cli/ralph.js.map +1 -1
  223. package/dist/cli/ralplan.d.ts +5 -7
  224. package/dist/cli/ralplan.d.ts.map +1 -1
  225. package/dist/cli/ralplan.js +83 -134
  226. package/dist/cli/ralplan.js.map +1 -1
  227. package/dist/cli/session-search.d.ts +5 -0
  228. package/dist/cli/session-search.d.ts.map +1 -1
  229. package/dist/cli/session-search.js +87 -0
  230. package/dist/cli/session-search.js.map +1 -1
  231. package/dist/cli/setup-preferences.d.ts +15 -0
  232. package/dist/cli/setup-preferences.d.ts.map +1 -1
  233. package/dist/cli/setup-preferences.js +27 -1
  234. package/dist/cli/setup-preferences.js.map +1 -1
  235. package/dist/cli/setup.d.ts +8 -0
  236. package/dist/cli/setup.d.ts.map +1 -1
  237. package/dist/cli/setup.js +119 -47
  238. package/dist/cli/setup.js.map +1 -1
  239. package/dist/cli/sparkshell.d.ts.map +1 -1
  240. package/dist/cli/sparkshell.js +52 -9
  241. package/dist/cli/sparkshell.js.map +1 -1
  242. package/dist/cli/ultragoal.d.ts.map +1 -1
  243. package/dist/cli/ultragoal.js +2 -2
  244. package/dist/cli/ultragoal.js.map +1 -1
  245. package/dist/cli/uninstall.d.ts +9 -0
  246. package/dist/cli/uninstall.d.ts.map +1 -1
  247. package/dist/cli/uninstall.js +71 -30
  248. package/dist/cli/uninstall.js.map +1 -1
  249. package/dist/cli/update-worker.d.ts +2 -0
  250. package/dist/cli/update-worker.d.ts.map +1 -0
  251. package/dist/cli/update-worker.js +142 -0
  252. package/dist/cli/update-worker.js.map +1 -0
  253. package/dist/cli/update.d.ts +14 -22
  254. package/dist/cli/update.d.ts.map +1 -1
  255. package/dist/cli/update.js +192 -241
  256. package/dist/cli/update.js.map +1 -1
  257. package/dist/compat/__tests__/rust-runtime-compat.test.js +1 -1
  258. package/dist/config/__tests__/generator-idempotent.test.js +503 -30
  259. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  260. package/dist/config/__tests__/generator-notify.test.js +5 -3
  261. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  262. package/dist/config/__tests__/models.test.js +67 -3
  263. package/dist/config/__tests__/models.test.js.map +1 -1
  264. package/dist/config/generator.d.ts +27 -21
  265. package/dist/config/generator.d.ts.map +1 -1
  266. package/dist/config/generator.js +610 -152
  267. package/dist/config/generator.js.map +1 -1
  268. package/dist/config/models.d.ts +12 -2
  269. package/dist/config/models.d.ts.map +1 -1
  270. package/dist/config/models.js +15 -1
  271. package/dist/config/models.js.map +1 -1
  272. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +25 -0
  273. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
  274. package/dist/goal-workflows/codex-goal-snapshot.d.ts +1 -1
  275. package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
  276. package/dist/goal-workflows/codex-goal-snapshot.js +2 -0
  277. package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
  278. package/dist/hooks/__tests__/agents-overlay.test.js +5 -3
  279. package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
  280. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +27 -4
  281. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
  282. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts +2 -0
  283. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts.map +1 -0
  284. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js +172 -0
  285. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js.map +1 -0
  286. package/dist/hooks/__tests__/keyword-detector.test.js +176 -37
  287. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  288. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +402 -545
  289. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  290. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +39 -4
  291. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  292. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +161 -26
  293. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  294. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +27 -0
  295. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
  296. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +10 -118
  297. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
  298. package/dist/hooks/__tests__/notify-hook-regression-205.test.js +7 -0
  299. package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
  300. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +533 -14
  301. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  302. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +159 -24
  303. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  304. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +482 -32
  305. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
  306. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +2 -1
  307. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -1
  308. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +68 -1
  309. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
  310. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js +7 -1
  311. package/dist/hooks/__tests__/notify-hook-tmux-scrollback.test.js.map +1 -1
  312. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +44 -4
  313. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  314. package/dist/hooks/__tests__/prompt-guidance-contract.test.js +9 -0
  315. package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +1 -1
  316. package/dist/hooks/__tests__/session.test.js +3130 -365
  317. package/dist/hooks/__tests__/session.test.js.map +1 -1
  318. package/dist/hooks/agents-overlay.js +1 -1
  319. package/dist/hooks/agents-overlay.js.map +1 -1
  320. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +108 -2
  321. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
  322. package/dist/hooks/extensibility/__tests__/sdk.test.js +151 -1
  323. package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -1
  324. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
  325. package/dist/hooks/extensibility/dispatcher.js +20 -3
  326. package/dist/hooks/extensibility/dispatcher.js.map +1 -1
  327. package/dist/hooks/extensibility/plugin-runner.js +1 -0
  328. package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
  329. package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
  330. package/dist/hooks/extensibility/runtime.js.map +1 -1
  331. package/dist/hooks/extensibility/sdk/paths.d.ts +1 -1
  332. package/dist/hooks/extensibility/sdk/paths.d.ts.map +1 -1
  333. package/dist/hooks/extensibility/sdk/paths.js +2 -2
  334. package/dist/hooks/extensibility/sdk/paths.js.map +1 -1
  335. package/dist/hooks/extensibility/sdk/runtime-state.d.ts +1 -1
  336. package/dist/hooks/extensibility/sdk/runtime-state.d.ts.map +1 -1
  337. package/dist/hooks/extensibility/sdk/runtime-state.js +55 -15
  338. package/dist/hooks/extensibility/sdk/runtime-state.js.map +1 -1
  339. package/dist/hooks/extensibility/sdk.d.ts +1 -0
  340. package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
  341. package/dist/hooks/extensibility/sdk.js +1 -1
  342. package/dist/hooks/extensibility/sdk.js.map +1 -1
  343. package/dist/hooks/extensibility/types.d.ts +7 -0
  344. package/dist/hooks/extensibility/types.d.ts.map +1 -1
  345. package/dist/hooks/keyword-detector.d.ts +10 -3
  346. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  347. package/dist/hooks/keyword-detector.js +116 -20
  348. package/dist/hooks/keyword-detector.js.map +1 -1
  349. package/dist/hooks/session.d.ts +204 -14
  350. package/dist/hooks/session.d.ts.map +1 -1
  351. package/dist/hooks/session.js +1500 -223
  352. package/dist/hooks/session.js.map +1 -1
  353. package/dist/hud/__tests__/hud-tmux-injection.test.js +6 -6
  354. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
  355. package/dist/hud/__tests__/index.test.js +26 -16
  356. package/dist/hud/__tests__/index.test.js.map +1 -1
  357. package/dist/hud/__tests__/reconcile.test.js +83 -78
  358. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  359. package/dist/hud/__tests__/state.test.js +36 -31
  360. package/dist/hud/__tests__/state.test.js.map +1 -1
  361. package/dist/hud/__tests__/tmux.test.js +155 -198
  362. package/dist/hud/__tests__/tmux.test.js.map +1 -1
  363. package/dist/hud/tmux.d.ts +42 -4
  364. package/dist/hud/tmux.d.ts.map +1 -1
  365. package/dist/hud/tmux.js +1017 -139
  366. package/dist/hud/tmux.js.map +1 -1
  367. package/dist/leader/__tests__/contract.test.js +124 -37
  368. package/dist/leader/__tests__/contract.test.js.map +1 -1
  369. package/dist/leader/contract.d.ts +17 -6
  370. package/dist/leader/contract.d.ts.map +1 -1
  371. package/dist/leader/contract.js +102 -26
  372. package/dist/leader/contract.js.map +1 -1
  373. package/dist/mcp/__tests__/code-intel-server.test.js +31 -3
  374. package/dist/mcp/__tests__/code-intel-server.test.js.map +1 -1
  375. package/dist/mcp/__tests__/hermes-bridge.test.js +17 -0
  376. package/dist/mcp/__tests__/hermes-bridge.test.js.map +1 -1
  377. package/dist/mcp/__tests__/server-lifecycle.test.js +4 -4
  378. package/dist/mcp/__tests__/state-paths.test.js +735 -4
  379. package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
  380. package/dist/mcp/__tests__/state-server.test.js +1 -1
  381. package/dist/mcp/__tests__/state-server.test.js.map +1 -1
  382. package/dist/mcp/__tests__/trace-server.test.js +2 -2
  383. package/dist/mcp/__tests__/trace-server.test.js.map +1 -1
  384. package/dist/mcp/__tests__/wiki-server.test.js +18 -0
  385. package/dist/mcp/__tests__/wiki-server.test.js.map +1 -1
  386. package/dist/mcp/code-intel-server.d.ts.map +1 -1
  387. package/dist/mcp/code-intel-server.js +13 -3
  388. package/dist/mcp/code-intel-server.js.map +1 -1
  389. package/dist/mcp/hermes-bridge.d.ts.map +1 -1
  390. package/dist/mcp/hermes-bridge.js +2 -2
  391. package/dist/mcp/hermes-bridge.js.map +1 -1
  392. package/dist/mcp/state-paths.d.ts +78 -4
  393. package/dist/mcp/state-paths.d.ts.map +1 -1
  394. package/dist/mcp/state-paths.js +543 -40
  395. package/dist/mcp/state-paths.js.map +1 -1
  396. package/dist/mcp/state-server.d.ts +4 -4
  397. package/dist/mcp/state-server.d.ts.map +1 -1
  398. package/dist/mcp/wiki-server.d.ts +11 -0
  399. package/dist/mcp/wiki-server.d.ts.map +1 -1
  400. package/dist/mcp/wiki-server.js +9 -2
  401. package/dist/mcp/wiki-server.js.map +1 -1
  402. package/dist/modes/__tests__/base-autopilot-gates.test.js +36 -7
  403. package/dist/modes/__tests__/base-autopilot-gates.test.js.map +1 -1
  404. package/dist/modes/__tests__/base-multi-state-compat.test.js +1 -1
  405. package/dist/modes/__tests__/base-multi-state-compat.test.js.map +1 -1
  406. package/dist/modes/__tests__/base-session-scope.test.js +17 -8
  407. package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
  408. package/dist/modes/__tests__/base-tmux-pane.test.js +4 -4
  409. package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -1
  410. package/dist/modes/base.d.ts +5 -5
  411. package/dist/modes/base.d.ts.map +1 -1
  412. package/dist/modes/base.js +76 -21
  413. package/dist/modes/base.js.map +1 -1
  414. package/dist/native-assets/archive.d.ts +17 -0
  415. package/dist/native-assets/archive.d.ts.map +1 -0
  416. package/dist/native-assets/archive.js +238 -0
  417. package/dist/native-assets/archive.js.map +1 -0
  418. package/dist/native-assets/policy.d.ts +42 -0
  419. package/dist/native-assets/policy.d.ts.map +1 -0
  420. package/dist/native-assets/policy.js +155 -0
  421. package/dist/native-assets/policy.js.map +1 -0
  422. package/dist/notifications/temp-contract.d.ts.map +1 -1
  423. package/dist/notifications/temp-contract.js +4 -0
  424. package/dist/notifications/temp-contract.js.map +1 -1
  425. package/dist/pipeline/__tests__/orchestrator.test.js +164 -42
  426. package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
  427. package/dist/pipeline/__tests__/stages.test.js +72 -155
  428. package/dist/pipeline/__tests__/stages.test.js.map +1 -1
  429. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  430. package/dist/pipeline/orchestrator.js +124 -18
  431. package/dist/pipeline/orchestrator.js.map +1 -1
  432. package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
  433. package/dist/pipeline/stages/ralplan.js +36 -8
  434. package/dist/pipeline/stages/ralplan.js.map +1 -1
  435. package/dist/ralplan/__tests__/consensus-gate.test.js +73 -1316
  436. package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -1
  437. package/dist/ralplan/__tests__/documented-leader-preflight.test.d.ts +2 -0
  438. package/dist/ralplan/__tests__/documented-leader-preflight.test.d.ts.map +1 -0
  439. package/dist/ralplan/__tests__/documented-leader-preflight.test.js +335 -0
  440. package/dist/ralplan/__tests__/documented-leader-preflight.test.js.map +1 -0
  441. package/dist/ralplan/__tests__/runtime.test.js +85 -101
  442. package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
  443. package/dist/ralplan/consensus-gate.d.ts +9 -1
  444. package/dist/ralplan/consensus-gate.d.ts.map +1 -1
  445. package/dist/ralplan/consensus-gate.js +82 -338
  446. package/dist/ralplan/consensus-gate.js.map +1 -1
  447. package/dist/ralplan/documented-leader-preflight.d.ts +41 -0
  448. package/dist/ralplan/documented-leader-preflight.d.ts.map +1 -0
  449. package/dist/ralplan/documented-leader-preflight.js +360 -0
  450. package/dist/ralplan/documented-leader-preflight.js.map +1 -0
  451. package/dist/ralplan/runtime.d.ts +2 -1
  452. package/dist/ralplan/runtime.d.ts.map +1 -1
  453. package/dist/ralplan/runtime.js +67 -168
  454. package/dist/ralplan/runtime.js.map +1 -1
  455. package/dist/runtime/__tests__/bridge.test.js +42 -1
  456. package/dist/runtime/__tests__/bridge.test.js.map +1 -1
  457. package/dist/runtime/bridge.d.ts +12 -0
  458. package/dist/runtime/bridge.d.ts.map +1 -1
  459. package/dist/runtime/bridge.js +52 -1
  460. package/dist/runtime/bridge.js.map +1 -1
  461. package/dist/runtime/run-state.d.ts +5 -1
  462. package/dist/runtime/run-state.d.ts.map +1 -1
  463. package/dist/runtime/run-state.js +15 -8
  464. package/dist/runtime/run-state.js.map +1 -1
  465. package/dist/scripts/__tests__/codex-native-hook.test.js +16323 -8978
  466. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  467. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts +2 -0
  468. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts.map +1 -0
  469. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js +225 -0
  470. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js.map +1 -0
  471. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts +2 -0
  472. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts.map +1 -0
  473. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js +188 -0
  474. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js.map +1 -0
  475. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts +2 -0
  476. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts.map +1 -0
  477. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js +259 -0
  478. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js.map +1 -0
  479. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts +2 -0
  480. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts.map +1 -0
  481. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js +491 -0
  482. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js.map +1 -0
  483. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts +2 -0
  484. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts.map +1 -0
  485. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js +708 -0
  486. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js.map +1 -0
  487. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts +2 -0
  488. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts.map +1 -0
  489. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js +208 -0
  490. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js.map +1 -0
  491. package/dist/scripts/__tests__/notify-state-io.test.js +26 -0
  492. package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
  493. package/dist/scripts/__tests__/notify-tmux-injection.test.js +23 -1
  494. package/dist/scripts/__tests__/notify-tmux-injection.test.js.map +1 -1
  495. package/dist/scripts/__tests__/postinstall.test.js +19 -1
  496. package/dist/scripts/__tests__/postinstall.test.js.map +1 -1
  497. package/dist/scripts/__tests__/reasoning-artifact-contract.test.d.ts +2 -0
  498. package/dist/scripts/__tests__/reasoning-artifact-contract.test.d.ts.map +1 -0
  499. package/dist/scripts/__tests__/reasoning-artifact-contract.test.js +108 -0
  500. package/dist/scripts/__tests__/reasoning-artifact-contract.test.js.map +1 -0
  501. package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js +63 -173
  502. package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js.map +1 -1
  503. package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js +74 -159
  504. package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js.map +1 -1
  505. package/dist/scripts/__tests__/smoke-packed-install.test.js +404 -13
  506. package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
  507. package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts +2 -0
  508. package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts.map +1 -0
  509. package/dist/scripts/__tests__/verify-native-release-assets.test.js +235 -0
  510. package/dist/scripts/__tests__/verify-native-release-assets.test.js.map +1 -0
  511. package/dist/scripts/codex-native-hook.d.ts +53 -1
  512. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  513. package/dist/scripts/codex-native-hook.js +14448 -1480
  514. package/dist/scripts/codex-native-hook.js.map +1 -1
  515. package/dist/scripts/codex-native-pre-post.d.ts +9 -0
  516. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
  517. package/dist/scripts/codex-native-pre-post.js +35 -12
  518. package/dist/scripts/codex-native-pre-post.js.map +1 -1
  519. package/dist/scripts/generate-native-release-manifest.js +80 -51
  520. package/dist/scripts/generate-native-release-manifest.js.map +1 -1
  521. package/dist/scripts/notify-fallback-watcher.js +78 -115
  522. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  523. package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
  524. package/dist/scripts/notify-hook/auto-nudge.js +74 -3
  525. package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
  526. package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
  527. package/dist/scripts/notify-hook/state-io.js +5 -0
  528. package/dist/scripts/notify-hook/state-io.js.map +1 -1
  529. package/dist/scripts/notify-hook/team-dispatch.d.ts +9 -0
  530. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  531. package/dist/scripts/notify-hook/team-dispatch.js +234 -79
  532. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  533. package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
  534. package/dist/scripts/notify-hook/team-leader-nudge.js +71 -16
  535. package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
  536. package/dist/scripts/notify-hook/team-tmux-guard.d.ts +12 -4
  537. package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
  538. package/dist/scripts/notify-hook/team-tmux-guard.js +365 -44
  539. package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
  540. package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
  541. package/dist/scripts/notify-hook/team-worker-stop.js +42 -21
  542. package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
  543. package/dist/scripts/notify-hook/team-worker.d.ts +3 -0
  544. package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
  545. package/dist/scripts/notify-hook/team-worker.js +82 -33
  546. package/dist/scripts/notify-hook/team-worker.js.map +1 -1
  547. package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -0
  548. package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
  549. package/dist/scripts/notify-hook/tmux-injection.js +32 -3
  550. package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
  551. package/dist/scripts/notify-hook.js +79 -82
  552. package/dist/scripts/notify-hook.js.map +1 -1
  553. package/dist/scripts/postinstall-advisory.d.ts +14 -0
  554. package/dist/scripts/postinstall-advisory.d.ts.map +1 -0
  555. package/dist/scripts/postinstall-advisory.js +49 -0
  556. package/dist/scripts/postinstall-advisory.js.map +1 -0
  557. package/dist/scripts/postinstall.d.ts +1 -1
  558. package/dist/scripts/postinstall.d.ts.map +1 -1
  559. package/dist/scripts/postinstall.js +1 -1
  560. package/dist/scripts/postinstall.js.map +1 -1
  561. package/dist/scripts/smoke-packed-install.d.ts +80 -4
  562. package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
  563. package/dist/scripts/smoke-packed-install.js +3162 -26
  564. package/dist/scripts/smoke-packed-install.js.map +1 -1
  565. package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
  566. package/dist/scripts/sync-plugin-mirror.js +16 -1
  567. package/dist/scripts/sync-plugin-mirror.js.map +1 -1
  568. package/dist/scripts/verify-native-release-assets.js +37 -23
  569. package/dist/scripts/verify-native-release-assets.js.map +1 -1
  570. package/dist/state/__tests__/mode-state-context.test.js +61 -0
  571. package/dist/state/__tests__/mode-state-context.test.js.map +1 -1
  572. package/dist/state/__tests__/operations.test.js +462 -850
  573. package/dist/state/__tests__/operations.test.js.map +1 -1
  574. package/dist/state/__tests__/skill-active.test.js +400 -2
  575. package/dist/state/__tests__/skill-active.test.js.map +1 -1
  576. package/dist/state/mode-state-context.d.ts +8 -0
  577. package/dist/state/mode-state-context.d.ts.map +1 -1
  578. package/dist/state/mode-state-context.js +73 -0
  579. package/dist/state/mode-state-context.js.map +1 -1
  580. package/dist/state/operations.d.ts +3 -0
  581. package/dist/state/operations.d.ts.map +1 -1
  582. package/dist/state/operations.js +144 -40
  583. package/dist/state/operations.js.map +1 -1
  584. package/dist/state/skill-active.d.ts +18 -1
  585. package/dist/state/skill-active.d.ts.map +1 -1
  586. package/dist/state/skill-active.js +420 -23
  587. package/dist/state/skill-active.js.map +1 -1
  588. package/dist/state/workflow-transition-reconcile.d.ts +3 -0
  589. package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
  590. package/dist/state/workflow-transition-reconcile.js +10 -4
  591. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  592. package/dist/state/workflow-transition.d.ts.map +1 -1
  593. package/dist/state/workflow-transition.js +3 -1
  594. package/dist/state/workflow-transition.js.map +1 -1
  595. package/dist/subagents/__tests__/leader-bootstrap-3181.test.js +53 -247
  596. package/dist/subagents/__tests__/leader-bootstrap-3181.test.js.map +1 -1
  597. package/dist/subagents/__tests__/tracker.test.js +837 -1048
  598. package/dist/subagents/__tests__/tracker.test.js.map +1 -1
  599. package/dist/subagents/tracker.d.ts +58 -135
  600. package/dist/subagents/tracker.d.ts.map +1 -1
  601. package/dist/subagents/tracker.js +811 -632
  602. package/dist/subagents/tracker.js.map +1 -1
  603. package/dist/team/__tests__/api-interop.test.js +91 -1
  604. package/dist/team/__tests__/api-interop.test.js.map +1 -1
  605. package/dist/team/__tests__/delivery-e2e-smoke.test.js +58 -17
  606. package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
  607. package/dist/team/__tests__/idle-nudge.test.js +45 -15
  608. package/dist/team/__tests__/idle-nudge.test.js.map +1 -1
  609. package/dist/team/__tests__/mcp-comm.test.js +197 -30
  610. package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
  611. package/dist/team/__tests__/model-contract.test.js +110 -3
  612. package/dist/team/__tests__/model-contract.test.js.map +1 -1
  613. package/dist/team/__tests__/notice-ledger.test.d.ts +2 -0
  614. package/dist/team/__tests__/notice-ledger.test.d.ts.map +1 -0
  615. package/dist/team/__tests__/notice-ledger.test.js +131 -0
  616. package/dist/team/__tests__/notice-ledger.test.js.map +1 -0
  617. package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts +2 -0
  618. package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts.map +1 -0
  619. package/dist/team/__tests__/pane-teardown-residue-e2e.test.js +410 -0
  620. package/dist/team/__tests__/pane-teardown-residue-e2e.test.js.map +1 -0
  621. package/dist/team/__tests__/phase-controller.test.js +20 -0
  622. package/dist/team/__tests__/phase-controller.test.js.map +1 -1
  623. package/dist/team/__tests__/runtime-cli.test.js +9 -0
  624. package/dist/team/__tests__/runtime-cli.test.js.map +1 -1
  625. package/dist/team/__tests__/runtime.test.js +3963 -428
  626. package/dist/team/__tests__/runtime.test.js.map +1 -1
  627. package/dist/team/__tests__/scaling.test.js +2405 -203
  628. package/dist/team/__tests__/scaling.test.js.map +1 -1
  629. package/dist/team/__tests__/state-root.test.js +117 -2
  630. package/dist/team/__tests__/state-root.test.js.map +1 -1
  631. package/dist/team/__tests__/state.test.js +804 -36
  632. package/dist/team/__tests__/state.test.js.map +1 -1
  633. package/dist/team/__tests__/team-ops-contract.test.js +6 -0
  634. package/dist/team/__tests__/team-ops-contract.test.js.map +1 -1
  635. package/dist/team/__tests__/tmux-session.test.js +4099 -1039
  636. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  637. package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts +2 -0
  638. package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts.map +1 -0
  639. package/dist/team/__tests__/tmux-source-authority-realtmux.test.js +149 -0
  640. package/dist/team/__tests__/tmux-source-authority-realtmux.test.js.map +1 -0
  641. package/dist/team/__tests__/tmux-test-fixture.d.ts +69 -0
  642. package/dist/team/__tests__/tmux-test-fixture.d.ts.map +1 -1
  643. package/dist/team/__tests__/tmux-test-fixture.js +242 -15
  644. package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
  645. package/dist/team/__tests__/tmux-test-fixture.test.js +177 -1
  646. package/dist/team/__tests__/tmux-test-fixture.test.js.map +1 -1
  647. package/dist/team/__tests__/worker-runtime-identity.test.js +53 -44
  648. package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
  649. package/dist/team/__tests__/worktree.test.js +6 -0
  650. package/dist/team/__tests__/worktree.test.js.map +1 -1
  651. package/dist/team/api-interop.d.ts.map +1 -1
  652. package/dist/team/api-interop.js +15 -9
  653. package/dist/team/api-interop.js.map +1 -1
  654. package/dist/team/exact-pane.d.ts +23 -0
  655. package/dist/team/exact-pane.d.ts.map +1 -0
  656. package/dist/team/exact-pane.js +133 -0
  657. package/dist/team/exact-pane.js.map +1 -0
  658. package/dist/team/idle-nudge.d.ts +12 -1
  659. package/dist/team/idle-nudge.d.ts.map +1 -1
  660. package/dist/team/idle-nudge.js +41 -14
  661. package/dist/team/idle-nudge.js.map +1 -1
  662. package/dist/team/model-contract.d.ts +2 -5
  663. package/dist/team/model-contract.d.ts.map +1 -1
  664. package/dist/team/model-contract.js +59 -17
  665. package/dist/team/model-contract.js.map +1 -1
  666. package/dist/team/notice-ledger.d.ts +54 -0
  667. package/dist/team/notice-ledger.d.ts.map +1 -0
  668. package/dist/team/notice-ledger.js +259 -0
  669. package/dist/team/notice-ledger.js.map +1 -0
  670. package/dist/team/phase-controller.d.ts.map +1 -1
  671. package/dist/team/phase-controller.js +2 -0
  672. package/dist/team/phase-controller.js.map +1 -1
  673. package/dist/team/runtime.d.ts +4 -1
  674. package/dist/team/runtime.d.ts.map +1 -1
  675. package/dist/team/runtime.js +1527 -291
  676. package/dist/team/runtime.js.map +1 -1
  677. package/dist/team/scaling.d.ts +13 -1
  678. package/dist/team/scaling.d.ts.map +1 -1
  679. package/dist/team/scaling.js +1503 -387
  680. package/dist/team/scaling.js.map +1 -1
  681. package/dist/team/state/dispatch.d.ts.map +1 -1
  682. package/dist/team/state/dispatch.js +26 -8
  683. package/dist/team/state/dispatch.js.map +1 -1
  684. package/dist/team/state/locks.d.ts.map +1 -1
  685. package/dist/team/state/locks.js +61 -13
  686. package/dist/team/state/locks.js.map +1 -1
  687. package/dist/team/state/monitor.d.ts +10 -0
  688. package/dist/team/state/monitor.d.ts.map +1 -1
  689. package/dist/team/state/monitor.js +13 -0
  690. package/dist/team/state/monitor.js.map +1 -1
  691. package/dist/team/state/tasks.d.ts.map +1 -1
  692. package/dist/team/state/tasks.js +4 -3
  693. package/dist/team/state/tasks.js.map +1 -1
  694. package/dist/team/state/types.d.ts +15 -0
  695. package/dist/team/state/types.d.ts.map +1 -1
  696. package/dist/team/state/types.js.map +1 -1
  697. package/dist/team/state-root.d.ts +12 -0
  698. package/dist/team/state-root.d.ts.map +1 -1
  699. package/dist/team/state-root.js +177 -0
  700. package/dist/team/state-root.js.map +1 -1
  701. package/dist/team/state.d.ts +85 -1
  702. package/dist/team/state.d.ts.map +1 -1
  703. package/dist/team/state.js +672 -129
  704. package/dist/team/state.js.map +1 -1
  705. package/dist/team/team-ops.d.ts +5 -0
  706. package/dist/team/team-ops.d.ts.map +1 -1
  707. package/dist/team/team-ops.js +4 -0
  708. package/dist/team/team-ops.js.map +1 -1
  709. package/dist/team/tmux-session.d.ts +163 -27
  710. package/dist/team/tmux-session.d.ts.map +1 -1
  711. package/dist/team/tmux-session.js +1682 -376
  712. package/dist/team/tmux-session.js.map +1 -1
  713. package/dist/team/worktree.d.ts.map +1 -1
  714. package/dist/team/worktree.js +4 -0
  715. package/dist/team/worktree.js.map +1 -1
  716. package/dist/ultragoal/__tests__/artifacts.test.js +950 -2
  717. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  718. package/dist/ultragoal/__tests__/docs-contract.test.js +1 -0
  719. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
  720. package/dist/ultragoal/artifacts.d.ts +35 -1
  721. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  722. package/dist/ultragoal/artifacts.js +232 -46
  723. package/dist/ultragoal/artifacts.js.map +1 -1
  724. package/dist/utils/__tests__/file-durability.test.d.ts +2 -0
  725. package/dist/utils/__tests__/file-durability.test.d.ts.map +1 -0
  726. package/dist/utils/__tests__/file-durability.test.js +114 -0
  727. package/dist/utils/__tests__/file-durability.test.js.map +1 -0
  728. package/dist/utils/__tests__/paths.test.js +21 -1
  729. package/dist/utils/__tests__/paths.test.js.map +1 -1
  730. package/dist/utils/file-durability.d.ts +25 -0
  731. package/dist/utils/file-durability.d.ts.map +1 -0
  732. package/dist/utils/file-durability.js +67 -0
  733. package/dist/utils/file-durability.js.map +1 -0
  734. package/dist/utils/paths.d.ts.map +1 -1
  735. package/dist/utils/paths.js +14 -6
  736. package/dist/utils/paths.js.map +1 -1
  737. package/dist/verification/__tests__/ci-rust-gates.test.js +49 -4
  738. package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
  739. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js +3 -0
  740. package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +1 -1
  741. package/dist/verification/__tests__/explore-harness-release-workflow.test.js +60 -0
  742. package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +1 -1
  743. package/dist/verification/__tests__/native-release-manifest.test.js +157 -4
  744. package/dist/verification/__tests__/native-release-manifest.test.js.map +1 -1
  745. package/dist/wiki/lint.d.ts +4 -1
  746. package/dist/wiki/lint.d.ts.map +1 -1
  747. package/dist/wiki/lint.js +3 -2
  748. package/dist/wiki/lint.js.map +1 -1
  749. package/package.json +13 -5
  750. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  751. package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +105 -17
  752. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +13 -5
  753. package/plugins/oh-my-codex/skills/cancel/SKILL.md +30 -85
  754. package/plugins/oh-my-codex/skills/ralph/SKILL.md +6 -4
  755. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +16 -17
  756. package/plugins/oh-my-codex/skills/team/SKILL.md +13 -9
  757. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +3 -2
  758. package/skills/autopilot/SKILL.md +13 -5
  759. package/skills/cancel/SKILL.md +30 -85
  760. package/skills/ralph/SKILL.md +6 -4
  761. package/skills/ralplan/SKILL.md +16 -17
  762. package/skills/team/SKILL.md +13 -9
  763. package/skills/ultragoal/SKILL.md +3 -2
  764. package/src/scripts/__tests__/codex-native-hook.test.ts +8831 -951
  765. package/src/scripts/__tests__/issue-3293-callsite-parity.test.ts +187 -0
  766. package/src/scripts/__tests__/issue-3293-cancel-transaction.test.ts +189 -0
  767. package/src/scripts/__tests__/issue-3293-hook-owned-cancel.test.ts +187 -0
  768. package/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts +591 -0
  769. package/src/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.ts +701 -0
  770. package/src/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.ts +211 -0
  771. package/src/scripts/__tests__/notify-state-io.test.ts +29 -0
  772. package/src/scripts/__tests__/notify-tmux-injection.test.ts +26 -1
  773. package/src/scripts/__tests__/postinstall.test.ts +23 -1
  774. package/src/scripts/__tests__/reasoning-artifact-contract.test.ts +129 -0
  775. package/src/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.ts +67 -185
  776. package/src/scripts/__tests__/role-intent-durable-recovery-3181.test.ts +79 -178
  777. package/src/scripts/__tests__/smoke-packed-install.test.ts +525 -16
  778. package/src/scripts/__tests__/verify-native-release-assets.test.ts +240 -0
  779. package/src/scripts/codex-native-hook.ts +14238 -1429
  780. package/src/scripts/codex-native-pre-post.ts +43 -12
  781. package/src/scripts/generate-native-release-manifest.ts +83 -79
  782. package/src/scripts/notify-fallback-watcher.ts +91 -122
  783. package/src/scripts/notify-hook/auto-nudge.ts +71 -3
  784. package/src/scripts/notify-hook/state-io.ts +11 -0
  785. package/src/scripts/notify-hook/team-dispatch.ts +242 -75
  786. package/src/scripts/notify-hook/team-leader-nudge.ts +72 -22
  787. package/src/scripts/notify-hook/team-tmux-guard.ts +366 -39
  788. package/src/scripts/notify-hook/team-worker-stop.ts +43 -20
  789. package/src/scripts/notify-hook/team-worker.ts +82 -31
  790. package/src/scripts/notify-hook/tmux-injection.ts +33 -3
  791. package/src/scripts/notify-hook.ts +84 -82
  792. package/src/scripts/postinstall-advisory.ts +67 -0
  793. package/src/scripts/postinstall.ts +1 -1
  794. package/src/scripts/smoke-packed-install.ts +3608 -39
  795. package/src/scripts/sync-plugin-mirror.ts +17 -1
  796. package/src/scripts/verify-native-release-assets.ts +39 -31
  797. package/templates/AGENTS.md +1 -0
  798. package/dist/subagents/__tests__/adapted-role-binding.test.d.ts +0 -2
  799. package/dist/subagents/__tests__/adapted-role-binding.test.d.ts.map +0 -1
  800. package/dist/subagents/__tests__/adapted-role-binding.test.js +0 -988
  801. package/dist/subagents/__tests__/adapted-role-binding.test.js.map +0 -1
  802. package/dist/subagents/adapted-role-binding.d.ts +0 -17
  803. package/dist/subagents/adapted-role-binding.d.ts.map +0 -1
  804. package/dist/subagents/adapted-role-binding.js +0 -75
  805. package/dist/subagents/adapted-role-binding.js.map +0 -1
@@ -1,125 +1,12 @@
1
1
  import assert from 'node:assert/strict';
2
- import { createHash } from 'node:crypto';
3
2
  import { spawn } from 'node:child_process';
4
- import { existsSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
5
- import { mkdtemp, mkdir, rm, symlink, writeFile } from 'node:fs/promises';
3
+ import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
4
+ import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
6
5
  import { hostname, tmpdir } from 'node:os';
7
6
  import { join } from 'node:path';
8
7
  import { describe, it } from 'node:test';
9
- import { getBaseStateDir } from '../../state/paths.js';
10
- import { canonicalizeOriginCwd } from '../../leader/contract.js';
11
- import { __setCrossProcessPublishBarrierForTest, __setCrossProcessQuarantineBarrierForTest, CrossProcessLockLostError, bindPendingRoleIntentUnderLock, buildSubagentResumeLedger, completeAdaptedRoleBinding, CROSS_PROCESS_LOCK_ARTIFACT_SWEEP_CAP, CROSS_PROCESS_LOCK_LEASE_MS, createSubagentTrackingState, crossProcessLockPath, consumePendingRoleIntent, recordSubagentTurn, NATIVE_SUBAGENT_PROVENANCE, OMX_ADAPTED_PROVENANCE, readProcessStartIdentity, readSubagentTrackingState, recordPendingRoleIntent, selectReusableSubagentEntry, summarizeSubagentSession, withCrossProcessFileLockSync } from '../tracker.js';
12
- import { subagentTrackingPath } from '../tracker.js';
8
+ import { __setCrossProcessPublishBarrierForTest, __setCrossProcessQuarantineBarrierForTest, consumeDirectChildReopenContext, CrossProcessLockLostError, buildSubagentResumeLedger, CROSS_PROCESS_LOCK_ARTIFACT_SWEEP_CAP, CROSS_PROCESS_LOCK_LEASE_MS, createSubagentTrackingState, crossProcessLockPath, DESCRIPTIVE_ADAPTED_PROVENANCE, fenceNativeSubagentAuthorities, forceGlobalAuthorityDenial, recordNativeSubagentAuthorityObservation, recordSubagentTurn, recordSubagentTurnForSession, NATIVE_SUBAGENT_PROVENANCE, readProcessStartIdentity, readSubagentTrackingState, readSubagentTrackingStateStrict, repairPersistedRootIdentity, revokeNativeSubagentAuthorities, selectReusableSubagentEntry, subagentTrackingPath, summarizeSubagentSession, withCrossProcessFileLockSync, writeSubagentTrackingState } from '../tracker.js';
13
9
  import { NATIVE_SUBAGENT_ROLE_ROUTING_MARKER_FILE, readRoleRoutingMarker, writeRoleRoutingMarker } from '../role-routing-marker.js';
14
- const credentialDigest = (value) => createHash('sha256').update(value).digest('hex');
15
- const canonicalCorrelationToken = (value) => credentialDigest(value).slice(0, 32);
16
- const canonicalClaimantToken = (value) => {
17
- const digest = credentialDigest(value);
18
- return `${digest.slice(0, 8)}-${digest.slice(8, 12)}-4${digest.slice(13, 16)}-8${digest.slice(17, 20)}-${digest.slice(20, 32)}`;
19
- };
20
- const PENDING_ROLE_INTENT_WORKER_SOURCE = `
21
- import { existsSync } from 'node:fs';
22
-
23
- const input = JSON.parse(process.env.OMX_PENDING_ROLE_INTENT_WORKER_INPUT ?? '{}');
24
- const tracker = await import(process.env.OMX_TRACKER_MODULE_URL ?? '');
25
- const startSignal = process.env.OMX_PENDING_ROLE_INTENT_START_SIGNAL ?? '';
26
- const waitArray = new Int32Array(new SharedArrayBuffer(4));
27
- const startedAt = Date.now();
28
-
29
- process.stdout.write('ready\\n');
30
- while (!existsSync(startSignal)) {
31
- if (Date.now() - startedAt > 10_000) {
32
- throw new Error('Timed out waiting for pending role intent test start signal');
33
- }
34
- Atomics.wait(waitArray, 0, 0, 5);
35
- }
36
-
37
- const result = input.operation === 'record'
38
- ? tracker.recordPendingRoleIntent(input.cwd, input)
39
- : input.operation === 'consume'
40
- ? tracker.consumePendingRoleIntent(input.cwd, input)
41
- : (await tracker.recordSubagentTurnForSession(input.cwd, input), { ok: true });
42
- process.stdout.write(JSON.stringify(result));
43
- `;
44
- function spawnPendingRoleIntentWorker(startSignal, input) {
45
- const child = spawn(process.execPath, ['--input-type=module', '--eval', PENDING_ROLE_INTENT_WORKER_SOURCE], {
46
- env: {
47
- ...process.env,
48
- OMX_PENDING_ROLE_INTENT_START_SIGNAL: startSignal,
49
- OMX_PENDING_ROLE_INTENT_WORKER_INPUT: JSON.stringify(input),
50
- OMX_TRACKER_MODULE_URL: new URL('../tracker.js', import.meta.url).href,
51
- },
52
- stdio: ['ignore', 'pipe', 'pipe'],
53
- });
54
- if (!child.stdout || !child.stderr) {
55
- throw new Error('Pending role intent test worker did not expose output streams');
56
- }
57
- let stdout = '';
58
- let stderr = '';
59
- let ready = false;
60
- let resolveReady;
61
- let rejectReady;
62
- let resolveResult;
63
- let rejectResult;
64
- const readyPromise = new Promise((resolve, reject) => {
65
- resolveReady = resolve;
66
- rejectReady = reject;
67
- });
68
- const resultPromise = new Promise((resolve, reject) => {
69
- resolveResult = resolve;
70
- rejectResult = reject;
71
- });
72
- child.stdout.setEncoding('utf-8');
73
- child.stdout.on('data', (chunk) => {
74
- stdout += chunk;
75
- if (!ready && stdout.includes('ready\n')) {
76
- ready = true;
77
- resolveReady();
78
- }
79
- });
80
- child.stderr.setEncoding('utf-8');
81
- child.stderr.on('data', (chunk) => {
82
- stderr += chunk;
83
- });
84
- child.once('error', (error) => {
85
- if (!ready)
86
- rejectReady(error);
87
- rejectResult(error);
88
- });
89
- child.once('close', (code) => {
90
- if (!ready) {
91
- rejectReady(new Error(`Pending role intent test worker exited before ready: ${stderr || `code ${code}`}`));
92
- }
93
- if (code !== 0) {
94
- rejectResult(new Error(`Pending role intent test worker failed: ${stderr || `code ${code}`}`));
95
- return;
96
- }
97
- try {
98
- const resultJson = stdout.slice(stdout.indexOf('ready\n') + 'ready\n'.length);
99
- resolveResult(JSON.parse(resultJson));
100
- }
101
- catch (error) {
102
- rejectResult(error instanceof Error ? error : new Error(String(error)));
103
- }
104
- });
105
- return { ready: readyPromise, result: resultPromise };
106
- }
107
- async function runConcurrentPendingRoleIntentWorkers(cwd, inputs) {
108
- const startSignal = join(cwd, 'pending-role-intent-workers-start');
109
- const workers = inputs.map((input) => spawnPendingRoleIntentWorker(startSignal, input));
110
- await Promise.all(workers.map((worker) => worker.ready));
111
- await writeFile(startSignal, 'start\n');
112
- return Promise.all(workers.map((worker) => worker.result));
113
- }
114
- function isSuccessfulRoleIntentRecord(result) {
115
- return result !== null && 'ok' in result && result.ok === true;
116
- }
117
- function isSingleFlightConflict(result) {
118
- return result !== null && 'ok' in result && result.ok === false && result.reason === 'single_flight_conflict';
119
- }
120
- function isConsumedRoleIntent(result) {
121
- return result !== null && 'role' in result;
122
- }
123
10
  const CROSS_PROCESS_LOCK_HOLDER_SOURCE = `
124
11
  const tracker = await import(process.env.OMX_TRACKER_MODULE_URL ?? '');
125
12
  const { existsSync, writeFileSync } = await import('node:fs');
@@ -139,6 +26,44 @@ const CROSS_PROCESS_LOCK_HOLDER_SOURCE = `
139
26
  }
140
27
  });
141
28
  `;
29
+ const AUTHORITY_COMPETITOR_SOURCE = `
30
+ const tracker = await import(process.env.OMX_TRACKER_MODULE_URL ?? '');
31
+ const { writeFileSync } = await import('node:fs');
32
+ const cwd = process.env.OMX_AUTHORITY_CWD ?? '';
33
+ const readyPath = process.env.OMX_AUTHORITY_READY_PATH ?? '';
34
+ const resultPath = process.env.OMX_AUTHORITY_RESULT_PATH ?? '';
35
+ const operation = process.env.OMX_AUTHORITY_OPERATION ?? '';
36
+ const waitArray = new Int32Array(new SharedArrayBuffer(4));
37
+ let observedContention = false;
38
+ for (let attempt = 0; attempt < 200; attempt += 1) {
39
+ try {
40
+ const result = operation === 'reopen'
41
+ ? tracker.consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' })
42
+ : tracker.recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'other-root'], childThreadId: 'child', parentThreadId: 'other-root', rootNativeSessionId: 'other-root', authorityEvidence: 'valid' });
43
+ writeFileSync(resultPath, JSON.stringify({ observedContention, result: operation === 'reopen' ? result : 'revoked' }));
44
+ process.exit(0);
45
+ } catch {
46
+ if (!observedContention) {
47
+ observedContention = true;
48
+ writeFileSync(readyPath, 'contended\\n');
49
+ }
50
+ Atomics.wait(waitArray, 0, 0, 25);
51
+ }
52
+ }
53
+ throw new Error('Authority competitor never acquired the released lock');
54
+ `;
55
+ function spawnAuthorityCompetitor(cwd, operation, readyPath, resultPath) {
56
+ return spawn(process.execPath, ['--input-type=module', '--eval', AUTHORITY_COMPETITOR_SOURCE], {
57
+ env: {
58
+ ...process.env,
59
+ OMX_TRACKER_MODULE_URL: new URL('../tracker.js', import.meta.url).href,
60
+ OMX_AUTHORITY_CWD: cwd,
61
+ OMX_AUTHORITY_OPERATION: operation,
62
+ OMX_AUTHORITY_READY_PATH: readyPath,
63
+ OMX_AUTHORITY_RESULT_PATH: resultPath,
64
+ },
65
+ });
66
+ }
142
67
  function crossProcessLockClaim(token, pid, acquiredAtMs, host = hostname(), pidStartId) {
143
68
  return `${JSON.stringify({
144
69
  token,
@@ -243,6 +168,802 @@ describe('subagents/tracker', () => {
243
168
  });
244
169
  assert.deepEqual(drained?.activeSubagentThreadIds, []);
245
170
  });
171
+ it('authorizes only attested direct children for persisted reopen', () => {
172
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-authority-'));
173
+ try {
174
+ const path = subagentTrackingPath(cwd);
175
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
176
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
177
+ root: { thread_id: 'root', kind: 'subagent', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
178
+ direct: { thread_id: 'direct', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
179
+ nested: { thread_id: 'nested', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'direct', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
180
+ revoked: { thread_id: 'revoked', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', reopen_authority_revoked: true, status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
181
+ } } } }));
182
+ const context = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
183
+ assert.match(context, /resume_agent\("direct"\)/);
184
+ assert.doesNotMatch(context, /resume_agent\("root"\)|resume_agent\("nested"\)|resume_agent\("revoked"\)/);
185
+ const persisted = JSON.parse(readFileSync(path, 'utf8'));
186
+ assert.match(persisted.sessions.root.threads.direct.resume_requested_at, /^\d{4}-\d{2}-\d{2}T/);
187
+ assert.equal(persisted.sessions.root.threads.root.resume_requested_at, undefined);
188
+ }
189
+ finally {
190
+ rmSync(cwd, { recursive: true, force: true });
191
+ }
192
+ });
193
+ it('atomically revokes conflicting direct-child authority across correlation records', () => {
194
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-conflict-'));
195
+ try {
196
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root-a'], childThreadId: 'child', parentThreadId: 'root-a', rootNativeSessionId: 'root-a' });
197
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root-b'], childThreadId: 'child', parentThreadId: 'root-b', rootNativeSessionId: 'root-b' });
198
+ const state = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
199
+ assert.equal(state.sessions.canonical.threads.child.reopen_authority_revoked, true);
200
+ assert.equal(state.sessions['root-a'].threads.child.reopen_authority_revoked, true);
201
+ assert.equal(state.sessions['root-b'].threads.child.reopen_authority_revoked, true);
202
+ assert.equal(state.sessions.canonical.threads.child.reopen_authority_conflict_reason, 'root_or_parent_mismatch');
203
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root-a'], childThreadId: 'child', parentThreadId: 'root-a', rootNativeSessionId: 'root-a' });
204
+ const repaired = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
205
+ assert.equal(repaired.sessions.canonical.threads.child.reopen_authority_revoked, undefined);
206
+ assert.equal(repaired.sessions['root-a'].threads.child.reopen_authority_revoked, undefined);
207
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root-a', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
208
+ }
209
+ finally {
210
+ rmSync(cwd, { recursive: true, force: true });
211
+ }
212
+ });
213
+ it('keeps malformed tracker bytes unchanged across authority reads and writes', () => {
214
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-malformed-'));
215
+ try {
216
+ const path = subagentTrackingPath(cwd);
217
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
218
+ const malformed = '{not-json\n';
219
+ writeFileSync(path, malformed);
220
+ assert.throws(() => recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root' }));
221
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /malformed_tracker_state/);
222
+ assert.equal(readFileSync(path, 'utf8'), malformed);
223
+ }
224
+ finally {
225
+ rmSync(cwd, { recursive: true, force: true });
226
+ }
227
+ });
228
+ it('denies a leader-colliding attested child without bookkeeping', () => {
229
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-leader-collision-'));
230
+ try {
231
+ const path = subagentTrackingPath(cwd);
232
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
233
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', leader_thread_id: 'child', updated_at: '2026-07-23T00:00:00.000Z', threads: {
234
+ child: { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
235
+ } } } }));
236
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }), null);
237
+ const state = JSON.parse(readFileSync(path, 'utf8'));
238
+ assert.equal(state.sessions.root.threads.child.resume_requested_at, undefined);
239
+ }
240
+ finally {
241
+ rmSync(cwd, { recursive: true, force: true });
242
+ }
243
+ });
244
+ it('denies malformed valid-JSON authority evidence without rewriting bytes', () => {
245
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-malformed-authority-'));
246
+ try {
247
+ const path = subagentTrackingPath(cwd);
248
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
249
+ const raw = JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
250
+ child: { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', reopen_authority_revoked: 'false', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
251
+ } } } });
252
+ writeFileSync(path, raw);
253
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /malformed_tracker_state/);
254
+ assert.equal(readFileSync(path, 'utf8'), raw);
255
+ }
256
+ finally {
257
+ rmSync(cwd, { recursive: true, force: true });
258
+ }
259
+ });
260
+ it('denies malformed status authority evidence without rewriting bytes', () => {
261
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-malformed-status-'));
262
+ try {
263
+ const path = subagentTrackingPath(cwd);
264
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
265
+ const raw = JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
266
+ child: { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'bogus', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
267
+ } } } });
268
+ writeFileSync(path, raw);
269
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /malformed_tracker_state/);
270
+ assert.equal(readFileSync(path, 'utf8'), raw);
271
+ }
272
+ finally {
273
+ rmSync(cwd, { recursive: true, force: true });
274
+ }
275
+ });
276
+ it('denies an unattested descriptive correlation view', () => {
277
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-partial-correlation-'));
278
+ try {
279
+ const path = subagentTrackingPath(cwd);
280
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
281
+ const common = { thread_id: 'child', kind: 'subagent', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 };
282
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: {
283
+ canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: { child: { ...common, provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root' } } },
284
+ correlation: { session_id: 'correlation', updated_at: '2026-07-23T00:00:00.000Z', threads: { child: common } },
285
+ } }));
286
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
287
+ }
288
+ finally {
289
+ rmSync(cwd, { recursive: true, force: true });
290
+ }
291
+ });
292
+ it('denies cross-partition authority disagreement', () => {
293
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-partition-disagreement-'));
294
+ try {
295
+ const path = subagentTrackingPath(cwd);
296
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
297
+ const thread = { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 };
298
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: {
299
+ canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: { child: thread } },
300
+ correlation: { session_id: 'correlation', updated_at: '2026-07-23T00:00:00.000Z', threads: { child: { ...thread, direct_child_root_id: 'foreign', direct_child_parent_id: 'foreign' } } },
301
+ } }));
302
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
303
+ }
304
+ finally {
305
+ rmSync(cwd, { recursive: true, force: true });
306
+ }
307
+ });
308
+ it('preserves attested authority on pointerless descriptive reobservation', () => {
309
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-pointerless-'));
310
+ try {
311
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root' });
312
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root' });
313
+ const state = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
314
+ assert.equal(state.sessions.canonical.threads.child.reopen_authority_revoked, undefined);
315
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
316
+ }
317
+ finally {
318
+ rmSync(cwd, { recursive: true, force: true });
319
+ }
320
+ });
321
+ it('revokes cached authority after an identity-untrusted reobservation', () => {
322
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-untrusted-reobserve-'));
323
+ try {
324
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
325
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', authorityEvidence: 'untrusted' });
326
+ const state = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
327
+ assert.equal(state.sessions.canonical.threads.child.reopen_authority_revoked, true);
328
+ assert.equal(state.sessions.root.threads.child.reopen_authority_revoked, true);
329
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
330
+ }
331
+ finally {
332
+ rmSync(cwd, { recursive: true, force: true });
333
+ }
334
+ });
335
+ it('allows legacy adapted descriptive records to coexist with a newly attested child', () => {
336
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-legacy-coexist-'));
337
+ try {
338
+ const path = subagentTrackingPath(cwd);
339
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
340
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: {
341
+ legacy: { thread_id: 'legacy', kind: 'subagent', provenance_kind: 'adapted', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
342
+ } } } }));
343
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
344
+ const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
345
+ assert.match(context, /resume_agent\("child"\)/);
346
+ assert.doesNotMatch(context, /resume_agent\("legacy"\)/);
347
+ }
348
+ finally {
349
+ rmSync(cwd, { recursive: true, force: true });
350
+ }
351
+ });
352
+ it('ignores a same-child adapted legacy peer when validating a newly attested child', () => {
353
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-adapted-peer-'));
354
+ try {
355
+ const path = subagentTrackingPath(cwd);
356
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
357
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: {
358
+ correlation: { session_id: 'correlation', updated_at: '2026-07-23T00:00:00.000Z', threads: {
359
+ child: { thread_id: 'child', kind: 'subagent', provenance_kind: DESCRIPTIVE_ADAPTED_PROVENANCE, status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
360
+ } },
361
+ } }));
362
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
363
+ const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
364
+ assert.match(context, /resume_agent\("child"\)/);
365
+ const persisted = JSON.parse(readFileSync(path, 'utf8'));
366
+ assert.equal(persisted.sessions.correlation.threads.child.provenance_kind, DESCRIPTIVE_ADAPTED_PROVENANCE);
367
+ assert.equal(persisted.sessions.correlation.threads.child.direct_child_root_id, undefined);
368
+ }
369
+ finally {
370
+ rmSync(cwd, { recursive: true, force: true });
371
+ }
372
+ });
373
+ it('keeps the generic shared writer fail closed on malformed authority bytes', async () => {
374
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-generic-writer-'));
375
+ try {
376
+ const path = subagentTrackingPath(cwd);
377
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
378
+ const raw = JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
379
+ child: { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', reopen_authority_revoked: 'false', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
380
+ } } } });
381
+ writeFileSync(path, raw);
382
+ const strict = await readSubagentTrackingStateStrict(cwd);
383
+ assert.equal(strict.ok, false);
384
+ const tolerantState = createSubagentTrackingState();
385
+ await assert.rejects(writeSubagentTrackingState(cwd, tolerantState));
386
+ assert.equal(readFileSync(path, 'utf8'), raw);
387
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /malformed_tracker_state/);
388
+ }
389
+ finally {
390
+ rmSync(cwd, { recursive: true, force: true });
391
+ }
392
+ });
393
+ it('denies a canonical-key-colliding attested child without destructive reclassification', () => {
394
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-canonical-collision-'));
395
+ try {
396
+ const path = subagentTrackingPath(cwd);
397
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
398
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: {
399
+ canonical: { thread_id: 'canonical', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', resume_requested_at: '2026-07-23T00:02:00.000Z', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
400
+ } } } }));
401
+ const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
402
+ assert.doesNotMatch(context, /resume_agent\("canonical"\)/);
403
+ const persisted = JSON.parse(readFileSync(path, 'utf8'));
404
+ assert.equal(persisted.sessions.canonical.threads.canonical.kind, 'subagent');
405
+ assert.equal(persisted.sessions.canonical.threads.canonical.reopen_authority_revoked, true);
406
+ assert.equal(persisted.sessions.canonical.threads.canonical.reopen_authority_conflict_reason, 'canonical_root_collision');
407
+ assert.equal(persisted.sessions.canonical.threads.canonical.resume_requested_at, undefined);
408
+ }
409
+ finally {
410
+ rmSync(cwd, { recursive: true, force: true });
411
+ }
412
+ });
413
+ it('keeps a legacy plain canonical-key collision as ambiguous without revocation or reclassification', () => {
414
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-legacy-collision-'));
415
+ try {
416
+ const path = subagentTrackingPath(cwd);
417
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
418
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: {
419
+ canonical: { thread_id: 'canonical', kind: 'subagent', resume_requested_at: '2026-07-23T00:02:00.000Z', status: 'closed', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
420
+ } } } }));
421
+ const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
422
+ assert.doesNotMatch(context, /resume_agent\("canonical"\)/);
423
+ const persisted = JSON.parse(readFileSync(path, 'utf8'));
424
+ assert.equal(persisted.sessions.canonical.threads.canonical.kind, 'subagent');
425
+ assert.equal(persisted.sessions.canonical.threads.canonical.reopen_authority_revoked, undefined);
426
+ assert.equal(persisted.sessions.canonical.threads.canonical.resume_requested_at, undefined);
427
+ }
428
+ finally {
429
+ rmSync(cwd, { recursive: true, force: true });
430
+ }
431
+ });
432
+ it('denies an adapted peer view recorded with leader kind', () => {
433
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-adapted-leader-'));
434
+ try {
435
+ const path = subagentTrackingPath(cwd);
436
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
437
+ const attested = { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 };
438
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: {
439
+ canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: { child: attested } },
440
+ correlation: { session_id: 'correlation', updated_at: '2026-07-23T00:00:00.000Z', threads: {
441
+ child: { thread_id: 'child', kind: 'leader', provenance_kind: DESCRIPTIVE_ADAPTED_PROVENANCE, status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
442
+ } },
443
+ } }));
444
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
445
+ }
446
+ finally {
447
+ rmSync(cwd, { recursive: true, force: true });
448
+ }
449
+ });
450
+ it('denies an adapted peer view colliding with the session leader boundary', () => {
451
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-adapted-leader-boundary-'));
452
+ try {
453
+ const path = subagentTrackingPath(cwd);
454
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
455
+ const attested = { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 };
456
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: {
457
+ canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: { child: attested } },
458
+ correlation: { session_id: 'correlation', leader_thread_id: 'child', updated_at: '2026-07-23T00:00:00.000Z', threads: {
459
+ child: { thread_id: 'child', kind: 'subagent', provenance_kind: DESCRIPTIVE_ADAPTED_PROVENANCE, status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
460
+ } },
461
+ } }));
462
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
463
+ }
464
+ finally {
465
+ rmSync(cwd, { recursive: true, force: true });
466
+ }
467
+ });
468
+ it('keeps the legacy notice silent when an authority-bearing denial is present in another partition', () => {
469
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-mixed-notice-'));
470
+ try {
471
+ const path = subagentTrackingPath(cwd);
472
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
473
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: {
474
+ canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: {
475
+ legacy: { thread_id: 'legacy', kind: 'subagent', provenance_kind: DESCRIPTIVE_ADAPTED_PROVENANCE, status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
476
+ } },
477
+ correlation: { session_id: 'correlation', updated_at: '2026-07-23T00:00:00.000Z', threads: {
478
+ legacy: { thread_id: 'legacy', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', reopen_authority_revoked: true, status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
479
+ } },
480
+ } }));
481
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
482
+ }
483
+ finally {
484
+ rmSync(cwd, { recursive: true, force: true });
485
+ }
486
+ });
487
+ it('rejects malformed proposed state in the generic writer even without an existing tracker', async () => {
488
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-malformed-proposed-'));
489
+ try {
490
+ const path = subagentTrackingPath(cwd);
491
+ const malformedProposed = { schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
492
+ child: { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', reopen_authority_revoked: 'false', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
493
+ } } } };
494
+ await assert.rejects(writeSubagentTrackingState(cwd, malformedProposed));
495
+ assert.equal(existsSync(path), false);
496
+ const validState = recordSubagentTurn(createSubagentTrackingState(), { sessionId: 'root', threadId: 'child', kind: 'subagent' });
497
+ await writeSubagentTrackingState(cwd, validState);
498
+ assert.equal(existsSync(path), true);
499
+ }
500
+ finally {
501
+ rmSync(cwd, { recursive: true, force: true });
502
+ }
503
+ });
504
+ it('refuses a stale generic write that would roll back a newer authority revocation', async () => {
505
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-stale-generic-write-'));
506
+ try {
507
+ const path = subagentTrackingPath(cwd);
508
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
509
+ // A descriptive caller snapshots the tracker outside the lock.
510
+ const stale = await readSubagentTrackingState(cwd);
511
+ // A competing negative observation revokes that authority.
512
+ revokeNativeSubagentAuthorities(cwd, ['child'], 'foreign_parent');
513
+ assert.equal(JSON.parse(readFileSync(path, 'utf8')).sessions.canonical.threads.child.reopen_authority_revoked, true);
514
+ // Publishing the stale snapshot must not resurrect the revoked authority.
515
+ await assert.rejects(writeSubagentTrackingState(cwd, stale), /Stale subagent tracker authority state/);
516
+ const persisted = JSON.parse(readFileSync(path, 'utf8'));
517
+ assert.equal(persisted.sessions.canonical.threads.child.reopen_authority_revoked, true);
518
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
519
+ }
520
+ finally {
521
+ rmSync(cwd, { recursive: true, force: true });
522
+ }
523
+ });
524
+ it('still allows a descriptive generic write when authority has not moved', async () => {
525
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-descriptive-write-ok-'));
526
+ try {
527
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
528
+ const snapshot = await readSubagentTrackingState(cwd);
529
+ const descriptive = recordSubagentTurn(snapshot, { sessionId: 'canonical', threadId: 'child', kind: 'subagent' });
530
+ await writeSubagentTrackingState(cwd, descriptive);
531
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
532
+ }
533
+ finally {
534
+ rmSync(cwd, { recursive: true, force: true });
535
+ }
536
+ });
537
+ it('leaves an uncorrelated partition untouched when a thread id collides with the canonical key', () => {
538
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-uncorrelated-collision-'));
539
+ try {
540
+ const path = subagentTrackingPath(cwd);
541
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
542
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: {
543
+ canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: {} },
544
+ unrelated: { session_id: 'unrelated', leader_thread_id: 'foreign-root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
545
+ canonical: { thread_id: 'canonical', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'foreign-root', direct_child_parent_id: 'foreign-root', resume_requested_at: '2026-07-23T00:02:00.000Z', resume_completed_at: '2026-07-23T00:03:00.000Z', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
546
+ } },
547
+ } }));
548
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
549
+ const persisted = JSON.parse(readFileSync(path, 'utf8'));
550
+ const foreignChild = persisted.sessions.unrelated.threads.canonical;
551
+ assert.equal(foreignChild.reopen_authority_revoked, undefined);
552
+ assert.equal(foreignChild.reopen_authority_conflict_reason, undefined);
553
+ assert.equal(foreignChild.direct_child_root_id, 'foreign-root');
554
+ assert.equal(foreignChild.resume_requested_at, '2026-07-23T00:02:00.000Z');
555
+ assert.equal(foreignChild.resume_completed_at, '2026-07-23T00:03:00.000Z');
556
+ }
557
+ finally {
558
+ rmSync(cwd, { recursive: true, force: true });
559
+ }
560
+ });
561
+ it('still quarantines a canonical-key collision inside a correlated partition', () => {
562
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-correlated-collision-'));
563
+ try {
564
+ const path = subagentTrackingPath(cwd);
565
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
566
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: {
567
+ correlated: { session_id: 'correlated', leader_thread_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
568
+ root: { thread_id: 'root', kind: 'leader', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
569
+ canonical: { thread_id: 'canonical', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', resume_requested_at: '2026-07-23T00:02:00.000Z', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
570
+ } },
571
+ } }));
572
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
573
+ const collided = JSON.parse(readFileSync(path, 'utf8')).sessions.correlated.threads.canonical;
574
+ assert.equal(collided.kind, 'subagent');
575
+ assert.equal(collided.reopen_authority_revoked, true);
576
+ assert.equal(collided.reopen_authority_conflict_reason, 'canonical_root_collision');
577
+ assert.equal(collided.resume_requested_at, undefined);
578
+ }
579
+ finally {
580
+ rmSync(cwd, { recursive: true, force: true });
581
+ }
582
+ });
583
+ it('keeps authority denied when a revocation could not be published', () => {
584
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-authority-fence-'));
585
+ try {
586
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
587
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
588
+ // Simulate a revocation whose transaction failed: the tracker still shows
589
+ // valid authority, but the fence records the unpublished denial.
590
+ fenceNativeSubagentAuthorities(cwd, ['child'], 'identity_untrusted_revocation_failed');
591
+ assert.equal(JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8')).sessions.canonical.threads.child.reopen_authority_revoked, undefined);
592
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
593
+ // Once the revocation is durably applied, the fence is released.
594
+ revokeNativeSubagentAuthorities(cwd, ['child'], 'identity_untrusted');
595
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
596
+ assert.equal(JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8')).sessions.canonical.threads.child.reopen_authority_revoked, true);
597
+ }
598
+ finally {
599
+ rmSync(cwd, { recursive: true, force: true });
600
+ }
601
+ });
602
+ it('fails closed for every id when the authority fence is unreadable', () => {
603
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-fence-unreadable-'));
604
+ try {
605
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
606
+ writeFileSync(`${subagentTrackingPath(cwd)}.authority-fence.json`, '{ not json');
607
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /unreadable_authority_fence/);
608
+ }
609
+ finally {
610
+ rmSync(cwd, { recursive: true, force: true });
611
+ }
612
+ });
613
+ it('refuses a fresh generic write that would grant or remove reopen authority', async () => {
614
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-fresh-generic-authority-'));
615
+ try {
616
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
617
+ revokeNativeSubagentAuthorities(cwd, ['child'], 'foreign_parent');
618
+ // A FRESH read still must not let the descriptive writer lift a revocation.
619
+ const fresh = await readSubagentTrackingState(cwd);
620
+ delete fresh.sessions.canonical.threads.child.reopen_authority_revoked;
621
+ delete fresh.sessions.canonical.threads.child.reopen_authority_conflict_reason;
622
+ delete fresh.sessions.canonical.threads.child.reopen_authority_conflict_at;
623
+ await assert.rejects(writeSubagentTrackingState(cwd, fresh), /Stale subagent tracker authority state/);
624
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
625
+ // A fresh read must equally not let it GRANT authority. Attaching a fresh
626
+ // attestation to a previously unattested thread is refused as a stale
627
+ // authority change rather than published.
628
+ const granting = await readSubagentTrackingState(cwd);
629
+ const plain = recordSubagentTurn(granting, { sessionId: 'canonical', threadId: 'newcomer', kind: 'subagent' });
630
+ plain.sessions.canonical.threads.newcomer.provenance_kind = NATIVE_SUBAGENT_PROVENANCE;
631
+ plain.sessions.canonical.threads.newcomer.direct_child_root_id = 'root';
632
+ plain.sessions.canonical.threads.newcomer.direct_child_parent_id = 'root';
633
+ await assert.rejects(writeSubagentTrackingState(cwd, plain), /Stale subagent tracker authority state/);
634
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
635
+ }
636
+ finally {
637
+ rmSync(cwd, { recursive: true, force: true });
638
+ }
639
+ });
640
+ it('refuses a generic write that would mint authority into a fresh tracker', async () => {
641
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-mint-authority-'));
642
+ try {
643
+ const minted = recordSubagentTurn(createSubagentTrackingState(), { sessionId: 'canonical', threadId: 'child', kind: 'subagent' });
644
+ minted.sessions.canonical.threads.child.provenance_kind = NATIVE_SUBAGENT_PROVENANCE;
645
+ minted.sessions.canonical.threads.child.direct_child_root_id = 'root';
646
+ minted.sessions.canonical.threads.child.direct_child_parent_id = 'root';
647
+ await assert.rejects(writeSubagentTrackingState(cwd, minted), /Stale subagent tracker authority state/);
648
+ assert.equal(existsSync(subagentTrackingPath(cwd)), false);
649
+ }
650
+ finally {
651
+ rmSync(cwd, { recursive: true, force: true });
652
+ }
653
+ });
654
+ it('lets a fresh generic write set a descriptive leader_thread_id but never mint authority', async () => {
655
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-mint-leader-'));
656
+ try {
657
+ // leader_thread_id alone is descriptive lifecycle data that legitimate
658
+ // first writers set; it never makes a thread an eligible reopen target.
659
+ const descriptive = recordSubagentTurn(createSubagentTrackingState(), { sessionId: 'canonical', threadId: 'child', kind: 'subagent', leaderThreadId: 'thread-leader' });
660
+ await writeSubagentTrackingState(cwd, descriptive);
661
+ assert.doesNotMatch(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /resume_agent\(/);
662
+ // Attaching attestation to that same fresh create is refused.
663
+ rmSync(subagentTrackingPath(cwd), { force: true });
664
+ const minted = recordSubagentTurn(createSubagentTrackingState(), { sessionId: 'canonical', threadId: 'child', kind: 'subagent', leaderThreadId: 'thread-leader' });
665
+ minted.sessions.canonical.threads.child.provenance_kind = NATIVE_SUBAGENT_PROVENANCE;
666
+ minted.sessions.canonical.threads.child.direct_child_root_id = 'root';
667
+ minted.sessions.canonical.threads.child.direct_child_parent_id = 'root';
668
+ await assert.rejects(writeSubagentTrackingState(cwd, minted), /Stale subagent tracker authority state/);
669
+ }
670
+ finally {
671
+ rmSync(cwd, { recursive: true, force: true });
672
+ }
673
+ });
674
+ it('denies every reopen target after a forced global authority denial', () => {
675
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-global-denial-'));
676
+ try {
677
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
678
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /resume_agent\("child"\)/);
679
+ // Simulates both the tracker revocation AND the locked fence failing.
680
+ assert.equal(forceGlobalAuthorityDenial(cwd, 'identity_untrusted_denial_escalated'), true);
681
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /unreadable_authority_fence/);
682
+ // The escalated denial survives an unrelated successful revocation.
683
+ revokeNativeSubagentAuthorities(cwd, ['other'], 'identity_untrusted');
684
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /unreadable_authority_fence/);
685
+ }
686
+ finally {
687
+ rmSync(cwd, { recursive: true, force: true });
688
+ }
689
+ });
690
+ it('refuses a generic write that would roll an authorized child back to available', async () => {
691
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-status-rollback-'));
692
+ try {
693
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
694
+ const snapshot = await readSubagentTrackingState(cwd);
695
+ snapshot.sessions.canonical.threads.child.status = 'unavailable';
696
+ await assert.rejects(writeSubagentTrackingState(cwd, snapshot), /Stale subagent tracker authority state/);
697
+ }
698
+ finally {
699
+ rmSync(cwd, { recursive: true, force: true });
700
+ }
701
+ });
702
+ it('never destroys an unreadable global fence during an unrelated revocation clear', () => {
703
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-fence-preserved-'));
704
+ try {
705
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'a', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
706
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'b', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
707
+ const fencePath = `${subagentTrackingPath(cwd)}.authority-fence.json`;
708
+ writeFileSync(fencePath, '{ not json');
709
+ // An unrelated revocation must not delete the global denial.
710
+ revokeNativeSubagentAuthorities(cwd, ['a'], 'identity_untrusted');
711
+ assert.equal(existsSync(fencePath), true);
712
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /unreadable_authority_fence/);
713
+ // A no-op revocation for an unknown id must not clear it either.
714
+ revokeNativeSubagentAuthorities(cwd, ['nonexistent'], 'identity_untrusted');
715
+ assert.equal(existsSync(fencePath), true);
716
+ }
717
+ finally {
718
+ rmSync(cwd, { recursive: true, force: true });
719
+ }
720
+ });
721
+ it('does not weaken an unreadable global fence when a later fence records more ids', () => {
722
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-fence-no-weaken-'));
723
+ try {
724
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
725
+ const fencePath = `${subagentTrackingPath(cwd)}.authority-fence.json`;
726
+ writeFileSync(fencePath, '{ not json');
727
+ assert.equal(fenceNativeSubagentAuthorities(cwd, ['other'], 'identity_untrusted_revocation_failed'), true);
728
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /unreadable_authority_fence/);
729
+ }
730
+ finally {
731
+ rmSync(cwd, { recursive: true, force: true });
732
+ }
733
+ });
734
+ it('clears only fully reconciled fence ids and keeps the rest denied', () => {
735
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-fence-partial-clear-'));
736
+ try {
737
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'a', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
738
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'b', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
739
+ assert.equal(fenceNativeSubagentAuthorities(cwd, ['a', 'b'], 'identity_untrusted_revocation_failed'), true);
740
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
741
+ revokeNativeSubagentAuthorities(cwd, ['a'], 'identity_untrusted');
742
+ // `b` is still fenced, so it must not be emitted even though its tracker
743
+ // record still looks valid.
744
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
745
+ const fence = JSON.parse(readFileSync(`${subagentTrackingPath(cwd)}.authority-fence.json`, 'utf8'));
746
+ assert.deepEqual(fence.ids, ['b']);
747
+ }
748
+ finally {
749
+ rmSync(cwd, { recursive: true, force: true });
750
+ }
751
+ });
752
+ it('repairs a root inversion even when the canonical tracker partition is missing', () => {
753
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-native-only-repair-'));
754
+ try {
755
+ const path = subagentTrackingPath(cwd);
756
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
757
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', leader_thread_id: 'turn-like-foreign', updated_at: '2026-07-23T00:00:00.000Z', threads: {
758
+ root: { thread_id: 'root', kind: 'subagent', status: 'closed', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
759
+ } } } }));
760
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
761
+ const persisted = JSON.parse(readFileSync(path, 'utf8'));
762
+ assert.equal(persisted.sessions.root.threads.root.kind, 'leader');
763
+ assert.equal(persisted.sessions.root.leader_thread_id, 'root');
764
+ }
765
+ finally {
766
+ rmSync(cwd, { recursive: true, force: true });
767
+ }
768
+ });
769
+ it('repairs a root inversion through the decoupled repair entrypoint', () => {
770
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-decoupled-repair-'));
771
+ try {
772
+ const path = subagentTrackingPath(cwd);
773
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
774
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', leader_thread_id: 'turn-like-foreign', updated_at: '2026-07-23T00:00:00.000Z', threads: {
775
+ root: { thread_id: 'root', kind: 'subagent', status: 'closed', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
776
+ } } } }));
777
+ assert.equal(repairPersistedRootIdentity(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root' }), true);
778
+ const persisted = JSON.parse(readFileSync(path, 'utf8'));
779
+ assert.equal(persisted.sessions.root.threads.root.kind, 'leader');
780
+ assert.equal(persisted.sessions.root.leader_thread_id, 'root');
781
+ }
782
+ finally {
783
+ rmSync(cwd, { recursive: true, force: true });
784
+ }
785
+ });
786
+ it('surfaces an explicit notice when only legacy non-authoritative records are excluded', () => {
787
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-legacy-notice-'));
788
+ try {
789
+ const path = subagentTrackingPath(cwd);
790
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
791
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { canonical: { session_id: 'canonical', updated_at: '2026-07-23T00:00:00.000Z', threads: {
792
+ legacy: { thread_id: 'legacy', kind: 'subagent', provenance_kind: DESCRIPTIVE_ADAPTED_PROVENANCE, status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
793
+ } } } }));
794
+ const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
795
+ assert.match(context, /\[Persisted subagent reopen\]/);
796
+ assert.match(context, /excluded as non-authoritative or legacy/);
797
+ assert.doesNotMatch(context, /resume_agent\(/);
798
+ const persisted = JSON.parse(readFileSync(path, 'utf8'));
799
+ assert.equal(persisted.sessions.canonical.threads.legacy.resume_requested_at, undefined);
800
+ }
801
+ finally {
802
+ rmSync(cwd, { recursive: true, force: true });
803
+ }
804
+ });
805
+ it('prevents descriptive writers from normalizing malformed authority into reopen access', async () => {
806
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-shared-writer-'));
807
+ try {
808
+ const path = subagentTrackingPath(cwd);
809
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
810
+ const raw = JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads: {
811
+ child: { thread_id: 'child', kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', reopen_authority_revoked: 'false', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 },
812
+ } } } });
813
+ writeFileSync(path, raw);
814
+ await assert.rejects(recordSubagentTurnForSession(cwd, { sessionId: 'root', threadId: 'other', kind: 'subagent' }));
815
+ assert.equal(readFileSync(path, 'utf8'), raw);
816
+ assert.match(consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '', /malformed_tracker_state/);
817
+ }
818
+ finally {
819
+ rmSync(cwd, { recursive: true, force: true });
820
+ }
821
+ });
822
+ it('counts omission caps from authorized targets and warnings only', () => {
823
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-caps-'));
824
+ try {
825
+ const path = subagentTrackingPath(cwd);
826
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
827
+ const threads = {};
828
+ for (let index = 0; index < 14; index += 1)
829
+ threads[`child-${index}`] = { thread_id: `child-${index}`, kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: `2026-07-23T00:${String(index).padStart(2, '0')}:00.000Z`, turn_count: 1 };
830
+ for (let index = 0; index < 10; index += 1)
831
+ threads[`warning-${index}`] = { thread_id: `warning-${index}`, kind: 'subagent', provenance_kind: NATIVE_SUBAGENT_PROVENANCE, direct_child_root_id: 'root', direct_child_parent_id: 'root', status: 'unavailable', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 };
832
+ threads.legacy = { thread_id: 'legacy', kind: 'subagent', status: 'available', first_seen_at: '2026-07-23T00:00:00.000Z', last_seen_at: '2026-07-23T00:00:00.000Z', turn_count: 1 };
833
+ writeFileSync(path, JSON.stringify({ schemaVersion: 1, sessions: { root: { session_id: 'root', updated_at: '2026-07-23T00:00:00.000Z', threads } } }));
834
+ const context = consumeDirectChildReopenContext(cwd, { sessionId: 'root', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
835
+ assert.match(context, /2 more saved subagent id\(s\) omitted/);
836
+ assert.match(context, /2 more warning\(s\) omitted/);
837
+ assert.doesNotMatch(context, /resume_agent\("legacy"\)/);
838
+ }
839
+ finally {
840
+ rmSync(cwd, { recursive: true, force: true });
841
+ }
842
+ });
843
+ it('revokes direct-child authority when an authoritative observation moves it under a nested parent', () => {
844
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-direct-to-nested-'));
845
+ try {
846
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root' });
847
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'nested-parent'], childThreadId: 'child', parentThreadId: 'nested-parent', rootNativeSessionId: 'root' });
848
+ const state = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
849
+ assert.equal(state.sessions.canonical.threads.child.reopen_authority_revoked, true);
850
+ assert.equal(state.sessions.root.threads.child.reopen_authority_revoked, true);
851
+ assert.equal(state.sessions['nested-parent'].threads.child.reopen_authority_revoked, true);
852
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
853
+ }
854
+ finally {
855
+ rmSync(cwd, { recursive: true, force: true });
856
+ }
857
+ });
858
+ it('linearizes revocation before reopen as a denied operation', () => {
859
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-revoke-first-'));
860
+ try {
861
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root' });
862
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'other-root'], childThreadId: 'child', parentThreadId: 'other-root', rootNativeSessionId: 'other-root' });
863
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
864
+ const state = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
865
+ assert.equal(state.sessions.canonical.threads.child.resume_requested_at, undefined);
866
+ }
867
+ finally {
868
+ rmSync(cwd, { recursive: true, force: true });
869
+ }
870
+ });
871
+ it('linearizes reopen before a later revocation and denies subsequent reopen', () => {
872
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-reopen-first-'));
873
+ try {
874
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root' });
875
+ const first = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
876
+ assert.match(first, /resume_agent\("child"\)/);
877
+ const requestedAt = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8')).sessions.canonical.threads.child.resume_requested_at;
878
+ assert.match(requestedAt, /^\d{4}-\d{2}-\d{2}T/);
879
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'other-root'], childThreadId: 'child', parentThreadId: 'other-root', rootNativeSessionId: 'other-root' });
880
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
881
+ const revoked = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
882
+ assert.equal(revoked.sessions.canonical.threads.child.resume_requested_at, requestedAt);
883
+ assert.equal(revoked.sessions.canonical.threads.child.reopen_authority_revoked, true);
884
+ }
885
+ finally {
886
+ rmSync(cwd, { recursive: true, force: true });
887
+ }
888
+ });
889
+ it('serializes a queued reopen behind revocation publication', async () => {
890
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-contended-revoke-first-'));
891
+ const readyPath = join(cwd, 'reopen-contended');
892
+ const resultPath = join(cwd, 'reopen-result.json');
893
+ let competitor;
894
+ try {
895
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
896
+ __setCrossProcessPublishBarrierForTest(() => {
897
+ competitor = spawnAuthorityCompetitor(cwd, 'reopen', readyPath, resultPath);
898
+ waitForFileSync(readyPath, 10_000);
899
+ });
900
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'other-root'], childThreadId: 'child', parentThreadId: 'other-root', rootNativeSessionId: 'other-root', authorityEvidence: 'valid' });
901
+ __setCrossProcessPublishBarrierForTest(null);
902
+ assert.ok(competitor);
903
+ await waitForChildExit(competitor);
904
+ const result = JSON.parse(readFileSync(resultPath, 'utf8'));
905
+ assert.equal(result.observedContention, true);
906
+ assert.equal(result.result, null);
907
+ const state = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
908
+ assert.equal(state.sessions.canonical.threads.child.resume_requested_at, undefined);
909
+ assert.equal(state.sessions.canonical.threads.child.reopen_authority_revoked, true);
910
+ }
911
+ finally {
912
+ __setCrossProcessPublishBarrierForTest(null);
913
+ await stopChild(competitor);
914
+ rmSync(cwd, { recursive: true, force: true });
915
+ }
916
+ });
917
+ it('serializes queued revocation behind completed reopen publication', async () => {
918
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-contended-reopen-first-'));
919
+ const readyPath = join(cwd, 'revoke-contended');
920
+ const resultPath = join(cwd, 'revoke-result.json');
921
+ let competitor;
922
+ try {
923
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence: 'valid' });
924
+ __setCrossProcessPublishBarrierForTest(() => {
925
+ competitor = spawnAuthorityCompetitor(cwd, 'revoke', readyPath, resultPath);
926
+ waitForFileSync(readyPath, 10_000);
927
+ });
928
+ const first = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
929
+ __setCrossProcessPublishBarrierForTest(null);
930
+ assert.match(first, /resume_agent\("child"\)/);
931
+ const requestedAt = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8')).sessions.canonical.threads.child.resume_requested_at;
932
+ assert.match(requestedAt, /^\d{4}-\d{2}-\d{2}T/);
933
+ assert.ok(competitor);
934
+ await waitForChildExit(competitor);
935
+ const result = JSON.parse(readFileSync(resultPath, 'utf8'));
936
+ assert.equal(result.observedContention, true);
937
+ assert.equal(result.result, 'revoked');
938
+ assert.equal(consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }), null);
939
+ const revoked = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
940
+ assert.equal(revoked.sessions.canonical.threads.child.resume_requested_at, requestedAt);
941
+ assert.equal(revoked.sessions.canonical.threads.child.reopen_authority_revoked, true);
942
+ }
943
+ finally {
944
+ __setCrossProcessPublishBarrierForTest(null);
945
+ await stopChild(competitor);
946
+ rmSync(cwd, { recursive: true, force: true });
947
+ }
948
+ });
949
+ it('never grants fresh authority from absent or untrusted evidence', () => {
950
+ for (const authorityEvidence of ['absent', 'untrusted']) {
951
+ const cwd = mkdtempSync(join(tmpdir(), `omx-3284-tracker-${authorityEvidence}-fresh-`));
952
+ try {
953
+ recordNativeSubagentAuthorityObservation(cwd, { sessionIds: ['canonical', 'root'], childThreadId: 'child', parentThreadId: 'root', rootNativeSessionId: 'root', authorityEvidence });
954
+ const state = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
955
+ assert.equal(state.sessions.canonical.threads.child.direct_child_root_id, undefined);
956
+ const context = consumeDirectChildReopenContext(cwd, { sessionId: 'canonical', rootNativeSessionId: 'root', source: 'resume' }) ?? '';
957
+ // Fail-closed denial: no authority, no bookkeeping, no resume output. An
958
+ // explicit exclusion notice is allowed in place of a bare null.
959
+ assert.doesNotMatch(context, /resume_agent\(/);
960
+ assert.equal(JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8')).sessions.canonical.threads.child.resume_requested_at, undefined);
961
+ }
962
+ finally {
963
+ rmSync(cwd, { recursive: true, force: true });
964
+ }
965
+ }
966
+ });
246
967
  it('can record an explicitly spawned subagent as subagent even when it is the first seen thread', () => {
247
968
  let state = createSubagentTrackingState();
248
969
  state = recordSubagentTurn(state, {
@@ -1106,937 +1827,5 @@ describe('subagents/tracker', () => {
1106
1827
  await rm(baseStateDir, { recursive: true, force: true });
1107
1828
  }
1108
1829
  });
1109
- it('rejects pending role intents for unknown roles', () => {
1110
- assert.deepEqual(recordPendingRoleIntent(process.cwd(), {
1111
- role: 'not-a-known-role',
1112
- sessionId: 'sess-role-intent',
1113
- parentThreadId: 'thread-parent',
1114
- correlationToken: canonicalCorrelationToken('correlation-token'),
1115
- }), { ok: false, reason: 'unknown_role' });
1116
- });
1117
- it('rejects pending role intents with an empty correlation token', () => {
1118
- assert.deepEqual(recordPendingRoleIntent(process.cwd(), {
1119
- role: 'architect',
1120
- sessionId: 'sess-role-intent',
1121
- parentThreadId: 'thread-parent',
1122
- correlationToken: '',
1123
- }), { ok: false, reason: 'invalid_correlation_token' });
1124
- });
1125
- it('rejects parser-invalid tokens before persistence and round-trips valid tokens', async () => {
1126
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-token-grammar-'));
1127
- try {
1128
- assert.deepEqual(recordPendingRoleIntent(cwd, {
1129
- role: 'architect',
1130
- sessionId: 'session-token-grammar',
1131
- parentThreadId: 'parent-token-grammar',
1132
- correlationToken: 'abc_def',
1133
- }), { ok: false, reason: 'invalid_correlation_token' });
1134
- assert.equal((await readSubagentTrackingState(cwd)).pending_role_intents.length, 0);
1135
- assert.equal(recordPendingRoleIntent(cwd, {
1136
- role: 'architect',
1137
- sessionId: 'session-token-grammar',
1138
- parentThreadId: 'parent-token-grammar',
1139
- correlationToken: canonicalCorrelationToken('abc123'),
1140
- }).ok, true);
1141
- assert.equal((await readSubagentTrackingState(cwd)).pending_role_intents[0]?.correlation_token, canonicalCorrelationToken('abc123'));
1142
- }
1143
- finally {
1144
- await rm(cwd, { recursive: true, force: true });
1145
- }
1146
- });
1147
- it('rejects a second live role intent for the same parent thread', async () => {
1148
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
1149
- try {
1150
- assert.equal(recordPendingRoleIntent(cwd, {
1151
- role: 'architect',
1152
- sessionId: 'sess-role-intent',
1153
- parentThreadId: 'thread-parent',
1154
- correlationToken: canonicalCorrelationToken('architecttoken'),
1155
- nowMs: 1_000,
1156
- }).ok, true);
1157
- assert.deepEqual(recordPendingRoleIntent(cwd, {
1158
- role: 'critic',
1159
- sessionId: 'sess-role-intent',
1160
- parentThreadId: 'thread-parent',
1161
- correlationToken: canonicalCorrelationToken('critictoken'),
1162
- nowMs: 1_001,
1163
- }), { ok: false, reason: 'single_flight_conflict' });
1164
- }
1165
- finally {
1166
- await rm(cwd, { recursive: true, force: true });
1167
- }
1168
- });
1169
- it('serializes concurrent pending role intent records across processes', async () => {
1170
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
1171
- try {
1172
- const results = await runConcurrentPendingRoleIntentWorkers(cwd, [
1173
- {
1174
- operation: 'record',
1175
- cwd,
1176
- role: 'architect',
1177
- sessionId: 'sess-role-intent-concurrent-record',
1178
- parentThreadId: 'thread-parent',
1179
- correlationToken: canonicalCorrelationToken('architecttoken'),
1180
- nowMs: 1_000,
1181
- },
1182
- {
1183
- operation: 'record',
1184
- cwd,
1185
- role: 'critic',
1186
- sessionId: 'sess-role-intent-concurrent-record',
1187
- parentThreadId: 'thread-parent',
1188
- correlationToken: canonicalCorrelationToken('critictoken'),
1189
- nowMs: 1_000,
1190
- },
1191
- ]);
1192
- assert.equal(results.filter(isSuccessfulRoleIntentRecord).length, 1);
1193
- assert.equal(results.filter(isSingleFlightConflict).length, 1);
1194
- }
1195
- finally {
1196
- await rm(cwd, { recursive: true, force: true });
1197
- }
1198
- });
1199
- it('preserves expired foreign-origin journals through successful pending-role lifecycle writes', async () => {
1200
- const sharedRoot = await mkdtemp(join(tmpdir(), 'omx-tracker-shared-writeback-'));
1201
- const cwdA = join(sharedRoot, 'workspace-a');
1202
- const cwdB = join(sharedRoot, 'workspace-b');
1203
- const previousStateRoot = process.env.OMX_STATE_ROOT;
1204
- try {
1205
- process.env.OMX_STATE_ROOT = sharedRoot;
1206
- await mkdir(cwdA, { recursive: true });
1207
- await mkdir(cwdB, { recursive: true });
1208
- assert.equal(getBaseStateDir(cwdA), getBaseStateDir(cwdB));
1209
- const foreignResult = recordPendingRoleIntent(cwdA, {
1210
- role: 'architect',
1211
- sessionId: 'session-foreign',
1212
- parentThreadId: 'parent-foreign',
1213
- correlationToken: canonicalCorrelationToken('tokenforeign'),
1214
- ttlMs: 1,
1215
- nowMs: 1_000,
1216
- });
1217
- assert.equal(foreignResult.ok, true);
1218
- if (!foreignResult.ok)
1219
- throw new Error('Expected the foreign role intent to record.');
1220
- const foreignIntent = foreignResult.intent;
1221
- const assertForeignRetained = async () => {
1222
- const retained = (await readSubagentTrackingState(cwdB)).pending_role_intents
1223
- .find((intent) => intent.correlation_token === foreignIntent.correlation_token);
1224
- assert.deepEqual(retained, foreignIntent);
1225
- };
1226
- const nowMs = 1_002;
1227
- assert.equal(recordPendingRoleIntent(cwdB, {
1228
- role: 'critic',
1229
- sessionId: 'session-bound',
1230
- parentThreadId: 'parent-bound',
1231
- correlationToken: canonicalCorrelationToken('tokenbound'),
1232
- nowMs,
1233
- }).ok, true);
1234
- await assertForeignRetained();
1235
- const binding = bindPendingRoleIntentUnderLock(cwdB, {
1236
- sessionId: 'session-bound',
1237
- parentThreadId: 'parent-bound',
1238
- correlationToken: canonicalCorrelationToken('tokenbound'),
1239
- nowMs,
1240
- }, (state) => state);
1241
- assert.ok(binding?.claimantToken);
1242
- await assertForeignRetained();
1243
- assert.equal(completeAdaptedRoleBinding(cwdB, {
1244
- sessionId: 'session-bound',
1245
- parentThreadId: 'parent-bound',
1246
- correlationToken: canonicalCorrelationToken('tokenbound'),
1247
- claimantToken: binding?.claimantToken,
1248
- nowMs,
1249
- }), 'completed');
1250
- await assertForeignRetained();
1251
- assert.equal(recordPendingRoleIntent(cwdB, {
1252
- role: 'critic',
1253
- sessionId: 'session-consume',
1254
- parentThreadId: 'parent-consume',
1255
- correlationToken: canonicalCorrelationToken('tokenconsume'),
1256
- nowMs,
1257
- }).ok, true);
1258
- assert.deepEqual(consumePendingRoleIntent(cwdB, {
1259
- sessionId: 'session-consume',
1260
- parentThreadId: 'parent-consume',
1261
- correlationToken: canonicalCorrelationToken('tokenconsume'),
1262
- nowMs,
1263
- }), { role: 'critic', provenanceKind: OMX_ADAPTED_PROVENANCE });
1264
- await assertForeignRetained();
1265
- }
1266
- finally {
1267
- if (previousStateRoot === undefined)
1268
- delete process.env.OMX_STATE_ROOT;
1269
- else
1270
- process.env.OMX_STATE_ROOT = previousStateRoot;
1271
- await rm(sharedRoot, { recursive: true, force: true });
1272
- }
1273
- });
1274
- it('binds a pending role intent only when its correlation token matches', async () => {
1275
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
1276
- const input = {
1277
- sessionId: 'sess-role-intent',
1278
- parentThreadId: 'thread-parent',
1279
- nowMs: 1_001,
1280
- };
1281
- let bindCount = 0;
1282
- const bind = (state, intent) => {
1283
- bindCount += 1;
1284
- assert.deepEqual(intent, { role: 'architect', provenanceKind: OMX_ADAPTED_PROVENANCE });
1285
- return state;
1286
- };
1287
- try {
1288
- assert.equal(recordPendingRoleIntent(cwd, {
1289
- role: 'architect',
1290
- sessionId: input.sessionId,
1291
- parentThreadId: input.parentThreadId,
1292
- correlationToken: canonicalCorrelationToken('expectedtoken'),
1293
- nowMs: 1_000,
1294
- }).ok, true);
1295
- assert.equal(bindPendingRoleIntentUnderLock(cwd, input, bind), null);
1296
- assert.equal(bindPendingRoleIntentUnderLock(cwd, { ...input, correlationToken: canonicalCorrelationToken('wrongtoken') }, bind), null);
1297
- assert.equal((await readSubagentTrackingState(cwd)).pending_role_intents[0]?.correlation_token, canonicalCorrelationToken('expectedtoken'));
1298
- const firstBinding = bindPendingRoleIntentUnderLock(cwd, { ...input, correlationToken: canonicalCorrelationToken('expectedtoken') }, bind);
1299
- assert.equal(firstBinding?.role, 'architect');
1300
- assert.equal(firstBinding?.provenanceKind, OMX_ADAPTED_PROVENANCE);
1301
- assert.equal(firstBinding?.alreadyBound, false);
1302
- assert.ok(firstBinding?.claimantToken);
1303
- const retainedIntent = (await readSubagentTrackingState(cwd)).pending_role_intents[0];
1304
- assert.equal(retainedIntent?.binding_state, 'bound');
1305
- assert.equal(retainedIntent?.binding_claimant_token, firstBinding?.claimantToken);
1306
- const replay = bindPendingRoleIntentUnderLock(cwd, { ...input, correlationToken: canonicalCorrelationToken('expectedtoken') }, bind);
1307
- assert.deepEqual(replay, {
1308
- role: 'architect',
1309
- provenanceKind: OMX_ADAPTED_PROVENANCE,
1310
- claimantToken: undefined,
1311
- alreadyBound: true,
1312
- });
1313
- assert.equal(bindCount, 1);
1314
- assert.equal(completeAdaptedRoleBinding(cwd, { ...input, correlationToken: canonicalCorrelationToken('expectedtoken'), claimantToken: replay?.claimantToken }), 'claimant_mismatch');
1315
- assert.equal(completeAdaptedRoleBinding(cwd, { ...input, correlationToken: canonicalCorrelationToken('expectedtoken'), claimantToken: firstBinding?.claimantToken }), 'completed');
1316
- }
1317
- finally {
1318
- await rm(cwd, { recursive: true, force: true });
1319
- }
1320
- });
1321
- it('migrates a same-workspace cwd-partitioned legacy journal on bind and still consumes one', async () => {
1322
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-legacy-'));
1323
- const previousOmxRoot = process.env.OMX_ROOT;
1324
- const previousTeamStateRoot = process.env.OMX_TEAM_STATE_ROOT;
1325
- const previousStateRoot = process.env.OMX_STATE_ROOT;
1326
- const nowMs = Date.now();
1327
- try {
1328
- delete process.env.OMX_ROOT;
1329
- delete process.env.OMX_TEAM_STATE_ROOT;
1330
- delete process.env.OMX_STATE_ROOT;
1331
- await mkdir(getBaseStateDir(cwd), { recursive: true });
1332
- const legacyIntent = {
1333
- role: 'architect',
1334
- session_id: 'legacy-session-bind',
1335
- parent_thread_id: 'legacy-parent-bind',
1336
- correlation_token: canonicalCorrelationToken('legacy-token-bind'),
1337
- created_at: new Date(nowMs).toISOString(),
1338
- expires_at: new Date(nowMs + 60_000).toISOString(),
1339
- };
1340
- await writeFile(subagentTrackingPath(cwd), `${JSON.stringify({
1341
- schemaVersion: 1,
1342
- sessions: {},
1343
- pending_role_intents: [legacyIntent],
1344
- })}\n`);
1345
- const binding = bindPendingRoleIntentUnderLock(cwd, {
1346
- sessionId: legacyIntent.session_id,
1347
- parentThreadId: legacyIntent.parent_thread_id,
1348
- correlationToken: legacyIntent.correlation_token,
1349
- nowMs,
1350
- }, (state) => state);
1351
- assert.equal(binding?.alreadyBound, false);
1352
- assert.ok(binding?.claimantToken);
1353
- assert.equal((await readSubagentTrackingState(cwd)).pending_role_intents[0]?.origin_cwd, canonicalizeOriginCwd(cwd));
1354
- assert.equal(completeAdaptedRoleBinding(cwd, {
1355
- sessionId: legacyIntent.session_id,
1356
- parentThreadId: legacyIntent.parent_thread_id,
1357
- correlationToken: legacyIntent.correlation_token,
1358
- claimantToken: binding?.claimantToken,
1359
- nowMs,
1360
- }), 'completed');
1361
- const legacyConsumeIntent = {
1362
- ...legacyIntent,
1363
- session_id: 'legacy-session-consume',
1364
- parent_thread_id: 'legacy-parent-consume',
1365
- correlation_token: canonicalCorrelationToken('legacy-token-consume'),
1366
- };
1367
- await writeFile(subagentTrackingPath(cwd), `${JSON.stringify({
1368
- schemaVersion: 1,
1369
- sessions: {},
1370
- pending_role_intents: [legacyConsumeIntent],
1371
- })}\n`);
1372
- assert.deepEqual(consumePendingRoleIntent(cwd, {
1373
- sessionId: legacyConsumeIntent.session_id,
1374
- parentThreadId: legacyConsumeIntent.parent_thread_id,
1375
- correlationToken: legacyConsumeIntent.correlation_token,
1376
- nowMs,
1377
- }), { role: 'architect', provenanceKind: OMX_ADAPTED_PROVENANCE });
1378
- }
1379
- finally {
1380
- if (previousOmxRoot === undefined)
1381
- delete process.env.OMX_ROOT;
1382
- else
1383
- process.env.OMX_ROOT = previousOmxRoot;
1384
- if (previousTeamStateRoot === undefined)
1385
- delete process.env.OMX_TEAM_STATE_ROOT;
1386
- else
1387
- process.env.OMX_TEAM_STATE_ROOT = previousTeamStateRoot;
1388
- if (previousStateRoot === undefined)
1389
- delete process.env.OMX_STATE_ROOT;
1390
- else
1391
- process.env.OMX_STATE_ROOT = previousStateRoot;
1392
- await rm(cwd, { recursive: true, force: true });
1393
- }
1394
- });
1395
- it('stamps an owned already-bound cwd-default legacy journal on bind replay without disclosing its claimant', async () => {
1396
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-bound-legacy-'));
1397
- const previousOmxRoot = process.env.OMX_ROOT;
1398
- const previousTeamStateRoot = process.env.OMX_TEAM_STATE_ROOT;
1399
- const previousStateRoot = process.env.OMX_STATE_ROOT;
1400
- const nowMs = Date.now();
1401
- try {
1402
- delete process.env.OMX_ROOT;
1403
- delete process.env.OMX_TEAM_STATE_ROOT;
1404
- delete process.env.OMX_STATE_ROOT;
1405
- await mkdir(getBaseStateDir(cwd), { recursive: true });
1406
- const legacyIntent = {
1407
- role: 'architect',
1408
- session_id: 'legacy-bound-session',
1409
- parent_thread_id: 'legacy-bound-parent',
1410
- correlation_token: canonicalCorrelationToken('a3118b'),
1411
- created_at: new Date(nowMs).toISOString(),
1412
- expires_at: new Date(nowMs + 60_000).toISOString(),
1413
- binding_state: 'bound',
1414
- binding_claimant_token: canonicalClaimantToken('legacy-claimant'),
1415
- bound_at: new Date(nowMs).toISOString(),
1416
- };
1417
- await writeFile(subagentTrackingPath(cwd), `${JSON.stringify({
1418
- schemaVersion: 1,
1419
- sessions: {},
1420
- pending_role_intents: [legacyIntent],
1421
- })}\n`);
1422
- let bindCalled = false;
1423
- assert.deepEqual(bindPendingRoleIntentUnderLock(cwd, {
1424
- sessionId: legacyIntent.session_id,
1425
- parentThreadId: legacyIntent.parent_thread_id,
1426
- correlationToken: legacyIntent.correlation_token,
1427
- nowMs,
1428
- }, (state) => {
1429
- bindCalled = true;
1430
- return state;
1431
- }), {
1432
- role: 'architect',
1433
- provenanceKind: OMX_ADAPTED_PROVENANCE,
1434
- claimantToken: undefined,
1435
- alreadyBound: true,
1436
- });
1437
- assert.equal(bindCalled, false);
1438
- assert.equal((await readSubagentTrackingState(cwd)).pending_role_intents[0]?.origin_cwd, canonicalizeOriginCwd(cwd));
1439
- }
1440
- finally {
1441
- if (previousOmxRoot === undefined)
1442
- delete process.env.OMX_ROOT;
1443
- else
1444
- process.env.OMX_ROOT = previousOmxRoot;
1445
- if (previousTeamStateRoot === undefined)
1446
- delete process.env.OMX_TEAM_STATE_ROOT;
1447
- else
1448
- process.env.OMX_TEAM_STATE_ROOT = previousTeamStateRoot;
1449
- if (previousStateRoot === undefined)
1450
- delete process.env.OMX_STATE_ROOT;
1451
- else
1452
- process.env.OMX_STATE_ROOT = previousStateRoot;
1453
- await rm(cwd, { recursive: true, force: true });
1454
- }
1455
- });
1456
- it('does not allow a shared-root workspace to claim another originless legacy journal', async () => {
1457
- const sharedRoot = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-shared-legacy-'));
1458
- const cwdA = join(sharedRoot, 'workspace-a');
1459
- const cwdB = join(sharedRoot, 'workspace-b');
1460
- const previousOmxRoot = process.env.OMX_ROOT;
1461
- const previousTeamStateRoot = process.env.OMX_TEAM_STATE_ROOT;
1462
- const previousStateRoot = process.env.OMX_STATE_ROOT;
1463
- const nowMs = Date.now();
1464
- try {
1465
- delete process.env.OMX_ROOT;
1466
- delete process.env.OMX_TEAM_STATE_ROOT;
1467
- process.env.OMX_STATE_ROOT = sharedRoot;
1468
- await mkdir(cwdA, { recursive: true });
1469
- await mkdir(cwdB, { recursive: true });
1470
- const legacyIntent = {
1471
- role: 'architect',
1472
- session_id: 'shared-legacy-session',
1473
- parent_thread_id: 'shared-legacy-parent',
1474
- correlation_token: canonicalCorrelationToken('shared-legacy-token'),
1475
- created_at: new Date(nowMs).toISOString(),
1476
- expires_at: new Date(nowMs + 60_000).toISOString(),
1477
- };
1478
- await mkdir(getBaseStateDir(cwdA), { recursive: true });
1479
- await writeFile(subagentTrackingPath(cwdA), `${JSON.stringify({
1480
- schemaVersion: 1,
1481
- sessions: {},
1482
- pending_role_intents: [legacyIntent],
1483
- })}\n`);
1484
- let bindCalled = false;
1485
- assert.equal(bindPendingRoleIntentUnderLock(cwdB, {
1486
- sessionId: legacyIntent.session_id,
1487
- parentThreadId: legacyIntent.parent_thread_id,
1488
- correlationToken: legacyIntent.correlation_token,
1489
- nowMs,
1490
- }, (state) => {
1491
- bindCalled = true;
1492
- return state;
1493
- }), null);
1494
- assert.equal(bindCalled, false);
1495
- assert.equal(consumePendingRoleIntent(cwdB, {
1496
- sessionId: legacyIntent.session_id,
1497
- parentThreadId: legacyIntent.parent_thread_id,
1498
- correlationToken: legacyIntent.correlation_token,
1499
- nowMs,
1500
- }), null);
1501
- assert.equal(completeAdaptedRoleBinding(cwdB, {
1502
- sessionId: legacyIntent.session_id,
1503
- parentThreadId: legacyIntent.parent_thread_id,
1504
- correlationToken: legacyIntent.correlation_token,
1505
- nowMs,
1506
- }), 'not_found');
1507
- assert.deepEqual((await readSubagentTrackingState(cwdA)).pending_role_intents, [legacyIntent]);
1508
- }
1509
- finally {
1510
- if (previousOmxRoot === undefined)
1511
- delete process.env.OMX_ROOT;
1512
- else
1513
- process.env.OMX_ROOT = previousOmxRoot;
1514
- if (previousTeamStateRoot === undefined)
1515
- delete process.env.OMX_TEAM_STATE_ROOT;
1516
- else
1517
- process.env.OMX_TEAM_STATE_ROOT = previousTeamStateRoot;
1518
- if (previousStateRoot === undefined)
1519
- delete process.env.OMX_STATE_ROOT;
1520
- else
1521
- process.env.OMX_STATE_ROOT = previousStateRoot;
1522
- await rm(sharedRoot, { recursive: true, force: true });
1523
- }
1524
- });
1525
- it('selects exact-origin duplicate journals deterministically and consumes every own duplicate', async () => {
1526
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-duplicate-origin-'));
1527
- const previousOmxRoot = process.env.OMX_ROOT;
1528
- const previousTeamStateRoot = process.env.OMX_TEAM_STATE_ROOT;
1529
- const previousStateRoot = process.env.OMX_STATE_ROOT;
1530
- const nowMs = Date.now();
1531
- const scope = {
1532
- sessionId: 'duplicate-session',
1533
- parentThreadId: 'duplicate-parent',
1534
- correlationToken: canonicalCorrelationToken('a3118d'),
1535
- };
1536
- try {
1537
- delete process.env.OMX_ROOT;
1538
- delete process.env.OMX_TEAM_STATE_ROOT;
1539
- delete process.env.OMX_STATE_ROOT;
1540
- await mkdir(getBaseStateDir(cwd), { recursive: true });
1541
- const journal = (role, originCwd, claimantToken) => ({
1542
- role,
1543
- session_id: scope.sessionId,
1544
- parent_thread_id: scope.parentThreadId,
1545
- correlation_token: scope.correlationToken,
1546
- created_at: new Date(nowMs).toISOString(),
1547
- expires_at: new Date(nowMs + 60_000).toISOString(),
1548
- ...(originCwd ? { origin_cwd: originCwd } : {}),
1549
- ...(claimantToken ? {
1550
- binding_state: 'bound',
1551
- binding_claimant_token: canonicalClaimantToken(claimantToken),
1552
- bound_at: new Date(nowMs).toISOString(),
1553
- } : {}),
1554
- });
1555
- const legacy = journal('architect');
1556
- const exact = journal('critic', cwd);
1557
- const writeJournals = async (pendingRoleIntents) => {
1558
- await writeFile(subagentTrackingPath(cwd), `${JSON.stringify({
1559
- schemaVersion: 1,
1560
- sessions: {},
1561
- pending_role_intents: pendingRoleIntents,
1562
- })}\n`);
1563
- };
1564
- for (const duplicateOrder of [[legacy, exact], [exact, legacy]]) {
1565
- await writeJournals(duplicateOrder);
1566
- assert.deepEqual(consumePendingRoleIntent(cwd, { ...scope, nowMs }), {
1567
- role: 'critic',
1568
- provenanceKind: OMX_ADAPTED_PROVENANCE,
1569
- });
1570
- assert.equal(consumePendingRoleIntent(cwd, { ...scope, nowMs }), null);
1571
- assert.deepEqual((await readSubagentTrackingState(cwd)).pending_role_intents, []);
1572
- }
1573
- for (const duplicateOrder of [[legacy, exact], [exact, legacy]]) {
1574
- await writeJournals(duplicateOrder);
1575
- let boundRole;
1576
- const binding = bindPendingRoleIntentUnderLock(cwd, { ...scope, nowMs }, (state, intent) => {
1577
- boundRole = intent.role;
1578
- return state;
1579
- });
1580
- assert.equal(binding?.role, 'critic');
1581
- assert.equal(boundRole, 'critic');
1582
- assert.ok(binding?.claimantToken);
1583
- assert.deepEqual((await readSubagentTrackingState(cwd)).pending_role_intents.map((intent) => intent.role), ['critic']);
1584
- assert.equal(completeAdaptedRoleBinding(cwd, {
1585
- ...scope,
1586
- claimantToken: binding?.claimantToken,
1587
- nowMs,
1588
- }), 'completed');
1589
- assert.deepEqual((await readSubagentTrackingState(cwd)).pending_role_intents, []);
1590
- }
1591
- const legacyBound = journal('architect', undefined, 'legacyclaimant');
1592
- const exactBound = journal('critic', cwd, 'exactclaimant');
1593
- for (const duplicateOrder of [[legacyBound, exactBound], [exactBound, legacyBound]]) {
1594
- await writeJournals(duplicateOrder);
1595
- assert.equal(completeAdaptedRoleBinding(cwd, {
1596
- ...scope,
1597
- claimantToken: canonicalClaimantToken('exactclaimant'),
1598
- nowMs,
1599
- }), 'completed');
1600
- assert.deepEqual((await readSubagentTrackingState(cwd)).pending_role_intents, []);
1601
- }
1602
- const mixedStates = [
1603
- {
1604
- name: 'exact-bound-with-legacy-pending',
1605
- bound: journal('critic', cwd, 'exact-bound-claimant'),
1606
- pending: journal('architect'),
1607
- },
1608
- {
1609
- name: 'legacy-bound-with-exact-pending',
1610
- bound: journal('critic', undefined, 'legacy-bound-claimant'),
1611
- pending: journal('architect', cwd),
1612
- },
1613
- ];
1614
- for (const { name, bound, pending } of mixedStates) {
1615
- for (const invocationOrder of [['bind', 'consume'], ['consume', 'bind']]) {
1616
- for (const journalOrder of [[bound, pending], [pending, bound]]) {
1617
- await writeJournals(journalOrder);
1618
- const authorizedRoles = [];
1619
- let bindCount = 0;
1620
- for (const operation of invocationOrder) {
1621
- if (operation === 'bind') {
1622
- const binding = bindPendingRoleIntentUnderLock(cwd, { ...scope, nowMs }, (state) => {
1623
- bindCount += 1;
1624
- return state;
1625
- });
1626
- assert.deepEqual(binding, {
1627
- role: 'critic',
1628
- provenanceKind: OMX_ADAPTED_PROVENANCE,
1629
- claimantToken: undefined,
1630
- alreadyBound: true,
1631
- }, `${name}:${invocationOrder.join('-')}:${journalOrder[0]?.role}`);
1632
- authorizedRoles.push(binding?.role ?? 'missing');
1633
- }
1634
- else {
1635
- assert.equal(consumePendingRoleIntent(cwd, { ...scope, nowMs }), null, `${name}:${invocationOrder.join('-')}:${journalOrder[0]?.role}`);
1636
- }
1637
- }
1638
- assert.deepEqual(authorizedRoles, ['critic']);
1639
- assert.equal(bindCount, 0);
1640
- const retained = (await readSubagentTrackingState(cwd)).pending_role_intents;
1641
- assert.equal(retained.length, 1);
1642
- assert.equal(retained[0]?.role, 'critic');
1643
- assert.equal(retained[0]?.binding_state, 'bound');
1644
- assert.equal(retained[0]?.correlation_token, scope.correlationToken);
1645
- }
1646
- }
1647
- }
1648
- }
1649
- finally {
1650
- if (previousOmxRoot === undefined)
1651
- delete process.env.OMX_ROOT;
1652
- else
1653
- process.env.OMX_ROOT = previousOmxRoot;
1654
- if (previousTeamStateRoot === undefined)
1655
- delete process.env.OMX_TEAM_STATE_ROOT;
1656
- else
1657
- process.env.OMX_TEAM_STATE_ROOT = previousTeamStateRoot;
1658
- if (previousStateRoot === undefined)
1659
- delete process.env.OMX_STATE_ROOT;
1660
- else
1661
- process.env.OMX_STATE_ROOT = previousStateRoot;
1662
- await rm(cwd, { recursive: true, force: true });
1663
- }
1664
- });
1665
- it('consumes a pending role intent exactly once', async () => {
1666
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
1667
- try {
1668
- assert.equal(recordPendingRoleIntent(cwd, {
1669
- role: 'architect',
1670
- sessionId: 'sess-role-intent',
1671
- parentThreadId: 'thread-parent',
1672
- correlationToken: canonicalCorrelationToken('architecttoken'),
1673
- nowMs: 1_000,
1674
- }).ok, true);
1675
- assert.deepEqual(consumePendingRoleIntent(cwd, {
1676
- sessionId: 'sess-role-intent',
1677
- parentThreadId: 'thread-parent',
1678
- correlationToken: canonicalCorrelationToken('architecttoken'),
1679
- nowMs: 1_001,
1680
- }), { role: 'architect', provenanceKind: OMX_ADAPTED_PROVENANCE });
1681
- assert.equal(consumePendingRoleIntent(cwd, {
1682
- sessionId: 'sess-role-intent',
1683
- parentThreadId: 'thread-parent',
1684
- correlationToken: canonicalCorrelationToken('architecttoken'),
1685
- nowMs: 1_002,
1686
- }), null);
1687
- }
1688
- finally {
1689
- await rm(cwd, { recursive: true, force: true });
1690
- }
1691
- });
1692
- it('completes retained adapted bindings only for the claimant that began them', async () => {
1693
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
1694
- const input = {
1695
- sessionId: 'sess-complete-binding',
1696
- parentThreadId: 'thread-parent',
1697
- correlationToken: canonicalCorrelationToken('completetoken'),
1698
- nowMs: 1_001,
1699
- };
1700
- try {
1701
- assert.equal(recordPendingRoleIntent(cwd, {
1702
- role: 'architect',
1703
- sessionId: input.sessionId,
1704
- parentThreadId: input.parentThreadId,
1705
- correlationToken: input.correlationToken,
1706
- nowMs: 1_000,
1707
- }).ok, true);
1708
- const binding = bindPendingRoleIntentUnderLock(cwd, input, (state) => state);
1709
- assert.ok(binding?.claimantToken);
1710
- assert.equal(completeAdaptedRoleBinding(cwd, { ...input, claimantToken: canonicalClaimantToken('wrong-claimant') }), 'claimant_mismatch');
1711
- assert.equal((await readSubagentTrackingState(cwd)).pending_role_intents.length, 1);
1712
- // Fail-closed: an OMITTED caller token must not complete a journal that carries a
1713
- // stored claimant token (prevents unauthenticated completion / successor theft).
1714
- assert.equal(completeAdaptedRoleBinding(cwd, {
1715
- sessionId: input.sessionId,
1716
- parentThreadId: input.parentThreadId,
1717
- correlationToken: input.correlationToken,
1718
- }), 'claimant_mismatch');
1719
- assert.equal((await readSubagentTrackingState(cwd)).pending_role_intents.length, 1);
1720
- assert.equal(completeAdaptedRoleBinding(cwd, { ...input, claimantToken: binding.claimantToken }), 'completed');
1721
- assert.equal(completeAdaptedRoleBinding(cwd, { ...input, claimantToken: binding.claimantToken }), 'not_found');
1722
- }
1723
- finally {
1724
- await rm(cwd, { recursive: true, force: true });
1725
- }
1726
- });
1727
- it('requires a claimant-less bound journal to receive its durable correlation token before completion', async () => {
1728
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-claimant-less-'));
1729
- const nowMs = Date.now();
1730
- const intent = {
1731
- role: 'architect',
1732
- session_id: 'claimant-less-session',
1733
- parent_thread_id: 'claimant-less-parent',
1734
- correlation_token: canonicalCorrelationToken('a3118f'),
1735
- created_at: new Date(nowMs).toISOString(),
1736
- expires_at: new Date(nowMs + 60_000).toISOString(),
1737
- binding_state: 'bound',
1738
- bound_at: new Date(nowMs).toISOString(),
1739
- origin_cwd: cwd,
1740
- };
1741
- try {
1742
- await mkdir(getBaseStateDir(cwd), { recursive: true });
1743
- await writeFile(subagentTrackingPath(cwd), `${JSON.stringify({
1744
- schemaVersion: 1,
1745
- sessions: {},
1746
- pending_role_intents: [intent],
1747
- })}\n`);
1748
- assert.equal(completeAdaptedRoleBinding(cwd, {
1749
- sessionId: intent.session_id,
1750
- parentThreadId: intent.parent_thread_id,
1751
- nowMs,
1752
- }), 'claimant_mismatch');
1753
- assert.deepEqual((await readSubagentTrackingState(cwd)).pending_role_intents, [intent]);
1754
- assert.equal(completeAdaptedRoleBinding(cwd, {
1755
- sessionId: intent.session_id,
1756
- parentThreadId: intent.parent_thread_id,
1757
- correlationToken: intent.correlation_token,
1758
- nowMs,
1759
- }), 'completed');
1760
- assert.deepEqual((await readSubagentTrackingState(cwd)).pending_role_intents, []);
1761
- }
1762
- finally {
1763
- await rm(cwd, { recursive: true, force: true });
1764
- }
1765
- });
1766
- it('serializes concurrent pending role intent consumes across processes', async () => {
1767
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
1768
- try {
1769
- assert.equal(recordPendingRoleIntent(cwd, {
1770
- role: 'architect',
1771
- sessionId: 'sess-role-intent-concurrent-consume',
1772
- parentThreadId: 'thread-parent',
1773
- correlationToken: canonicalCorrelationToken('architecttoken'),
1774
- nowMs: 1_000,
1775
- }).ok, true);
1776
- const results = await runConcurrentPendingRoleIntentWorkers(cwd, [
1777
- {
1778
- operation: 'consume',
1779
- cwd,
1780
- sessionId: 'sess-role-intent-concurrent-consume',
1781
- parentThreadId: 'thread-parent',
1782
- correlationToken: canonicalCorrelationToken('architecttoken'),
1783
- nowMs: 1_001,
1784
- },
1785
- {
1786
- operation: 'consume',
1787
- cwd,
1788
- sessionId: 'sess-role-intent-concurrent-consume',
1789
- parentThreadId: 'thread-parent',
1790
- correlationToken: canonicalCorrelationToken('architecttoken'),
1791
- nowMs: 1_001,
1792
- },
1793
- ]);
1794
- assert.equal(results.filter(isConsumedRoleIntent).length, 1);
1795
- assert.equal(results.filter((result) => result === null).length, 1);
1796
- }
1797
- finally {
1798
- await rm(cwd, { recursive: true, force: true });
1799
- }
1800
- });
1801
- it('serializes lifecycle tracking writes with pending role intent records and consumes', async () => {
1802
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
1803
- const sessionId = 'sess-role-intent-lifecycle-race';
1804
- const parentThreadId = 'thread-parent';
1805
- const correlationToken = canonicalCorrelationToken('architecttoken');
1806
- try {
1807
- const recordResults = await runConcurrentPendingRoleIntentWorkers(cwd, [
1808
- {
1809
- operation: 'record',
1810
- cwd,
1811
- role: 'architect',
1812
- sessionId,
1813
- parentThreadId,
1814
- correlationToken,
1815
- nowMs: 1_000,
1816
- },
1817
- {
1818
- operation: 'record-turn',
1819
- cwd,
1820
- sessionId,
1821
- threadId: 'thread-lifecycle-before-consume',
1822
- },
1823
- ]);
1824
- assert.equal(isSuccessfulRoleIntentRecord(recordResults[0]), true);
1825
- assert.equal(isSuccessfulRoleIntentRecord(recordResults[1]), true);
1826
- const recorded = await readSubagentTrackingState(cwd);
1827
- assert.equal(recorded.pending_role_intents.length, 1);
1828
- assert.equal(recorded.pending_role_intents[0]?.role, 'architect');
1829
- assert.equal(recorded.sessions[sessionId]?.threads['thread-lifecycle-before-consume']?.kind, 'leader');
1830
- const consumeResults = await runConcurrentPendingRoleIntentWorkers(cwd, [
1831
- {
1832
- operation: 'consume',
1833
- cwd,
1834
- sessionId,
1835
- parentThreadId,
1836
- correlationToken,
1837
- nowMs: 1_001,
1838
- },
1839
- {
1840
- operation: 'record-turn',
1841
- cwd,
1842
- sessionId,
1843
- threadId: 'thread-lifecycle-after-consume',
1844
- },
1845
- ]);
1846
- assert.equal(isConsumedRoleIntent(consumeResults[0]), true);
1847
- assert.equal(isSuccessfulRoleIntentRecord(consumeResults[1]), true);
1848
- const consumed = await readSubagentTrackingState(cwd);
1849
- assert.deepEqual(consumed.pending_role_intents, []);
1850
- assert.equal(consumed.sessions[sessionId]?.threads['thread-lifecycle-before-consume']?.kind, 'leader');
1851
- assert.equal(consumed.sessions[sessionId]?.threads['thread-lifecycle-after-consume']?.kind, 'subagent');
1852
- }
1853
- finally {
1854
- await rm(cwd, { recursive: true, force: true });
1855
- }
1856
- });
1857
- it('does not consume expired pending role intents', async () => {
1858
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
1859
- try {
1860
- assert.equal(recordPendingRoleIntent(cwd, {
1861
- role: 'architect',
1862
- sessionId: 'sess-role-intent',
1863
- parentThreadId: 'thread-parent',
1864
- correlationToken: canonicalCorrelationToken('architecttoken'),
1865
- nowMs: 1_000,
1866
- ttlMs: 10,
1867
- }).ok, true);
1868
- assert.equal(consumePendingRoleIntent(cwd, {
1869
- sessionId: 'sess-role-intent',
1870
- parentThreadId: 'thread-parent',
1871
- correlationToken: canonicalCorrelationToken('architecttoken'),
1872
- nowMs: 1_010,
1873
- }), null);
1874
- }
1875
- finally {
1876
- await rm(cwd, { recursive: true, force: true });
1877
- }
1878
- });
1879
- it('retains invalid durable credentials and rejects whitespace callers without fallthrough', async () => {
1880
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-credentials-'));
1881
- const nowMs = Date.now();
1882
- const scope = { session_id: 'credential-session', parent_thread_id: 'credential-parent' };
1883
- const base = {
1884
- role: 'architect',
1885
- ...scope,
1886
- created_at: new Date(nowMs).toISOString(),
1887
- expires_at: new Date(nowMs + 60_000).toISOString(),
1888
- binding_state: 'bound',
1889
- origin_cwd: cwd,
1890
- };
1891
- try {
1892
- await mkdir(getBaseStateDir(cwd), { recursive: true });
1893
- await writeFile(subagentTrackingPath(cwd), `${JSON.stringify({
1894
- schemaVersion: 1,
1895
- sessions: {},
1896
- pending_role_intents: [
1897
- { ...base, correlation_token: '', binding_claimant_token: canonicalClaimantToken('claimant') },
1898
- { ...base, correlation_token: canonicalCorrelationToken('validtoken'), binding_claimant_token: canonicalClaimantToken('claimant') },
1899
- ],
1900
- })}\n`);
1901
- const retained = (await readSubagentTrackingState(cwd)).pending_role_intents;
1902
- assert.equal(retained[0]?.correlation_token, '');
1903
- assert.equal(retained[0]?.binding_claimant_token, canonicalClaimantToken('claimant'));
1904
- assert.equal(completeAdaptedRoleBinding(cwd, {
1905
- sessionId: scope.session_id, parentThreadId: scope.parent_thread_id,
1906
- correlationToken: canonicalCorrelationToken('validtoken'), claimantToken: canonicalClaimantToken('claimant'), nowMs,
1907
- }), 'claimant_mismatch');
1908
- assert.equal((await readSubagentTrackingState(cwd)).pending_role_intents.length, 2);
1909
- await writeFile(subagentTrackingPath(cwd), `${JSON.stringify({
1910
- schemaVersion: 1, sessions: {}, pending_role_intents: [{
1911
- ...base, correlation_token: canonicalCorrelationToken('validtoken'), binding_claimant_token: canonicalClaimantToken('claimant'),
1912
- }],
1913
- })}\n`);
1914
- assert.equal(completeAdaptedRoleBinding(cwd, {
1915
- sessionId: scope.session_id, parentThreadId: scope.parent_thread_id,
1916
- correlationToken: ' validtoken ', claimantToken: ' claimant ', nowMs,
1917
- }), 'claimant_mismatch');
1918
- }
1919
- finally {
1920
- await rm(cwd, { recursive: true, force: true });
1921
- }
1922
- });
1923
- it('rejects noncanonical caller correlation credentials without changing a retained intent', async () => {
1924
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-caller-credential-'));
1925
- const correlationToken = canonicalCorrelationToken('caller-correlation');
1926
- const scope = { sessionId: 'caller-session', parentThreadId: 'caller-parent', correlationToken, nowMs: Date.now() };
1927
- try {
1928
- assert.equal(recordPendingRoleIntent(cwd, { role: 'architect', ...scope }).ok, true);
1929
- for (const invalid of ['', ' ', null, 1, true, [], {}]) {
1930
- assert.equal(bindPendingRoleIntentUnderLock(cwd, { ...scope, correlationToken: invalid }, (state) => state), null);
1931
- assert.equal(consumePendingRoleIntent(cwd, { ...scope, correlationToken: invalid }), null);
1932
- assert.equal(completeAdaptedRoleBinding(cwd, { ...scope, correlationToken: invalid }), 'not_found');
1933
- }
1934
- assert.equal((await readSubagentTrackingState(cwd)).pending_role_intents.length, 1);
1935
- }
1936
- finally {
1937
- await rm(cwd, { recursive: true, force: true });
1938
- }
1939
- });
1940
- it('rejects every malformed completion credential without rewriting durable bound journals', async () => {
1941
- const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-completion-credentials-'));
1942
- const nowMs = Date.now();
1943
- const correlationToken = canonicalCorrelationToken('completion-correlation');
1944
- const claimantToken = canonicalClaimantToken('completion-claimant');
1945
- const scope = { sessionId: 'completion-session', parentThreadId: 'completion-parent', nowMs };
1946
- const base = {
1947
- role: 'architect',
1948
- session_id: scope.sessionId,
1949
- parent_thread_id: scope.parentThreadId,
1950
- created_at: new Date(nowMs).toISOString(),
1951
- expires_at: new Date(nowMs + 60_000).toISOString(),
1952
- binding_state: 'bound',
1953
- bound_at: new Date(nowMs).toISOString(),
1954
- origin_cwd: cwd,
1955
- };
1956
- const writeJournal = async (journal) => {
1957
- const raw = `${JSON.stringify({ schemaVersion: 1, sessions: {}, pending_role_intents: [journal] })}\n`;
1958
- await writeFile(subagentTrackingPath(cwd), raw);
1959
- return raw;
1960
- };
1961
- const assertRetainedMismatch = async (label, journal, input) => {
1962
- const raw = await writeJournal(journal);
1963
- assert.equal(completeAdaptedRoleBinding(cwd, input), 'claimant_mismatch', label);
1964
- assert.equal(readFileSync(subagentTrackingPath(cwd), 'utf-8'), raw, label);
1965
- };
1966
- try {
1967
- await mkdir(getBaseStateDir(cwd), { recursive: true });
1968
- const claimantLess = { ...base, correlation_token: correlationToken };
1969
- const claimed = { ...claimantLess, binding_claimant_token: claimantToken };
1970
- const invalidCorrelations = [
1971
- ['omitted', undefined], ['empty', ''], ['ascii-whitespace', ' '], ['tab-cr-lf-wrapped', `\t${correlationToken}\r\n`],
1972
- ['uppercase', correlationToken.toUpperCase()], ['wrong-length', correlationToken.slice(1)], ['non-hex', 'g'.repeat(32)],
1973
- ['wrong-canonical', canonicalCorrelationToken('other-correlation')], ['null', null], ['number', 1], ['boolean', true], ['array', []], ['object', {}],
1974
- ];
1975
- for (const [name, value] of invalidCorrelations) {
1976
- const input = { ...scope, correlationToken: value, claimantToken };
1977
- await assertRetainedMismatch(`claimant-less correlation ${name}`, claimantLess, input);
1978
- await assertRetainedMismatch(`claimed correlation ${name}`, claimed, input);
1979
- }
1980
- const invalidClaimants = [
1981
- ['omitted', undefined], ['empty', ''], ['ascii-whitespace', ' '], ['tab-cr-lf-wrapped', `\t${claimantToken}\r\n`],
1982
- ['uppercase', claimantToken.toUpperCase()], ['wrong-length', claimantToken.slice(1)], ['non-hex', 'x'.repeat(36)],
1983
- ['wrong-canonical', canonicalClaimantToken('other-claimant')], ['null', null], ['number', 1], ['boolean', true], ['array', []], ['object', {}],
1984
- ];
1985
- for (const [name, value] of invalidClaimants) {
1986
- await assertRetainedMismatch(`claimed claimant ${name}`, claimed, { ...scope, correlationToken, claimantToken: value });
1987
- }
1988
- await writeJournal(claimantLess);
1989
- assert.equal(completeAdaptedRoleBinding(cwd, { ...scope, correlationToken }), 'completed');
1990
- assert.deepEqual((await readSubagentTrackingState(cwd)).pending_role_intents, []);
1991
- await writeJournal(claimed);
1992
- assert.equal(completeAdaptedRoleBinding(cwd, { ...scope, correlationToken, claimantToken }), 'completed');
1993
- assert.deepEqual((await readSubagentTrackingState(cwd)).pending_role_intents, []);
1994
- for (const persistedCorrelation of ['', ' ', null, 1, true, [], {}]) {
1995
- await assertRetainedMismatch('claimed persisted correlation', { ...claimed, correlation_token: persistedCorrelation }, { ...scope, correlationToken, claimantToken });
1996
- await assertRetainedMismatch('claimant-less persisted correlation', { ...claimantLess, correlation_token: persistedCorrelation }, { ...scope, correlationToken });
1997
- }
1998
- for (const persistedClaimant of ['', ' ', null, 1, true, [], {}]) {
1999
- await assertRetainedMismatch('claimed persisted claimant', { ...claimed, binding_claimant_token: persistedClaimant }, { ...scope, correlationToken, claimantToken });
2000
- }
2001
- }
2002
- finally {
2003
- await rm(cwd, { recursive: true, force: true });
2004
- }
2005
- });
2006
- it('rejects NUL and ELOOP origins before creating tracking artifacts', async () => {
2007
- const parent = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-origin-'));
2008
- const stateRoot = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-origin-state-'));
2009
- const loop = join(parent, 'loop');
2010
- const validCwd = join(parent, 'valid');
2011
- const previousStateRoot = process.env.OMX_STATE_ROOT;
2012
- const assertNoArtifacts = () => assert.deepEqual(readdirSync(stateRoot), []);
2013
- try {
2014
- process.env.OMX_STATE_ROOT = stateRoot;
2015
- await symlink(loop, loop);
2016
- for (const cwd of [`${parent}\u0000suffix`, loop]) {
2017
- assert.deepEqual(recordPendingRoleIntent(cwd, {
2018
- role: 'architect', sessionId: 'origin-session', parentThreadId: 'origin-parent', correlationToken: canonicalCorrelationToken('origintoken'),
2019
- }), { ok: false, reason: 'invalid_origin' });
2020
- assertNoArtifacts();
2021
- }
2022
- await mkdir(validCwd);
2023
- const recorded = recordPendingRoleIntent(validCwd, {
2024
- role: 'architect', sessionId: 'valid-origin-session', parentThreadId: 'valid-origin-parent', correlationToken: canonicalCorrelationToken('validorigintoken'),
2025
- });
2026
- assert.equal(recorded.ok, true);
2027
- assert.equal(recorded.ok && recorded.intent.origin_cwd, canonicalizeOriginCwd(validCwd));
2028
- const state = await readSubagentTrackingState(validCwd);
2029
- assert.deepEqual(state.pending_role_intents, recorded.ok ? [recorded.intent] : []);
2030
- assert.equal(existsSync(subagentTrackingPath(validCwd)), true);
2031
- }
2032
- finally {
2033
- if (previousStateRoot === undefined)
2034
- delete process.env.OMX_STATE_ROOT;
2035
- else
2036
- process.env.OMX_STATE_ROOT = previousStateRoot;
2037
- await rm(parent, { recursive: true, force: true });
2038
- await rm(stateRoot, { recursive: true, force: true });
2039
- }
2040
- });
2041
1830
  });
2042
1831
  //# sourceMappingURL=tracker.test.js.map