@ours.network/fleet 1.2.0-nightly.8 → 1.2.0-nightly.81

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 (429) hide show
  1. package/README.md +280 -68
  2. package/dist/account-origin.d.ts +5 -0
  3. package/dist/account-origin.js +31 -0
  4. package/dist/agent-ours/bridge.js +26 -9
  5. package/dist/agent-ours/correspondence.d.ts +10 -0
  6. package/dist/agent-ours/correspondence.js +1 -0
  7. package/dist/agent-ours/file-rpc.d.ts +12 -0
  8. package/dist/agent-ours/file-rpc.js +18 -4
  9. package/dist/agent-ours/harness.js +9 -1
  10. package/dist/agent-ours/mcp-endpoint.d.ts +22 -0
  11. package/dist/agent-ours/mcp-endpoint.js +101 -25
  12. package/dist/agent-ours/runtime.d.ts +9 -1
  13. package/dist/agent-ours/runtime.js +50 -2
  14. package/dist/agent-ours/service.d.ts +27 -1
  15. package/dist/agent-ours/service.js +107 -13
  16. package/dist/application/codex-models.d.ts +15 -0
  17. package/dist/application/codex-models.js +56 -0
  18. package/dist/application/conversation-history.d.ts +34 -0
  19. package/dist/application/conversation-history.js +294 -0
  20. package/dist/application/conversation-role-observer.d.ts +62 -0
  21. package/dist/application/conversation-role-observer.js +206 -0
  22. package/dist/application/fleet-query-service.d.ts +1 -1
  23. package/dist/application/fleet-query-service.js +3 -3
  24. package/dist/application/log-service.js +8 -8
  25. package/dist/application/model-catalog.d.ts +1 -1
  26. package/dist/application/model-catalog.js +5 -2
  27. package/dist/application/preset-provenance.d.ts +19 -0
  28. package/dist/application/preset-provenance.js +59 -0
  29. package/dist/application/resource-observer.d.ts +43 -0
  30. package/dist/application/resource-observer.js +323 -0
  31. package/dist/application/role-creation-service.js +3 -2
  32. package/dist/application/role-removal-service.js +17 -3
  33. package/dist/application/role-repository.d.ts +1 -1
  34. package/dist/application/role-repository.js +30 -7
  35. package/dist/application/room-layout-definitions.d.ts +45 -0
  36. package/dist/application/room-layout-definitions.js +130 -0
  37. package/dist/application/session-control.d.ts +63 -17
  38. package/dist/application/session-control.js +221 -23
  39. package/dist/application/supervisor-ours-tools.js +5 -11
  40. package/dist/application/task-layouts.d.ts +91 -0
  41. package/dist/application/task-layouts.js +261 -0
  42. package/dist/application/task-room-service.d.ts +101 -3
  43. package/dist/application/task-room-service.js +286 -33
  44. package/dist/application/types.d.ts +2 -0
  45. package/dist/atomic-file.d.ts +34 -1
  46. package/dist/atomic-file.js +161 -18
  47. package/dist/briefing.d.ts +3 -1
  48. package/dist/briefing.js +120 -31
  49. package/dist/build-info.json +9 -4
  50. package/dist/capabilities.d.ts +9 -1
  51. package/dist/capabilities.js +13 -0
  52. package/dist/cli.js +402 -38
  53. package/dist/client-profile.d.ts +5 -17
  54. package/dist/client-profile.js +4 -127
  55. package/dist/config.d.ts +45 -0
  56. package/dist/config.js +57 -6
  57. package/dist/creation.d.ts +1 -1
  58. package/dist/creation.js +4 -4
  59. package/dist/daemon-recovery.d.ts +14 -9
  60. package/dist/daemon-recovery.js +124 -115
  61. package/dist/docs.d.ts +1 -1
  62. package/dist/docs.js +227 -19
  63. package/dist/doctor.d.ts +4 -1
  64. package/dist/doctor.js +75 -60
  65. package/dist/erased-resources.d.ts +9 -0
  66. package/dist/erased-resources.js +87 -0
  67. package/dist/file-delivery/reader.d.ts +15 -0
  68. package/dist/file-delivery/reader.js +63 -0
  69. package/dist/file-delivery/store.d.ts +15 -0
  70. package/dist/file-delivery/store.js +124 -0
  71. package/dist/file-delivery/types.d.ts +19 -0
  72. package/dist/file-delivery/types.js +1 -0
  73. package/dist/fleet-command-audit.d.ts +13 -0
  74. package/dist/fleet-command-audit.js +31 -9
  75. package/dist/harness/agent-session.d.ts +4 -0
  76. package/dist/harness/claude-code-session.js +1 -1
  77. package/dist/harness/claude-code.js +21 -11
  78. package/dist/harness/claude-runtime.d.ts +12 -0
  79. package/dist/harness/claude-runtime.js +43 -0
  80. package/dist/harness/codex-app-server-proxy.d.ts +4 -1
  81. package/dist/harness/codex-app-server-proxy.js +41 -5
  82. package/dist/harness/codex-reasoning.d.ts +5 -0
  83. package/dist/harness/codex-reasoning.js +12 -0
  84. package/dist/harness/codex-runtime.d.ts +11 -1
  85. package/dist/harness/codex-runtime.js +31 -4
  86. package/dist/harness/codex-session.js +2 -2
  87. package/dist/harness/codex.js +24 -12
  88. package/dist/init-wizard.d.ts +2 -0
  89. package/dist/init-wizard.js +38 -19
  90. package/dist/isolation/policy.js +6 -1
  91. package/dist/isolation/types.d.ts +5 -0
  92. package/dist/managed-cli.d.ts +253 -0
  93. package/dist/managed-cli.js +923 -0
  94. package/dist/managed-recovery.d.ts +13 -0
  95. package/dist/managed-recovery.js +31 -0
  96. package/dist/minimal-setup.d.ts +2 -0
  97. package/dist/minimal-setup.js +44 -0
  98. package/dist/monitor.d.ts +9 -34
  99. package/dist/monitor.js +90 -153
  100. package/dist/notifications/fleet-producer.d.ts +31 -0
  101. package/dist/notifications/fleet-producer.js +351 -0
  102. package/dist/notifications/outbox.d.ts +59 -0
  103. package/dist/notifications/outbox.js +199 -0
  104. package/dist/notifications/target-cleanup.d.ts +16 -0
  105. package/dist/notifications/target-cleanup.js +75 -0
  106. package/dist/notifications/task-producer.d.ts +20 -0
  107. package/dist/notifications/task-producer.js +100 -0
  108. package/dist/ops.d.ts +2 -0
  109. package/dist/ops.js +20 -3
  110. package/dist/owner-channel/channel.js +17 -6
  111. package/dist/owner-channel/commands.d.ts +4 -0
  112. package/dist/owner-channel/commands.js +8 -0
  113. package/dist/owner-channel/lifecycle-outbox.js +4 -3
  114. package/dist/owner-channel/ours-client.js +2 -17
  115. package/dist/paths.d.ts +5 -0
  116. package/dist/paths.js +5 -0
  117. package/dist/preset-migration.js +55 -0
  118. package/dist/process-incarnation.d.ts +23 -0
  119. package/dist/process-incarnation.js +42 -0
  120. package/dist/reminders/manager.d.ts +75 -0
  121. package/dist/reminders/manager.js +278 -0
  122. package/dist/reminders/runtime.d.ts +27 -0
  123. package/dist/reminders/runtime.js +32 -0
  124. package/dist/reminders/schedule.d.ts +37 -0
  125. package/dist/reminders/schedule.js +104 -0
  126. package/dist/reminders/store.d.ts +341 -0
  127. package/dist/reminders/store.js +762 -0
  128. package/dist/reminders/tools.d.ts +20 -0
  129. package/dist/reminders/tools.js +114 -0
  130. package/dist/resolved-plan.js +1 -0
  131. package/dist/rooms-tasks/add-member.d.ts +48 -0
  132. package/dist/rooms-tasks/add-member.js +84 -0
  133. package/dist/rooms-tasks/archived-absence.d.ts +4 -0
  134. package/dist/rooms-tasks/archived-absence.js +11 -0
  135. package/dist/rooms-tasks/cli.js +182 -5
  136. package/dist/rooms-tasks/close.d.ts +5 -2
  137. package/dist/rooms-tasks/close.js +224 -36
  138. package/dist/rooms-tasks/config.d.ts +1 -1
  139. package/dist/rooms-tasks/config.js +11 -4
  140. package/dist/rooms-tasks/cowork-adapter.d.ts +12 -5
  141. package/dist/rooms-tasks/cowork-adapter.js +15 -121
  142. package/dist/rooms-tasks/cowork-http.js +56 -6
  143. package/dist/rooms-tasks/deletion.d.ts +1 -1
  144. package/dist/rooms-tasks/deletion.js +66 -10
  145. package/dist/rooms-tasks/erasure.d.ts +6 -0
  146. package/dist/rooms-tasks/erasure.js +173 -0
  147. package/dist/rooms-tasks/external-worker.d.ts +1 -1
  148. package/dist/rooms-tasks/external-worker.js +3 -4
  149. package/dist/rooms-tasks/layout-binding-client.d.ts +11 -0
  150. package/dist/rooms-tasks/layout-binding-client.js +56 -0
  151. package/dist/rooms-tasks/layout-binding-grants.d.ts +21 -0
  152. package/dist/rooms-tasks/layout-binding-grants.js +128 -0
  153. package/dist/rooms-tasks/layout-cli.d.ts +4 -0
  154. package/dist/rooms-tasks/layout-cli.js +107 -0
  155. package/dist/rooms-tasks/layout-config.d.ts +11 -0
  156. package/dist/rooms-tasks/layout-config.js +89 -0
  157. package/dist/rooms-tasks/layout-control.d.ts +21 -0
  158. package/dist/rooms-tasks/layout-control.js +52 -0
  159. package/dist/rooms-tasks/layout-member-retirement.d.ts +10 -0
  160. package/dist/rooms-tasks/layout-member-retirement.js +90 -0
  161. package/dist/rooms-tasks/layout-service.d.ts +43 -0
  162. package/dist/rooms-tasks/layout-service.js +203 -0
  163. package/dist/rooms-tasks/layout.d.ts +121 -0
  164. package/dist/rooms-tasks/layout.js +286 -0
  165. package/dist/rooms-tasks/legacy-task-member.d.ts +19 -0
  166. package/dist/rooms-tasks/legacy-task-member.js +116 -0
  167. package/dist/rooms-tasks/live-readiness.d.ts +18 -0
  168. package/dist/rooms-tasks/live-readiness.js +85 -0
  169. package/dist/rooms-tasks/member-ownership.d.ts +5 -0
  170. package/dist/rooms-tasks/member-ownership.js +40 -0
  171. package/dist/rooms-tasks/member-startup.d.ts +1 -0
  172. package/dist/rooms-tasks/member-startup.js +2 -0
  173. package/dist/rooms-tasks/provision.d.ts +3 -0
  174. package/dist/rooms-tasks/provision.js +101 -49
  175. package/dist/rooms-tasks/recovery.d.ts +19 -0
  176. package/dist/rooms-tasks/recovery.js +110 -0
  177. package/dist/rooms-tasks/room-state.d.ts +4 -2
  178. package/dist/rooms-tasks/room-state.js +47 -8
  179. package/dist/rooms-tasks/task-review.d.ts +113 -0
  180. package/dist/rooms-tasks/task-review.js +561 -0
  181. package/dist/rooms-tasks/task-service-retirement.d.ts +11 -0
  182. package/dist/rooms-tasks/task-service-retirement.js +21 -0
  183. package/dist/rooms-tasks/task-state.d.ts +51 -5
  184. package/dist/rooms-tasks/task-state.js +358 -50
  185. package/dist/rooms-tasks/task-tools.d.ts +35 -0
  186. package/dist/rooms-tasks/task-tools.js +134 -0
  187. package/dist/rooms-tasks/types.d.ts +78 -0
  188. package/dist/rooms-tasks/workspace-artifacts.d.ts +6 -0
  189. package/dist/rooms-tasks/workspace-artifacts.js +93 -0
  190. package/dist/rooms-tasks/workspace.d.ts +35 -0
  191. package/dist/rooms-tasks/workspace.js +325 -0
  192. package/dist/runner.d.ts +33 -4
  193. package/dist/runner.js +410 -62
  194. package/dist/session/acp.d.ts +75 -2
  195. package/dist/session/acp.js +345 -82
  196. package/dist/session/arbiter.d.ts +98 -0
  197. package/dist/session/arbiter.js +272 -3
  198. package/dist/session/codex-app-server.d.ts +45 -1
  199. package/dist/session/codex-app-server.js +225 -32
  200. package/dist/session/control.d.ts +17 -3
  201. package/dist/session/control.js +219 -23
  202. package/dist/session/conversation-normalizer.d.ts +2 -1
  203. package/dist/session/conversation-normalizer.js +1 -1
  204. package/dist/session/conversation-observation.d.ts +25 -0
  205. package/dist/session/conversation-observation.js +100 -0
  206. package/dist/session/conversation-replay.d.ts +50 -0
  207. package/dist/session/conversation-replay.js +203 -0
  208. package/dist/session/conversation-store.d.ts +15 -1
  209. package/dist/session/conversation-store.js +213 -26
  210. package/dist/session/conversation-types.d.ts +57 -4
  211. package/dist/session/prompt-batch.d.ts +79 -0
  212. package/dist/session/prompt-batch.js +120 -0
  213. package/dist/session/task-notice.d.ts +14 -0
  214. package/dist/session/task-notice.js +13 -0
  215. package/dist/session/types.d.ts +42 -1
  216. package/dist/setup-tunnel-preflight.d.ts +34 -0
  217. package/dist/setup-tunnel-preflight.js +62 -0
  218. package/dist/socket-path.d.ts +2 -0
  219. package/dist/socket-path.js +22 -0
  220. package/dist/spawn.d.ts +5 -1
  221. package/dist/spawn.js +40 -4
  222. package/dist/startup-prompt.d.ts +15 -0
  223. package/dist/startup-prompt.js +71 -0
  224. package/dist/startup-readiness.d.ts +32 -0
  225. package/dist/startup-readiness.js +101 -0
  226. package/dist/startup-telemetry.d.ts +16 -0
  227. package/dist/startup-telemetry.js +46 -0
  228. package/dist/subscriptions/cli.d.ts +91 -0
  229. package/dist/subscriptions/cli.js +223 -0
  230. package/dist/subscriptions/launch.d.ts +37 -0
  231. package/dist/subscriptions/launch.js +93 -0
  232. package/dist/subscriptions/login.d.ts +77 -0
  233. package/dist/subscriptions/login.js +215 -0
  234. package/dist/subscriptions/observed.d.ts +7 -0
  235. package/dist/subscriptions/observed.js +44 -0
  236. package/dist/subscriptions/probe.d.ts +10 -0
  237. package/dist/subscriptions/probe.js +73 -0
  238. package/dist/subscriptions/service.d.ts +102 -0
  239. package/dist/subscriptions/service.js +364 -0
  240. package/dist/subscriptions/store.d.ts +71 -0
  241. package/dist/subscriptions/store.js +143 -0
  242. package/dist/supervisor/adoption.d.ts +8 -0
  243. package/dist/supervisor/adoption.js +78 -0
  244. package/dist/supervisor/catalog.d.ts +62 -0
  245. package/dist/supervisor/catalog.js +254 -0
  246. package/dist/supervisor/fleet.d.ts +8 -0
  247. package/dist/supervisor/fleet.js +89 -0
  248. package/dist/supervisor/index.js +3 -6
  249. package/dist/supervisor/launchd.d.ts +1 -1
  250. package/dist/supervisor/launchd.js +26 -13
  251. package/dist/supervisor/legacy.d.ts +35 -0
  252. package/dist/supervisor/legacy.js +524 -0
  253. package/dist/supervisor/manager.d.ts +15 -0
  254. package/dist/supervisor/manager.js +270 -0
  255. package/dist/supervisor/registration-refresh.d.ts +45 -0
  256. package/dist/supervisor/registration-refresh.js +266 -0
  257. package/dist/supervisor/scope.d.ts +4 -0
  258. package/dist/supervisor/scope.js +10 -0
  259. package/dist/supervisor/systemd.d.ts +2 -2
  260. package/dist/supervisor/systemd.js +19 -33
  261. package/dist/task-supervision.d.ts +9 -0
  262. package/dist/task-supervision.js +145 -0
  263. package/dist/temp-idle.d.ts +17 -0
  264. package/dist/temp-idle.js +42 -0
  265. package/dist/temp-lifecycle.d.ts +23 -8
  266. package/dist/temp-lifecycle.js +123 -66
  267. package/dist/temp-supervisor-recovery.d.ts +1 -1
  268. package/dist/temp-supervisor-recovery.js +2 -2
  269. package/dist/tunnel-setup-completion.d.ts +7 -0
  270. package/dist/tunnel-setup-completion.js +13 -0
  271. package/dist/tunnel-setup-input.d.ts +19 -0
  272. package/dist/tunnel-setup-input.js +130 -0
  273. package/dist/watchdog/query.d.ts +3 -1
  274. package/dist/watchdog/query.js +2 -1
  275. package/dist/web/agent-attachments.d.ts +29 -0
  276. package/dist/web/agent-attachments.js +162 -0
  277. package/dist/web/auth.d.ts +65 -2
  278. package/dist/web/auth.js +201 -11
  279. package/dist/web/available-port.d.ts +2 -0
  280. package/dist/web/available-port.js +23 -0
  281. package/dist/web/control.d.ts +3 -3
  282. package/dist/web/control.js +10 -8
  283. package/dist/web/conversation-stream-codec.d.ts +23 -0
  284. package/dist/web/conversation-stream-codec.js +110 -0
  285. package/dist/web/conversation-stream.d.ts +26 -0
  286. package/dist/web/conversation-stream.js +239 -0
  287. package/dist/web/events.d.ts +2 -0
  288. package/dist/web/events.js +9 -0
  289. package/dist/web/fleet-config-service.d.ts +7 -1
  290. package/dist/web/fleet-config-service.js +61 -16
  291. package/dist/web/prefix-gateway.d.ts +32 -0
  292. package/dist/web/prefix-gateway.js +248 -0
  293. package/dist/web/resource-views.d.ts +135 -0
  294. package/dist/web/resource-views.js +494 -0
  295. package/dist/web/runtime.d.ts +3 -1
  296. package/dist/web/runtime.js +132 -34
  297. package/dist/web/server.d.ts +19 -0
  298. package/dist/web/server.js +893 -71
  299. package/dist/web/service.d.ts +11 -2
  300. package/dist/web/service.js +30 -4
  301. package/dist/web/workspace-devices.d.ts +107 -0
  302. package/dist/web/workspace-devices.js +277 -0
  303. package/dist/web/workspace-tunnel.d.ts +1 -0
  304. package/dist/web/workspace-tunnel.js +34 -0
  305. package/dist/workspace-enrollment.d.ts +83 -0
  306. package/dist/workspace-enrollment.js +605 -0
  307. package/dist/workspace-replacement.d.ts +66 -0
  308. package/dist/workspace-replacement.js +238 -0
  309. package/docs/acp-files.md +146 -0
  310. package/docs/conversation-stream.md +216 -0
  311. package/docs/fleet-migration.md +54 -0
  312. package/docs/live-voice.md +13 -0
  313. package/docs/room-layouts.md +227 -0
  314. package/docs/self-reminders.md +374 -0
  315. package/docs/task-progress-review.md +143 -0
  316. package/docs/task-workspaces.md +225 -0
  317. package/docs/validation/managed-cli-permissions.md +421 -0
  318. package/examples/room-layouts/fresh.yaml +27 -0
  319. package/examples/room-layouts/scoped.yaml +21 -0
  320. package/examples/room-layouts/shared.yaml +19 -0
  321. package/package.json +25 -20
  322. package/presets/README.md +78 -0
  323. package/presets/brain-catalog.json +8 -2
  324. package/presets/fleet/agent_templates/Critic.yaml +1 -1
  325. package/presets/fleet/agent_templates/Developer.yaml +1 -1
  326. package/presets/fleet/agent_templates/Engineer.yaml +5 -0
  327. package/presets/fleet/agent_templates/LocalCoordinator.yaml +6 -3
  328. package/presets/fleet/agents/FleetCoordinator.yaml +1 -1
  329. package/presets/fleet/brains/claude-fable-5-1-high.yaml +5 -0
  330. package/presets/fleet/brains/claude-fable-5-1-low.yaml +5 -0
  331. package/presets/fleet/brains/claude-fable-5-1-max.yaml +5 -0
  332. package/presets/fleet/brains/claude-fable-5-1-medium.yaml +5 -0
  333. package/presets/fleet/brains/claude-fable-5-1-xhigh.yaml +5 -0
  334. package/presets/fleet/brains/claude-fable-5-high.yaml +1 -1
  335. package/presets/fleet/brains/claude-fable-5-low.yaml +1 -1
  336. package/presets/fleet/brains/claude-fable-5-max.yaml +1 -1
  337. package/presets/fleet/brains/claude-fable-5-medium.yaml +1 -1
  338. package/presets/fleet/brains/claude-fable-5-xhigh.yaml +1 -1
  339. package/presets/fleet/brains/claude-haiku-4-5-20251001-default.yaml +4 -0
  340. package/presets/fleet/brains/claude-opus-5-5-high.yaml +5 -0
  341. package/presets/fleet/brains/claude-opus-5-5-low.yaml +5 -0
  342. package/presets/fleet/brains/claude-opus-5-5-max.yaml +5 -0
  343. package/presets/fleet/brains/claude-opus-5-5-medium.yaml +5 -0
  344. package/presets/fleet/brains/claude-opus-5-5-xhigh.yaml +5 -0
  345. package/presets/fleet/brains/claude-opus-5-high.yaml +1 -1
  346. package/presets/fleet/brains/claude-opus-5-low.yaml +1 -1
  347. package/presets/fleet/brains/claude-opus-5-max.yaml +1 -1
  348. package/presets/fleet/brains/claude-opus-5-medium.yaml +1 -1
  349. package/presets/fleet/brains/claude-opus-5-xhigh.yaml +1 -1
  350. package/presets/fleet/brains/claude-sonnet-5-high.yaml +1 -1
  351. package/presets/fleet/brains/claude-sonnet-5-low.yaml +1 -1
  352. package/presets/fleet/brains/claude-sonnet-5-max.yaml +1 -1
  353. package/presets/fleet/brains/claude-sonnet-5-medium.yaml +1 -1
  354. package/presets/fleet/brains/claude-sonnet-5-xhigh.yaml +1 -1
  355. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-high.yaml +1 -1
  356. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-low.yaml +1 -1
  357. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-medium.yaml +1 -1
  358. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-xhigh.yaml +1 -1
  359. package/presets/fleet/brains/codex-gpt-5-4-high.yaml +1 -1
  360. package/presets/fleet/brains/codex-gpt-5-4-low.yaml +1 -1
  361. package/presets/fleet/brains/codex-gpt-5-4-medium.yaml +1 -1
  362. package/presets/fleet/brains/codex-gpt-5-4-mini-high.yaml +1 -1
  363. package/presets/fleet/brains/codex-gpt-5-4-mini-low.yaml +1 -1
  364. package/presets/fleet/brains/codex-gpt-5-4-mini-medium.yaml +1 -1
  365. package/presets/fleet/brains/codex-gpt-5-4-mini-xhigh.yaml +1 -1
  366. package/presets/fleet/brains/codex-gpt-5-4-xhigh.yaml +1 -1
  367. package/presets/fleet/brains/codex-gpt-5-5-high.yaml +1 -1
  368. package/presets/fleet/brains/codex-gpt-5-5-low.yaml +1 -1
  369. package/presets/fleet/brains/codex-gpt-5-5-medium.yaml +1 -1
  370. package/presets/fleet/brains/codex-gpt-5-5-xhigh.yaml +1 -1
  371. package/presets/fleet/brains/codex-gpt-5-6-luna-high.yaml +1 -1
  372. package/presets/fleet/brains/codex-gpt-5-6-luna-low.yaml +1 -1
  373. package/presets/fleet/brains/codex-gpt-5-6-luna-max.yaml +1 -1
  374. package/presets/fleet/brains/codex-gpt-5-6-luna-medium.yaml +1 -1
  375. package/presets/fleet/brains/codex-gpt-5-6-luna-xhigh.yaml +1 -1
  376. package/presets/fleet/brains/codex-gpt-5-6-sol-high.yaml +1 -1
  377. package/presets/fleet/brains/codex-gpt-5-6-sol-low.yaml +1 -1
  378. package/presets/fleet/brains/codex-gpt-5-6-sol-max.yaml +1 -1
  379. package/presets/fleet/brains/codex-gpt-5-6-sol-medium.yaml +1 -1
  380. package/presets/fleet/brains/codex-gpt-5-6-sol-ultra.yaml +1 -1
  381. package/presets/fleet/brains/codex-gpt-5-6-sol-xhigh.yaml +1 -1
  382. package/presets/fleet/brains/codex-gpt-5-6-terra-high.yaml +1 -1
  383. package/presets/fleet/brains/codex-gpt-5-6-terra-low.yaml +1 -1
  384. package/presets/fleet/brains/codex-gpt-5-6-terra-max.yaml +1 -1
  385. package/presets/fleet/brains/codex-gpt-5-6-terra-medium.yaml +1 -1
  386. package/presets/fleet/brains/codex-gpt-5-6-terra-ultra.yaml +1 -1
  387. package/presets/fleet/brains/codex-gpt-5-6-terra-xhigh.yaml +1 -1
  388. package/presets/fleet/brains/codex-gpt-6-1-sol-high.yaml +5 -0
  389. package/presets/fleet/brains/codex-gpt-6-1-sol-low.yaml +5 -0
  390. package/presets/fleet/brains/codex-gpt-6-1-sol-max.yaml +5 -0
  391. package/presets/fleet/brains/codex-gpt-6-1-sol-medium.yaml +5 -0
  392. package/presets/fleet/brains/codex-gpt-6-1-sol-ultra.yaml +5 -0
  393. package/presets/fleet/brains/codex-gpt-6-1-sol-xhigh.yaml +5 -0
  394. package/presets/fleet/brains/codex-gpt-6-astra-high.yaml +1 -1
  395. package/presets/fleet/brains/codex-gpt-6-astra-low.yaml +1 -1
  396. package/presets/fleet/brains/codex-gpt-6-astra-max.yaml +1 -1
  397. package/presets/fleet/brains/codex-gpt-6-astra-medium.yaml +1 -1
  398. package/presets/fleet/brains/codex-gpt-6-astra-ultra.yaml +1 -1
  399. package/presets/fleet/brains/codex-gpt-6-astra-xhigh.yaml +1 -1
  400. package/presets/fleet/brains/codex-gpt-6-luna-high.yaml +5 -0
  401. package/presets/fleet/brains/codex-gpt-6-luna-low.yaml +5 -0
  402. package/presets/fleet/brains/codex-gpt-6-luna-max.yaml +5 -0
  403. package/presets/fleet/brains/codex-gpt-6-luna-medium.yaml +5 -0
  404. package/presets/fleet/brains/codex-gpt-6-luna-xhigh.yaml +5 -0
  405. package/presets/fleet/brains/codex-gpt-6-sol-high.yaml +5 -0
  406. package/presets/fleet/brains/codex-gpt-6-sol-low.yaml +5 -0
  407. package/presets/fleet/brains/codex-gpt-6-sol-max.yaml +5 -0
  408. package/presets/fleet/brains/codex-gpt-6-sol-medium.yaml +5 -0
  409. package/presets/fleet/brains/codex-gpt-6-sol-ultra.yaml +5 -0
  410. package/presets/fleet/brains/codex-gpt-6-sol-xhigh.yaml +5 -0
  411. package/presets/fleet/roles/Coordinator.yaml +21 -13
  412. package/presets/fleet/roles/Critic.yaml +24 -0
  413. package/presets/fleet/roles/Developer.yaml +32 -0
  414. package/presets/fleet/roles/Engineer.yaml +72 -0
  415. package/presets/fleet/roles/LocalCoordinator.yaml +17 -0
  416. package/presets/fleet/room_layouts/engineering.yaml +25 -0
  417. package/presets/fleet/room_layouts/pair.yaml +24 -0
  418. package/presets/fleet/room_layouts/single.yaml +17 -0
  419. package/presets/fleet/room_layouts/team.yaml +30 -0
  420. package/presets/fleet/room_templates/engineering.yaml +19 -0
  421. package/presets/manifest.json +2 -2
  422. package/dist/web-app/assets/index-59GF-gsZ.css +0 -1
  423. package/dist/web-app/assets/index-C0h3ALvs.js +0 -10
  424. package/dist/web-app/icons/ours-fleet-maskable.svg +0 -4
  425. package/dist/web-app/icons/ours-fleet.svg +0 -4
  426. package/dist/web-app/index.html +0 -17
  427. package/dist/web-app/manifest.webmanifest +0 -15
  428. package/dist/web-app/offline.html +0 -18
  429. package/dist/web-app/sw.js +0 -51
@@ -0,0 +1,35 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { publicProgressEntry } from './task-review.js';
3
+ import type { TaskContributionAuthor, TaskProgressEntry } from './types.js';
4
+ /** The task this agent belongs to, from supervisor launch records; never from tool arguments. */
5
+ export interface TaskToolBinding {
6
+ taskId: string;
7
+ role: string;
8
+ identityCid?: string;
9
+ /** Launched as a task-owned temporary member (layout participant). */
10
+ taskOwned: boolean;
11
+ }
12
+ export declare const TASK_TOOL_NAMES: readonly ["fleet_task_progress_list", "fleet_task_progress_append", "fleet_task_review_show", "fleet_task_review_set", "fleet_task_review_detach"];
13
+ export declare const PROGRESS_PAGE_MAX = 50;
14
+ /** One chronological page of the log; `next_after` continues after the last returned entry. */
15
+ export declare function progressPage(entries: TaskProgressEntry[], input: {
16
+ after?: string;
17
+ limit?: number;
18
+ }): {
19
+ progress: ReturnType<typeof publicProgressEntry>[];
20
+ total: number;
21
+ next_after?: string;
22
+ };
23
+ /**
24
+ * Confirm the binding against the task record: a listed member must match by
25
+ * name and identity; an unlisted caller must be a task-owned launch.
26
+ */
27
+ export declare function verifiedTaskAuthor(binding: TaskToolBinding): TaskContributionAuthor;
28
+ /**
29
+ * Task Progress and To review tools on the agent's own managed MCP endpoint.
30
+ * The task and author come from the caller's supervisor, so an agent can only
31
+ * read and write the task it was launched for. Review files are attached with
32
+ * `ours-fleet task review-package <id> --attach <path>`, which reads the file
33
+ * under the agent's own permissions.
34
+ */
35
+ export declare function registerTaskTools(server: McpServer, binding: () => TaskToolBinding | undefined, admit: () => Promise<() => void>): void;
@@ -0,0 +1,134 @@
1
+ import { z } from 'zod';
2
+ import { appendTaskProgress, detachTaskReviewArtifact, getTaskReview, listTaskProgress, publicProgressEntry, publicReview, setTaskReviewMarkdown, TaskReviewError, PROGRESS_TEXT_MAX, REVIEW_MARKDOWN_MAX, } from './task-review.js';
3
+ import { getTask, TaskStateError } from './task-state.js';
4
+ export const TASK_TOOL_NAMES = Object.freeze([
5
+ 'fleet_task_progress_list', 'fleet_task_progress_append',
6
+ 'fleet_task_review_show', 'fleet_task_review_set', 'fleet_task_review_detach',
7
+ ]);
8
+ /** Compact JSON: a result is carried twice (text and structured) inside one bounded bridge frame. */
9
+ function result(value) {
10
+ return {
11
+ content: [{ type: 'text', text: JSON.stringify(value) }],
12
+ structuredContent: value,
13
+ isError: false,
14
+ };
15
+ }
16
+ export const PROGRESS_PAGE_MAX = 50;
17
+ /** Serialized entry bytes per page, well inside the bridge's frame limit even at maximal escaping. */
18
+ const PROGRESS_PAGE_BYTES = 200_000;
19
+ /** One chronological page of the log; `next_after` continues after the last returned entry. */
20
+ export function progressPage(entries, input) {
21
+ const limit = input.limit ?? PROGRESS_PAGE_MAX;
22
+ if (!Number.isInteger(limit) || limit < 1 || limit > PROGRESS_PAGE_MAX)
23
+ throw new TaskReviewError('invalid_request', `limit must be 1..${PROGRESS_PAGE_MAX}`);
24
+ let start = 0;
25
+ if (input.after !== undefined) {
26
+ start = entries.findIndex(entry => entry.id === input.after) + 1;
27
+ if (!start)
28
+ throw new TaskReviewError('invalid_request', 'after must be the id of an entry in this log');
29
+ }
30
+ const page = [];
31
+ let bytes = 0;
32
+ for (const entry of entries.slice(start, start + limit)) {
33
+ const visible = publicProgressEntry(entry), size = Buffer.byteLength(JSON.stringify(visible));
34
+ if (page.length && bytes + size > PROGRESS_PAGE_BYTES)
35
+ break;
36
+ page.push(visible);
37
+ bytes += size;
38
+ }
39
+ const end = start + page.length;
40
+ return { progress: page, total: entries.length, ...(end < entries.length ? { next_after: entries[end - 1].id } : {}) };
41
+ }
42
+ function failure(code, message) {
43
+ return { content: [{ type: 'text', text: JSON.stringify({ error: code, message }) }], isError: true };
44
+ }
45
+ /**
46
+ * Confirm the binding against the task record: a listed member must match by
47
+ * name and identity; an unlisted caller must be a task-owned launch.
48
+ */
49
+ export function verifiedTaskAuthor(binding) {
50
+ const task = getTask(binding.taskId);
51
+ const member = task.member_roles.find(item => item.name === binding.role);
52
+ if (member ? (binding.identityCid && member.identity_cid !== binding.identityCid) : !binding.taskOwned)
53
+ throw new TaskReviewError('conflict', `agent ${binding.role} is not a member of task ${binding.taskId}`);
54
+ return { kind: 'agent', role: binding.role, ...(binding.identityCid ? { identity_cid: binding.identityCid } : {}), surface: 'mcp' };
55
+ }
56
+ /**
57
+ * Task Progress and To review tools on the agent's own managed MCP endpoint.
58
+ * The task and author come from the caller's supervisor, so an agent can only
59
+ * read and write the task it was launched for. Review files are attached with
60
+ * `ours-fleet task review-package <id> --attach <path>`, which reads the file
61
+ * under the agent's own permissions.
62
+ */
63
+ export function registerTaskTools(server, binding, admit) {
64
+ const run = async (operation) => {
65
+ let release;
66
+ try {
67
+ release = await admit();
68
+ }
69
+ catch {
70
+ return failure('runtime_not_ready', 'the managed runtime is not admitting tool calls right now; nothing was read or changed');
71
+ }
72
+ try {
73
+ const bound = binding();
74
+ if (!bound)
75
+ return failure('task_unavailable', 'this agent was not launched for a Fleet task');
76
+ try {
77
+ return result(operation(bound, verifiedTaskAuthor(bound)));
78
+ }
79
+ catch (error) {
80
+ if (error instanceof TaskReviewError)
81
+ return failure(error.code, error.message);
82
+ if (error instanceof TaskStateError)
83
+ return failure('task_unavailable', error.message);
84
+ return failure('task_store_failed', 'the task could not be read or updated; nothing was changed');
85
+ }
86
+ }
87
+ finally {
88
+ release();
89
+ }
90
+ };
91
+ server.registerTool('fleet_task_progress_list', {
92
+ description: 'Read the Progress milestone log of the task you were launched for, oldest first, one page at a time. '
93
+ + 'When next_after is present, call again with after set to it for the following entries.',
94
+ inputSchema: {
95
+ after: z.string().optional().describe('Entry id from the previous page\'s next_after; omit for the first page.'),
96
+ limit: z.number().int().optional().describe(`Maximum entries per page (1..${PROGRESS_PAGE_MAX}, default ${PROGRESS_PAGE_MAX}). Pages are also bounded in size.`),
97
+ },
98
+ }, async (args) => run(bound => ({ task_id: bound.taskId, ...progressPage(listTaskProgress(bound.taskId), args) })));
99
+ server.registerTool('fleet_task_progress_append', {
100
+ description: 'Append ONE significant, verified milestone to your task\'s Progress log (e.g. root cause found, PR opened with link, '
101
+ + 'measured result with its scope, final deliverable ready). Not for routine status, handoffs or review chatter. '
102
+ + 'Entries are permanent and shown to the Owner as written. Repeating a call with the same request_key and text returns the original entry.',
103
+ inputSchema: {
104
+ text: z.string().describe(`Free-form milestone text, kept exactly as written (max ${PROGRESS_TEXT_MAX} characters).`),
105
+ request_key: z.string().optional().describe('Stable key for this milestone so a retried call cannot add it twice (e.g. "pr-opened-123").'),
106
+ },
107
+ }, async (args) => run((bound, author) => {
108
+ const appended = appendTaskProgress(bound.taskId, { text: args.text, requestKey: args.request_key, author });
109
+ return { task_id: bound.taskId, entry: publicProgressEntry(appended.entry), replayed: appended.replayed };
110
+ }));
111
+ server.registerTool('fleet_task_review_show', {
112
+ description: 'Read your task\'s To review package: its Markdown and the retained files attached to it.',
113
+ inputSchema: {},
114
+ }, async () => run(bound => {
115
+ const review = getTaskReview(bound.taskId);
116
+ return { task_id: bound.taskId, review: review ? publicReview(review) : null };
117
+ }));
118
+ server.registerTool('fleet_task_review_set', {
119
+ description: 'Replace the Markdown of your task\'s To review package: the self-contained material the Owner reviews without reading the room or task description '
120
+ + '(outcome, clickable PR/spec links, validation and CI, independent verdict, limits, decisions needed). '
121
+ + 'Pass the Markdown you last read as expected_markdown ("" when empty); a concurrent change is refused instead of overwritten.',
122
+ inputSchema: {
123
+ markdown: z.string().describe(`Review Markdown (max ${REVIEW_MARKDOWN_MAX} characters). Links use the same safe rules as task descriptions.`),
124
+ expected_markdown: z.string().describe('The current Markdown as you last read it, or "" if there is none.'),
125
+ },
126
+ }, async (args) => run((bound, author) => ({
127
+ task_id: bound.taskId,
128
+ review: publicReview(setTaskReviewMarkdown(bound.taskId, { markdown: args.markdown, expectedMarkdown: args.expected_markdown, author })),
129
+ })));
130
+ server.registerTool('fleet_task_review_detach', {
131
+ description: 'Remove one file from your task\'s To review package by artifact_id (from fleet_task_review_show).',
132
+ inputSchema: { artifact_id: z.string() },
133
+ }, async (args) => run((bound, author) => ({ task_id: bound.taskId, detached: detachTaskReviewArtifact(bound.taskId, args.artifact_id, { author }) })));
134
+ }
@@ -62,6 +62,8 @@ export type TaskDeletionMemberPhase = 'pending' | 'stop_requested' | 'liveness_a
62
62
  export interface TaskDeletionMemberCursor {
63
63
  name: string;
64
64
  identity_cid: string;
65
+ action_id?: string;
66
+ task_supervised?: boolean;
65
67
  phase: TaskDeletionMemberPhase;
66
68
  launch_id?: string;
67
69
  archive_path?: string;
@@ -88,13 +90,79 @@ export interface TaskDeletionIntent {
88
90
  /** Snapshot of managed members at acceptance; the missing-room retirement evidence. */
89
91
  members: TaskDeletionMemberCursor[];
90
92
  archived_absences?: ArchivedMemberAbsence[];
93
+ absent_members?: string[];
94
+ /** Archive proofs were verified before owned workspace cleanup may consume them. */
95
+ workspace_cleanup_started_at?: string;
91
96
  error?: string;
92
97
  error_at?: string;
93
98
  recovery_hint?: string;
94
99
  first_failure?: string;
95
100
  first_recovery_hint?: string;
96
101
  }
102
+ export interface TaskLayoutLink {
103
+ name: string;
104
+ /** Deterministic `task-<task_id>` Room Layout run ID. */
105
+ run_id: string;
106
+ /** sha256 of the canonical source layout definition the run must snapshot. */
107
+ definition_hash: string;
108
+ }
109
+ export interface TaskNotificationEvent {
110
+ eventId: string;
111
+ title: string;
112
+ body: string;
113
+ target: {
114
+ kind: 'task' | 'task-deleted';
115
+ taskId: string;
116
+ };
117
+ taskId: string;
118
+ }
119
+ /** Who wrote a progress entry or review change, as established by the Fleet surface. */
120
+ export type TaskContributionAuthor = {
121
+ kind: 'agent';
122
+ role: string;
123
+ identity_cid?: string;
124
+ surface: 'mcp' | 'cli';
125
+ } | {
126
+ kind: 'local_control';
127
+ surface: 'cli' | 'web';
128
+ };
129
+ /** One append-only milestone; text is stored exactly as authored. */
130
+ export interface TaskProgressEntry {
131
+ id: string;
132
+ at: string;
133
+ author: TaskContributionAuthor;
134
+ text: string;
135
+ /** Caller retry key, scoped to the author. */
136
+ request_key?: string;
137
+ }
138
+ /** Metadata of a retained review file; bytes live in Fleet's private task review store. */
139
+ export interface TaskReviewArtifact {
140
+ id: string;
141
+ name: string;
142
+ mime: string;
143
+ size: number;
144
+ sha256: string;
145
+ added_at: string;
146
+ added_by: TaskContributionAuthor;
147
+ request_key?: string;
148
+ }
149
+ /** Self-contained material the Owner reviews: Markdown plus retained files. */
150
+ export interface TaskReview {
151
+ /** Increases with every change to the Markdown or the files; absent on packages written before it. */
152
+ revision?: number;
153
+ markdown: string;
154
+ updated_at: string;
155
+ updated_by: TaskContributionAuthor;
156
+ artifacts: TaskReviewArtifact[];
157
+ }
97
158
  export interface TaskRecord {
159
+ /** Optional milestone log; absent on tasks that never recorded one. */
160
+ progress?: TaskProgressEntry[];
161
+ /** Optional To review package; absent until an agent prepares it. */
162
+ review?: TaskReview;
163
+ /** Pending lifecycle events, committed atomically with their task change. */
164
+ notification_events?: TaskNotificationEvent[];
165
+ workspace?: import('./workspace.js').OwnedWorkspace;
98
166
  task_id: string;
99
167
  /** Stable organizational list identifier. Missing legacy values mean `default`. */
100
168
  list_id: string;
@@ -115,6 +183,12 @@ export interface TaskRecord {
115
183
  plan_hash: string;
116
184
  };
117
185
  no_room?: boolean;
186
+ /** Multi-room task: rooms and participants come from a Room Layout run. */
187
+ layout?: TaskLayoutLink;
188
+ /** Set when the room plan (layout or one-room template) was changed after creation, before start. */
189
+ room_plan_changed_at?: string;
190
+ /** Fingerprint of the room plan requested at creation; idempotent retries compare against it after later plan edits. */
191
+ creation_plan?: string;
118
192
  room_id?: string;
119
193
  room_identity_cid?: string;
120
194
  member_roles: TaskMemberRole[];
@@ -153,6 +227,7 @@ export interface RoomRoleBriefingDefinition {
153
227
  last_error?: string;
154
228
  }
155
229
  export interface RoomMemberLaunchState {
230
+ task_supervised?: boolean;
156
231
  state: 'pending' | 'intent' | 'launched' | 'stopped' | 'failed';
157
232
  attempt: number;
158
233
  action_id?: string;
@@ -209,6 +284,7 @@ export type RoomHistoryEvidence = {
209
284
  };
210
285
  export type MemberRetirementPhase = 'stop_requested' | 'liveness_absent' | 'archive_secured' | 'identity_absent';
211
286
  export interface MemberRetirement {
287
+ absence_verified?: boolean;
212
288
  phase: MemberRetirementPhase;
213
289
  launch_id: string;
214
290
  updated_at: string;
@@ -235,12 +311,14 @@ export interface RoomMemberSeat {
235
311
  retirement?: MemberRetirement;
236
312
  }
237
313
  export interface RoomOrchestrationRecord {
314
+ workspace?: import('./workspace.js').OwnedWorkspace;
238
315
  room_id: string;
239
316
  room_identity_cid?: string;
240
317
  room_name: string;
241
318
  goal?: string;
242
319
  task_id?: string;
243
320
  template_snapshot?: TemplateSnapshot;
321
+ additional_member_templates?: TemplateSnapshot[];
244
322
  /** Resolved once at launch; legacy absence means non-anonymous. */
245
323
  room_policy?: RoomLaunchPolicy;
246
324
  saga: SagaCursor;
@@ -0,0 +1,6 @@
1
+ import { type OwnedWorkspace } from './workspace.js';
2
+ /** Runtime control state stays in Fleet's live roster and recovery store. Its
3
+ * durable launch descriptor, not a name prefix or caller-supplied path, proves
4
+ * artifact ownership. Audit receipts/journals intentionally outlive deletion.
5
+ */
6
+ export declare function collectWorkspaceArchives(workspace: OwnedWorkspace): void;
@@ -0,0 +1,93 @@
1
+ import { lstatSync, mkdirSync, readdirSync, readFileSync, renameSync } from 'node:fs';
2
+ import { basename, join } from 'node:path';
3
+ import { parse } from 'yaml';
4
+ import { stateRoot } from '../paths.js';
5
+ import { assertSafeAncestors, auditWorkspaceGit, validateWorkspace, ensureWorkspace, WorkspaceError } from './workspace.js';
6
+ /** Runtime control state stays in Fleet's live roster and recovery store. Its
7
+ * durable launch descriptor, not a name prefix or caller-supplied path, proves
8
+ * artifact ownership. Audit receipts/journals intentionally outlive deletion.
9
+ */
10
+ export function collectWorkspaceArchives(workspace) {
11
+ validateWorkspace(workspace);
12
+ const root = join(stateRoot(), 'recovery', 'temporary');
13
+ assertSafeAncestors(root);
14
+ let entries;
15
+ try {
16
+ entries = readdirSync(root, { withFileTypes: true });
17
+ }
18
+ catch (e) {
19
+ if (e.code === 'ENOENT')
20
+ return;
21
+ throw e;
22
+ }
23
+ const owned = [];
24
+ for (const entry of entries) {
25
+ if (!entry.isDirectory() || entry.isSymbolicLink())
26
+ continue;
27
+ const path = join(root, entry.name);
28
+ const roleFile = join(path, 'role.yaml');
29
+ let role;
30
+ try {
31
+ const s = lstatSync(roleFile);
32
+ if (!s.isFile() || s.isSymbolicLink())
33
+ continue;
34
+ role = parse(readFileSync(roleFile, 'utf8'));
35
+ }
36
+ catch {
37
+ continue;
38
+ } // no ownership proof: never adopt a foreign archive
39
+ const recorded = role?.roomMemberStartup?.workspace;
40
+ if (recorded?.owner !== workspace.owner || recorded.id !== workspace.id)
41
+ continue;
42
+ if (JSON.stringify(recorded) !== JSON.stringify(workspace))
43
+ throw new WorkspaceError('workspace archive ownership mismatch');
44
+ assertSafeAncestors(path);
45
+ const termination = join(path, 'termination.jsonl');
46
+ if (!lstatSync(termination).isFile() || lstatSync(termination).isSymbolicLink())
47
+ throw new WorkspaceError('unsafe workspace archive termination evidence');
48
+ const supervisorPath = join(path, '.temp-supervisor.json');
49
+ let supervisor;
50
+ try {
51
+ if (!lstatSync(supervisorPath).isFile() || lstatSync(supervisorPath).isSymbolicLink())
52
+ throw new WorkspaceError('unsafe workspace archive supervisor evidence');
53
+ supervisor = JSON.parse(readFileSync(supervisorPath, 'utf8'));
54
+ }
55
+ catch (e) {
56
+ if (e.code !== 'ENOENT')
57
+ throw e;
58
+ }
59
+ if (supervisor && (supervisor.role !== role.name || !supervisor.launchId))
60
+ throw new WorkspaceError('workspace archive launch ownership mismatch');
61
+ const terminated = readFileSync(termination, 'utf8').trim().split('\n').some(line => {
62
+ const value = JSON.parse(line);
63
+ return value.version === 1 && value.role === role.name
64
+ && value.launchId === supervisor?.launchId
65
+ && ['retired', 'reclaimed', 'failed'].includes(value.outcome);
66
+ });
67
+ if (!terminated || entry.name.endsWith('.retiring'))
68
+ throw new WorkspaceError('workspace archive retirement is incomplete');
69
+ auditWorkspaceGit(path, { forDeletion: true });
70
+ owned.push(path);
71
+ }
72
+ // Preflight the entire set before mutation; task/room record remains until all succeed.
73
+ if (!owned.length)
74
+ return;
75
+ ensureWorkspace(workspace);
76
+ const destination = join(workspace.path, '.fleet-retired-agents');
77
+ assertSafeAncestors(destination);
78
+ mkdirSync(destination, { recursive: true, mode: 0o700 });
79
+ for (const path of owned) {
80
+ const target = join(destination, basename(path));
81
+ try {
82
+ lstatSync(target);
83
+ throw new WorkspaceError('archive collection destination exists');
84
+ }
85
+ catch (e) {
86
+ if (e.code !== 'ENOENT')
87
+ throw e;
88
+ }
89
+ // Atomic transfer before workspace deletion: a crash never loses ownership
90
+ // evidence halfway through recursively removing a global recovery archive.
91
+ renameSync(path, target);
92
+ }
93
+ }
@@ -0,0 +1,35 @@
1
+ /** Persisted before allocation. Never infer ownership from an Agent's cwd. */
2
+ export interface OwnedWorkspace {
3
+ version: 1;
4
+ owner: 'task' | 'room';
5
+ id: string;
6
+ path: string;
7
+ token: string;
8
+ }
9
+ export declare class WorkspaceError extends Error {
10
+ }
11
+ export declare function assertSafeAncestors(path: string): void;
12
+ export declare function planWorkspace(owner: OwnedWorkspace['owner'], id: string): OwnedWorkspace;
13
+ export declare function validateWorkspace(w: OwnedWorkspace, owner?: "task" | "room", id?: string): void;
14
+ /** Read-only recovery proof; never allocate a replacement for a missing workspace. */
15
+ export declare function assertWorkspacePresent(w: OwnedWorkspace, owner: OwnedWorkspace['owner'], id: string): void;
16
+ /** Caller must first prove the exact workspace marker or retired archive
17
+ * provenance, and hold its lifecycle lock with all managed writers retired.
18
+ * Directories need owner rwx for recursive removal; ordinary files do not.
19
+ */
20
+ export declare function prepareOwnedDeletionTree(path: string): void;
21
+ /** Atomic directory publication; retry uses the durable token, never adopts another folder. */
22
+ export declare function ensureWorkspace(w: OwnedWorkspace): string;
23
+ /** Audit both directions of Git worktree registration, without executing repository config/hooks.
24
+ * All registrations and common dirs must be inside this workspace. Removing the complete
25
+ * workspace then removes their registries atomically with the owned repositories; never prune.
26
+ */
27
+ export declare function auditWorkspaceGit(path: string, options?: {
28
+ forDeletion?: boolean;
29
+ }): void;
30
+ /** Called only after all managed writers retire, under the owner's lifecycle lock.
31
+ * The tombstone is derived from the durable unguessable token. A crash during rm
32
+ * resumes that exact tombstone even if rm already removed its marker.
33
+ */
34
+ export declare function assertWorkspaceDeletable(w: OwnedWorkspace, owner: OwnedWorkspace['owner'], id: string): void;
35
+ export declare function deleteWorkspace(w: OwnedWorkspace, owner: OwnedWorkspace['owner'], id: string): void;