Skip to content
Merged
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
11 changes: 5 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,11 @@
login` from silently writing a plaintext refresh token to the alternate
directory, including a workspace path that syncs back to the host.

- **Install Codex's complete runtime package** (#442) — Recent Codex releases
use a companion `codex-code-mode-host` executable, but coop installed only
the raw `codex` binary, causing Code Mode to fail closed at startup. Image
builds and `coop agent update --codex` now verify and install the upstream
package with its host and runtime resources intact, root-owned and behind a
shared current-release link.
- **Install the full native Codex package** (#442) — Image provisioning and
`coop agent update --codex` use OpenAI's native installer, preserving bundled
tools and upstream setup. The guest user owns the installation and can run
`codex update` directly. `/usr/local/bin/codex` remains a compatibility link,
and host-driven updates migrate older direct-binary installations.

- **`install.sh` and `coop update` verify provenance without a GitHub
credential** (#421) — Verification ran `gh attestation verify --repo
Expand Down
18 changes: 16 additions & 2 deletions docs/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,28 @@ This skips the guest bootstrap sequence entirely. The VM still includes both CLI

## Updating Codex

Codex is installed "latest at build time" during `coop setup` and has no background updater, so it stays at that version until the image is rebuilt. Unlike Claude Code, it does not refresh itself. coop installs the complete upstream package, including the `codex-code-mode-host` companion and runtime resources, under `/usr/local/lib/codex`; stable entrypoints live in `/usr/local/bin`. To update Codex in a running VM without rebuilding the image:
`coop setup` uses [OpenAI's native installer](https://developers.openai.com/codex/cli/)
to install the full Codex package, including bundled tools, as the configured
guest user. The installer manages its package under the user's home directory
and exposes `~/.local/bin/codex`. coop retains `/usr/local/bin/codex` as a
compatibility link for existing wrappers and scripts.

To update directly inside the VM, run `codex update` as the guest user; sudo
is not required. To update from the host:

```bash
coop agent update --codex # update Codex to the latest release
coop agent update --check # report installed vs. latest, change nothing
```

This re-runs coop's own Codex installer inside the guest as root, verifies the published package checksums, and switches the CLI and code-mode host through the same current-package link. To refresh the golden image so new VMs ship the latest Codex, rebuild it with `coop setup --rebuild`. See [`agent update`](commands.md#agent-update).
`coop agent update --codex` re-runs the native installer as the guest user and
refreshes the compatibility link. It also migrates older direct-binary
installations without rebuilding the VM or replacing the user's Codex config.
A profile-provided `/usr/local/bin/codex` is preserved during image setup;
an explicit update replaces it with the native installation.

Updates affect that VM. To refresh the golden image for new VMs, run
`coop setup --rebuild`. See [`agent update`](commands.md#agent-update).

## Local model support

Expand Down
10 changes: 5 additions & 5 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,11 @@ coop agent update [NAME] [--claude] [--codex] [--check] [-y]
With no agent flag, both agents are updated; passing both `--claude` and
`--codex` is the same as passing neither. The VM must be running.

Codex has no background updater, so `coop agent update --codex` re-runs coop's
own installer inside the guest as root. It installs the complete upstream
package, verifies its published checksums, and switches the CLI and code-mode
host through the same current-release link.
Claude Code already auto-updates in the background;
`coop agent update --codex` re-runs OpenAI's native installer as the guest
user, including when migrating an older direct-binary installation. The full
package stays in the user's home directory, with `/usr/local/bin/codex` linked
to `~/.local/bin/codex`. The guest user can also run `codex update` directly
without sudo. Claude Code already auto-updates in the background;
`coop agent update --claude` runs `claude update` now, synchronously — a
convenience rather than a fix.

Expand Down
10 changes: 6 additions & 4 deletions docs/images-and-profiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ Every template installs these packages regardless of profile selection.

**Claude Code CLI:** installed via the native installer during the template build.

**Codex CLI:** installed as a complete package during the template build. The
package contains the CLI, its code-mode host, and bundled runtime resources;
stable entrypoints under `/usr/local/bin` share one current-package link.
**Codex CLI:** installed with OpenAI's native installer as the guest user during
the template build. The full package, including bundled tools, stays under the
user's home directory. `~/.local/bin/codex` is the native launcher;
`/usr/local/bin/codex` is a compatibility link. The guest user can run
`codex update` directly without sudo.
The image also installs `/usr/local/bin/codex-account`, a wrapper used by
`[codex] auth = "chatgpt"` to run Codex with a D-Bus session and guest Linux
Secret Service storage. The wrapper and its three supporting packages
Expand All @@ -40,7 +42,7 @@ Codex, so it costs nothing at run time.

Both agents are installed at whatever version was current when the template was built, and that version is not part of the staleness hash — a plain `coop setup` does not refresh them. There are two ways to get newer agents:

- **A live instance:** `coop agent update [--claude] [--codex]` updates the binaries inside a running VM in place (see [`agent update`](commands.md#agent-update)). Claude Code also auto-updates itself in the background; Codex does not, so it is the one that typically needs this.
- **A live instance:** run `codex update` inside the VM, or `coop agent update [--claude] [--codex]` from the host (see [`agent update`](commands.md#agent-update)). Claude Code also auto-updates itself in the background.
- **The golden image:** `coop setup --rebuild` rebuilds the template from a fresh base, so every new instance ships the latest agents.

## Built-in profiles
Expand Down
11 changes: 9 additions & 2 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,19 @@ When adding new features, consider whether they should be covered here. New
commands or guest-visible changes are good candidates for a new test phase.

Run `python3 tests/test-integration-probes.py` for host-only regression tests
of address discovery, ping result handling, and bounded HTTP retries. These
use a temporary loopback HTTP server and require Python 3, Bash, and curl;
of Codex installer failure propagation, update/config assertions, address
discovery, ping result handling, and bounded HTTP retries. These use a
temporary loopback HTTP server and require Python 3, Bash, and curl;
Linux CI runs them. The full VM suite additionally checks these probes against
real guests. A host FORWARD policy other than ACCEPT still causes an explicit
skip of the routed guest-isolation probe, since it would mask the coop rule.

The full Codex update tests install native release `0.153.0` before running
`codex update` as the guest user, and require the installed version to change.
They compare the actual `config.toml` contents across host updates, self-updates,
and migration from a profile-provided system command. Package layout and
completeness remain the native installer's responsibility.

## Host-only bridge isolation test

`./tests/run-integration.sh --full` runs the bridge isolation gate before
Expand Down
7 changes: 7 additions & 0 deletions docs/trust-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,13 @@ These are deliberate and documented in [`AGENTS.md`](../AGENTS.md) /
[`docs/ARCHITECTURE.md`](ARCHITECTURE.md). Don't "fix" them without
understanding the rationale; do flag a change that *widens* them:

- **Native agent installers are trusted build inputs.** Provisioning fetches
Claude's installer from `claude.ai` and Codex's from
`https://chatgpt.com/codex/install.sh` over HTTPS, then runs them as the
configured guest user. On Firecracker this happens in the host-side chroot;
a chroot does not provide VM isolation. Lima provisioning and live agent
updates execute inside a VM. This build-time trust is distinct from the
untrusted guest boundary described above.
- **`DOCKER_INSECURE_NO_IPTABLES_RAW=1`** in the guest. The Firecracker CI
kernel lacks `iptable_raw`, so Docker 28+ can't install its raw-table
"direct access filtering" rule. Without it, other hosts on the guest's LAN
Expand Down
Loading