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

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 (423) hide show
  1. package/README.md +279 -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 +19 -0
  11. package/dist/agent-ours/mcp-endpoint.js +98 -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 +24 -1
  15. package/dist/agent-ours/service.js +97 -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 +97 -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 +400 -37
  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 +207 -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 +7 -0
  74. package/dist/fleet-command-audit.js +24 -8
  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 +43 -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 +65 -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 +63 -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-service-retirement.d.ts +11 -0
  180. package/dist/rooms-tasks/task-service-retirement.js +21 -0
  181. package/dist/rooms-tasks/task-state.d.ts +43 -5
  182. package/dist/rooms-tasks/task-state.js +244 -22
  183. package/dist/rooms-tasks/types.d.ts +35 -0
  184. package/dist/rooms-tasks/workspace-artifacts.d.ts +6 -0
  185. package/dist/rooms-tasks/workspace-artifacts.js +93 -0
  186. package/dist/rooms-tasks/workspace.d.ts +35 -0
  187. package/dist/rooms-tasks/workspace.js +325 -0
  188. package/dist/runner.d.ts +33 -4
  189. package/dist/runner.js +410 -62
  190. package/dist/session/acp.d.ts +75 -2
  191. package/dist/session/acp.js +345 -82
  192. package/dist/session/arbiter.d.ts +98 -0
  193. package/dist/session/arbiter.js +272 -3
  194. package/dist/session/codex-app-server.d.ts +45 -1
  195. package/dist/session/codex-app-server.js +225 -32
  196. package/dist/session/control.d.ts +17 -3
  197. package/dist/session/control.js +219 -23
  198. package/dist/session/conversation-normalizer.d.ts +2 -1
  199. package/dist/session/conversation-normalizer.js +1 -1
  200. package/dist/session/conversation-observation.d.ts +25 -0
  201. package/dist/session/conversation-observation.js +100 -0
  202. package/dist/session/conversation-replay.d.ts +50 -0
  203. package/dist/session/conversation-replay.js +203 -0
  204. package/dist/session/conversation-store.d.ts +15 -1
  205. package/dist/session/conversation-store.js +213 -26
  206. package/dist/session/conversation-types.d.ts +57 -4
  207. package/dist/session/prompt-batch.d.ts +79 -0
  208. package/dist/session/prompt-batch.js +120 -0
  209. package/dist/session/task-notice.d.ts +14 -0
  210. package/dist/session/task-notice.js +13 -0
  211. package/dist/session/types.d.ts +42 -1
  212. package/dist/setup-tunnel-preflight.d.ts +34 -0
  213. package/dist/setup-tunnel-preflight.js +62 -0
  214. package/dist/socket-path.d.ts +2 -0
  215. package/dist/socket-path.js +22 -0
  216. package/dist/spawn.d.ts +5 -1
  217. package/dist/spawn.js +40 -4
  218. package/dist/startup-prompt.d.ts +15 -0
  219. package/dist/startup-prompt.js +71 -0
  220. package/dist/startup-readiness.d.ts +32 -0
  221. package/dist/startup-readiness.js +101 -0
  222. package/dist/startup-telemetry.d.ts +16 -0
  223. package/dist/startup-telemetry.js +46 -0
  224. package/dist/subscriptions/cli.d.ts +91 -0
  225. package/dist/subscriptions/cli.js +223 -0
  226. package/dist/subscriptions/launch.d.ts +37 -0
  227. package/dist/subscriptions/launch.js +93 -0
  228. package/dist/subscriptions/login.d.ts +77 -0
  229. package/dist/subscriptions/login.js +215 -0
  230. package/dist/subscriptions/observed.d.ts +7 -0
  231. package/dist/subscriptions/observed.js +44 -0
  232. package/dist/subscriptions/probe.d.ts +10 -0
  233. package/dist/subscriptions/probe.js +73 -0
  234. package/dist/subscriptions/service.d.ts +102 -0
  235. package/dist/subscriptions/service.js +364 -0
  236. package/dist/subscriptions/store.d.ts +71 -0
  237. package/dist/subscriptions/store.js +143 -0
  238. package/dist/supervisor/adoption.d.ts +8 -0
  239. package/dist/supervisor/adoption.js +78 -0
  240. package/dist/supervisor/catalog.d.ts +62 -0
  241. package/dist/supervisor/catalog.js +254 -0
  242. package/dist/supervisor/fleet.d.ts +8 -0
  243. package/dist/supervisor/fleet.js +89 -0
  244. package/dist/supervisor/index.js +3 -6
  245. package/dist/supervisor/launchd.d.ts +1 -1
  246. package/dist/supervisor/launchd.js +26 -13
  247. package/dist/supervisor/legacy.d.ts +35 -0
  248. package/dist/supervisor/legacy.js +524 -0
  249. package/dist/supervisor/manager.d.ts +15 -0
  250. package/dist/supervisor/manager.js +270 -0
  251. package/dist/supervisor/registration-refresh.d.ts +45 -0
  252. package/dist/supervisor/registration-refresh.js +266 -0
  253. package/dist/supervisor/scope.d.ts +4 -0
  254. package/dist/supervisor/scope.js +10 -0
  255. package/dist/supervisor/systemd.d.ts +2 -2
  256. package/dist/supervisor/systemd.js +19 -33
  257. package/dist/task-supervision.d.ts +9 -0
  258. package/dist/task-supervision.js +145 -0
  259. package/dist/temp-idle.d.ts +17 -0
  260. package/dist/temp-idle.js +42 -0
  261. package/dist/temp-lifecycle.d.ts +23 -8
  262. package/dist/temp-lifecycle.js +123 -66
  263. package/dist/temp-supervisor-recovery.d.ts +1 -1
  264. package/dist/temp-supervisor-recovery.js +2 -2
  265. package/dist/tunnel-setup-completion.d.ts +7 -0
  266. package/dist/tunnel-setup-completion.js +13 -0
  267. package/dist/tunnel-setup-input.d.ts +19 -0
  268. package/dist/tunnel-setup-input.js +130 -0
  269. package/dist/watchdog/query.d.ts +3 -1
  270. package/dist/watchdog/query.js +2 -1
  271. package/dist/web/agent-attachments.d.ts +29 -0
  272. package/dist/web/agent-attachments.js +162 -0
  273. package/dist/web/auth.d.ts +65 -2
  274. package/dist/web/auth.js +201 -11
  275. package/dist/web/available-port.d.ts +2 -0
  276. package/dist/web/available-port.js +23 -0
  277. package/dist/web/control.d.ts +3 -3
  278. package/dist/web/control.js +10 -8
  279. package/dist/web/conversation-stream-codec.d.ts +23 -0
  280. package/dist/web/conversation-stream-codec.js +110 -0
  281. package/dist/web/conversation-stream.d.ts +26 -0
  282. package/dist/web/conversation-stream.js +239 -0
  283. package/dist/web/events.d.ts +2 -0
  284. package/dist/web/events.js +9 -0
  285. package/dist/web/fleet-config-service.d.ts +7 -1
  286. package/dist/web/fleet-config-service.js +61 -16
  287. package/dist/web/prefix-gateway.d.ts +32 -0
  288. package/dist/web/prefix-gateway.js +248 -0
  289. package/dist/web/resource-views.d.ts +135 -0
  290. package/dist/web/resource-views.js +486 -0
  291. package/dist/web/runtime.d.ts +3 -1
  292. package/dist/web/runtime.js +132 -34
  293. package/dist/web/server.d.ts +19 -0
  294. package/dist/web/server.js +821 -68
  295. package/dist/web/service.d.ts +11 -2
  296. package/dist/web/service.js +30 -4
  297. package/dist/web/workspace-devices.d.ts +107 -0
  298. package/dist/web/workspace-devices.js +277 -0
  299. package/dist/web/workspace-tunnel.d.ts +1 -0
  300. package/dist/web/workspace-tunnel.js +34 -0
  301. package/dist/workspace-enrollment.d.ts +83 -0
  302. package/dist/workspace-enrollment.js +605 -0
  303. package/dist/workspace-replacement.d.ts +66 -0
  304. package/dist/workspace-replacement.js +238 -0
  305. package/docs/acp-files.md +146 -0
  306. package/docs/conversation-stream.md +216 -0
  307. package/docs/fleet-migration.md +54 -0
  308. package/docs/live-voice.md +13 -0
  309. package/docs/room-layouts.md +227 -0
  310. package/docs/self-reminders.md +374 -0
  311. package/docs/task-workspaces.md +225 -0
  312. package/docs/validation/managed-cli-permissions.md +421 -0
  313. package/examples/room-layouts/fresh.yaml +27 -0
  314. package/examples/room-layouts/scoped.yaml +21 -0
  315. package/examples/room-layouts/shared.yaml +19 -0
  316. package/package.json +24 -20
  317. package/presets/README.md +78 -0
  318. package/presets/brain-catalog.json +8 -2
  319. package/presets/fleet/agent_templates/Critic.yaml +1 -1
  320. package/presets/fleet/agent_templates/Developer.yaml +1 -1
  321. package/presets/fleet/agent_templates/Engineer.yaml +5 -0
  322. package/presets/fleet/agent_templates/LocalCoordinator.yaml +4 -2
  323. package/presets/fleet/agents/FleetCoordinator.yaml +1 -1
  324. package/presets/fleet/brains/claude-fable-5-1-high.yaml +5 -0
  325. package/presets/fleet/brains/claude-fable-5-1-low.yaml +5 -0
  326. package/presets/fleet/brains/claude-fable-5-1-max.yaml +5 -0
  327. package/presets/fleet/brains/claude-fable-5-1-medium.yaml +5 -0
  328. package/presets/fleet/brains/claude-fable-5-1-xhigh.yaml +5 -0
  329. package/presets/fleet/brains/claude-fable-5-high.yaml +1 -1
  330. package/presets/fleet/brains/claude-fable-5-low.yaml +1 -1
  331. package/presets/fleet/brains/claude-fable-5-max.yaml +1 -1
  332. package/presets/fleet/brains/claude-fable-5-medium.yaml +1 -1
  333. package/presets/fleet/brains/claude-fable-5-xhigh.yaml +1 -1
  334. package/presets/fleet/brains/claude-haiku-4-5-20251001-default.yaml +4 -0
  335. package/presets/fleet/brains/claude-opus-5-5-high.yaml +5 -0
  336. package/presets/fleet/brains/claude-opus-5-5-low.yaml +5 -0
  337. package/presets/fleet/brains/claude-opus-5-5-max.yaml +5 -0
  338. package/presets/fleet/brains/claude-opus-5-5-medium.yaml +5 -0
  339. package/presets/fleet/brains/claude-opus-5-5-xhigh.yaml +5 -0
  340. package/presets/fleet/brains/claude-opus-5-high.yaml +1 -1
  341. package/presets/fleet/brains/claude-opus-5-low.yaml +1 -1
  342. package/presets/fleet/brains/claude-opus-5-max.yaml +1 -1
  343. package/presets/fleet/brains/claude-opus-5-medium.yaml +1 -1
  344. package/presets/fleet/brains/claude-opus-5-xhigh.yaml +1 -1
  345. package/presets/fleet/brains/claude-sonnet-5-high.yaml +1 -1
  346. package/presets/fleet/brains/claude-sonnet-5-low.yaml +1 -1
  347. package/presets/fleet/brains/claude-sonnet-5-max.yaml +1 -1
  348. package/presets/fleet/brains/claude-sonnet-5-medium.yaml +1 -1
  349. package/presets/fleet/brains/claude-sonnet-5-xhigh.yaml +1 -1
  350. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-high.yaml +1 -1
  351. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-low.yaml +1 -1
  352. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-medium.yaml +1 -1
  353. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-xhigh.yaml +1 -1
  354. package/presets/fleet/brains/codex-gpt-5-4-high.yaml +1 -1
  355. package/presets/fleet/brains/codex-gpt-5-4-low.yaml +1 -1
  356. package/presets/fleet/brains/codex-gpt-5-4-medium.yaml +1 -1
  357. package/presets/fleet/brains/codex-gpt-5-4-mini-high.yaml +1 -1
  358. package/presets/fleet/brains/codex-gpt-5-4-mini-low.yaml +1 -1
  359. package/presets/fleet/brains/codex-gpt-5-4-mini-medium.yaml +1 -1
  360. package/presets/fleet/brains/codex-gpt-5-4-mini-xhigh.yaml +1 -1
  361. package/presets/fleet/brains/codex-gpt-5-4-xhigh.yaml +1 -1
  362. package/presets/fleet/brains/codex-gpt-5-5-high.yaml +1 -1
  363. package/presets/fleet/brains/codex-gpt-5-5-low.yaml +1 -1
  364. package/presets/fleet/brains/codex-gpt-5-5-medium.yaml +1 -1
  365. package/presets/fleet/brains/codex-gpt-5-5-xhigh.yaml +1 -1
  366. package/presets/fleet/brains/codex-gpt-5-6-luna-high.yaml +1 -1
  367. package/presets/fleet/brains/codex-gpt-5-6-luna-low.yaml +1 -1
  368. package/presets/fleet/brains/codex-gpt-5-6-luna-max.yaml +1 -1
  369. package/presets/fleet/brains/codex-gpt-5-6-luna-medium.yaml +1 -1
  370. package/presets/fleet/brains/codex-gpt-5-6-luna-xhigh.yaml +1 -1
  371. package/presets/fleet/brains/codex-gpt-5-6-sol-high.yaml +1 -1
  372. package/presets/fleet/brains/codex-gpt-5-6-sol-low.yaml +1 -1
  373. package/presets/fleet/brains/codex-gpt-5-6-sol-max.yaml +1 -1
  374. package/presets/fleet/brains/codex-gpt-5-6-sol-medium.yaml +1 -1
  375. package/presets/fleet/brains/codex-gpt-5-6-sol-ultra.yaml +1 -1
  376. package/presets/fleet/brains/codex-gpt-5-6-sol-xhigh.yaml +1 -1
  377. package/presets/fleet/brains/codex-gpt-5-6-terra-high.yaml +1 -1
  378. package/presets/fleet/brains/codex-gpt-5-6-terra-low.yaml +1 -1
  379. package/presets/fleet/brains/codex-gpt-5-6-terra-max.yaml +1 -1
  380. package/presets/fleet/brains/codex-gpt-5-6-terra-medium.yaml +1 -1
  381. package/presets/fleet/brains/codex-gpt-5-6-terra-ultra.yaml +1 -1
  382. package/presets/fleet/brains/codex-gpt-5-6-terra-xhigh.yaml +1 -1
  383. package/presets/fleet/brains/codex-gpt-6-1-sol-high.yaml +5 -0
  384. package/presets/fleet/brains/codex-gpt-6-1-sol-low.yaml +5 -0
  385. package/presets/fleet/brains/codex-gpt-6-1-sol-max.yaml +5 -0
  386. package/presets/fleet/brains/codex-gpt-6-1-sol-medium.yaml +5 -0
  387. package/presets/fleet/brains/codex-gpt-6-1-sol-ultra.yaml +5 -0
  388. package/presets/fleet/brains/codex-gpt-6-1-sol-xhigh.yaml +5 -0
  389. package/presets/fleet/brains/codex-gpt-6-astra-high.yaml +1 -1
  390. package/presets/fleet/brains/codex-gpt-6-astra-low.yaml +1 -1
  391. package/presets/fleet/brains/codex-gpt-6-astra-max.yaml +1 -1
  392. package/presets/fleet/brains/codex-gpt-6-astra-medium.yaml +1 -1
  393. package/presets/fleet/brains/codex-gpt-6-astra-ultra.yaml +1 -1
  394. package/presets/fleet/brains/codex-gpt-6-astra-xhigh.yaml +1 -1
  395. package/presets/fleet/brains/codex-gpt-6-luna-high.yaml +5 -0
  396. package/presets/fleet/brains/codex-gpt-6-luna-low.yaml +5 -0
  397. package/presets/fleet/brains/codex-gpt-6-luna-max.yaml +5 -0
  398. package/presets/fleet/brains/codex-gpt-6-luna-medium.yaml +5 -0
  399. package/presets/fleet/brains/codex-gpt-6-luna-xhigh.yaml +5 -0
  400. package/presets/fleet/brains/codex-gpt-6-sol-high.yaml +5 -0
  401. package/presets/fleet/brains/codex-gpt-6-sol-low.yaml +5 -0
  402. package/presets/fleet/brains/codex-gpt-6-sol-max.yaml +5 -0
  403. package/presets/fleet/brains/codex-gpt-6-sol-medium.yaml +5 -0
  404. package/presets/fleet/brains/codex-gpt-6-sol-ultra.yaml +5 -0
  405. package/presets/fleet/brains/codex-gpt-6-sol-xhigh.yaml +5 -0
  406. package/presets/fleet/roles/Coordinator.yaml +12 -11
  407. package/presets/fleet/roles/Critic.yaml +13 -0
  408. package/presets/fleet/roles/Developer.yaml +13 -0
  409. package/presets/fleet/roles/Engineer.yaml +53 -0
  410. package/presets/fleet/room_layouts/engineering.yaml +25 -0
  411. package/presets/fleet/room_layouts/pair.yaml +24 -0
  412. package/presets/fleet/room_layouts/single.yaml +17 -0
  413. package/presets/fleet/room_layouts/team.yaml +30 -0
  414. package/presets/fleet/room_templates/engineering.yaml +19 -0
  415. package/presets/manifest.json +2 -2
  416. package/dist/web-app/assets/index-59GF-gsZ.css +0 -1
  417. package/dist/web-app/assets/index-C0h3ALvs.js +0 -10
  418. package/dist/web-app/icons/ours-fleet-maskable.svg +0 -4
  419. package/dist/web-app/icons/ours-fleet.svg +0 -4
  420. package/dist/web-app/index.html +0 -17
  421. package/dist/web-app/manifest.webmanifest +0 -15
  422. package/dist/web-app/offline.html +0 -18
  423. package/dist/web-app/sw.js +0 -51
@@ -0,0 +1,374 @@
1
+ # Self-reminders
2
+
3
+ A Fleet-managed agent can schedule a one-time reminder that wakes **itself** at a
4
+ later date and time. When the reminder is due, the agent's own supervisor starts
5
+ a turn for it; the agent reads the reminder and decides what to do.
6
+
7
+ A reminder is not a message. It has no recipient, chat, route, API key or
8
+ Telegram setting, and Fleet never sends anything on the agent's behalf. If the
9
+ agent decides someone should hear about it, it uses its ordinary messaging tools
10
+ under its existing instructions and authorization.
11
+
12
+ It works for every managed session (`session: acp` or `session: codex-app-server`,
13
+ Claude or Codex) and every lifetime: persistent, temporary and task-owned. There
14
+ is nothing to install or enable.
15
+
16
+ ## When to use it
17
+
18
+ - Come back to something at a known time: "check whether the release CI finished
19
+ at 16:00", "follow up on the review on Monday morning".
20
+ - Replace polling or sleeping inside a turn. A reminder costs nothing while it
21
+ waits; a turn that sleeps or a loop that polls costs model time every tick.
22
+ - Wait for a peer without forgetting the task: see [Waiting on a peer](#waiting-on-a-peer).
23
+ - Not for recurring maintenance: use configured `loops` for that.
24
+
25
+ ## Tools
26
+
27
+ The tools are served by the agent's own fixed-identity ours MCP server. No
28
+ argument names an agent or identity: every call acts on the caller's own
29
+ reminders, and an id that belongs to another agent is simply not found.
30
+
31
+ | Tool | Arguments | Result |
32
+ | --- | --- | --- |
33
+ | `fleet_reminder_create` | `request_key`, `title`, `note`?, `local_time`, `time_zone`, `fold`?, `late_window_seconds`?, `interrupt`? | the reminder (`id`, `revision`, `due_at`, `expires_at`, `interrupt`, …) and `created` |
34
+ | `fleet_reminder_list` | `state`? (`open` default, `closed`, `all`), `limit`? (1–100), `after`? | a page of reminders, `more`, `after`, `uncertain_events` |
35
+ | `fleet_reminder_update` | `id`, `expected_revision`, any of the schedule fields | the reminder at its new revision |
36
+ | `fleet_reminder_cancel` | `id`, `expected_revision` | the cancelled reminder |
37
+ | `fleet_reminder_inspect` | `event_id` | the event (with `interrupt` / `interrupt_deferred` for an urgent one), its reminder (with `note`), `current`, `eligible` |
38
+ | `fleet_reminder_ack` | `event_id`, `expected_revision` | `acknowledged` (repeat calls return `duplicate: true`) |
39
+
40
+ ### Time
41
+
42
+ `local_time` is a calendar date and wall-clock time **without** an offset
43
+ (`2027-01-20T16:00` or `2027-01-20T16:00:00`); `time_zone` is an IANA zone such
44
+ as `Europe/London`, `America/New_York` or `UTC`. Use the zone of the person or
45
+ task the reminder is about; Fleet never assumes the host's zone. "Tomorrow at
46
+ nine" must be resolved by the agent to a real date first.
47
+
48
+ Daylight-saving changes are explicit:
49
+
50
+ - A time skipped when clocks go forward (`2027-03-28T01:30` in `Europe/London`)
51
+ does not exist and is refused (`nonexistent_local_time`).
52
+ - A time that occurs twice when clocks go back (`2027-10-31T01:30` in
53
+ `Europe/London`) needs `fold`: `0` for the first occurrence, `1` for the second
54
+ (`ambiguous_local_time` otherwise).
55
+ - Invalid dates (`2027-02-30`) are refused. The time must be in the future and
56
+ within five years.
57
+
58
+ `late_window_seconds` (60–604800, default 3600) is how late the wake may still
59
+ arrive if the agent, Fleet or the host was down, paused or busy at the due time.
60
+ After the window the reminder expires without a turn.
61
+
62
+ `interrupt` (default `false`) marks a reminder as urgent; see
63
+ [Urgent reminders](#urgent-reminders-interrupt-true). Leave it out for ordinary
64
+ reminders.
65
+
66
+ ### Idempotency and revisions
67
+
68
+ `request_key` identifies one scheduling decision. Repeating `create` with the same
69
+ key and the same input returns the existing reminder, so a retried call after a
70
+ timeout never creates a second one; the same key with different input is refused
71
+ (`request_key_conflict`). Keys are remembered while the reminder is retained (the
72
+ 200 most recent closed reminders are kept; at most 100 can be open).
73
+
74
+ An urgent request differs from an ordinary one: repeating a call made without
75
+ `interrupt` (or with `interrupt: false`) matches the original, while the same key
76
+ with `interrupt: true` is a `request_key_conflict`. `update` can turn urgency on or
77
+ off; it keeps its current value when not given.
78
+
79
+ Every `update` and `cancel` names the revision it expects (`stale_revision`
80
+ otherwise) and bumps it. A wake issued for an older revision is void: if it is
81
+ still waiting it is dropped before it reaches the model, and if it was already
82
+ delivered it can no longer be acknowledged.
83
+
84
+ ## Example
85
+
86
+ ```json
87
+ fleet_reminder_create {
88
+ "request_key": "release-ci-check-2027-01-20",
89
+ "title": "Check release CI",
90
+ "note": "PR #412 on prerelease. If CI is green, post the result in the task room; do not merge.",
91
+ "local_time": "2027-01-20T16:00",
92
+ "time_zone": "Europe/London"
93
+ }
94
+ ```
95
+
96
+ At 16:00 London time the agent receives a turn like:
97
+
98
+ ```text
99
+ [fleet-reminder]
100
+ event_id: rev_7c0d…
101
+ reminder_id: rem_1b9e…
102
+ revision: 1
103
+ title: "Check release CI"
104
+ due: 2027-01-20T16:00:00 Europe/London (2027-01-20T16:00:00.000Z)
105
+
106
+ This is a reminder you scheduled for yourself through Fleet. …
107
+ ```
108
+
109
+ It then calls `fleet_reminder_inspect {"event_id": "rev_7c0d…"}`, does the work
110
+ (or decides nothing is needed), and calls
111
+ `fleet_reminder_ack {"event_id": "rev_7c0d…", "expected_revision": 1}`. To
112
+ postpone instead, it calls `fleet_reminder_update` with a new `local_time`; the
113
+ current wake becomes void and a new one is issued at the new time.
114
+
115
+ ## Delivery guarantees and limits
116
+
117
+ - **Who keeps time.** The supervisor process that runs the agent owns the timer
118
+ and the private state (`.self-reminders.json`, mode 0600, in the agent's state
119
+ directory). With no open reminders it arms no timer; otherwise it checks at the
120
+ next due time and at least once a minute. Only a due reminder creates a model
121
+ turn.
122
+ - **When it arrives.** By default, at the first idle turn boundary after the
123
+ due time, and only after the agent's startup turn has succeeded. An ordinary
124
+ wake never interrupts the agent and never waits in a queue behind other work;
125
+ a busy agent receives it when its current work finishes. An urgent reminder may
126
+ instead stop interruptible busy work once (next section). A reminder wake always
127
+ runs as its own turn and is never combined with owner or mail input.
128
+ - **Offline.** Nothing runs while the host is off or asleep, or while Fleet or the
129
+ agent is stopped. Reminders are kept, and those still inside their late window
130
+ are delivered when the agent is back; the rest expire without a turn. Pause and
131
+ restart keep reminders; they never start a stopped agent.
132
+ - **Deletion.** Removing or retiring an agent, or deleting or finishing its task,
133
+ cancels its reminders and deletes their state, including from retained
134
+ evidence. A replaced identity or a new agent with the same name never inherits
135
+ them: a store is bound to the agent's role and identity (and, for a temporary
136
+ or task agent, its runtime instance), and a store that does not match is set
137
+ aside and nothing in it is delivered.
138
+ - **At most once.** Four facts are separate: the supervisor queued the wake, the
139
+ wake was released to the model, the agent acknowledged it, and any external
140
+ action the agent took. A wake is recorded as dispatched, durably, at the moment
141
+ it is handed to the model; if that record cannot be written, it is not handed
142
+ over. After a crash, an event that was never released is retried as the same
143
+ event; an event that may have reached the model is held as `uncertain` and is
144
+ never sent again. `list` reports `uncertain_events`; the agent checks its own
145
+ records, then acknowledges it or schedules something new.
146
+ - **Privacy.** Titles and notes are visible only through the agent's own tools.
147
+ The wake text contains the title, not the note, and the conversation ledger
148
+ stores only a digest of the wake. Logs carry event ids, never reminder text.
149
+
150
+ ## Urgent reminders (`interrupt: true`)
151
+
152
+ An ordinary reminder waits for the agent to be idle, so a long busy turn delays
153
+ it. For a return that is genuinely bound to a time — a deadline, a meeting, a
154
+ window that closes — the agent can create the reminder with `interrupt: true`.
155
+ When it is due and the agent is busy, the supervisor may ask the current turn to
156
+ stop and then start the wake in the same session, instead of waiting.
157
+
158
+ What happens, as separate recorded facts:
159
+
160
+ 1. **Due.** The reminder reaches its time (nothing happens before it).
161
+ 2. **Interruption requested.** Only if the busy turn is interruptible (below).
162
+ The request and its exact target (the turn's source, prompt id and session
163
+ generation; `inspect` shows them as `interrupt.target`) are durably recorded
164
+ *before* the session is asked to stop. Each reminder revision may request
165
+ this **once**. Urgent reminders that may still interrupt are considered
166
+ before ordinary ones and before urgent ones whose interruption is spent.
167
+ 3. **Terminal.** How the stop ended, shown by `inspect` as `interrupt.state`:
168
+ `cancelled` (the target turn's own result confirms this request cancelled it),
169
+ `ended` (the session reported it settled, but cancellation is not confirmed),
170
+ `forced` (the adapter ignored the stop and was restarted), `failed` (the
171
+ control call failed) or `unknown` (Fleet restarted before the outcome).
172
+ 4. **Released.** The wake is handed to the model through the same release fence
173
+ as every reminder. After `forced` or `failed` it is not queued; it is
174
+ delivered later, idle-only, within its late window.
175
+ 5. **Acknowledged**, and any **external action** the agent then takes, are the
176
+ agent's own and remain separate facts.
177
+
178
+ The session and its context are kept: nothing is reset, no second agent and no
179
+ parallel model turn is started. The wake tells the agent what it interrupted so
180
+ it can re-check and resume that work. It sends nothing to anyone and grants no
181
+ authority.
182
+
183
+ An urgent reminder **never** stops, and instead waits like an ordinary one:
184
+
185
+ - an owner-channel request or an owner admin-console turn (owner commands keep
186
+ priority, and cancelling one would end the owner's request and its reply);
187
+ - the startup turn, a stall-recovery turn, or another reminder's wake;
188
+ - a turn with a pending permission decision;
189
+ - work queued behind the current turn, or another admission waiting for the role;
190
+ - a turn Fleet cannot identify exactly (for example one started by adapter-side
191
+ steering, which reports the role idle).
192
+
193
+ Interruptible turns are mail wakes, scheduled loops and local-console prompts.
194
+ When the reminder defers, `inspect` shows why in `event.interrupt_deferred`, and it
195
+ interrupts at a later boundary if one becomes interruptible. A mail wake that was
196
+ stopped is retried by the monitor and queued behind the reminder; it cannot stop
197
+ the reminder in turn.
198
+
199
+ Limits:
200
+
201
+ - Not a hard real-time alarm: the dispatcher checks at least once a minute, and
202
+ stopping a turn and starting a model turn both take time.
203
+ - Nothing happens while the host is off or asleep, or Fleet or the agent is down.
204
+ - One interruption per revision: after it (whatever its outcome) the wake is
205
+ idle-only. A failed or forced stop means the urgency was lost for that event,
206
+ and `inspect` says so; it never reports a successful interruption.
207
+ - Use it sparingly. Ordinary coordination waits stay `interrupt: false`.
208
+
209
+ ## Waiting on a peer
210
+
211
+ In paired work (Developer and Critic, Engineer and Critic) an agent that stops to
212
+ wait for a review, answer, artifact or check schedules **one** idle-only reminder
213
+ about 20 minutes out (or at the agreed time), naming the task or room and the
214
+ exact expectation:
215
+
216
+ ```json
217
+ fleet_reminder_create {
218
+ "request_key": "pr-412-wait-critic-final-1",
219
+ "title": "PR 412: Critic FINAL on head 1a2b3c",
220
+ "note": "Task room for PR 412: waiting for the Critic's FINAL on head 1a2b3c. If it arrived, just ack.",
221
+ "local_time": "2027-01-20T16:20",
222
+ "time_zone": "UTC"
223
+ }
224
+ ```
225
+
226
+ - The answer arrives, the state changes or the work is finished: `cancel` (or
227
+ `update`) the reminder with its current revision.
228
+ - On the wake: `inspect`, re-check the task. Resolved or closed: `ack`, nothing
229
+ else. Still waiting: one concise follow-up in the same room, `ack`, and at most
230
+ one more reminder; if that one finds no progress either, report the
231
+ nonresponse or blocker once through the configured routes and stop reminding.
232
+ - Never a short polling interval, a recurring chain of reminders, repeated
233
+ follow-ups or acknowledgements, or a "done" status because a reminder fired.
234
+ - A deleted or finished task removes the agent's reminders, so a closed task
235
+ produces no wake.
236
+
237
+ Operators can see an agent's reminders through the existing supervisor tool
238
+ route, which acts as that agent's supervisor:
239
+
240
+ ```sh
241
+ ours-fleet ours call DeveloperA fleet_reminder_list
242
+ ```
243
+
244
+ ## Migrating from the standalone `self-reminders` worker
245
+
246
+ The standalone skill ran one Python worker, its own SQLite ledger and a user
247
+ service per agent. Built-in reminders replace it; the worker is deprecated.
248
+ Personal-assistant reminder, source and outbound messaging stores are separate
249
+ systems and are not touched by this procedure. Migration is a deliberate,
250
+ separately authorized operation per agent; nothing migrates automatically.
251
+
252
+ Reminder data is handled **by the agent itself** with both tool sets, so its text
253
+ never passes through an operator. The operator only fences and later removes the
254
+ old service.
255
+
256
+ ### 1. Preconditions
257
+
258
+ - The agent runs a Fleet release with built-in reminders:
259
+ `ours-fleet ours tools Name` lists `fleet_reminder_create`.
260
+ - `fleet_reminder_list {"state": "all"}` (every page) shows each reminder's
261
+ `request_key`. Any key starting with `legacy:` belongs to an earlier attempt:
262
+ reconcile it with the rollback table below before starting again. Keys map
263
+ back to old ids (`legacy:<old id>:r<old revision>`), so an interrupted run
264
+ is always resumable from the two lists.
265
+
266
+ ### 2. Fence the old producer persistently
267
+
268
+ A `stop` alone is not a fence: an enabled unit starts again at the next login or
269
+ boot. The operator records the unit's prior state and its unit file, then
270
+ disables it. The old setup enabled a generated unit by absolute path outside the
271
+ unit search path, so disabling removes its only link; keep the recorded path and
272
+ do not delete that file until step 6:
273
+
274
+ ```sh
275
+ systemctl --user is-enabled self-reminders-Name.service # record: enabled/linked/...
276
+ systemctl --user is-active self-reminders-Name.service # record: active/inactive
277
+ systemctl --user show -p FragmentPath self-reminders-Name.service # record the absolute unit file
278
+ systemctl --user disable --now self-reminders-Name.service
279
+ systemctl --user is-enabled self-reminders-Name.service # must not be enabled
280
+ systemctl --user is-active self-reminders-Name.service # must be inactive
281
+ ```
282
+
283
+ From here on no old wake can be produced, across worker, Fleet or host
284
+ restarts, until someone deliberately re-enables the unit. Do not run the old
285
+ `tick` or `serve` commands during the cutover.
286
+
287
+ ### 3. Classify every old reminder
288
+
289
+ The old CLI lists reminders but not events, and its `cancel` leaves earlier
290
+ events in whatever state they had. Classification therefore uses the old
291
+ system's own eligibility rule, not raw event states: an event is **live** only
292
+ if its reminder is still `active`, the event's revision equals the reminder's
293
+ current revision, and its state is `submitting`, `queued` or `uncertain`.
294
+ Anything else is historical: superseded by an update or cancellation, or
295
+ belonging to a reminder that is already `handled`, `cancelled` or `expired`.
296
+
297
+ The operator supplies the metadata with a read-only query that selects no
298
+ title or context:
299
+
300
+ ```sh
301
+ sqlite3 -readonly /path/to/old/ledger.sqlite "
302
+ SELECT r.id, r.revision, r.state,
303
+ datetime(r.due, 'unixepoch'), datetime(r.expires, 'unixepoch'),
304
+ e.id, e.revision, e.state
305
+ FROM self_reminders r LEFT JOIN self_events e
306
+ ON e.reminder_id = r.id AND e.revision = r.revision
307
+ ORDER BY r.due, r.id"
308
+ ```
309
+
310
+ Each old reminder falls into exactly one row:
311
+
312
+ | Old reminder (current revision) | Meaning | Action |
313
+ | --- | --- | --- |
314
+ | `handled`, `cancelled` or `expired` | finished; its events are historical | nothing |
315
+ | `active`, `expires` already passed | lapsed while fenced; the old worker would expire it | old `cancel`, nothing to migrate |
316
+ | `active`, due in the future, no event | not yet fired | **migrate** (step 4), then old `cancel` (step 5) |
317
+ | `active`, already due, no event or event `pending` | due, never submitted | **decide**: migrate to a new future time, or old `cancel`; never both |
318
+ | `active`, event `submitting`, `queued` or `uncertain` | live: may already have reached the agent | **hold**: check the conversation and your own records. If handled and still inside its window, old `complete`. Otherwise old `cancel`, which makes the event historical, and create a new reminder only if one is still useful. Never re-create the old event as-is |
319
+ | `active`, event `handled`, `failed` or `invalidated` | finished for this revision | old `cancel` |
320
+
321
+ **Stop condition:** do not continue to step 6 while any old reminder is still
322
+ `active`. When every row above has been applied, nothing is active and no
323
+ event is live.
324
+
325
+ ### 4. Re-create the reminders that migrate
326
+
327
+ For each reminder marked *migrate*, the agent calls `fleet_reminder_create` with:
328
+
329
+ - `request_key` `legacy:<old id>:r<old revision>`;
330
+ - the same title, with the old `context` as `note`;
331
+ - the same `local_time`, `timezone` and `fold`;
332
+ - the old window (`expires − due`) as `late_window_seconds`.
333
+
334
+ The key makes this step safe to repeat. A reminder whose time has meanwhile
335
+ passed is refused as not in the future. It is then a *decide* row: pick a new
336
+ time, using `request_key` `legacy:<old id>:r<old revision>:retimed`, or let it
337
+ lapse.
338
+
339
+ ### 5. Verify, then retire the old entries
340
+
341
+ `fleet_reminder_list` shows exactly one `legacy:` reminder per migrated old id.
342
+ The agent then cancels each migrated old reminder with the old `cancel` (`id`,
343
+ `expected_revision`). Afterwards the old `list` shows no `active` reminders and
344
+ no unsettled events.
345
+
346
+ ### 6. Remove the old service
347
+
348
+ Only after step 5 is verified, the operator removes the user unit and the
349
+ worker's config (it is already disabled and stopped). Keep or delete the old
350
+ ledger according to the owner's retention policy; never point Fleet at it.
351
+
352
+ ### Rollback
353
+
354
+ Rollback is a reconciliation, not a restart. While the old unit stays disabled,
355
+ the agent goes through each `legacy:` Fleet reminder:
356
+
357
+ | Fleet reminder state | Action before the old producer may run again |
358
+ | --- | --- |
359
+ | open, no event or event `pending` | First check the old reminder named by the key (`legacy:<old id>:…`). Only if it is still `active` in the old system, `fleet_reminder_cancel` the Fleet copy. If the old one is no longer active, the Fleet copy is the only schedule: keep it |
360
+ | event `dispatched` or `uncertain`, or `acknowledged` | the wake already happened in Fleet: **cancel the old reminder** so it cannot fire again, and keep the Fleet record |
361
+ | `cancelled` or `expired` | nothing; make sure the old reminder is not active either unless that is intended |
362
+
363
+ Only when every `legacy:` reminder has been reconciled may the operator restore
364
+ the unit to its recorded prior state from the recorded unit file, for example
365
+ `systemctl --user enable --now /recorded/FragmentPath/self-reminders-Name.service`
366
+ if it was enabled and active. Never have both producers active for the same
367
+ reminder.
368
+
369
+ ### Instructions to update
370
+
371
+ Remove instructions that tell the agent to run the worker script, and replace
372
+ them with: "Use the `fleet_reminder_*` tools to schedule wakes for yourself. A
373
+ due wake is an internal event: inspect it, decide, then acknowledge it. Message
374
+ anyone only through your normal configured channels."
@@ -0,0 +1,225 @@
1
+ # Task workspaces and artifact retention
2
+
3
+ New Tasks allocate a private workspace at
4
+ `$OURS_FLEET_HOME/.ours-fleet/workspaces/tasks/<task-id>` (the user's home is the
5
+ default for `OURS_FLEET_HOME`). New standalone Rooms use
6
+ `.ours-fleet/workspaces/rooms/<room-id>`. A linked Room shares its Task's workspace.
7
+ The absolute path, owner kind/ID and random ownership token are stored in the
8
+ record before directory allocation; `.fleet-workspace.json` proves ownership.
9
+ The path is visible in Task/Room JSON from both CLI and API. A folder of the same
10
+ name without the matching marker is never adopted.
11
+
12
+ Every newly managed member starts at that exact workspace, including retries.
13
+ An explicit template/member `cwd` remains in the sealed input execution plan as
14
+ source context, but the owned workspace overrides the effective launch cwd.
15
+ Copy or clone required source into the workspace; Fleet does not move or delete
16
+ the configured source directory. Briefings explain this rule. Use separate
17
+ per-agent branches/directories inside the workspace for concurrent edits.
18
+
19
+ All execution artifacts, dependency checkouts and worktrees belong inside the
20
+ workspace. Clone each repository there first, then use `git worktree add` with
21
+ destinations inside the same workspace. Git's native worktree registry is the
22
+ registry of record. Fleet audits `.git`, `commondir` and reverse `gitdir` links
23
+ before deletion; both the common repository and all registered worktrees must
24
+ be inside the workspace. An external repository's worktree inside the workspace,
25
+ or an internal repository's worktree outside it, blocks deletion. No broad
26
+ `git worktree prune`, branch deletion, reset or modification of unrelated Git
27
+ metadata is performed. Removing the owned repositories also removes their
28
+ complete internal worktree registries, including dirty and stale owned entries.
29
+
30
+ | Operation | Workspace and execution artifacts | Member runtime evidence |
31
+ | --- | --- | --- |
32
+ | Complete, fail, cancel | Retained while Task is recorded | Retained in Fleet recovery archives |
33
+ | Linked Room retirement or deletion | Task workspace retained | Retained |
34
+ | Internal standalone Room retirement | Room workspace retained | Retained |
35
+ | Explicit Task deletion | Removed after member retirement | All proven owned retired launches removed |
36
+ | Explicit standalone Room deletion | Removed after member retirement | All proven owned retired launches removed |
37
+
38
+ Internal room close means retirement, not destructive Task deletion.
39
+ The existing CLI `room close ID ID` remains a deprecated alias for explicit
40
+ `room delete ID ID`: it deletes standalone room-owned artifacts, but always
41
+ retains a linked Task workspace. Its repeated-ID confirmation is unchanged. To remove a Task's
42
+ artifacts, explicitly delete the Task. Cancellation is not deletion. Automatic
43
+ compatibility cleanup of legacy closed Rooms skips records with owned workspaces.
44
+ These choices reconcile close/remove wording with the requirement that completed,
45
+ recorded Tasks retain all artifacts.
46
+
47
+ Fleet's active member state (briefings, logs, session state and WORKLOG) remains
48
+ under `.ours-fleet/tmp` while supervisors run, then in
49
+ `.ours-fleet/recovery/temporary`. The launch stores the workspace descriptor.
50
+ Explicit deletion first proves managed agents retired, then identifies all
51
+ matching archived launches, including failed and replaced attempts, using the
52
+ workspace descriptor plus role and termination/launch evidence. It preflights
53
+ these archives and atomically transfers them to `.fleet-retired-agents` in the
54
+ workspace before removal. Unrelated archives are not adopted by a name prefix.
55
+ Explicit deletion also erases legacy archives with exact launch/action or room
56
+ provenance, matching private supervisor journals and admission/launch descriptors,
57
+ and the exact retired-launch rows in the global termination journal. It never
58
+ infers ownership from an Agent's shared `cwd`. Artifact removal uses a durable
59
+ manifest, ownership fingerprints and per-entry rename/removal checkpoints, so
60
+ an interrupted deletion can resume without deleting a replacement at the old path.
61
+ Task deletion acceptance receipts exist only during cleanup and are erased after
62
+ settlement (including retry after a crash between Task unlink and receipt cleanup).
63
+ Shared Fleet command audit and lifecycle delivery ledgers have exactly attributed
64
+ target labels, configuration and command arguments removed; unrelated entries are
65
+ preserved. Delivery/deduplication metadata and a content-free erased-resource ID
66
+ registry remain so a running writer cannot resurrect erased content. Infrastructure
67
+ logs without structured ownership, backups, and copies already delivered to other
68
+ identities are external retention boundaries; this is not a claim to erase every
69
+ external copy.
70
+
71
+ Provisioning serializes Task operation then Room close locks, including bounded
72
+ seat waits, so concurrent retries cannot publish competing members and deletion
73
+ cannot race a member launch. Local published Rooms are reused if the Task link
74
+ write was interrupted. Workspace allocation publishes a marked staging directory;
75
+ restart reuses the durable token. Deletion renames the validated workspace to a
76
+ token-specific sibling tombstone before removal. A crash during removal resumes
77
+ that exact tombstone; the Task record is unlinked last. Before collecting archives,
78
+ Task deletion durably checkpoints verified retirement evidence. Retries verify
79
+ any remaining original archive and still refuse replacement live member state
80
+ or a recreated identity even after the archive has been consumed. Failed deletion
81
+ remains retryable with its recorded error.
82
+
83
+ Explicit deletion restores missing owner read/write/traversal bits on real
84
+ directories inside a proven owned workspace or retired archive before the Git
85
+ audit and removal. This handles restrictive artifacts left by tests even when
86
+ they belong to the same Unix user. It adds no group/other access, follows no
87
+ artifact symlinks, crosses no mounted device boundary, and never changes the
88
+ owner. Only Git pointer files that the audit must read may gain owner-read;
89
+ hardlinked unreadable pointers are refused to avoid changing an outside alias.
90
+ Permission changes target a verified open inode. Readable foreign-UID directories
91
+ may be traversed unchanged; missing owner access is never repaired for another
92
+ UID. On Linux, traversal and Git pointer reads use pinned directory/file
93
+ descriptors, and a detected pathname replacement stops cleanup before descending.
94
+ Unreadable entries
95
+ use an `O_PATH` descriptor through `/proc/self/fd`; other platforms retain the
96
+ error if they cannot open the entry safely. A restricted workspace root is
97
+ temporarily accessible to verify its exact ownership marker; failed marker
98
+ verification restores its original mode. Partial token-derived deletion
99
+ tombstones resume directory cleanup without re-reading already-removed Git
100
+ metadata. List, show, and ordinary Git audit do not repair permissions.
101
+
102
+ An accepted deletion is hidden from ordinary task lists while cleanup settles.
103
+ Use `ours-fleet task list --include-deleting --json` (or the API's
104
+ `includeDeleting=true`) to include retained cleanup intents, and `task show ID`
105
+ to see pending/error/retry information. Disappearance from the ordinary list is
106
+ not proof of completed deletion; successful deletion removes the task record
107
+ after workspace and member cleanup.
108
+ Cowork HTTP transport failures record the RPC method, failing stage and a
109
+ bounded error category in the cleanup intent. Credential rejection remains an
110
+ explicit `unauthorized` protocol error. Transport diagnostics do not include
111
+ request bodies, credentials, URLs or raw exception text, and failed mutations
112
+ are never automatically replayed.
113
+
114
+ Deletion rejects traversal, foreign recorded paths, changed markers and symlinked
115
+ workspace ancestors. Ordinary artifact symlinks are unlinked without following
116
+ their targets. Git control symlinks and foreign pointers are refused. As with
117
+ Fleet's other filesystem lifecycle operations, a hostile same-UID process that
118
+ mutates paths during validation requires OS isolation; application checks are
119
+ not a security boundary against that process. Fleet enforces launch cwd and
120
+ safe deletion; unrestricted agents can still write outside cwd, so the artifact
121
+ placement rule also requires agent compliance and/or filesystem isolation.
122
+
123
+ ## Compatibility and limits
124
+
125
+ Records from before this feature without `workspace` remain unmanaged. Existing
126
+ agents retain their cwd and exact briefing/fingerprint so restart matching works.
127
+ Fleet never claims an old cwd, an outcome artifact path, or a legacy recovery
128
+ archive as owned merely because it was mentioned by a Task. Create a new managed
129
+ Task and explicitly copy desired artifacts to migrate; deleting a legacy Task
130
+ continues its previous lifecycle and does not delete arbitrary old files.
131
+
132
+ Changing `OURS_FLEET_HOME` does not silently rebase recorded absolute ownership
133
+ paths. Restore the original state root or explicitly migrate records and files
134
+ with the supervisors stopped; mismatched paths fail closed. Archive transfer
135
+ uses same-filesystem rename and reports a recoverable failure across mounts.
136
+
137
+ Cowork's remote create operation has no idempotency key in this interface. A crash
138
+ after remote creation but before local Room publication is an existing uncertain
139
+ remote result; this change deduplicates locally recorded rooms and does not claim
140
+ to solve that remote transaction window. Inspect remote room ownership before
141
+ retrying ambiguous remote creation. No services or installed Fleet code are
142
+ changed by building or testing this feature.
143
+
144
+
145
+ ## Broken provisioning and deletion recovery
146
+
147
+ Deletion accepts every lifecycle state. Missing temporary directories, identities,
148
+ remote rooms and already-erased artifacts are settled outcomes. Retry the same
149
+ explicit delete after an interruption. A missing local member CID is recovered
150
+ only from a matching authenticated seat in the pinned room (exact invite and
151
+ role, uniquely matched), or a supervisor journal tied to the selected daemon,
152
+ temporary instance and recorded creation action. These sources must agree.
153
+ The recovered CID is persisted before retirement consumes the evidence.
154
+
155
+ A contradictory CID, replacement launch, ambiguous seat, unreadable/corrupt
156
+ record, or unreachable authority is not evidence of absence. Cleanup retains its
157
+ cursor and reports the conflict instead of deleting an unrelated resource or
158
+ claiming complete erasure. An identity with no recoverable authenticated binding
159
+ requires restoring its actual ownership evidence; a name-only force removal is
160
+ not supported. Room deletion removes the linked Task's dead room/member links and preserves its workspace; use explicit
161
+ Task deletion when the request includes the associated Task and its artifacts.
162
+
163
+
164
+ ## Retained task agents
165
+
166
+ Task agents use the common Fleet service and existing runners while remaining
167
+ outside the standalone agent roster. Recovery retains their original identity,
168
+ private runtime owner, launch, working directory, admitted room and supported
169
+ backend conversation. `ours-fleet task recover-members TASK_ID` resumes proven
170
+ stopped members or resets their held restart circuit; it never creates identities
171
+ or invitations. See [upgrade and rollback](fleet-migration.md) for legacy tasks.
172
+
173
+ Recovery delivers an undispatched assignment once, continues interrupted work,
174
+ and sends no readiness/work prompt to a completed idle conversation. An uncertain
175
+ dispatch gets a continuation instead of replaying the assignment. First-session
176
+ retry requires proof that no readiness/work was submitted; established session
177
+ loss requires restoration of the original context. Task agents require a resumable
178
+ harness. Missing ownership, workspace or room evidence keeps recovery held.
179
+
180
+ Parent shutdown suspends task agents. Explicit member stop terminally releases
181
+ the exact saved owner and archives its launch; it does not complete the task.
182
+ Finish/cancel/review retain their existing semantics. Task deletion stops and
183
+ unregisters only owned members, verifies identity absence and retries cleanup
184
+ before erasing task/room/workspace resources. Permanent siblings remain intact.
185
+ Standalone CLI/web removal refuses `TASK_MEMBER_IS_TASK_OWNED`; use the owning
186
+ task lifecycle. Lost/corrupt task or launch records require restoring original
187
+ backup evidence or explicit ownership reconciliation before deletion can finish.
188
+
189
+ ## Owner lifecycle notifications
190
+
191
+ A task mutation commits its notification event in the same atomic task record as
192
+ its effective status. Creation, backlog, provisioning, active, review, done,
193
+ cancelled and failed are covered; block/unblock and deletion are effective changes
194
+ as well. Editing a description, list, block reason or saga checkpoint is not a
195
+ status transition. Each event freezes the task identity, title, old/new status and
196
+ navigation route at commit time, so several transitions between delivery polls
197
+ remain separate. Legacy records begin emitting on their next actual change and
198
+ are not retroactively announced as newly created.
199
+
200
+ The Fleet manager drains committed task events without requiring the web console
201
+ or restarting agents. Its notification producer uses the installation's existing
202
+ owner-scoped credential; it grants no agent arbitrary-send capability. Missing
203
+ configuration or service failure retains the events. Delivery acknowledgement
204
+ runs under the task lock and removes only the accepted event, preserving newer
205
+ changes. A corrupt/unreadable task record is isolated with a safe warning, so
206
+ other tasks continue. Bounded rotating batches prevent one rejected task from
207
+ blocking the entire sender. The built-in `default` task list is unchanged.
208
+
209
+ Deleting is announced only after its intent commits. Before unlink, settlement
210
+ prepares retained pending events plus a stable deleted event outside the task-owned
211
+ workspace. The sender admits that retained copy only when the original task record
212
+ is absent; an interrupted or failed unlink cannot announce deletion. The final
213
+ event opens the task list and includes the removed task's identity. Earlier events
214
+ keep their immutable detail routes, which may be absent after explicit deletion.
215
+
216
+ A service restart or producer crash after acceptance may replay an event; the
217
+ Notifications service must retain its acceptance receipts across read/delete to
218
+ make that replay harmless. Upgrade Notifications alongside Fleet to obtain this
219
+ stronger guarantee. The service's authenticated delivery diagnostics distinguish
220
+ provider acceptance, retry, expired subscription and foreground suppression.
221
+ Provider acceptance is not evidence of actual phone receipt. iPhone Web Push
222
+ requires a supported Home Screen installation and granted device/browser permission;
223
+ reopen the workspace to reconcile an expired subscription and explicitly re-enable
224
+ permission if it was revoked. Every received push must display a notification to
225
+ honor Safari's user-visible push requirement.