@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.
- package/README.md +279 -68
- package/dist/account-origin.d.ts +5 -0
- package/dist/account-origin.js +31 -0
- package/dist/agent-ours/bridge.js +26 -9
- package/dist/agent-ours/correspondence.d.ts +10 -0
- package/dist/agent-ours/correspondence.js +1 -0
- package/dist/agent-ours/file-rpc.d.ts +12 -0
- package/dist/agent-ours/file-rpc.js +18 -4
- package/dist/agent-ours/harness.js +9 -1
- package/dist/agent-ours/mcp-endpoint.d.ts +19 -0
- package/dist/agent-ours/mcp-endpoint.js +98 -25
- package/dist/agent-ours/runtime.d.ts +9 -1
- package/dist/agent-ours/runtime.js +50 -2
- package/dist/agent-ours/service.d.ts +24 -1
- package/dist/agent-ours/service.js +97 -13
- package/dist/application/codex-models.d.ts +15 -0
- package/dist/application/codex-models.js +56 -0
- package/dist/application/conversation-history.d.ts +34 -0
- package/dist/application/conversation-history.js +294 -0
- package/dist/application/conversation-role-observer.d.ts +62 -0
- package/dist/application/conversation-role-observer.js +206 -0
- package/dist/application/fleet-query-service.d.ts +1 -1
- package/dist/application/fleet-query-service.js +3 -3
- package/dist/application/log-service.js +8 -8
- package/dist/application/model-catalog.d.ts +1 -1
- package/dist/application/model-catalog.js +5 -2
- package/dist/application/preset-provenance.d.ts +19 -0
- package/dist/application/preset-provenance.js +59 -0
- package/dist/application/resource-observer.d.ts +43 -0
- package/dist/application/resource-observer.js +323 -0
- package/dist/application/role-creation-service.js +3 -2
- package/dist/application/role-removal-service.js +17 -3
- package/dist/application/role-repository.d.ts +1 -1
- package/dist/application/role-repository.js +30 -7
- package/dist/application/room-layout-definitions.d.ts +45 -0
- package/dist/application/room-layout-definitions.js +130 -0
- package/dist/application/session-control.d.ts +63 -17
- package/dist/application/session-control.js +221 -23
- package/dist/application/supervisor-ours-tools.js +5 -11
- package/dist/application/task-layouts.d.ts +91 -0
- package/dist/application/task-layouts.js +261 -0
- package/dist/application/task-room-service.d.ts +101 -3
- package/dist/application/task-room-service.js +286 -33
- package/dist/application/types.d.ts +2 -0
- package/dist/atomic-file.d.ts +34 -1
- package/dist/atomic-file.js +161 -18
- package/dist/briefing.d.ts +3 -1
- package/dist/briefing.js +97 -31
- package/dist/build-info.json +9 -4
- package/dist/capabilities.d.ts +9 -1
- package/dist/capabilities.js +13 -0
- package/dist/cli.js +400 -37
- package/dist/client-profile.d.ts +5 -17
- package/dist/client-profile.js +4 -127
- package/dist/config.d.ts +45 -0
- package/dist/config.js +57 -6
- package/dist/creation.d.ts +1 -1
- package/dist/creation.js +4 -4
- package/dist/daemon-recovery.d.ts +14 -9
- package/dist/daemon-recovery.js +124 -115
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +207 -19
- package/dist/doctor.d.ts +4 -1
- package/dist/doctor.js +75 -60
- package/dist/erased-resources.d.ts +9 -0
- package/dist/erased-resources.js +87 -0
- package/dist/file-delivery/reader.d.ts +15 -0
- package/dist/file-delivery/reader.js +63 -0
- package/dist/file-delivery/store.d.ts +15 -0
- package/dist/file-delivery/store.js +124 -0
- package/dist/file-delivery/types.d.ts +19 -0
- package/dist/file-delivery/types.js +1 -0
- package/dist/fleet-command-audit.d.ts +7 -0
- package/dist/fleet-command-audit.js +24 -8
- package/dist/harness/agent-session.d.ts +4 -0
- package/dist/harness/claude-code-session.js +1 -1
- package/dist/harness/claude-code.js +21 -11
- package/dist/harness/claude-runtime.d.ts +12 -0
- package/dist/harness/claude-runtime.js +43 -0
- package/dist/harness/codex-app-server-proxy.d.ts +4 -1
- package/dist/harness/codex-app-server-proxy.js +41 -5
- package/dist/harness/codex-reasoning.d.ts +5 -0
- package/dist/harness/codex-reasoning.js +12 -0
- package/dist/harness/codex-runtime.d.ts +11 -1
- package/dist/harness/codex-runtime.js +31 -4
- package/dist/harness/codex-session.js +2 -2
- package/dist/harness/codex.js +24 -12
- package/dist/init-wizard.d.ts +2 -0
- package/dist/init-wizard.js +38 -19
- package/dist/isolation/policy.js +6 -1
- package/dist/isolation/types.d.ts +5 -0
- package/dist/managed-cli.d.ts +253 -0
- package/dist/managed-cli.js +923 -0
- package/dist/managed-recovery.d.ts +13 -0
- package/dist/managed-recovery.js +31 -0
- package/dist/minimal-setup.d.ts +2 -0
- package/dist/minimal-setup.js +44 -0
- package/dist/monitor.d.ts +9 -34
- package/dist/monitor.js +90 -153
- package/dist/notifications/fleet-producer.d.ts +31 -0
- package/dist/notifications/fleet-producer.js +351 -0
- package/dist/notifications/outbox.d.ts +59 -0
- package/dist/notifications/outbox.js +199 -0
- package/dist/notifications/target-cleanup.d.ts +16 -0
- package/dist/notifications/target-cleanup.js +75 -0
- package/dist/notifications/task-producer.d.ts +20 -0
- package/dist/notifications/task-producer.js +100 -0
- package/dist/ops.d.ts +2 -0
- package/dist/ops.js +20 -3
- package/dist/owner-channel/channel.js +17 -6
- package/dist/owner-channel/commands.d.ts +4 -0
- package/dist/owner-channel/commands.js +8 -0
- package/dist/owner-channel/lifecycle-outbox.js +4 -3
- package/dist/owner-channel/ours-client.js +2 -17
- package/dist/paths.d.ts +5 -0
- package/dist/paths.js +5 -0
- package/dist/preset-migration.js +43 -0
- package/dist/process-incarnation.d.ts +23 -0
- package/dist/process-incarnation.js +42 -0
- package/dist/reminders/manager.d.ts +75 -0
- package/dist/reminders/manager.js +278 -0
- package/dist/reminders/runtime.d.ts +27 -0
- package/dist/reminders/runtime.js +32 -0
- package/dist/reminders/schedule.d.ts +37 -0
- package/dist/reminders/schedule.js +104 -0
- package/dist/reminders/store.d.ts +341 -0
- package/dist/reminders/store.js +762 -0
- package/dist/reminders/tools.d.ts +20 -0
- package/dist/reminders/tools.js +114 -0
- package/dist/resolved-plan.js +1 -0
- package/dist/rooms-tasks/add-member.d.ts +48 -0
- package/dist/rooms-tasks/add-member.js +84 -0
- package/dist/rooms-tasks/archived-absence.d.ts +4 -0
- package/dist/rooms-tasks/archived-absence.js +11 -0
- package/dist/rooms-tasks/cli.js +65 -5
- package/dist/rooms-tasks/close.d.ts +5 -2
- package/dist/rooms-tasks/close.js +224 -36
- package/dist/rooms-tasks/config.d.ts +1 -1
- package/dist/rooms-tasks/config.js +11 -4
- package/dist/rooms-tasks/cowork-adapter.d.ts +12 -5
- package/dist/rooms-tasks/cowork-adapter.js +15 -121
- package/dist/rooms-tasks/cowork-http.js +56 -6
- package/dist/rooms-tasks/deletion.d.ts +1 -1
- package/dist/rooms-tasks/deletion.js +63 -10
- package/dist/rooms-tasks/erasure.d.ts +6 -0
- package/dist/rooms-tasks/erasure.js +173 -0
- package/dist/rooms-tasks/external-worker.d.ts +1 -1
- package/dist/rooms-tasks/external-worker.js +3 -4
- package/dist/rooms-tasks/layout-binding-client.d.ts +11 -0
- package/dist/rooms-tasks/layout-binding-client.js +56 -0
- package/dist/rooms-tasks/layout-binding-grants.d.ts +21 -0
- package/dist/rooms-tasks/layout-binding-grants.js +128 -0
- package/dist/rooms-tasks/layout-cli.d.ts +4 -0
- package/dist/rooms-tasks/layout-cli.js +107 -0
- package/dist/rooms-tasks/layout-config.d.ts +11 -0
- package/dist/rooms-tasks/layout-config.js +89 -0
- package/dist/rooms-tasks/layout-control.d.ts +21 -0
- package/dist/rooms-tasks/layout-control.js +52 -0
- package/dist/rooms-tasks/layout-member-retirement.d.ts +10 -0
- package/dist/rooms-tasks/layout-member-retirement.js +90 -0
- package/dist/rooms-tasks/layout-service.d.ts +43 -0
- package/dist/rooms-tasks/layout-service.js +203 -0
- package/dist/rooms-tasks/layout.d.ts +121 -0
- package/dist/rooms-tasks/layout.js +286 -0
- package/dist/rooms-tasks/legacy-task-member.d.ts +19 -0
- package/dist/rooms-tasks/legacy-task-member.js +116 -0
- package/dist/rooms-tasks/live-readiness.d.ts +18 -0
- package/dist/rooms-tasks/live-readiness.js +85 -0
- package/dist/rooms-tasks/member-ownership.d.ts +5 -0
- package/dist/rooms-tasks/member-ownership.js +40 -0
- package/dist/rooms-tasks/member-startup.d.ts +1 -0
- package/dist/rooms-tasks/member-startup.js +2 -0
- package/dist/rooms-tasks/provision.d.ts +3 -0
- package/dist/rooms-tasks/provision.js +101 -49
- package/dist/rooms-tasks/recovery.d.ts +19 -0
- package/dist/rooms-tasks/recovery.js +110 -0
- package/dist/rooms-tasks/room-state.d.ts +4 -2
- package/dist/rooms-tasks/room-state.js +47 -8
- package/dist/rooms-tasks/task-service-retirement.d.ts +11 -0
- package/dist/rooms-tasks/task-service-retirement.js +21 -0
- package/dist/rooms-tasks/task-state.d.ts +43 -5
- package/dist/rooms-tasks/task-state.js +244 -22
- package/dist/rooms-tasks/types.d.ts +35 -0
- package/dist/rooms-tasks/workspace-artifacts.d.ts +6 -0
- package/dist/rooms-tasks/workspace-artifacts.js +93 -0
- package/dist/rooms-tasks/workspace.d.ts +35 -0
- package/dist/rooms-tasks/workspace.js +325 -0
- package/dist/runner.d.ts +33 -4
- package/dist/runner.js +410 -62
- package/dist/session/acp.d.ts +75 -2
- package/dist/session/acp.js +345 -82
- package/dist/session/arbiter.d.ts +98 -0
- package/dist/session/arbiter.js +272 -3
- package/dist/session/codex-app-server.d.ts +45 -1
- package/dist/session/codex-app-server.js +225 -32
- package/dist/session/control.d.ts +17 -3
- package/dist/session/control.js +219 -23
- package/dist/session/conversation-normalizer.d.ts +2 -1
- package/dist/session/conversation-normalizer.js +1 -1
- package/dist/session/conversation-observation.d.ts +25 -0
- package/dist/session/conversation-observation.js +100 -0
- package/dist/session/conversation-replay.d.ts +50 -0
- package/dist/session/conversation-replay.js +203 -0
- package/dist/session/conversation-store.d.ts +15 -1
- package/dist/session/conversation-store.js +213 -26
- package/dist/session/conversation-types.d.ts +57 -4
- package/dist/session/prompt-batch.d.ts +79 -0
- package/dist/session/prompt-batch.js +120 -0
- package/dist/session/task-notice.d.ts +14 -0
- package/dist/session/task-notice.js +13 -0
- package/dist/session/types.d.ts +42 -1
- package/dist/setup-tunnel-preflight.d.ts +34 -0
- package/dist/setup-tunnel-preflight.js +62 -0
- package/dist/socket-path.d.ts +2 -0
- package/dist/socket-path.js +22 -0
- package/dist/spawn.d.ts +5 -1
- package/dist/spawn.js +40 -4
- package/dist/startup-prompt.d.ts +15 -0
- package/dist/startup-prompt.js +71 -0
- package/dist/startup-readiness.d.ts +32 -0
- package/dist/startup-readiness.js +101 -0
- package/dist/startup-telemetry.d.ts +16 -0
- package/dist/startup-telemetry.js +46 -0
- package/dist/subscriptions/cli.d.ts +91 -0
- package/dist/subscriptions/cli.js +223 -0
- package/dist/subscriptions/launch.d.ts +37 -0
- package/dist/subscriptions/launch.js +93 -0
- package/dist/subscriptions/login.d.ts +77 -0
- package/dist/subscriptions/login.js +215 -0
- package/dist/subscriptions/observed.d.ts +7 -0
- package/dist/subscriptions/observed.js +44 -0
- package/dist/subscriptions/probe.d.ts +10 -0
- package/dist/subscriptions/probe.js +73 -0
- package/dist/subscriptions/service.d.ts +102 -0
- package/dist/subscriptions/service.js +364 -0
- package/dist/subscriptions/store.d.ts +71 -0
- package/dist/subscriptions/store.js +143 -0
- package/dist/supervisor/adoption.d.ts +8 -0
- package/dist/supervisor/adoption.js +78 -0
- package/dist/supervisor/catalog.d.ts +62 -0
- package/dist/supervisor/catalog.js +254 -0
- package/dist/supervisor/fleet.d.ts +8 -0
- package/dist/supervisor/fleet.js +89 -0
- package/dist/supervisor/index.js +3 -6
- package/dist/supervisor/launchd.d.ts +1 -1
- package/dist/supervisor/launchd.js +26 -13
- package/dist/supervisor/legacy.d.ts +35 -0
- package/dist/supervisor/legacy.js +524 -0
- package/dist/supervisor/manager.d.ts +15 -0
- package/dist/supervisor/manager.js +270 -0
- package/dist/supervisor/registration-refresh.d.ts +45 -0
- package/dist/supervisor/registration-refresh.js +266 -0
- package/dist/supervisor/scope.d.ts +4 -0
- package/dist/supervisor/scope.js +10 -0
- package/dist/supervisor/systemd.d.ts +2 -2
- package/dist/supervisor/systemd.js +19 -33
- package/dist/task-supervision.d.ts +9 -0
- package/dist/task-supervision.js +145 -0
- package/dist/temp-idle.d.ts +17 -0
- package/dist/temp-idle.js +42 -0
- package/dist/temp-lifecycle.d.ts +23 -8
- package/dist/temp-lifecycle.js +123 -66
- package/dist/temp-supervisor-recovery.d.ts +1 -1
- package/dist/temp-supervisor-recovery.js +2 -2
- package/dist/tunnel-setup-completion.d.ts +7 -0
- package/dist/tunnel-setup-completion.js +13 -0
- package/dist/tunnel-setup-input.d.ts +19 -0
- package/dist/tunnel-setup-input.js +130 -0
- package/dist/watchdog/query.d.ts +3 -1
- package/dist/watchdog/query.js +2 -1
- package/dist/web/agent-attachments.d.ts +29 -0
- package/dist/web/agent-attachments.js +162 -0
- package/dist/web/auth.d.ts +65 -2
- package/dist/web/auth.js +201 -11
- package/dist/web/available-port.d.ts +2 -0
- package/dist/web/available-port.js +23 -0
- package/dist/web/control.d.ts +3 -3
- package/dist/web/control.js +10 -8
- package/dist/web/conversation-stream-codec.d.ts +23 -0
- package/dist/web/conversation-stream-codec.js +110 -0
- package/dist/web/conversation-stream.d.ts +26 -0
- package/dist/web/conversation-stream.js +239 -0
- package/dist/web/events.d.ts +2 -0
- package/dist/web/events.js +9 -0
- package/dist/web/fleet-config-service.d.ts +7 -1
- package/dist/web/fleet-config-service.js +61 -16
- package/dist/web/prefix-gateway.d.ts +32 -0
- package/dist/web/prefix-gateway.js +248 -0
- package/dist/web/resource-views.d.ts +135 -0
- package/dist/web/resource-views.js +486 -0
- package/dist/web/runtime.d.ts +3 -1
- package/dist/web/runtime.js +132 -34
- package/dist/web/server.d.ts +19 -0
- package/dist/web/server.js +821 -68
- package/dist/web/service.d.ts +11 -2
- package/dist/web/service.js +30 -4
- package/dist/web/workspace-devices.d.ts +107 -0
- package/dist/web/workspace-devices.js +277 -0
- package/dist/web/workspace-tunnel.d.ts +1 -0
- package/dist/web/workspace-tunnel.js +34 -0
- package/dist/workspace-enrollment.d.ts +83 -0
- package/dist/workspace-enrollment.js +605 -0
- package/dist/workspace-replacement.d.ts +66 -0
- package/dist/workspace-replacement.js +238 -0
- package/docs/acp-files.md +146 -0
- package/docs/conversation-stream.md +216 -0
- package/docs/fleet-migration.md +54 -0
- package/docs/live-voice.md +13 -0
- package/docs/room-layouts.md +227 -0
- package/docs/self-reminders.md +374 -0
- package/docs/task-workspaces.md +225 -0
- package/docs/validation/managed-cli-permissions.md +421 -0
- package/examples/room-layouts/fresh.yaml +27 -0
- package/examples/room-layouts/scoped.yaml +21 -0
- package/examples/room-layouts/shared.yaml +19 -0
- package/package.json +24 -20
- package/presets/README.md +78 -0
- package/presets/brain-catalog.json +8 -2
- package/presets/fleet/agent_templates/Critic.yaml +1 -1
- package/presets/fleet/agent_templates/Developer.yaml +1 -1
- package/presets/fleet/agent_templates/Engineer.yaml +5 -0
- package/presets/fleet/agent_templates/LocalCoordinator.yaml +4 -2
- package/presets/fleet/agents/FleetCoordinator.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-1-high.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-low.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-max.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-medium.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-xhigh.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-high.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-low.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-max.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-medium.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/claude-haiku-4-5-20251001-default.yaml +4 -0
- package/presets/fleet/brains/claude-opus-5-5-high.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-low.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-max.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-medium.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-xhigh.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-high.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-low.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-max.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-medium.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-high.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-low.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-max.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-medium.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-ultra.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-ultra.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-1-sol-high.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-low.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-max.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-medium.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-ultra.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-xhigh.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-astra-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-ultra.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-luna-high.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-low.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-max.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-medium.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-xhigh.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-high.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-low.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-max.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-medium.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-ultra.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-xhigh.yaml +5 -0
- package/presets/fleet/roles/Coordinator.yaml +12 -11
- package/presets/fleet/roles/Critic.yaml +13 -0
- package/presets/fleet/roles/Developer.yaml +13 -0
- package/presets/fleet/roles/Engineer.yaml +53 -0
- package/presets/fleet/room_layouts/engineering.yaml +25 -0
- package/presets/fleet/room_layouts/pair.yaml +24 -0
- package/presets/fleet/room_layouts/single.yaml +17 -0
- package/presets/fleet/room_layouts/team.yaml +30 -0
- package/presets/fleet/room_templates/engineering.yaml +19 -0
- package/presets/manifest.json +2 -2
- package/dist/web-app/assets/index-59GF-gsZ.css +0 -1
- package/dist/web-app/assets/index-C0h3ALvs.js +0 -10
- package/dist/web-app/icons/ours-fleet-maskable.svg +0 -4
- package/dist/web-app/icons/ours-fleet.svg +0 -4
- package/dist/web-app/index.html +0 -17
- package/dist/web-app/manifest.webmanifest +0 -15
- package/dist/web-app/offline.html +0 -18
- 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.
|