Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d5e5b41
fix(codex): keep npm Node cache within inspection lifetime
luvs01 Oct 22, 2026
840ca43
feat(codex): add confirmed CLI update apply candidate
luvs01 Oct 22, 2026
e9fdc4b
fix(codex): preserve canonical staging and complete install preimages
luvs01 Oct 22, 2026
12b7c59
fix(codex): await archive descriptor release before readback
luvs01 Oct 22, 2026
09bf422
feat(codex): stage durable CLI update job management
luvs01 Oct 22, 2026
26a070e
fix(codex): bind management launches and preserve uncertain job lifet…
luvs01 Oct 22, 2026
b06e809
test(codex): align POSIX CLI job consumer contracts
luvs01 Oct 23, 2026
3df99b8
fix(codex): initialize confirmed CLI update jobs safely
luvs01 Oct 22, 2026
8e0eeaa
test(codex): preserve job DTO evidence during matching
luvs01 Oct 23, 2026
224e797
test(codex): isolate npm wrapper module scope
luvs01 Oct 23, 2026
7299e4b
docs(codex): describe POSIX update apply and job consumers
luvs01 Oct 23, 2026
40a1075
fix(cli): document Codex updater resource parity
luvs01 Oct 23, 2026
13cf987
fix(codex): preserve update job results across store failures
luvs01 Oct 23, 2026
d617ec4
fix(api): advertise retry delay for CLI job admission contention
luvs01 Oct 23, 2026
3c25ae9
fix(codex): recover owned job locks and signal apply failures
luvs01 Oct 23, 2026
d67b167
test(codex): isolate admission lock replacement identity guards
luvs01 Oct 23, 2026
4c22308
test(codex): align unapplied CLI consumer exit expectation
luvs01 Oct 23, 2026
670824f
Merge dev into POSIX CLI update recovery
luvs01 Oct 23, 2026
76b4ee0
Merge latest dev layout fix into POSIX CLI update recovery
luvs01 Oct 23, 2026
c7dcd65
fix(codex): preserve CLI results after persistence failure
luvs01 Oct 23, 2026
6aac61f
Merge commit 'c4d4bb2da2162e23c314befafc5ec104292902a0' into codex/cl…
luvs01 Oct 23, 2026
9e5a917
fix(test): promote Bun 1.4.4 with independent runner role verification
luvs01 Oct 23, 2026
1deb67d
docs: align Docker Bun comments with unified role defaults
luvs01 Oct 23, 2026
41f08ff
test: use a draining TLS origin for early upload replies
luvs01 Oct 23, 2026
a9c3d12
test: confine draining origin to buffered HTTP/1 upload
luvs01 Oct 23, 2026
f011a94
merge: align test-runner role branch with dev 2.93.0 dependency baseline
luvs01 Oct 24, 2026
1523ba3
fix(codex): run cli-update registry queries and session scans async
luvs01 Oct 24, 2026
d36b804
fix(codex): settle cli-update metadata on the child's terminal event
luvs01 Oct 24, 2026
320781b
Merge current dev into Codex CLI async metadata integration
luvs01 Oct 24, 2026
7e7c553
test(codex): pin gated registry fixtures to x64
luvs01 Oct 24, 2026
f3ed578
Merge current dev into Codex CLI update parent
luvs01 Oct 24, 2026
cd582f4
Merge shared Bun 1.4.4 baseline into Codex CLI update parent
luvs01 Oct 24, 2026
bebc5a9
ci: record measured Codex CLI apply batch weight
luvs01 Oct 24, 2026
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
4 changes: 2 additions & 2 deletions .github/actions/setup-project-bun/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ description: >-
# (#6713 run 37631558263: Linux 1/4, macOS 2/2, Windows 9/9). It moved from 1.4.0 to
# 1.4.3 for oven-sh/bun#44581: 1.4.0's Bun.spawnSync could lose a child's exit after
# finalizers ran inside an earlier call and spin past its own timeout (#4956).
# Rejoin only after the upstream runner crash is fixed and a green lane=all
# dispatch proves the unified version; then delete testRunnerBun and this role input.
# Both roles now default to the package's 1.4.4 security transition, retaining role validation.
# Promotion requires a green full cross-platform lane=all run on the exact candidate head.
inputs:
role:
description: Bun role to install (runtime or test-runner).
Expand Down
10 changes: 4 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -621,12 +621,10 @@ jobs:
printf 'Scheduled run: workflow from %s, testing dev at %s\n' "$GITHUB_SHA" "$sha" >> "$GITHUB_STEP_SUMMARY"
printf 'scheduled run tests dev at %s (workflow %s)\n' "$sha" "$GITHUB_SHA"
# Bun roles (#6713): runtime 1.4.2 fixes #6684's Windows Bun.fetch streaming;
# the test runner skipped 1.4.2's multi-file --isolate preload segfault (#4821
# reverted #4064; run 37631558263: Linux 1/4, macOS 2/2, Windows 9/9) and runs
# 1.4.3, whose oven-sh/bun#44581 stops Bun.spawnSync losing a child's exit (#4956).
# Rejoin after the upstream runner crash is fixed and a green lane=all dispatch
# proves the unified version, then delete testRunnerBun and the action's role input.
# Bun runtime and test-runner roles both read their 1.4.4 defaults from package.json.
# Keep role validation after the historical isolate preload and spawnSync failures
# (#6713, #4956). Promotion requires a green full cross-platform lane=all run on
# the exact candidate head; focused local results do not replace that proof.
# The suite, split by file across four Linux runners.
#
# `scripts/ci/run-bun-test-batches.sh` assigns files to shards by the per-file
Expand Down
6 changes: 4 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ A ready-for-review PR is the author's claim that the change is complete, underst

## Local validation and hooks

The suite uses Bun 1.4.3 (`testRunnerBun`) while the shipped runtime is 1.4.4.
`scripts/test.ts` finds a 1.4.3 binary on PATH or in `~/.bun/bin`, or uses
The suite uses Bun 1.4.4 (`testRunnerBun`) while the shipped runtime is 1.4.4.
`scripts/test.ts` finds a 1.4.4 binary on PATH or in `~/.bun/bin`, or uses
`OCX_TEST_RUNNER_BUN`; install that version locally if it is missing.
The roles remain independently checked even when their versions match. Promotion requires
a successful full cross-platform `lane=all` run on the candidate head.

Run `bun run test` before review readiness. If the full local suite is too costly
for the task or available resources, run at least focused regression tests for
Expand Down
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

# Keep the runtime aligned with package.json and pin the multi-platform image index.
# Runtime 1.4.4 keeps 1.4.2's #6684 Windows Bun.fetch streaming fix and ships NSS
# 3.131.1 roots without the compromised eMudhra CAs; CI tests run on 1.4.3
# because 1.4.2 segfaults reloading preloads in multi-file --isolate (#4821;
# #6713 run 37631558263: Linux 1/4, macOS 2/2, Windows 9/9) and 1.4.0's spawnSync
# can lose a child's exit (#4956, oven-sh/bun#44581). Rejoin after the
# upstream crash fix passes a unified-version lane=all dispatch, then delete
# package.json's testRunnerBun pin and setup-project-bun's role input.
# 3.131.1 roots without the compromised eMudhra CAs. Runtime and test-runner
# defaults are both 1.4.4; keep package.json's testRunnerBun pin and
# setup-project-bun's role input independently validated. Promotion requires
# an exact-head cross-platform lane=all dispatch, including multi-file --isolate:
# historical 1.4.2 preload crashes (#4821; #6713 run 37631558263) and 1.4.0
# spawnSync exit loss (#4956, oven-sh/bun#44581) remain regression risks.
ARG BUN_IMAGE=oven/bun:1.4.4@sha256:1d22548f177f4ff38e0c15baa3c2c46c6c2060ba2d1bc573bb4720b407548f1d

FROM ${BUN_IMAGE} AS manifest
Expand Down
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
6 changes: 4 additions & 2 deletions docs-site/src/content/docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ bun run privacy:scan # credential/privacy scan used by CI
bun run prepare:package # refresh package launchers/assets
```

The suite uses Bun 1.4.3 (`package.json`'s `testRunnerBun`) while the shipped runtime is 1.4.4.
`scripts/test.ts` finds a 1.4.3 binary on PATH or in `~/.bun/bin`, or uses `OCX_TEST_RUNNER_BUN`.
The suite uses Bun 1.4.4 (`package.json`'s `testRunnerBun`) while the shipped runtime is 1.4.4.
`scripts/test.ts` finds a 1.4.4 binary on PATH or in `~/.bun/bin`, or uses `OCX_TEST_RUNNER_BUN`.
Install that version locally if it is missing; the resolver never downloads it.
The roles remain independently checked even when their versions match. Promotion requires
a successful full cross-platform `lane=all` run on the candidate head.

Run `bun run test` by default. If a full run is disproportionately expensive for the task size,
available machine resources, or concurrent worktrees, you must at least run focused regression tests
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
38 changes: 35 additions & 3 deletions docs-site/src/content/docs/reference/cli/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -1188,12 +1188,44 @@ 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 exits 0 only for an `applied` job; `not_applied`, `refused`, `ambiguous` and pending duplicate jobs
exit 1, including with `--json`. 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.
The private ledger retains up to 64 jobs, including finished jobs, without automatic pruning. At that
limit, new request IDs are refused with `store_full`; existing matching retries still return their
original job. Capacity and operator recovery remain a separate follow-up that must preserve this
deduplication contract. A busy admission ledger reports `job_store_busy` (HTTP 503 with `Retry-After: 1`);
permanent admission failures have no retry-delay header. Missing or unreadable CLI
status returns `job_unavailable` and a nonzero exit. Completion persistence failures do not rerun the
installer or turn an uncertain job into a confirmed success.
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: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"trustedDependencies": [
"bun"
],
"testRunnerBun": "1.4.3",
"testRunnerBun": "1.4.4",
"scripts": {
"dev": "bun run src/cli/index.ts start",
"dev:proxy": "bun run src/cli/index.ts start",
Expand Down
3 changes: 2 additions & 1 deletion scripts/ci/test-durations.tsv
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Per-file Bun test durations in milliseconds, read from hosted CI job logs.
# Consumed by scripts/ci/run-bun-test-batches.sh to balance shards; a file without a row weighs the median.
# Regenerate with scripts/ci/test-durations.ts (usage in its header); do not edit by hand.
# Source: run 38250055508 (dev dc45bb2ca9, lane=all), Linux test 1/4-4/4 and macos 1/3-3/3
# Source: run 38250055508 (dev dc45bb2ca9, lane=all), Linux test 1/4-4/4 and macos 1/3-3/3; selected row tests/codex-integration/codex-cli-update-apply.test.ts from run 40084641010 @700dc1d8bfe3 job 120850286088 (test 2/4, Bun 1.4.4); other rows retained
271 tests/adapters/abort-race.test.ts
643 tests/adapters/adapter-buffered-tool-conformance.test.ts
270 tests/adapters/adapter-error-inline.test.ts
Expand Down Expand Up @@ -693,6 +693,7 @@
169 tests/codex-integration/codex-cli-install-provenance.test.ts
100 tests/codex-integration/codex-cli-installation-identity.test.ts
127 tests/codex-integration/codex-cli-installation-targets.test.ts
94979 tests/codex-integration/codex-cli-update-apply.test.ts
104 tests/codex-integration/codex-cli-update-launcher-policy.test.ts
1197 tests/codex-integration/codex-cli-update-zero-effect.test.ts
92 tests/codex-integration/codex-cli-windows-installation-files.test.ts
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-sync-user-edits.test.ts": "codex-integration",
"codex-stored-main-duplicate.test.ts": "codex-integration",
"codex-account-slot-identity.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 @@ -1501,6 +1509,6 @@ Original invocation order. These headings preserve links to the previous single-

## Counts

- declared capabilities: 363
- of those, state-changing: 222
- declared capabilities: 365
- of those, state-changing: 223
- head-resolved invocations: 2
45 changes: 43 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,53 @@ 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.
- Exit 0 requires an applied job; refused, not_applied, ambiguous and pending duplicate jobs exit 1, including with --json.
- 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
Loading
Loading