Skip to content

feat(agent): refresh agent CLIs on docker build --force and flag stale images - #70

Merged
radim10 merged 2 commits into
masterfrom
feat/agent-docker-force-refresh
Oct 9, 2026
Merged

radim10 merged 2 commits into
masterfrom
feat/agent-docker-force-refresh

Conversation

@radim10

@radim10 radim10 commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Problem

agent docker build --force didn't actually update Claude Code or Codex. It ran a plain docker build, and Docker caches a RUN step by its command text, not by what the installer would download today, so the install layer was replayed from cache. Since the image pins both CLIs (DISABLE_AUTOUPDATER=1, read-only install tree), there was no way to upgrade them short of docker rmi + pruning the build cache.

Changes

--force now refreshes the image

  • Passes --pull so the base image (and its OS patches) is re-resolved.
  • For the default image, passes a fresh AGENT_CLI_CACHEBUST build arg. The ARG is declared just above the Claude Code/Codex install step, so only that step onward re-runs and the apt layer stays cached.
  • Custom profile Dockerfiles get --pull only (they don't declare the arg).
  • The implicit first-use build in agent run is unchanged.

Stale images are now visible

  • agent docker doctor shows the default image's age and the Claude Code/Codex versions inside it (read via a throwaway --network none container). --json gains default_image_created_at, default_image_stale, claude_code_version, codex_version. Staleness doesn't affect ready / the exit code.
  • agent run prints a one-line stderr hint when the agent runs from the default image and it's older than 14 days. One docker image inspect, no container start; suppressed by --silent; not shown for custom-image profiles.

Verification

  • agent docker build --force on a real image: Claude Code 2.1.292 → 2.1.295, Codex 0.160.1 → 0.162.0; the apt layer stayed CACHED.
  • agent docker doctor then reports built today (Claude Code 2.1.295, Codex 0.162.0).
  • New unit tests: build args with/without refresh (incl. a fresh cache-bust value per build), ARG placement in the Dockerfile, age formatting, the 14-day threshold, version parsing.
  • cargo fmt --check clean, cargo test passes; no new clippy warnings.

Test fix

sandbox_image_lifecycle now builds the default image only when it's missing. It used to do a cached rebuild every run, which re-tagged a developer's local :latest back to the first cached install layer and silently undid --force. Fresh CI runners still exercise the real build.

…e images

`agent docker build --force` replayed Docker's layer cache, which keys a
RUN step on its command text, so the rebuilt image kept the old Claude
Code and Codex binaries. A forced build now passes --pull and a fresh
AGENT_CLI_CACHEBUST build arg (declared just above the install step, so
the apt layer stays cached).

Since the image pins both CLIs, also surface when it goes stale:
`agent docker doctor` reports the image's age and the Claude Code/Codex
versions inside it, and `agent run` prints a rebuild hint once the
default image is older than 14 days.
A cached rebuild over an existing image re-tagged :latest to the first
cached install layer, undoing a `agent docker build --force` on every
test run with Docker available. Fresh CI runners still build it.
@radim10 radim10 self-assigned this Oct 9, 2026
@radim10
radim10 merged commit 369d9ba into master Oct 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant