@ctlflow/fleet 0.0.0-stage → 0.1.1

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/docs/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # Fleet guides
2
+
3
+ - [Install and enroll a fleet](getting-started.md)
4
+ - [Directory structure, TOML schemas and runtime options](configuration.md)
5
+ - [Commands, operation outcomes and lifecycle](commands.md)
6
+ - [Stop, full-history resume and confirmed fresh-history controls](sessions.md)
7
+ - [SSH controllers and terminal attachment](remote.md)
8
+ - [Updates, backups, portability and troubleshooting](operations.md)
9
+ - [fleetd lifecycle and private API](https://github.com/control-flow-project/crossfire/blob/main/services/fleetd/docs/README.md)
10
+ - [Crossfire rooms, approvals and wake authority](https://github.com/control-flow-project/crossfire/blob/main/services/crossfire/docs/management.md)
11
+ - [Canonical contracts and acceptance requirements](https://github.com/control-flow-project/crossfire/blob/main/docs/specification.md)
@@ -0,0 +1,136 @@
1
+ # Fleet commands
2
+
3
+ ## Controller selection
4
+
5
+ ```sh
6
+ fleet setup --descriptor PERSONALIZED_SETUP_JSON_URL
7
+ fleet setup --descriptor PERSONALIZED_SETUP_JSON_URL --config /absolute/private/research/runtime.toml
8
+ fleet daemon start --name laptop --root /absolute/private/controller
9
+ fleet daemon status
10
+ fleet daemon stop
11
+ fleet daemon restart
12
+ fleet --root /absolute/private/controller list
13
+ fleet remote add office --ssh operator@office-host --root /absolute/private/controller
14
+ fleet --remote office list
15
+ ```
16
+
17
+ The local root/remote connection is private CLI state. Labels are not credentials.
18
+ Remote commands use SSH and the same private controller API.
19
+
20
+ ## Fleet and agent lifecycle
21
+
22
+ ```sh
23
+ fleet add /absolute/private/research
24
+ fleet list
25
+ fleet show research
26
+ fleet test research
27
+ fleet start research
28
+ fleet start research --fresh-history
29
+ fleet agent list research
30
+ fleet agent add research analyst-west --definition analyst
31
+ fleet agent start research analyst-west
32
+ fleet agent start research analyst-west --fresh-history
33
+ fleet agent attach research analyst-west
34
+ fleet agent contexts research analyst-west
35
+ fleet agent attach research analyst-west --context '!ORIGINAL_ROOM_ID:YOUR_SERVER'
36
+ fleet agent stop research analyst-west
37
+ fleet agent remove research analyst-west
38
+ fleet stop research
39
+ fleet remove research
40
+ ```
41
+
42
+ Add registers an explicit directory or instance. New identities need owner
43
+ approval. Start automatically resumes the full saved native histories. Missing
44
+ or broken established history is an error, not permission to create a new one.
45
+ Local start starts or reuses the configured controller. Status/list/show/test,
46
+ contexts, attachment and registry edits never start it. Stop ends addressed
47
+ listeners and owned Codex processes. Instance removal retires its fleet registration;
48
+ whole-fleet removal archives the approved registration. Actual stopped native
49
+ evidence and settled decisions are required. Files, history, identity and audit
50
+ records are preserved; removal never creates an independent agent. Closing the
51
+ CLI does not cancel accepted controller work.
52
+
53
+ Operation results distinguish pending approval, success and per-instance failure.
54
+ Idempotency keys and expected revisions prevent conflicting replays.
55
+ Fleet-wide and per-agent start and stop commands accept `--operation-id UUID` for an
56
+ exact retry after uncertain submission; the command prints its ID before submission.
57
+ Name collisions, missing credentials and invalid native settings stay errors.
58
+
59
+ Contexts lists exact saved histories even when stopped or sleeping, without
60
+ starting native processes. `fleet show` reports native phase, desired activation,
61
+ last activity and history availability. Explicit `fleet agent start` wakes a
62
+ sleeping native engine without input or binding replacement. Attach
63
+ without a context selects the shared history, or private control history in
64
+ per-room mode. `--context` chooses an existing listed context; it never creates
65
+ a new room conversation or reads credentials into public management output.
66
+
67
+ `start --fresh-history` explicitly selects the controller's reset operation, for
68
+ one agent or the whole fleet. It stops selected owned processes, verifies complete
69
+ available authorized history and nonsecret configuration exports, then starts fresh
70
+ native contexts with the same identities and current definition parameters.
71
+ It is not normal resumption. Use `--operation-id UUID` with the identical command
72
+ to retry an uncertain request. The independent coding session doing setup is
73
+ never controlled here.
74
+ - [Session controls, full-history resume and fresh-history confirmation](sessions.md)
75
+ - [Export, boundaries and reset retention](https://github.com/control-flow-project/crossfire/blob/main/services/crossfire/docs/history.md)
76
+
77
+ ## Delivery control and broadcast
78
+
79
+ ```sh
80
+ fleet deactivate research
81
+ fleet activate research
82
+ fleet message research --text "Review the updated assignment"
83
+ fleet message research --message-id YOUR_UUID --text "Review the updated assignment"
84
+ ```
85
+
86
+ Deactivate pauses fleet-bound delivery but retains controller connections,
87
+ engines and sessions. Activate resumes those bindings and unread positions.
88
+ Crossfire UI provides equivalent revision-checked control. Connection loss pauses
89
+ delivery; reconnect applies current server intent. Every receiver is fleet-bound.
90
+
91
+ Message queues explicit input per enrolled agent through the controller. It
92
+ does not join rooms, alter wake rules or revive explicitly stopped agents.
93
+ A sleeping active binding resumes its exact native history for eligible input.
94
+ The CLI prints
95
+ a message UUID before submission. Retry uncertain submission with the same UUID
96
+ and identical text; conflicting reuse fails. The fleet must be enabled and
97
+ controller connected; messages expire after ten minutes.
98
+
99
+ Management exposes delivered/pending/skipped/failed/expired outcomes. A native
100
+ receipt proves publication, not completed model work.
101
+
102
+ ## Model-free readiness
103
+
104
+ `fleet test research` reads each desired receiver through the actual shared
105
+ listener control endpoint. It checks exact native identity, authentication,
106
+ membership, idle availability and enabled delivery. It creates no model turn,
107
+ conversation or unread-position update. Busy, paused, unavailable and stopped
108
+ bindings fail explicitly; a sleeping receiver can pass without waking Codex.
109
+
110
+ ## Explicit software update
111
+
112
+ After human consent and installing the exact new public release, use that newly
113
+ installed executable:
114
+
115
+ ```sh
116
+ fleet update research
117
+ fleet agent update research analyst-east
118
+ fleet daemon restart
119
+ ```
120
+
121
+ Update sends the installed controller's declared immutable artifact directory to
122
+ fleetd. The lifecycle operation stops selected receivers/native processes,
123
+ installs pinned agent tools/skills and resumes only previously desired agents
124
+ with their exact histories. Stopped agents stay stopped. It never re-enrolls or
125
+ uses a standalone connection command. Review every per-instance outcome.
126
+ Restart replaces the controller binary after update and retains desired intent.
127
+
128
+ For an SSH controller, the source directory must exist on that computer:
129
+
130
+ ```sh
131
+ fleet --remote office update research --release-directory /absolute/private/installed/node_modules/@ctlflow/fleetd/dist/assets
132
+ ```
133
+
134
+ The controller validates that exact directory and release before replacement.
135
+ Alternatively invoke the newly installed CLI directly over SSH. `daemon restart`
136
+ runs locally on the controller computer, not through the remote CLI tunnel.
@@ -0,0 +1,239 @@
1
+ # Fleet configuration
2
+
3
+ ## Files and ownership
4
+
5
+ ```text
6
+ research/
7
+ runtime.toml
8
+ rooms.toml
9
+ agents/
10
+ analyst/
11
+ agent.toml
12
+ AGENTS.md
13
+ workarea/
14
+ analyst-east/
15
+ analyst-west/
16
+ ```
17
+
18
+ A definition owns native settings/instructions. Instances share a definition,
19
+ not mutable sessions or work areas. Different native settings require different
20
+ definitions; listener history settings belong to each roster instance.
21
+ The fleet's private `.fleet` state holds bindings, desired enrollment and reset
22
+ evidence. Each instance's private workarea holds `.codex` native provider/history
23
+ and `.crossfire` delivery/tool state. Never commit private state.
24
+
25
+ ## runtime.toml
26
+
27
+ ```toml
28
+ fleet = "research"
29
+
30
+ [coordination]
31
+ adapter = "crossfire"
32
+ server = "https://YOUR_SERVER"
33
+ owner = "@YOUR_ACCOUNT:YOUR_SERVER"
34
+
35
+ [[instances]]
36
+ key = "analyst-east"
37
+ name = "analyst-east"
38
+ definition = "analyst"
39
+ workarea = "agents/analyst/workarea/analyst-east"
40
+
41
+ [instances.listener_options]
42
+ history_mode = "shared"
43
+
44
+ [[instances]]
45
+ key = "analyst-west"
46
+ name = "analyst-west"
47
+ definition = "analyst"
48
+ workarea = "agents/analyst/workarea/analyst-west"
49
+
50
+ [instances.listener_options]
51
+ history_mode = "per-room"
52
+ ```
53
+
54
+ Keys/names start with a lowercase letter, contain lowercase letters, digits or
55
+ hyphens, and are at most 40 characters. Instance names, keys and work areas must
56
+ be distinct. Work areas are non-overlapping relative children of
57
+ `agents/<definition>/workarea/`; symlinked or unsafe private paths fail.
58
+
59
+ Optional `workspace = "/absolute/project"` on an instance changes only the native
60
+ cwd. It defaults to that instance's private workarea. It must be canonical, owned
61
+ and not writable by other users; existing project modes are not tightened.
62
+ Private state remains in the workarea, passed separately to the native adapter as
63
+ `stateDirectory`. The adapter's private native home retains the managed histories
64
+ and intended provider configuration/authentication, without overwriting or
65
+ importing the project's `.codex/config.toml`, history or coding session. Role
66
+ instructions, administrator setup instructions and the pinned Crossfire skill
67
+ are delivered via native developer instructions on both create and resume;
68
+ external cwd does not rely on private workarea ancestor skill discovery.
69
+
70
+ Default project setup generates this same roster with one `project` definition,
71
+ the chosen project as `workspace` and a stable private workarea. Definitions
72
+ without `workspace` keep their original private cwd; this is one configuration
73
+ model, not another deployment mode.
74
+
75
+ The coordination block supplies server/owner once. It contains no approval room,
76
+ runtime transport, session UUID or secret. The private owner DM opens automatically
77
+ on first owner contact, terminal output or native decision, not at fleet startup.
78
+
79
+ ### Listener options
80
+
81
+ | Field | Accepted values | When omitted |
82
+ | --- | --- | --- |
83
+ | `history_mode` | `shared`, `per-room` | `shared` |
84
+
85
+ Crossfire instance policy owns the incoming inline-message threshold, default
86
+ 65536 UTF-8 bytes, including origin and verified sender metadata. It applies to
87
+ every agent and is not a roster override. Larger messages/batches use complete
88
+ private files and a compact manifest pointer. Ordinary native tool/file output
89
+ uses separate protocol and owner-output resource bounds.
90
+ - [Message files, catch-up and reset](https://github.com/control-flow-project/crossfire/blob/main/services/crossfire/docs/history.md)
91
+
92
+ Shared history preserves context across all rooms, DMs and private operator
93
+ input. Per-room history retains one exact native conversation per room ID and a
94
+ separate private control history for fleet messages, schedules and maintenance.
95
+ It is the same process, workarea and identity. Returning to a room resumes its
96
+ history, not an empty conversation. Files/tools/credentials remain shared;
97
+ terminal output still goes privately to the owner. This is not a security sandbox.
98
+
99
+ Listener changes apply on stopped-to-running transition. A pending publication
100
+ must finish receipt recovery before its history configuration changes.
101
+ History-mode changes preserve old sessions/cursors without copying, merging,
102
+ forking or replaying them. Pending native decisions also prevent a mode switch.
103
+
104
+ ## agent.toml
105
+
106
+ ```toml
107
+ name = "Research analyst"
108
+ runtime = "codex"
109
+
110
+ [runtime_options]
111
+ model = "YOUR_SUPPORTED_MODEL"
112
+ model_reasoning_effort = "high"
113
+ sandbox_mode = "danger-full-access"
114
+ approval_policy = "on-request"
115
+
116
+ [coordination_options]
117
+ wake_mode = "owner-agents"
118
+ permissions = ["room.agent.invite"]
119
+ ```
120
+
121
+ The roster's optional workspace, or private workarea by default, supplies native
122
+ cwd. The companion `AGENTS.md` supplies
123
+ role instructions. The functional Codex adapter alone validates/translates native
124
+ options; fleetd does not interpret Codex-specific settings.
125
+
126
+ The role's separate `coordination_options` declares Crossfire wake authority and
127
+ invitation defaults for every instance. Owner approval applies the exact policy
128
+ to current ordinary grants and future admissions without another setup step.
129
+ Omitting the whole block requests owner-only wake and no invitation delegation.
130
+ Changed policies require owner review on stop/start; unchanged restarts preserve
131
+ manual room-specific edits. Configuration grants no room membership or native power.
132
+ - [Fields, selected identities, approval and removal rules](https://github.com/control-flow-project/crossfire/blob/main/services/fleetd/docs/coordination.md)
133
+
134
+ | Field | Accepted values | When omitted |
135
+ | --- | --- | --- |
136
+ | `model` | Nonempty native model ID, up to 200 characters | Native provider/config selection |
137
+ | `model_reasoning_effort` | `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, `ultra` | Native config selection |
138
+ | `sandbox_mode` | `read-only`, `workspace-write`, `danger-full-access` | `danger-full-access` |
139
+ | `approval_policy` | `untrusted`, `on-failure`, `on-request`, `never` | `on-request` |
140
+ | `dangerously_bypass_approvals_and_sandbox` | Boolean | Disabled |
141
+ | `features.default_mode_request_user_input` | Boolean in `[runtime_options.features]` | Native default (off in verified Codex 0.160.0) |
142
+
143
+ The selected model/provider must support the chosen effort and native policy.
144
+ Unknown keys, wrong types, unavailable models and refused settings fail; they are
145
+ not silently ignored. Native effective settings are checked after create/resume.
146
+ `max` is passed unchanged to Codex; it is not an alias for `xhigh` or `ultra`.
147
+ Check the selected native model catalog before choosing it. `ultra` can enable
148
+ native automatic delegation and is not selected by requesting `max`.
149
+
150
+ Full access is unsandboxed execution with the controller user's filesystem and
151
+ network privileges, not root access. It does not imply automatic approval:
152
+ `on-request` still routes native permission review links to the owner's private DM.
153
+ Restricted sandbox choices remain available. Native restricted-policy defects
154
+ are not repaired by changing one utility or weakening project privacy checks.
155
+
156
+ ### Native bypass option
157
+
158
+ This uses Codex's native flag name, expressed as a TOML key:
159
+ ```toml
160
+ [runtime_options]
161
+ model = "YOUR_SUPPORTED_MODEL"
162
+ model_reasoning_effort = "high"
163
+ dangerously_bypass_approvals_and_sandbox = true
164
+ ```
165
+
166
+ It selects `sandbox_mode = "danger-full-access"` and
167
+ `approval_policy = "never"`, equivalent to
168
+ `--dangerously-bypass-approvals-and-sandbox`. The app-server CLI does not accept
169
+ that TUI flag; the adapter supplies the corresponding native thread settings.
170
+ Conflicting explicit sandbox/approval values fail. Compatible explicit values
171
+ are allowed. `false` leaves ordinary values/defaults in effect. There is no
172
+ `yolo` configuration alias. Use only when this unsandboxed, no-confirmation
173
+ execution is intended.
174
+
175
+ ### Structured questions
176
+
177
+ To offer native human questions in Codex Default mode:
178
+ ```toml
179
+ [runtime_options.features]
180
+ default_mode_request_user_input = true
181
+ ```
182
+
183
+ This is an explicit native under-development feature, not global configuration
184
+ or terminal prose interception. Enabling it requires the selected native binary
185
+ to expose `default_mode_request_user_input` in `codex features list`. Startup
186
+ checks the capability before spawning an engine, in addition to the baseline
187
+ stock Codex 0.158.0+ requirement. Missing capabilities fail explicitly, never
188
+ silently disable the option. All native questions
189
+ in one request retain their identities, option/free/secret-answer flags and
190
+ deadline. The owner receives Crossfire links and explicitly submits the complete
191
+ answer; clicking a link never grants permission. Native Default-mode questions
192
+ may be nonblocking and expire. Linux/inert-provider proofs do not certify a
193
+ particular paid model or macOS. Unsupported interactive stdin is not emulated.
194
+ - [Human decisions and disclosure boundaries](https://github.com/control-flow-project/crossfire/blob/main/services/crossfire/docs/runtime.md)
195
+
196
+ ### Apply changes
197
+
198
+ Stop and start the affected agent:
199
+ ```sh
200
+ fleet agent stop research analyst-east
201
+ fleet agent start research analyst-east
202
+ ```
203
+
204
+ Or stop/start the fleet. Current definition model, reasoning, sandbox and approval
205
+ settings apply to the original saved history/histories; identity/cursors remain intact.
206
+ Editing a running definition does not hot-reconfigure an engine.
207
+ Do not append native permission flags to a remote TUI resume command.
208
+
209
+ ## rooms.toml
210
+
211
+ Rooms must already exist in Matrix. This file is a reviewed management plan, not
212
+ an implicit startup action or room creator:
213
+ ```toml
214
+ fleet = "research"
215
+
216
+ [[agents]]
217
+ instance = "analyst-east"
218
+
219
+ [[agents.grants]]
220
+ room = "!EXISTING_STABLE_ROOM_ID:YOUR_SERVER"
221
+ access = "reply"
222
+ muted = false
223
+ ```
224
+
225
+ Open the fleet Room plan tab, submit the plan, review its diff and explicitly
226
+ confirm. Native authority, owner ceiling and revisions are checked at application.
227
+ Read-only, reply and custom-power grants remain separate from wake selection.
228
+ Custom access uses `access = "custom"` with an integer `level`. Invitation
229
+ defaults come from owner-approved `agent.toml` coordination settings; management
230
+ can adjust a room's applied permission set. Neither belongs in `rooms.toml`.
231
+ Empty grants remove discretionary access for included instances; the built-in
232
+ owner DM is preserved. Omitted instances are untouched. Owner DM access and
233
+ delegation cannot be edited through this plan.
234
+
235
+ Invitation permission allows an agent to invite registered agents across owners
236
+ and remove admissions it introduced, subject to Matrix authority. Membership
237
+ alone does not wake all agents. Assign the smallest room set and wake authority
238
+ needed; remove specialists when their work ends.
239
+ - [Permissions and wake rules](https://github.com/control-flow-project/crossfire/blob/main/services/crossfire/docs/management.md)
@@ -0,0 +1,111 @@
1
+ # Set up a managed agent or fleet
2
+
3
+ ## Requirements
4
+
5
+ The controller supports native Linux and macOS ownership primitives. Requires
6
+ Node.js 26+, npm 11.17+, Git and stock Codex 0.158.0+ with its native provider
7
+ authentication. Runtime checks validate the executable, requested capabilities
8
+ and provider configuration before enrollment or managed native startup. Linux
9
+ inert-provider proofs do not certify macOS hardware or paid-model behavior.
10
+ Remote management uses existing OpenSSH authentication.
11
+
12
+ Install missing software using its official instructions and the human's normal
13
+ permission policy. Never request Matrix passwords, administrator credentials,
14
+ ports or session IDs. Do not silently use sudo or change host services/global
15
+ skills. The CLI contains no installer hooks that start agents.
16
+
17
+ ## Personalized project setup
18
+
19
+ Open Connect in the Crossfire management UI. Paste its minimal personalized guide
20
+ URL into the existing coding session. The guide explains the system, verifies
21
+ the actual human owner and supplies the exact npm version. Follow its private
22
+ user-prefix install command, then run its installed `fleet` executable from the
23
+ chosen project directory:
24
+
25
+ ```sh
26
+ fleet setup --descriptor 'https://YOUR_SERVER/onboarding/setup.json?ownerMatrixId=ENCODED_OWNER_MATRIX_ID'
27
+ ```
28
+
29
+ No configuration or name questions are asked. Setup verifies the installed exact
30
+ package against the descriptor, starts or reuses the private controller, creates
31
+ one ordinary fleet definition and persists project-derived names. The existing
32
+ coding session stays independent. A new fleet-managed conversation uses the
33
+ project as native cwd and a separate private per-instance workarea for credentials,
34
+ native history and delivery state. Existing project modes, `.codex/config.toml`
35
+ and native histories are not modified or imported.
36
+
37
+ Controller state defaults to `$HOME/.ctlflow/controller`. Project definitions
38
+ live below its private `projects/` directory. Private connection/setup profiles
39
+ live below `$XDG_CONFIG_HOME/fleet`, or `$HOME/.config/fleet` when unset.
40
+ `--root /absolute/private/controller` selects a different private root on first
41
+ setup. Persisted authority cannot be silently replaced by another server, owner,
42
+ workspace, configuration or root. Repeating `fleet setup` from that project uses
43
+ the saved descriptor and stable configuration.
44
+
45
+ ## Optional explicit configuration
46
+
47
+ Role fleets use the same lifecycle and listener architecture. Supply an existing
48
+ validated configuration with its exact server/owner from the personalized guide:
49
+
50
+ ```sh
51
+ fleet setup --descriptor 'https://YOUR_SERVER/onboarding/setup.json?ownerMatrixId=ENCODED_OWNER_MATRIX_ID' --config /absolute/private/research/runtime.toml
52
+ ```
53
+
54
+ `--config` alone derives the structured descriptor URL from its validated
55
+ coordination fields; no text guessing occurs. Normal role fleets default native
56
+ cwd to their private workarea. Optional instance `workspace` overrides only cwd,
57
+ not private state. Explicit names retain exact validation; only generated default
58
+ names are normalized. There is no filesystem fleet discovery or current-session
59
+ adoption.
60
+ - [Directory and configuration examples](configuration.md)
61
+
62
+ ## Approval and ready state
63
+
64
+ The initial setup prints one roster approval URL/code and waits. The owner reviews
65
+ the exact names, wake authors and invitation defaults and approves once in Crossfire.
66
+ Declared settings apply automatically; no subsequent permission setup is required.
67
+ Name collisions are rejected;
68
+ a partial outcome does not invent replacement names or identities.
69
+
70
+ Show the exact approval URL and code immediately while the command continues
71
+ waiting. Do not model-poll, re-enroll or start another receiver. Interrupting the
72
+ CLI does not cancel an accepted controller operation. Repeating setup observes
73
+ the same pending operation; a failed incomplete setup can retry without changing
74
+ its fleet identity.
75
+
76
+ Enrollment, installation, native startup, diagnostics and heartbeats use ordinary
77
+ code, not model turns. Setup checks the actual shared listener's authentication,
78
+ exact native session, room access and delivery readiness. Busy or paused bindings
79
+ are reported as not ready, not hidden by process-only success. A sleeping binding
80
+ can be ready without starting its native process. The protected owner DM opens on first use,
81
+ not at startup. Other room membership remains explicit; invitation defaults apply
82
+ when an authorized ordinary-room admission occurs.
83
+
84
+ Read-only follow-up:
85
+
86
+ ```sh
87
+ fleet daemon status
88
+ fleet show RETURNED_FLEET_KEY
89
+ fleet test RETURNED_FLEET_KEY
90
+ ```
91
+
92
+ Repeat setup never silently upgrades tools or activates previously stopped agents.
93
+ To resume or deliberately apply a configuration edit:
94
+ ```sh
95
+ fleet stop research
96
+ fleet start research
97
+ fleet show research
98
+ ```
99
+
100
+ Normal start resumes saved histories. Missing credentials/history or a failed
101
+ native resume is an error, not permission to create a replacement identity.
102
+ Only an explicit `--fresh-history` requests fresh context.
103
+
104
+ ## Distribution
105
+
106
+ Only `@ctlflow/fleet` and `@ctlflow/fleetd` are public. The CLI depends on the exact
107
+ matching controller version. Both are self-contained bundles; no private registry
108
+ package or monorepo source path is needed. The durable private installation prefix,
109
+ not an ephemeral `npx` cache, supplies future controller launches. Reuse that
110
+ installed executable or add its bin directory to PATH explicitly; setup edits no
111
+ shell rc or global npm state.
@@ -0,0 +1,85 @@
1
+ # Fleet operations
2
+
3
+ ## Update and deploy
4
+
5
+ Use an exact verified public package release after human consent. Before changing
6
+ production state, back up and verify the private controller root, fleet directory
7
+ and provider state. Preserve private modes; keep credentials out of logs/source.
8
+
9
+ Install the new matching `@ctlflow/fleet`/`@ctlflow/fleetd` release into the private
10
+ durable user prefix. Merely installing a package does not replace live code.
11
+ Using that new installed executable, run `fleet update FLEET` for each addressed
12
+ fleet, or `fleet agent update FLEET INSTANCE`. The canonical lifecycle operation
13
+ stops selected receivers/native processes, validates and installs the package's
14
+ pinned local tools/skill assets, then resumes only previously desired agents.
15
+ Stopped agents stay stopped. Exact identities, histories and unread positions are
16
+ retained. Failures are per-instance, without discarding successful peers.
17
+
18
+ Then `fleet daemon restart` replaces the controller binary at the same private
19
+ root, preserving desired activation and exact histories. Do not reverse this
20
+ order and resume with old skills before update. Native approval requests use the
21
+ protected owner DM. Check `fleet show FLEET`, `fleet test FLEET` and effective
22
+ settings, not just controller connectivity. No room grants are needed for a
23
+ model-free readiness check.
24
+
25
+ Running releases are never silently replaced. Update notices ask for owner
26
+ consent and direct the model to the controller-owned command; no standalone
27
+ agent connect, second installer or competing receiver exists. The advanced
28
+ `--release-directory` addresses an actual immutable installed artifact directory
29
+ on the controller computer, including SSH targets; it is validated before use.
30
+
31
+ ## Backup and portability
32
+
33
+ A stopped fleet directory contains its definitions, private Crossfire binding,
34
+ work areas, sessions and receipts. Preserve private modes, credentials and native
35
+ provider configuration when transferring it. The target requires the same runtime
36
+ and provider prerequisites. Register its new absolute directory explicitly.
37
+ Preserve the private controller root, including `desired-intent.json`, when
38
+ restarting on the same machine. Daemon shutdown retains active intent; explicit
39
+ fleet/agent stop clears it. The controller registry is machine-local; the fleet's private state is not a
40
+ public lookup or identity-recovery credential substitute.
41
+
42
+ Never run two controllers against the same active private fleet state. Exclusive
43
+ native locks own controller, fleet and receiver lifetimes; timeout guessing is
44
+ not ownership. Do not remove state to bypass a lock or failed resume.
45
+
46
+ ## Troubleshooting
47
+
48
+ | Symptom | Action |
49
+ | --- | --- |
50
+ | Pending approval | Review the roster URL/code; do not enroll again or poll with a model. |
51
+ | Name collision | Choose an authorized distinct name before creating the instance. |
52
+ | Runtime unavailable | Inspect the exact controller error and executable/provider prerequisites. |
53
+ | Native history has an active writer after controller death | Safely stop the verified orphaned Codex app-server on its owning machine; retain private state and history. Never delete locks or guess processes. |
54
+ | Native state sleeping | The listener can still be online. Eligible input resumes retained history; metadata GETs never wake it. |
55
+ | Permission/question waits | Open its owner-DM Crossfire review link and explicitly submit the complete native decision. |
56
+ | Listener offline | Check controller connection, agent phase, native binding and account access. |
57
+ | Room messages do not wake | Check grants, native membership, wake sources and fleet delivery intent. |
58
+ | Config change not applied | Stop/start the affected instance; inspect effective native settings. |
59
+ | Terminal pointer expired | Obtain a fresh attachment after restart. |
60
+ | One failed agent | Inspect its original error; do not restart successful peers unnecessarily. |
61
+ | Shared/per-room switch refused | Recover original pending publications/decisions; do not discard journals or copy histories. |
62
+ | Room reply absent despite work | Inspect the exact room context and owner DM; terminal output is private, room replies require an intentional tool call. |
63
+
64
+ Session in management shows native state/settings and decisions independently of
65
+ heartbeats. One private Crossfire management DM per member reports confirmed
66
+ failures or unknown lost contact, deduplicated by episode with recovery updates.
67
+ Controller failures persist in `.fleet/failures.json` until the scoped report is
68
+ accepted. A reporting failure is visible in controller status; it does not
69
+ silently discard the original failure. The controller closes the exact failed
70
+ generation and retries transient failures with one-to-sixty-second exponential
71
+ backoff, preserving deployed parameters, installed software, identity and native
72
+ history. Explicit stop cancels recovery. Permanent configuration/authorization
73
+ errors and failed cleanup require operator action. Uncertain publications remain
74
+ receipt-safe; recovery never silently replaces context or upgrades software.
75
+ - [Runtime observation, privacy and decisions](https://github.com/control-flow-project/crossfire/blob/main/services/crossfire/docs/runtime.md)
76
+
77
+ Normal stop ends owned listeners and Codex engines. Abruptly killing fleetd can
78
+ leave the native WebSocket app-server alive; a competing history writer is
79
+ refused rather than adopted or replaced. This is not automatic crash recovery.
80
+ A full machine restart ends the native engine and allows ordinary saved-history
81
+ restoration. The product also does not supervise every detached tool descendant
82
+ after force-kill/crash. It installs no systemd,
83
+ global skills, privileged supervisor or host service.
84
+
85
+ - [Abrupt controller death and native writer ownership](https://github.com/control-flow-project/crossfire/blob/main/services/fleetd/docs/operations.md#abrupt-controller-death)
package/docs/remote.md ADDED
@@ -0,0 +1,46 @@
1
+ # Remote controllers and agent terminals
2
+
3
+ ## SSH management
4
+
5
+ Start fleetd as the normal user on the controller computer. Then:
6
+ ```sh
7
+ fleet remote add office --ssh operator@office-host --root /absolute/private/controller
8
+ fleet --remote office list
9
+ fleet --remote office add /absolute/private/research
10
+ fleet --remote office start research
11
+ fleet --remote office agent attach research analyst-east
12
+ fleet --remote office agent contexts research analyst-east
13
+ fleet --remote office agent attach research analyst-east --context '!ORIGINAL_ROOM_ID:YOUR_SERVER'
14
+ fleet --remote office stop research
15
+ ```
16
+
17
+ Remote directories refer to that computer. Existing SSH authentication, host-key
18
+ verification and Unix-socket forwarding authorize the connection. The CLI changes
19
+ no SSH configuration, keys, permissions or public listening ports. Closing its
20
+ temporary tunnel does not stop the controller.
21
+
22
+ ## Native TUI pointer
23
+
24
+ `fleet agent attach research analyst-east` prints a ready-to-run native command
25
+ for the exact running saved session. Copy and run it manually. The command starts
26
+ a terminal client, not another engine/session/listener. Closing the TUI leaves
27
+ fleet execution running.
28
+
29
+ For a per-room instance, first list contexts. Attach defaults to its separate
30
+ private control history; pass the exact listed room ID to inspect that room's
31
+ conversation. Multiple histories share one engine/identity/workarea. A pointer
32
+ does not create, seed or replay a conversation. The coding session performing
33
+ setup is independent and has no fleet attachment pointer.
34
+
35
+ The runtime adapter owns session selection and native arguments. The private
36
+ token is read from a run-local file into the client's environment, never printed
37
+ in command text/API/logs. The engine's native home, executable and search path
38
+ are retained, including software installed through NVM.
39
+
40
+ Remote attachment prints an SSH-wrapped command that executes on the controller.
41
+ No additional public port or forwarding service is needed. Request a fresh pointer
42
+ after engine restart; old run-local credentials are removed.
43
+
44
+ Model and permissions belong in the definition, not remote resume overrides.
45
+ Stop/start applies configuration to the saved session.
46
+ - [Runtime configuration](configuration.md)