Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion bin/ocx.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import {
CODEX_CLI_TRANSPORT_ENV_KEYS,
CODEX_CLI_VERSION_MANAGER_ROOT_ENV_SLOTS,
codexCliInspectionLookupSeeds,
carriesCodexCliUpdateInspectionContext,
isCodexCliUpdateInspectionArgv,
} from "../src/update/codex-cli-update-launch-policy.mjs";
import {
Expand Down Expand Up @@ -1086,6 +1087,10 @@ if (updateHelpRequested) {
}

const codexCliUpdateInspection = isCodexCliUpdateInspectionArgv(process.argv);
// Windows inspection currently refuses before candidate I/O, so a long-lived
// Windows server does not duplicate PATH into its inherited environment block.
const codexCliUpdateInspectionContext = codexCliUpdateInspection
|| (process.platform !== "win32" && carriesCodexCliUpdateInspectionContext(process.argv));
if (codexCliUpdateInspection && typeof process.versions.bun === "string") {
console.error("opencodex: codex-cli-update inspection must use the published Node launcher.");
process.exit(1);
Expand Down Expand Up @@ -1217,7 +1222,7 @@ function createNodeLaunchContext() {
version: 1,
proof: launchProof,
anthropicEnvSlots: preBunAnthropicSlots,
codexCliInspectionEnv: codexCliUpdateInspection ? {
codexCliInspectionEnv: codexCliUpdateInspectionContext ? {
codexCliPath: preBunCodexCliPath,
path: preBunPath,
pathExt: preBunPathExt,
Expand Down
5 changes: 5 additions & 0 deletions docs-site/src/content/docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ Registry queries use isolated temporary npm configuration, cache and logs with b
No software is installed and no process is signalled. Windows returns `windows_inspection_deferred`.
See [planning details](/reference/cli/agents/#read-only-codex-cli-update-plan).

For a reviewed POSIX non-shim npm-global plan, `ocx system codex-cli-update apply --plan-id <id> --yes`
performs the exact update and returns a durable job. `ocx system codex-cli-update status <job-id> --json`
reads its result; use a stable `--request-id` for a lost-response retry. See
[confirmation and job states](/reference/cli/agents/#confirmed-posix-codex-cli-apply-and-job-status).

For Windows x64 installation observation, see [the `attest` command](/reference/cli/agents/#explicit-installation-observation-on-windows-x64). Without explicit paths it observes the selected candidate identified from the proof-bound launcher snapshot; it does not grant update authority or attest runtime selection.

List or status is the default where unambiguous. Use `--json` only on leaves that support it, and
Expand Down
30 changes: 27 additions & 3 deletions docs-site/src/content/docs/reference/cli/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -1179,12 +1179,36 @@ using the launcher's captured PATH and isolated temporary npm configuration, cac
settings and `NODE_EXTRA_CA_CERTS` remain supported; cleanup is best-effort. No Codex command runs.

An applicable plan reports `applicable: true` and a deterministic `planId` binding platform,
installation-root digest, installed version, channel and target version/integrity. The plan is never
installation-root/content digests, installed version, channel and exact main/platform artifacts. The plan is never
persisted. It refuses downgrades, already-current versions, active Codex sessions and incomplete
process observation. Windows returns `windows_inspection_deferred` before registry/process queries.
A refusal exits 0: inspect `applicable` and `refusal`. The printed install argv is indicative; this
command installs nothing, changes no application state and never signals a session. No apply command
is exposed, and a plan ID is not installation authorization.
command installs nothing, changes no application state and never signals a session. A plan ID alone
is not installation authorization: apply requires separate explicit confirmation.

#### Confirmed POSIX Codex CLI apply and job status

```bash
ocx system codex-cli-update apply --plan-id <32-hex> --yes --request-id <stable-key> --json
ocx system codex-cli-update status <job-id> --json
```

Apply supports only the selected, managed, non-shim npm-global CLI on Linux/macOS. It revalidates the
approved plan under an installation lease, verifies the exact main/platform archives, installs them
offline with lifecycle scripts disabled, and checks installed files and the selected CLI's version.
Existing Codex sessions are never stopped; active or unknown process observations refuse the update.
Windows apply, shim repair, native apps and other installation managers remain unsupported.

Apply returns a job with `applied`, `not_applied`, `refused` or `ambiguous` outcome. Status reads the
same private job record without a running proxy or GUI token. Reuse the same optional request ID after
a lost response: the same key and plan return the original job; a changed plan with that key refuses.
An ambiguous result is never automatically retried or rolled back. After an owner restart, an unfinished
job reports unknown ownership instead of claiming the old process stopped. Inspect the job's outcome,
child/lease state and cleanup errors; command exit status alone does not establish an installation result.

The management API provides authenticated plan/status reads and confirmed trusted-loopback GUI-session
apply admission. A published Node `ocx start` supplies the required inspection snapshot; direct Bun or
compiled sidecar startup does not provide that proof. The Dashboard update panel is a separate follow-up.

#### Explicit installation observation on Windows x64

Expand Down
2 changes: 2 additions & 0 deletions scripts/test-layout/layout-codex-collision.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"codex-cli-update-artifacts.test.ts": "codex-integration",
"codex-cli-update-apply.test.ts": "codex-integration",
"codex-stored-main-duplicate.test.ts": "codex-integration",
"codex-pool-caller-fallback-policy.test.ts": "codex-integration",
"codex-windows-current-sid.test.ts": "codex-integration"
Expand Down
14 changes: 11 additions & 3 deletions skills/ocx/references/01_management_surface.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ These answer in the CLI head and never reach the proxy, so they work with nothin
| [accounts](01_surface_accounts.md) | 42 |
| [agents-routing](01_surface_agents-routing.md) | 67 |
| [integrations](01_surface_integrations.md) | 41 |
| [observe-system](01_surface_observe-system.md) | 96 |
| [observe-system](01_surface_observe-system.md) | 98 |
| [access-remote](01_surface_access-remote.md) | 33 |
| [lab](01_surface_lab.md) | 21 |

Expand Down Expand Up @@ -279,6 +279,14 @@ Original invocation order. These headings preserve links to the previous single-

[Read-oriented task](01_surface_observe-system.md#ocx-system-codex-cli-update-plan)

### `ocx system codex-cli-update apply`

[State-changing task](01_surface_observe-system.md#ocx-system-codex-cli-update-apply)

### `ocx system codex-cli-update status`

[Read-oriented task](01_surface_observe-system.md#ocx-system-codex-cli-update-status)

### `ocx system codex-restart`

[State-changing task](01_surface_observe-system.md#ocx-system-codex-restart)
Expand Down Expand Up @@ -1497,6 +1505,6 @@ Original invocation order. These headings preserve links to the previous single-

## Counts

- declared capabilities: 362
- of those, state-changing: 221
- declared capabilities: 364
- of those, state-changing: 222
- head-resolved invocations: 2
44 changes: 42 additions & 2 deletions skills/ocx/references/01_surface_observe-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Use these declarations to choose a task, then check its flags and authority before execution.
Non-mutating probes may still contact providers, consume quota or refresh caches.

Declared capabilities: 96.
Declared capabilities: 98.

### `ocx companion`

Expand Down Expand Up @@ -392,12 +392,52 @@ Drives no management route.
| `--channel` | string | Registry channel to resolve. Only the stable latest channel is offered. |
| `--json` | boolean | Emit the plan as JSON. |

- Local counterpart of GET /api/codex/cli-update/plan: runs the same proof-bound plan builder without HTTP transport.
- Adds the three inputs check leaves out: an exact registry version with its sha512 integrity, a fail-closed process-table read, and a decision.
- The registry evidence is pinned to the official npm registry with project/user npm configuration isolated, so a redirected .npmrc cannot supply the answer.
- Installs nothing and mutates no application state; registry evidence is gathered under an isolated temporary npm root (npmrc, cwd, cache and logs) removed best-effort afterwards. A refusal is a normal dry-run answer and still exits 0.
- The plan id is a digest of the evidence the decision rests on — ownership, the installed version, a digest of the canonical install root, the resolved target — not a stored job. There is no plan state on disk to expire, collide or clean up.
- The plan id is a digest of the evidence; apply re-observes it before any mutation.
- Apply durably admits a bounded, same-user job before running; request IDs deduplicate retries and a conflicting payload is rejected. Unresolved records are retained rather than expired.
- An unreadable process table refuses rather than reading as no live session.

### `ocx system codex-cli-update apply`

Usage: `ocx system codex-cli-update apply --plan-id <32-hex> --yes [--request-id <key>] [--json]`

Apply a confirmed Codex CLI update as a durable job.

State-changing: yes. JSON mode: `envelope`.

Drives no management route.

| Flag | Value | Meaning |
|---|---|---|
| `--plan-id` | string | Required 32-hex id from the current plan. |
| `--yes` | boolean | Required confirmation. |
| `--request-id` | string | Optional stable retry key. |
| `--json` | boolean | Emit the public job status. |

- Local counterpart of POST /api/codex/cli-update/apply: invokes the same durable job owner with --yes confirmation; HTTP admission separately requires a trusted loopback GUI session.
- Admission is stored under the protected current-user config root before the installer can run.
- Only POSIX npm-global managed installs are currently supported; Windows, shims and other managers remain refused.

### `ocx system codex-cli-update status`

Usage: `ocx system codex-cli-update status <job-id> [--json]`

Read a Codex CLI update job by opaque id.

State-changing: no. JSON mode: `envelope`.

Drives no management route.

| Flag | Value | Meaning |
|---|---|---|
| `--json` | boolean | Emit the path-free job status. |

- Local counterpart of GET /api/codex/cli-update/jobs/{jobId}: reads the same path-free job status without HTTP transport.
- Reads the protected job record directly; the job id is not an authorization credential.

### `ocx system codex-restart`

Usage: `ocx system codex-restart --yes [--json]`
Expand Down
19 changes: 18 additions & 1 deletion src/cli/capabilities-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,14 +602,31 @@ export const CAPABILITIES: readonly Capability[] = [
mutates: false,
json: "envelope",
details: [
"Local counterpart of GET /api/codex/cli-update/plan: runs the same proof-bound plan builder without HTTP transport.",
"Adds the three inputs check leaves out: an exact registry version with its sha512 integrity, a fail-closed process-table read, and a decision.",
"The registry evidence is pinned to the official npm registry with project/user npm configuration isolated, so a redirected .npmrc cannot supply the answer.",
"Installs nothing and mutates no application state; registry evidence is gathered under an isolated temporary npm root (npmrc, cwd, cache and logs) removed best-effort afterwards. A refusal is a normal dry-run answer and still exits 0.",
"The plan id is a digest of the evidence the decision rests on — ownership, the installed version, a digest of the canonical install root, the resolved target — not a stored job. There is no plan state on disk to expire, collide or clean up.",
"The plan id is a digest of the evidence; apply re-observes it before any mutation.",
"Apply durably admits a bounded, same-user job before running; request IDs deduplicate retries and a conflicting payload is rejected. Unresolved records are retained rather than expired.",
"An unreadable process table refuses rather than reading as no live session.",
],
usage: "ocx system codex-cli-update plan [--channel latest] [--json]",
},
{
command: ["system", "codex-cli-update", "apply"],
summary: "Apply a confirmed Codex CLI update as a durable job.",
routes: [],
flags: [{ name: "--plan-id", value: "string", summary: "Required 32-hex id from the current plan." }, { name: "--yes", value: "boolean", summary: "Required confirmation." }, { name: "--request-id", value: "string", summary: "Optional stable retry key." }, { name: "--json", value: "boolean", summary: "Emit the public job status." }],
mutates: true, json: "envelope",
details: ["Local counterpart of POST /api/codex/cli-update/apply: invokes the same durable job owner with --yes confirmation; HTTP admission separately requires a trusted loopback GUI session.", "Admission is stored under the protected current-user config root before the installer can run.", "Only POSIX npm-global managed installs are currently supported; Windows, shims and other managers remain refused."],
usage: "ocx system codex-cli-update apply --plan-id <32-hex> --yes [--request-id <key>] [--json]",
},
{
command: ["system", "codex-cli-update", "status"],
summary: "Read a Codex CLI update job by opaque id.", routes: [], flags: [{ name: "--json", value: "boolean", summary: "Emit the path-free job status." }],
mutates: false, json: "envelope", details: ["Local counterpart of GET /api/codex/cli-update/jobs/{jobId}: reads the same path-free job status without HTTP transport.", "Reads the protected job record directly; the job id is not an authorization credential."],
usage: "ocx system codex-cli-update status <job-id> [--json]",
},
{
command: ["system","codex-restart"],
summary: "Restart the Codex app-servers, and the desktop app when its model picker predates the catalog.",
Expand Down
Loading
Loading