@ours.network/fleet-codex 0.10.0-nightly.4 → 0.11.0

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ours-fleet",
3
- "version": "0.10.0-nightly.4",
3
+ "version": "0.11.0",
4
4
  "description": "Spawn, configure, and oversee ours-fleet roles from OpenAI Codex.",
5
5
  "author": {
6
6
  "name": "Adapt Framework Solutions Ltd",
@@ -9,14 +9,7 @@
9
9
  "homepage": "https://github.com/adapt-toolkit/ours-fleet/tree/main/integrations/codex/ours-fleet",
10
10
  "repository": "https://github.com/adapt-toolkit/ours-fleet",
11
11
  "license": "FSL-1.1-Apache-2.0",
12
- "keywords": [
13
- "codex",
14
- "ours.network",
15
- "fleet",
16
- "agents",
17
- "spawn",
18
- "oversight"
19
- ],
12
+ "keywords": ["codex", "ours.network", "fleet", "agents", "spawn", "oversight"],
20
13
  "skills": "./skills/",
21
14
  "interface": {
22
15
  "displayName": "ours.network Fleet",
@@ -24,11 +17,7 @@
24
17
  "longDescription": "Create temporary or supervised ours-fleet roles, configure Codex models and permissions, and keep spawned agents healthy from inside Codex.",
25
18
  "developerName": "Adapt Framework Solutions Ltd",
26
19
  "category": "Productivity",
27
- "capabilities": [
28
- "Interactive",
29
- "Read",
30
- "Write"
31
- ],
20
+ "capabilities": ["Interactive", "Read", "Write"],
32
21
  "websiteURL": "https://ours.network",
33
22
  "defaultPrompt": [
34
23
  "Spawn a new Codex fleet agent for this task.",
package/README.md CHANGED
@@ -19,6 +19,8 @@ Then ask Codex to “spawn an ours agent”, “create a persistent Codex role
19
19
  “keep an eye on my fleet agents”.
20
20
 
21
21
  Codex may ask for one-time authorization before individual ours MCP tools run.
22
- Mail wake is consent-first: a spawned role receives `--monitor` only when the
23
- user explicitly requests it. `ours-codex` supplies background wake; native
24
- `codex` remains the supported foreground-monitor fallback.
22
+ Native Codex mail wake is consent-first: a spawned role receives the legacy
23
+ `--monitor` consent flag only when the user explicitly requests it.
24
+ In fleet YAML, `monitor.mode: fleet|native` separately chooses whether
25
+ ours-fleet or the harness owns wake delivery. `ours-codex` supplies native
26
+ background wake; plain `codex` remains the supported native foreground fallback.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/fleet-codex",
3
- "version": "0.10.0-nightly.4",
3
+ "version": "0.11.0",
4
4
  "description": "Native Codex plugin for spawning, configuring, and overseeing ours-fleet agents.",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",
@@ -11,32 +11,13 @@
11
11
  "url": "git+https://github.com/adapt-toolkit/ours-fleet.git",
12
12
  "directory": "integrations/codex/ours-fleet"
13
13
  },
14
- "keywords": [
15
- "codex",
16
- "openai",
17
- "plugin",
18
- "fleet",
19
- "agents",
20
- "spawn",
21
- "oversight",
22
- "ours.network"
23
- ],
24
- "files": [
25
- ".codex-plugin",
26
- "skills",
27
- "bin",
28
- "README.md",
29
- "LICENSE"
30
- ],
14
+ "keywords": ["codex", "openai", "plugin", "fleet", "agents", "spawn", "oversight", "ours.network"],
15
+ "files": [".codex-plugin", "skills", "bin", "README.md", "LICENSE"],
31
16
  "bin": {
32
17
  "ours-fleet-codex-install": "bin/ours-fleet-codex-install.mjs"
33
18
  },
34
- "engines": {
35
- "node": ">=20"
36
- },
37
- "publishConfig": {
38
- "access": "public"
39
- },
19
+ "engines": { "node": ">=20" },
20
+ "publishConfig": { "access": "public" },
40
21
  "scripts": {
41
22
  "test": "node --test"
42
23
  }
@@ -26,21 +26,45 @@ Identify wards from the user's request, the current role briefing, or agents
26
26
  just spawned. Confirm the desired check interval when ongoing oversight is
27
27
  requested; default to five minutes only after the user agrees.
28
28
 
29
- This plugin does not add a timer or Claude Code's generic scheduled background
30
- monitor. Before promising recurring checks, identify an explicit timer/recurring
31
- monitor tool that is actually available in the current Codex session. The ours
32
- mail monitor is event-driven and does not provide five-minute timer wakeups. If
33
- no real timer tool is present, say that the interval cannot be armed: offer
34
- active foreground observation or manual checks instead. Never say “I created a
29
+ This plugin does not add a timer or a generic scheduled background monitor.
30
+ Before promising recurring checks, identify an explicit timer/recurring monitor
31
+ tool that is actually available in the current Codex session. The ours mail
32
+ monitor is event-driven and does not provide five-minute timer wakeups. If no
33
+ real timer tool is present, say that the interval cannot be armed: offer active
34
+ foreground observation or manual checks instead. Never say “I created a
35
35
  recurring monitor” based only on this skill. For durable operation, recommend a
36
36
  supervised coordinator role and message-driven wake through `ours-codex`, while
37
37
  remaining clear that messages—not elapsed time—wake it.
38
38
 
39
- ## On each check
39
+ ## One console command is not a liveness verdict
40
40
 
41
- Peek once and classify the evidence:
41
+ This is the mistake that gets busy agents killed. `peek` and `send` tell you what
42
+ happened to YOUR REQUEST. Only one of their outcomes is evidence that the agent
43
+ is gone. On each check run BOTH — they answer different questions:
42
44
 
43
- - **Active and progressing:** leave it alone.
45
+ ```sh
46
+ ours-fleet status <Name> # is the role supervised and alive?
47
+ ours-fleet peek <Name> # what is on its console right now?
48
+ ```
49
+
50
+ Read the result you actually got:
51
+
52
+ - **queued** — the session accepted the prompt for '<Name>'; a turn already running is not a failure. → Nothing. Do not resend, and do not read the absence of a reply as a stall — check progress with: ours-fleet peek <Name>
53
+ - **timeout** — '<Name>' did not answer in time; a busy agent looks exactly like this. Check: ours-fleet status <Name> → Treat delivery as UNCERTAIN — the request may already have been acted on, so do not resend it blindly.
54
+ - **rejected** — '<Name>' is running and refused the request. → Fix the request, not the agent. A refusal is proof of life.
55
+ - **control-unavailable** — this says nothing about whether '<Name>' is alive — its control plane did not answer; check: ours-fleet status <Name> → Read the role logs as well. The control plane and the agent are separate things, and one being unreachable is not evidence about the other.
56
+ - **backend** — this is a transport failure, not evidence that '<Name>' is gone; check: ours-fleet status <Name> → Investigate the transport, not the agent.
57
+ - **offline** — '<Name>' is confirmed offline. → This is the ONLY result that justifies a restart on its own: ours-fleet restart <Name> for a permanent role. Read the logs first.
58
+
59
+ Never translate any other result into "dead". `ours-fleet` prints the same
60
+ liveness note the CLI derived the result from, so quote what it said rather than
61
+ paraphrasing it as "not running".
62
+
63
+ ## Judge the console content
64
+
65
+ Once you know the role is alive, classify the evidence:
66
+
67
+ - **Active and progressing:** leave it alone. A long turn is not a stall.
44
68
  - **Codex MCP authorization prompt:** surface the requested tool and scope.
45
69
  Session-only approval is safer for tests; persistent approval requires the
46
70
  user's explicit authorization.
@@ -50,8 +74,8 @@ Peek once and classify the evidence:
50
74
  context; otherwise escalate.
51
75
  - **Idle with unfinished work:** ask for status and direct it to continue or
52
76
  declare `BLOCKED`.
53
- - **Crash or shell prompt:** inspect logs, diagnose, then restart permanent
54
- roles with `ours-fleet restart <Name>` when safe.
77
+ - **Crash or shell prompt:** inspect logs and diagnose. Restart a permanent role
78
+ with `ours-fleet restart <Name>` only once `status` confirms it is offline.
55
79
  - **Completed temporary role:** report the result and let its supervisor clean
56
80
  up; stop checking it.
57
81
 
@@ -8,26 +8,89 @@ description: Spawn and configure a new ours-fleet agent from Codex, with a perma
8
8
  Use the `ours-fleet` CLI to create the role. Do not simulate a subagent inside
9
9
  the current conversation.
10
10
 
11
- ## 1. Check the host
12
-
13
- Run:
11
+ ## 1. Read the installed CLI reference — this step is not optional
14
12
 
15
13
  ```sh
16
14
  ours-fleet docs
17
15
  ours-fleet doctor --harness codex
18
16
  ```
19
17
 
20
- Treat `ours-fleet docs` from the installed CLI as authoritative for supported
21
- session backends, common permissions, and flags. Stop at a failed required
22
- doctor check.
23
-
24
- ## 2. Resolve the role design
18
+ `ours-fleet docs` from the INSTALLED CLI is authoritative for supported session
19
+ backends, permissions, and flags. This skill ships with a plugin and the CLI is
20
+ upgraded separately, so where the two differ the installed reference wins. Stop
21
+ at a failed required doctor check.
22
+
23
+ ## 2. Understand the two permission traps before you choose anything
24
+
25
+ Both traps produce the same symptom: an agent that does less than its briefing
26
+ told it to and reports no error, because the refusal happened inside the harness
27
+ with no console attached to see it.
28
+
29
+ **Trap 1 — a mode that suppresses the prompt without granting the action.** On
30
+ Claude Code this is `dontAsk`, which hides the permission prompt and still
31
+ refuses the action; it is why neutral `--approval allow` maps to
32
+ `bypassPermissions` rather than to the mode whose name sounds milder. On Codex
33
+ the same shape applies to native approval: only `never` reaches the tools
34
+ without a console, and `on-request` becomes a refusal when nobody can answer.
35
+ Judge a native mode by what it grants, not by how permissive its name sounds.
36
+
37
+ **Trap 2 — the unattended capability floor.** A role with no console cannot
38
+ answer a permission request, so the request is refused. `ours-fleet` checks each
39
+ role's resolved permissions against a fixed floor before launch:
40
+
41
+ - `read-state` — read its briefing, ROUTINES.md, and WORKLOG.md
42
+ - `write-state` — append its WORKLOG and its own state files
43
+ - `messaging` — bind its identity, send and receive ours mail
44
+ - `monitor` — arm and observe its mail monitor
45
+ - `workspace-edit` — edit and test files in its working directory
46
+ - `status-commands` — run the inspection commands its briefing prescribes
47
+
48
+ `ours-fleet config` and `ours-fleet doctor` report this per role as
49
+ `unattended floor: <Name>`. Under `--unattended deny` a shortfall FAILS doctor,
50
+ because those requests will be denied silently. Under `--unattended wait` it
51
+ warns, because a human can still attach and answer.
52
+
53
+ What this means in practice, on this harness:
54
+
55
+ | Neutral intent | Native settings | Meets the floor? |
56
+ | --- | --- | --- |
57
+ | `--approval allow --filesystem workspace` | `approval=never sandbox=workspace-write` | yes |
58
+ | `--approval allow --filesystem read-only` | `approval=never sandbox=read-only` | no — no `write-state`, no `workspace-edit` |
59
+ | `--approval ask` | `approval=on-request` | no — `read-state` only |
60
+ | `--approval deny` | `approval=on-request` | no — `read-state` only |
61
+
62
+ ## 3. Choose permissions from the job, not from a default
63
+
64
+ There is no safe blanket default. Ask what the role has to do and whether the
65
+ user authorizes it, then pick:
66
+
67
+ - **It must work with nobody watching** (the usual reason to spawn a fleet
68
+ role): it needs `--approval allow --filesystem workspace`. That is a real
69
+ grant, so get the user's explicit authorization for it, and confine the role
70
+ with `--isolation-file` rather than by withholding permissions it needs.
71
+ Use `--unattended deny` so the role never blocks on an unanswerable request.
72
+ - **A human will attach and answer prompts**: `--approval ask --filesystem
73
+ workspace --unattended wait`. Doctor warns that the floor is unmet — that
74
+ warning is correct and expected; the role will block until someone answers.
75
+ - **The user will not authorize `allow`, and nobody will attend it**: say so
76
+ plainly. That role cannot do its job, and doctor will fail it. Reduce the job
77
+ or get the authorization; do not paper over it with a mode that only hides
78
+ the prompt.
79
+
80
+ Never choose `--filesystem unrestricted`, `--sandbox danger-full-access`, or a
81
+ native `--permission-mode` override without the user asking for it by name and
82
+ understanding what it grants. `harness_options` wins over the neutral block at
83
+ launch, so stating intent in both places and disagreeing is how a role runs on
84
+ settings nobody chose — `ours-fleet config` and `doctor` print a
85
+ `permission conflict: <Name>` line when that happens.
86
+
87
+ ## 4. Resolve the rest of the role design
25
88
 
26
89
  Ask only for choices not already supplied:
27
90
 
28
91
  - **Lifetime:** permanent (supervised, restartable, survives reboot) or
29
92
  temporary (detached supervisor, removed on exit/reboot).
30
- - **Session:** `tmux` or `acp`; both permanent and temporary roles support both.
93
+ - **Session:** `tmux` or `acp`; both lifetimes support both.
31
94
  - **Name:** `[A-Za-z0-9_-]+`; confirm it is absent from `ours-fleet config` and
32
95
  `ours-fleet ls`.
33
96
  - **Mission and working directory.**
@@ -36,16 +99,11 @@ Ask only for choices not already supplied:
36
99
  - **Persona:** local operating contract covering mandate, quality bar,
37
100
  boundaries, and escalation. Use the writing-agent-bios skill when available.
38
101
  - **Coordinator:** optionally announce readiness to an existing ours identity.
39
- - **Mail monitoring:** explicitly ask whether to arm it. Pass `--monitor` only
40
- after a clear yes. This consent persists in the role configuration.
41
-
42
- Prefer common permission intent:
102
+ - **Native Codex mail monitoring:** explicitly ask whether to arm it. Pass the
103
+ legacy `--monitor` consent flag only after a clear yes. This is distinct from
104
+ fleet YAML `monitor.mode: fleet|native`, which chooses the wake owner.
43
105
 
44
- - approval: `--approval ask|allow|deny`
45
- - filesystem: `--filesystem read-only|workspace|unrestricted`
46
- - unattended ACP behavior: `--unattended deny|wait`
47
-
48
- Offer Codex-native controls when relevant:
106
+ Codex-native controls, offered when relevant:
49
107
 
50
108
  - model: launcher default or `--model <id>`
51
109
  - native approval: `--permission-mode untrusted|on-request|never`
@@ -56,43 +114,76 @@ Offer Codex-native controls when relevant:
56
114
  - arbitrary config: repeatable `--codex-config key=value`
57
115
  - additional writable roots: repeatable `--add-dir <path>`
58
116
 
59
- Default to `--harness codex --session tmux --launcher auto --approval ask
60
- --filesystem workspace --unattended deny`. Never select unrestricted access,
61
- `danger-full-access`, `never`, or common `allow` without explicit user direction.
62
-
63
- ## 3. Materialize approved profile text
117
+ ## 5. Materialize approved profile text
64
118
 
65
119
  Use `apply_patch` to write the approved bio and persona to uniquely named files
66
120
  under `/tmp`. Do not interpolate untrusted text into a shell heredoc.
67
121
 
68
- ## 4. Spawn
122
+ ## 6. Confine the role at creation, not later
69
123
 
70
- Build an argument array from the approved choices. Permanent example:
124
+ `--isolation-file <path>` supplies the role's sandbox policy at creation, so the
125
+ FIRST launch is already confined. A role that only gains `isolation:` on a later
126
+ `up` ran unsandboxed until then. The file holds exactly the `isolation:` mapping
127
+ documented in `ours-fleet docs` and nothing else:
128
+
129
+ ```yaml
130
+ network: deny
131
+ fs:
132
+ read: [/opt/reference]
133
+ resources:
134
+ mem: 2G
135
+ ```
136
+
137
+ An invalid file is rejected before anything is created — no config, no state
138
+ directory, no identity reservation. This is the right control for a role that
139
+ needs `--approval allow`: isolation is the outer boundary a permission mode
140
+ cannot cross.
141
+
142
+ ## 7. Spawn
143
+
144
+ Build an argument array from the approved choices. Permanent, unattended:
71
145
 
72
146
  ```sh
73
147
  ours-fleet spawn Worker --harness codex --launcher auto \
74
148
  --session <tmux|acp> \
75
149
  --mission "Own the worker implementation" --cwd /absolute/project \
76
150
  --bio-file /tmp/worker-bio.md --persona-file /tmp/worker-persona.md \
77
- --approval ask --filesystem workspace --unattended deny \
151
+ --approval allow --filesystem workspace --unattended deny \
152
+ --isolation-file /tmp/worker-isolation.yaml \
78
153
  --coordinator Coordinator
79
154
  ```
80
155
 
156
+ Permanent, attended — a human will answer its prompts:
157
+
158
+ ```sh
159
+ ours-fleet spawn Worker --harness codex --launcher auto \
160
+ --session <tmux|acp> \
161
+ --mission "Own the worker implementation" --cwd /absolute/project \
162
+ --bio-file /tmp/worker-bio.md --persona-file /tmp/worker-persona.md \
163
+ --approval ask --filesystem workspace --unattended wait
164
+ ```
165
+
81
166
  Add `--temp` for a temporary role; it can also use `--session acp`.
82
- Pass `--monitor` only after monitoring consent.
167
+ Pass the legacy `--monitor` flag only after consent to arm Codex's native
168
+ monitor. It does not select the wake owner; `monitor.mode` does that in YAML.
83
169
  Pass model, profile, search, config, and additional directories exactly as
84
170
  approved. Do not persist secrets in `--codex-config` or fleet YAML; use the
85
171
  role's `env` configuration for environment-based credentials.
86
172
 
87
- ## 5. Verify the real session
88
-
89
- Run:
173
+ ## 8. Verify the real session
90
174
 
91
175
  ```sh
176
+ ours-fleet doctor --harness codex
92
177
  ours-fleet peek <Name> 60
93
178
  ours-fleet status <Name>
94
179
  ```
95
180
 
181
+ Read doctor's `permissions: <Name>` and `unattended floor: <Name>` lines for the
182
+ role you just created. `permissions:` shows the neutral intent and the native
183
+ settings it translated to; the floor line lists what the role actually grants,
184
+ or names what is missing. A failure there means the role will silently do less
185
+ than its briefing says — fix the permissions rather than starting it.
186
+
96
187
  For ACP, `status` must report `backend: acp`, `alive: true`, and a running/idle
97
188
  readiness. For a temporary tmux role, the pane is authoritative. Confirm that
98
189
  Codex loaded its briefing and reached identity binding. First use can display
@@ -106,7 +197,7 @@ If monitoring was approved, confirm the console reports `arm_monitor` success.
106
197
  Under native Codex, expect the role to surface the `ours-codex` recommendation
107
198
  before offering the blocking foreground fallback.
108
199
 
109
- ## 6. Hand off oversight
200
+ ## 9. Hand off oversight
110
201
 
111
202
  Treat the spawned role as a ward. Use the `oversee-agents` skill for immediate
112
203
  checks and interventions. State clearly whether ongoing timed oversight is