Minimum release age gate for developer CLI auto-updates

A supply-chain mitigation that delays devcontainer CLI updates until they are at least three days old.

The devcontainer updates its developer CLIs automatically on startup. To prevent a just-published, potentially compromised release from being installed immediately, the auto-updater now enforces a minimum release age. A tool must be public for at least three days before the devcontainer will install it.

Every tool block in the manifest now requires a minimumReleaseAgeDays value. When a newer version is known to exist, the gate walks backward through the release history to find the newest release that clears the bar. For Claude Code, Codex CLI, and pnpm, this works well. They are npm-installable, so the script bypasses their own updaters and uses a version-pinned npm install for the fallback candidate.

flowchart TD
  accTitle: Minimum release age gate decision flow
  accDescr: When a newer release exists, the gate checks whether it is at least three days old. An old-enough release installs directly. A too-young release triggers a walk back through release history for the newest release that clears the age bar; if one is found it installs, otherwise the update is held. An unconfirmable release age is also held.

  A["Newer release detected"] --> B{"At least 3 days old?"}
  B -->|Yes| C["Install this release"]
  B -->|No| D["Walk back through<br/>release history"]
  B -->|Age unconfirmable| G["HELD"]
  D --> E{"Eligible release found?"}
  E -->|Yes| F["Install that release"]
  E -->|No| G

  class G warn
A release younger than three days triggers a walk back through history for an eligible one; failure to confirm age at any step holds the update rather than installing it.

Antigravity is the exception to the fallback mechanism. It has no npm-style version pinning and no verified download URL for anything but its current latest version. It can only ever update to that latest version if it clears the age bar, or hold. It cannot fall back to an intermediate version. This is a permanent limitation of its distribution channel, not a gap to close later.

The startup log now distinguishes a policy-driven wait from a data problem with three distinct HELD statuses: a too-young target, no eligible release in the window, or an unconfirmed release age. With the gate in place, the devcontainer’s runtime update path is secure against supply-chain attacks that rely on immediate installation.