agents/openai.yaml
interface:
display_name: "AI Coding Agents — Release And Distribution"
short_description: "Design release and distribution systems for coding-agent CLIs"
default_prompt: "Use $ai-coding-agents-release-distribution to design packaging, update channels, plugin compatibility, cache migrations, or install footprints for a coding-agent CLI."
assets/templates/compatibility-matrix.md
# Release Compatibility Matrix
Tracks which runtime versions are compatible with which plugin API, cache schema, and settings schema versions. Update this table with every release. Incompatible combinations must be blocked at the upgrade gate.
---
## How to Use
- **Runtime version** — the released version of the coding-agent binary.
- **Plugin API** — the plugin manifest schema version the runtime loads. A plugin compiled against API `v2` will not load in a runtime that only supports `v1`.
- **Cache schema** — the on-disk session-cache format version. Incompatible cache schemas require a migration or a cache wipe on upgrade.
- **Settings schema** — the `settings.json` format version. Incompatible settings require a migration or reset to defaults.
- **Min plugin API** — oldest plugin API the runtime still accepts (for backwards compatibility).
- **Notes** — breaking changes or migration steps required.
---
## Matrix
| Runtime Version | Plugin API | Min Plugin API | Cache Schema | Settings Schema | Notes |
|----------------|-----------|----------------|--------------|-----------------|-------|
| `0.1.x` | `v1` | `v1` | `v1` | `v1` | Initial release |
| `0.2.x` | `v1` | `v1` | `v1` | `v1` | Bug fixes; no schema changes |
| `0.3.x` | `v2` | `v1` | `v1` | `v2` | Settings schema v2 adds `bypassPermissions` field; v1 settings auto-migrated on first launch |
| `0.4.x` | `v2` | `v1` | `v2` | `v2` | Cache schema v2 adds `resume_token`; v1 caches invalidated (wipe required); plugin API v1 still loads with deprecation warning |
| `1.0.x` | `v3` | `v2` | `v2` | `v3` | **BREAKING**: plugin API v1 dropped; cache v2 preserved; settings v3 adds `managedPolicy` block; migrate with `agent migrate-settings` |
| `1.1.x` | `v3` | `v2` | `v2` | `v3` | No schema changes; feature additions only |
| `1.2.x` | `v4` | `v3` | `v3` | `v3` | **BREAKING**: cache schema v3 encrypts session tokens; migration script required (`agent migrate-cache --encrypt`); plugin API v2 loads with deprecation warning |
---
## Upgrade Gate Rules
1. **Plugin API**: if a plugin's manifest `runtime.min_agent_version` is higher than the installed runtime version, refuse to load and surface a clear error.
2. **Cache schema**: if the on-disk cache schema version is newer than the runtime supports, refuse to start and prompt the user to downgrade or wipe.
3. **Settings schema**: if the settings file schema version is newer than the runtime supports, load with defaults and warn. Never silently overwrite user settings.
4. **Downgrade protection**: if the runtime version is lower than the `baseline.min_runtime` recorded in a cache file, refuse to open the cache (downgrade-protection).
---
## Migration Commands
| From → To | Command | Side Effects |
|-----------|---------|--------------|
| Settings v1 → v2 | Automatic on first launch | Adds `bypassPermissions: false` |
| Cache v1 → v2 | Automatic on first launch | Existing sessions lose `resume_token`; they can still be re-opened from transcript |
| Cache v2 → v3 | `agent migrate-cache --encrypt` | Tokens encrypted at rest; old unencrypted cache deleted |
| Settings v2 → v3 | `agent migrate-settings` | Adds `managedPolicy: null`; existing policy rules preserved |
| Plugin API v1 → v2 | Update plugin `plugin.manifest.json` `runtime.min_agent_version` | Plugin author must bump manifest and re-publish |
assets/templates/deny.toml.example
# deny.toml.example
#
# Supply-chain security policy for coding-agent custom distributions.
# Based on the Goose custom-distro and cargo-deny pattern.
# Copy this file to your distribution's root as `deny.toml` and fill in values.
#
# This file is checked by the distribution build pipeline before packaging.
# A build that violates any rule below must fail with a clear error message.
[meta]
# Minimum deny.toml schema version the build tool must support.
schema_version = "1"
# ── Licenses ──────────────────────────────────────────────────────────────────
# Specify which licenses are allowed in runtime dependencies.
# Unlisted licenses cause the build to fail.
[licenses]
allow = [
"MIT",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"MPL-2.0", # copyleft but file-scoped; review before including
"CC0-1.0",
"Unlicense",
]
# Licenses that are explicitly denied.
deny = [
"GPL-2.0",
"GPL-3.0",
"AGPL-3.0", # network copyleft; incompatible with closed distributions
"LGPL-2.0",
"LGPL-2.1",
"LGPL-3.0",
"SSPL-1.0",
"BSL-1.1",
]
# Packages to exempt from the license check (e.g. dev-only tooling).
# Format: "package-name@version-range"
exceptions = [
# "some-dev-tool@*",
]
# ── Providers ─────────────────────────────────────────────────────────────────
# Pin which model providers are allowed in this distribution.
# Any provider not in this list will be rejected at runtime startup.
[providers]
allow = [
"anthropic",
# "openai",
# "gemini",
# "ollama",
]
# ── Plugins ───────────────────────────────────────────────────────────────────
# Control which plugins may be installed by end users.
[plugins]
# "all" allows any plugin from approved registries.
# "pinned" only allows plugins explicitly listed in [[plugins.pinned]].
mode = "pinned"
[[plugins.pinned]]
id = "example-plugin"
version = ">=1.0.0, <2.0.0"
sha256 = "abc123..." # set to the expected SHA-256 of the plugin archive
# ── Registries ────────────────────────────────────────────────────────────────
# Approved plugin registries. Only plugins from these registries will be fetched.
[registries]
allow = [
"https://plugins.yourorg.example/registry",
]
deny = [
# Block the public registry in enterprise distributions.
# "https://plugins.agent.example/registry",
]
# ── Network ───────────────────────────────────────────────────────────────────
# Egress policy for the distribution binary itself (not agent sandbox — see sandbox-policy.toml).
[network]
# Allow telemetry to your own endpoint only; deny to third-party analytics.
allow_telemetry_hosts = [
"telemetry.yourorg.example",
]
deny_telemetry_hosts = [
"analytics.third-party.example",
]
# ── Updates ───────────────────────────────────────────────────────────────────
[updates]
# Channel this distribution receives updates from.
channel = "stable" # stable | beta | nightly
# Minimum version that may be auto-installed. Prevents downgrade attacks.
min_auto_install_version = "1.0.0"
# Require cryptographic signature verification before installing updates.
require_signature = true
signing_key_path = "keys/update-signing.pub"
assets/templates/install-script-skeleton.sh
#!/usr/bin/env bash
# install-script-skeleton.sh
#
# Skeleton for a coding-agent distribution installer.
# Fill in the TODO sections before shipping.
#
# Design principles:
# 1. Detect platform and architecture before downloading anything.
# 2. Verify the downloaded archive against a SHA-256 checksum.
# 3. Check for conflicting existing installs before writing to disk.
# 4. Support dry-run mode (AGENT_INSTALL_DRY_RUN=1) for CI smoke tests.
# 5. Print clear resolution instructions on every failure, not just error codes.
#
# Usage:
# curl -fsSL https://get.yourorg.example/install.sh | bash
# AGENT_INSTALL_DRY_RUN=1 bash install.sh # dry-run: detect and plan, no writes
set -euo pipefail
# ── Configuration (fill in before shipping) ───────────────────────────────────
AGENT_NAME="your-agent" # TODO: set binary name
AGENT_VERSION="${AGENT_VERSION:-1.0.0}" # TODO: update on release
DOWNLOAD_BASE="https://releases.yourorg.example" # TODO: set your release CDN
INSTALL_DIR="${AGENT_INSTALL_DIR:-/usr/local/bin}" # override via env
CHECKSUM_URL="${DOWNLOAD_BASE}/${AGENT_VERSION}/checksums.txt"
DRY_RUN="${AGENT_INSTALL_DRY_RUN:-0}"
# ── Helpers ───────────────────────────────────────────────────────────────────
info() { echo "[install] $*"; }
warn() { echo "[install] WARN: $*" >&2; }
error() { echo "[install] ERROR: $*" >&2; exit 1; }
dry_run_guard() {
if [[ "$DRY_RUN" == "1" ]]; then
echo "[dry-run] would run: $*"
else
"$@"
fi
}
# ── 1. Detect OS and architecture ─────────────────────────────────────────────
detect_platform() {
local os arch
os="$(uname -s)"
arch="$(uname -m)"
case "$os" in
Linux) os="linux" ;;
Darwin) os="darwin" ;;
*) error "Unsupported OS: $os. Resolution: install manually from $DOWNLOAD_BASE." ;;
esac
case "$arch" in
x86_64 | amd64) arch="amd64" ;;
arm64 | aarch64) arch="arm64" ;;
*) error "Unsupported architecture: $arch. Resolution: install manually from $DOWNLOAD_BASE." ;;
esac
PLATFORM="${os}-${arch}"
info "Detected platform: $PLATFORM"
}
# ── 2. Check for existing install ─────────────────────────────────────────────
check_existing() {
if command -v "$AGENT_NAME" &>/dev/null; then
local existing_version
existing_version="$("$AGENT_NAME" --version 2>/dev/null | head -1 || echo "unknown")"
warn "$AGENT_NAME is already installed: $existing_version"
warn "Resolution: run '$AGENT_NAME update' to upgrade, or set AGENT_INSTALL_DIR to install alongside."
if [[ "$DRY_RUN" != "1" ]]; then
read -r -p "Overwrite existing install? [y/N] " answer
[[ "$answer" =~ ^[Yy]$ ]] || error "Installation cancelled."
fi
fi
}
# ── 3. Download archive ───────────────────────────────────────────────────────
download_archive() {
ARCHIVE_NAME="${AGENT_NAME}-${AGENT_VERSION}-${PLATFORM}.tar.gz"
ARCHIVE_URL="${DOWNLOAD_BASE}/${AGENT_VERSION}/${ARCHIVE_NAME}"
TMPDIR_LOCAL="$(mktemp -d)"
ARCHIVE_PATH="${TMPDIR_LOCAL}/${ARCHIVE_NAME}"
info "Downloading $ARCHIVE_URL"
if [[ "$DRY_RUN" == "1" ]]; then
echo "[dry-run] would download: $ARCHIVE_URL → $ARCHIVE_PATH"
return
fi
if command -v curl &>/dev/null; then
curl -fsSL --retry 3 "$ARCHIVE_URL" -o "$ARCHIVE_PATH"
elif command -v wget &>/dev/null; then
wget -q --tries=3 "$ARCHIVE_URL" -O "$ARCHIVE_PATH"
else
error "Neither curl nor wget found. Resolution: install curl or wget, then re-run this script."
fi
}
# ── 4. Verify checksum ────────────────────────────────────────────────────────
verify_checksum() {
if [[ "$DRY_RUN" == "1" ]]; then
echo "[dry-run] would verify SHA-256 of $ARCHIVE_PATH against $CHECKSUM_URL"
return
fi
info "Verifying checksum..."
local checksums_file="${TMPDIR_LOCAL}/checksums.txt"
if command -v curl &>/dev/null; then
curl -fsSL "$CHECKSUM_URL" -o "$checksums_file"
else
wget -q "$CHECKSUM_URL" -O "$checksums_file"
fi
local expected_hash
expected_hash="$(grep "$ARCHIVE_NAME" "$checksums_file" | awk '{print $1}')"
if [[ -z "$expected_hash" ]]; then
error "Checksum for $ARCHIVE_NAME not found in $CHECKSUM_URL. Resolution: report to the distribution maintainer."
fi
local actual_hash
if command -v sha256sum &>/dev/null; then
actual_hash="$(sha256sum "$ARCHIVE_PATH" | awk '{print $1}')"
elif command -v shasum &>/dev/null; then
actual_hash="$(shasum -a 256 "$ARCHIVE_PATH" | awk '{print $1}')"
else
error "No SHA-256 tool found (sha256sum or shasum). Resolution: install one, then re-run."
fi
if [[ "$actual_hash" != "$expected_hash" ]]; then
error "Checksum mismatch! Expected $expected_hash, got $actual_hash. Resolution: the archive may be corrupt or tampered; delete it and re-run."
fi
info "Checksum verified."
}
# ── 5. Extract and install ────────────────────────────────────────────────────
install_binary() {
if [[ "$DRY_RUN" == "1" ]]; then
echo "[dry-run] would extract $ARCHIVE_PATH and install binary to $INSTALL_DIR/$AGENT_NAME"
return
fi
info "Extracting archive..."
tar -xzf "$ARCHIVE_PATH" -C "$TMPDIR_LOCAL"
local binary_path="${TMPDIR_LOCAL}/${AGENT_NAME}"
if [[ ! -f "$binary_path" ]]; then
# Some archives nest the binary in a subdirectory
binary_path="$(find "$TMPDIR_LOCAL" -type f -name "$AGENT_NAME" | head -1)"
[[ -n "$binary_path" ]] || error "Binary '$AGENT_NAME' not found in archive. Resolution: check the archive structure at $DOWNLOAD_BASE."
fi
dry_run_guard install -m 755 "$binary_path" "$INSTALL_DIR/$AGENT_NAME"
info "Installed $AGENT_NAME to $INSTALL_DIR/$AGENT_NAME"
}
# ── 6. Verify installed binary ────────────────────────────────────────────────
verify_install() {
if [[ "$DRY_RUN" == "1" ]]; then
echo "[dry-run] would verify: $AGENT_NAME --version"
return
fi
if ! "$INSTALL_DIR/$AGENT_NAME" --version &>/dev/null; then
error "Installed binary failed to run. Resolution: check that $INSTALL_DIR is in PATH and the binary is executable."
fi
info "Installed version: $("$INSTALL_DIR/$AGENT_NAME" --version 2>&1 | head -1)"
}
# ── 7. Cleanup ────────────────────────────────────────────────────────────────
cleanup() {
[[ -n "${TMPDIR_LOCAL:-}" ]] && rm -rf "$TMPDIR_LOCAL"
}
trap cleanup EXIT
# ── Main ──────────────────────────────────────────────────────────────────────
main() {
[[ "$DRY_RUN" == "1" ]] && info "DRY-RUN mode — no changes will be written."
detect_platform
check_existing
download_archive
verify_checksum
install_binary
verify_install
info "Installation complete. Run: $AGENT_NAME --help"
}
main "$@"
data/sources.json
{
"metadata": {
"skill": "ai-coding-agents-release-distribution",
"title": "AI Coding Agents Release And Distribution - Sources",
"description": "Official documentation and implementation references for packaging, update channels, plugin compatibility, and state migrations in coding-agent CLIs",
"last_updated": "2026-07-11",
"updated": "2026-07-11",
"total_sources": 12,
"version": "1.1"
},
"categories": {
"official_documentation": [
{
"name": "Anthropic Claude Code Documentation",
"url": "https://code.claude.com/docs/en/",
"type": "documentation",
"relevance": "Useful runtime-facing documentation for packaging expectations, settings, and extensions around Claude Code-class CLIs",
"update_frequency": "monthly",
"access": "free",
"add_as_web_search": true
},
{
"name": "Semantic Versioning Specification",
"url": "https://semver.org/",
"type": "specification",
"relevance": "Reference for compatibility policy across core runtime, plugins, and state schemas",
"update_frequency": "yearly",
"access": "free",
"add_as_web_search": true
}
],
"implementation_references": [
{
"name": "Claude Code GitHub Repository",
"url": "https://github.com/anthropics/claude-code",
"type": "repository",
"relevance": "Primary implementation reference for plugin cache, runtime state, and release-shape assumptions",
"update_frequency": "weekly",
"access": "free",
"add_as_web_search": false
},
{
"name": "Codex CLI Repository",
"url": "https://github.com/openai/codex",
"type": "repository",
"relevance": "Cross-runtime comparison point for packaging and distribution patterns in AI coding CLIs",
"update_frequency": "monthly",
"access": "free",
"add_as_web_search": false
},
{
"name": "OpenAI Codex CLI Main Source",
"url": "https://github.com/openai/codex/blob/9f42c89c0112771dc29100a6f3fc904049b2655f/codex-rs/cli/src/main.rs",
"type": "repository_source",
"relevance": "Pinned first-party source for install/update/doctor/app-server subcommands and CLI release surface boundaries",
"update_frequency": "pinned",
"access": "free",
"add_as_web_search": false
},
{
"name": "OpenAI Codex Doctor Source",
"url": "https://github.com/openai/codex/tree/9f42c89c0112771dc29100a6f3fc904049b2655f/codex-rs/cli/src/doctor",
"type": "repository_source",
"relevance": "Pinned first-party source for install provenance, update-target checks, sandbox helper readiness, app-server status, and redacted JSON diagnostics",
"update_frequency": "pinned",
"access": "free",
"add_as_web_search": false
},
{
"name": "OpenAI Codex Product Page",
"url": "https://openai.com/codex/",
"type": "product_page",
"relevance": "Current first-party distribution and product-surface context for Codex app, CLI, IDE, worktrees, skills, and enterprise workflows",
"update_frequency": "monthly",
"access": "free",
"add_as_web_search": true
},
{
"name": "Model Context Protocol Specification",
"url": "https://modelcontextprotocol.io/",
"type": "specification",
"relevance": "Reference for compatibility boundaries when CLI releases affect server, tool, or plugin interfaces",
"update_frequency": "quarterly",
"access": "free",
"add_as_web_search": true
},
{
"name": "Linux Foundation: Formation of the Agentic AI Foundation",
"url": "https://www.linuxfoundation.org/press/linux-foundation-announces-the-formation-of-the-agentic-ai-foundation",
"type": "press_release",
"relevance": "December 2025 announcement of AAIF formation; founding Platinum members: AWS, Anthropic, Block, Bloomberg, Cloudflare, Google, Microsoft, OpenAI; 170+ total members. Governance and trust baseline for AAIF-hosted OSS coding agents.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": false
},
{
"name": "Claude Code Settings (autoUpdatesChannel, DISABLE_AUTOUPDATER, requiredMinimumVersion / requiredMaximumVersion / minimumVersion)",
"url": "https://code.claude.com/docs/en/settings",
"type": "documentation",
"relevance": "Verified 2026-07-11: autoUpdatesChannel takes only \"latest\" (default) or \"stable\" (no \"disabled\" value exists); updates are stopped via the DISABLE_AUTOUPDATER env var, a separate control. requiredMinimumVersion/requiredMaximumVersion are managed-settings-only hard startup blockers that fail open on an invalid value (stripped, not enforced); minimumVersion is the older soft floor that blocks downgrades but not startup. Relevant to enterprise-managed distribution and update-channel design.",
"update_frequency": "monthly",
"access": "free",
"add_as_web_search": true
},
{
"name": "OpenAI Codex Environment Variables Reference (CODEX_HOME) and GitHub install instructions",
"url": "https://developers.openai.com/codex/environment-variables",
"type": "documentation",
"relevance": "Verified 2026-07-11: CODEX_HOME overrides the root directory (default ~/.codex) for config.toml, auth.json, logs, transcripts, and plugin metadata; it is a state-root override, not an install channel. Confirmed exact install commands: npm install -g @openai/codex (scoped package name is load-bearing) and brew install --cask codex.",
"update_frequency": "monthly",
"access": "free",
"add_as_web_search": true
},
{
"name": "Goose 2.0: ACP and new TUI",
"url": "https://goose-docs.ai/blog/2026/04/08/goose-acp-and-new-tui/",
"type": "announcement",
"relevance": "April 8, 2026: Goose 2.0 architecture — TypeScript TUI beta, Electron → Tauri desktop migration, ACP as default server interface. Case study for desktop-runtime upgrade as a distribution concern.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": false
}
]
}
}
learnings.consolidated.md
# ai-coding-agents-release-distribution — Consolidated Learnings
Curated, dated, committed memory for this skill. Pruned from raw `learnings.md` via `agents-skills-feedback-loop/scripts/consolidate.py`. Human-approved.
Cap: 60 entries. When exceeded, promote durable rules to `references/`.
## Filter Override
<!-- Add 2-4 bullets that sharpen what counts as a learning for this skill. Leave empty to use the default filter from agents-skills-feedback-loop/references/learnings-format.md. -->
## Patterns That Work
## Mistakes to Avoid
## Domain Knowledge
## Open Questions
## Consolidated Principles
learnings.md
# ai-coding-agents-release-distribution — Raw Learnings
Dated, append-only. Consolidated periodically into `learnings.consolidated.md` via `agents-skills-feedback-loop/scripts/consolidate.py`.
- 2026-07-11: Audited SKILL.md and references against current primary sources (code.claude.com/docs/en/settings, github.com/openai/codex, developers.openai.com/codex, Linux Foundation/AAIF press materials, goose-docs.ai). Confirmed `autoUpdatesChannel` only accepts `latest`/`stable` (no `disabled` value) and that updates are stopped via `DISABLE_AUTOUPDATER`, not a channel setting — added this as an explicit Known Trap since a sibling skill in this cluster had fabricated a `"disabled"` channel value. Confirmed `requiredMinimumVersion`/`requiredMaximumVersion` are managed-settings-only and fail open (invalid value stripped, not enforced) rather than being unconditional hard blocks — added as expert-judgment nuance for anyone designing their own version gates. Corrected the Codex reference file: `CODEX_HOME` is a state-root override (default `~/.codex`), not itself an install channel; verified exact commands `npm install -g @openai/codex` and `brew install --cask codex`. AAIF formation date (Dec 9, 2025) and Goose 2.0 Electron→Tauri migration (blog dated April 8, 2026) both check out against current sources and were left largely as-is.
references/cache-migrations-and-install-channels.md
# Cache Migrations And Install Channels
Local state is part of the product surface for a coding-agent CLI.
## Version what matters
Version these independently when needed:
- session-state schema
- plugin cache schema
- tool-registry cache schema
- settings or policy schema
- binary or package version
One app version number is rarely enough to reason about all local state safely.
## Migration rules
- Prefer additive migrations where possible.
- Keep startup checks fast and deterministic.
- Make destructive cache resets explicit when they are unavoidable.
- Support downgrade detection, not only upgrade migration.
- Separate “must migrate now” from “best-effort cleanup.”
## Install-channel behavior
Different channels may justify different migration posture:
- stable should bias toward conservative compatibility
- beta may run migrations earlier but must still surface risk clearly
- nightly can invalidate caches aggressively, but only if the product makes that expectation explicit
## Edge cases
- **Old session resumes on new binary**: decide whether resume is supported, migrated, or blocked with an explanation.
- **Plugin cache from incompatible channel**: a stable binary should not blindly trust a nightly-generated cache.
- **Rollback after partial migration**: if rollback is possible, keep enough version metadata to refuse unsafe startup.
- **Local footprint growth**: logs, traces, session histories, and downloaded registries need retention limits.
## Practical tip
The cleanest migration system is the one that can explain, in one sentence, why a given local artifact is reused, migrated, or discarded.
references/openai-codex-install-update-and-doctor.md
# OpenAI Codex Install Update And Doctor
Source snapshot: OpenAI Codex commit `9f42c89c0112771dc29100a6f3fc904049b2655f` (2026-05-24), especially `README.md`, `codex-rs/cli/src/main.rs`, `codex-rs/cli/src/doctor`, `.github/scripts/build-codex-package-archive.sh`, and `codex-rs/app-server-daemon/README.md`.
Web sources checked 2026-05-25:
- Codex product page: https://openai.com/codex/
- OpenAI, "Running Codex safely at OpenAI", May 8, 2026: https://openai.com/index/running-codex-safely/
- OpenAI, "Building a safe, effective sandbox to enable Codex on Windows", May 13, 2026: https://openai.com/index/building-codex-windows-sandbox/
Re-verified 2026-07-11 against `github.com/openai/codex` (install methods, npm/Homebrew commands) and `developers.openai.com/codex/environment-variables` (`CODEX_HOME` semantics). Install-channel commands and `CODEX_HOME` behavior below confirmed current as of this date.
## Table Of Contents
- [Design Goal](#design-goal)
- [Install Channels](#install-channels)
- [Update Target Checks](#update-target-checks)
- [Package Variants](#package-variants)
- [Doctor As Release Support](#doctor-as-release-support)
- [Known Traps](#known-traps)
## Design Goal
Release design for a coding-agent CLI must cover more than publishing a binary. Codex has multiple install paths, managed package roots, app-server variants, update checks, sandbox helpers, plugin bundles, and diagnostics that explain whether an update will hit the running install.
## Install Channels
Codex supports (verified 2026-07-11 against `github.com/openai/codex` and `developers.openai.com/codex`):
- hosted install script (`curl -fsSL https://chatgpt.com/codex/install.sh | sh`; PowerShell equivalent for Windows)
- npm package: `npm install -g @openai/codex` (the unscoped `codex` package on npm is an unrelated project — the scope is load-bearing)
- Homebrew cask: `brew install --cask codex`
- GitHub release archives (platform-specific binaries, e.g. `codex-aarch64-apple-darwin.tar.gz`, `codex-x86_64-unknown-linux-musl.tar.gz`)
`CODEX_HOME` is not itself an install channel — it is an environment variable that overrides the root directory (`~/.codex` by default) for all persistent state: `config.toml`, `auth.json`, logs, session transcripts, and installed-plugin metadata. Any of the four channels above can point at a relocated `CODEX_HOME` (e.g. a project-scoped automation identity: `CODEX_HOME=$(pwd)/.codex codex exec ...`). Do not conflate "where Codex is installed" with "where Codex keeps its state" — they vary independently, and a doctor/diagnostic check needs both.
For your own runtime, document which channel is authoritative for each environment and what update command owns it.
## Update Target Checks
Codex doctor checks whether an npm update would target the package root that launched the current binary. This prevents a common failure: `npm install -g` updates one installation while the shell keeps running another.
Copy the pattern:
- record install provenance at launch
- compare update target with running package root
- warn when the update command cannot be proven
- include remediation, not just a failed status
## Package Variants
Codex release scripts distinguish primary and app-server package bundles. The app-server entrypoint is a separate release concern because remote clients may depend on it independently of the interactive CLI.
Design implication:
- treat CLI, app-server, shell completions, sandbox helpers, and plugin bundle archives as release artifacts with compatibility contracts
- version their schemas and protocol boundaries
- test partial upgrade and downgrade behavior
## Doctor As Release Support
Codex's `doctor` command is part of release distribution. It checks installation, updates, config, auth, MCP, sandbox helpers, terminal environment, app-server state, and more. It can emit redacted JSON for support tooling.
Release checklist:
- every install channel should be diagnosable
- every helper binary should have a readiness check
- every update path should have a target check
- remote/app-server background state should be inspectable without mutating it
## Known Traps
- Publishing several install channels without proving which one `update` affects.
- Treating app-server as an internal detail when remote clients depend on it.
- Shipping sandbox helpers without doctor checks for missing or unsupported helpers.
- Making support ask users for screenshots instead of a redacted JSON report.
- Updating daemon and app-server processes in the wrong order.
references/packaging-updates-and-compatible-plugins.md
# Packaging, Updates, And Compatible Plugins
Treat a coding-agent CLI as a distributed product, not just a local binary.
## Packaging questions to answer early
- how the CLI is installed
- whether dependencies are embedded or discovered dynamically
- whether plugins ship in-tree, from a marketplace, or from local paths
- how enterprise-managed installs differ from self-serve installs
## Update channels
Common channels:
- stable
- beta
- nightly
- enterprise-pinned or managed
Each channel should define:
- who receives it
- how fast it rolls out
- whether auto-update is allowed
- what rollback path exists
## Plugin compatibility
Keep separate compatibility contracts for:
- core runtime API
- plugin manifest shape
- plugin capability negotiation
- cached plugin assets
Do not let “plugin installed successfully” imply “plugin is semantically compatible.”
## Edge cases
- **Marketplace lag**: a plugin built for the previous core version may still install but behave incorrectly.
- **Partial upgrades**: cached plugin bundles or generated metadata may survive an upgrade and need a compatibility check at startup.
- **Managed enterprise builds**: channel pinning and plugin allowlists may intentionally lag the public release cadence.
- **Remote runtimes**: client and server versions may differ and need explicit negotiation rather than optimistic assumptions.
## Practical tip
The runtime should detect plugin or cache incompatibility before a user starts a session, not halfway through a task.
SKILL.md
---
name: ai-coding-agents-release-distribution
description: "Designs release and distribution systems for coding-agent CLIs. Use when modeling packaging, auto-update channels, plugin compatibility, cache migrations, or install footprints."
compatibility: Portable core. Works on Claude Code and Codex.
version: "1.1"
last_validated: 2026-07-11
---
# AI Coding Agents Release And Distribution
Use this skill to design or review how a coding-agent CLI ships and evolves: packaging, install channels, auto-update policy, plugin compatibility, cache versioning, migration strategy, and local footprint management.
This skill covers the productization layer that matters once the runtime itself already exists.
## ASCII Flow
```text
runtime build
|
v
package artifact
binary/app bundle/npm/pip/homebrew + bundled assets + plugin ABI
|
v
release channel
dev | canary | stable | enterprise-managed
|
v
install or update
compatibility checks + cache migrations + rollback hooks
|
v
post-update verification
version, plugin compatibility, migrated state, telemetry, rollback signal
```
## Quick Reference
| Question | Read | Outcome |
|----------|------|---------|
| How should packaging, updates, and compatibility work? | [`references/packaging-updates-and-compatible-plugins.md`](references/packaging-updates-and-compatible-plugins.md) | Install channels, version policy, plugin compatibility, and release discipline |
| How should caches, migrations, and local state evolve safely? | [`references/cache-migrations-and-install-channels.md`](references/cache-migrations-and-install-channels.md) | Cache keys, migration boundaries, rollback posture, and footprint control |
| How does OpenAI Codex handle install channels, update targets, app-server packages, and doctor? | [`references/openai-codex-install-update-and-doctor.md`](references/openai-codex-install-update-and-doctor.md) | Install provenance, update target checks, package variants, redacted support diagnostics |
## When To Use
- Design packaging and distribution for a coding-agent CLI
- Add auto-update channels or controlled rollout strategy
- Review plugin compatibility and extension version policy
- Model local caches, migration safety, or install footprint changes
- Decide how release engineering should handle breaking runtime changes
## Use Other Skills
| Need | Use Instead |
|------|-------------|
| Plugin manifest and extension architecture | [`../ai-coding-agents-plugins/SKILL.md`](../ai-coding-agents-plugins/SKILL.md) |
| Settings and policy migration concerns | [`../ai-coding-agents-settings-policy/SKILL.md`](../ai-coding-agents-settings-policy/SKILL.md) |
| Session-state compatibility and resume boundaries | [`../ai-coding-agents-sessions/SKILL.md`](../ai-coding-agents-sessions/SKILL.md) |
| Broader coding-agent architecture | [`../ai-coding-agents/SKILL.md`](../ai-coding-agents/SKILL.md) |
## Default Workflow
1. **Define the artifact strategy.** Decide what ships as the CLI, what is embedded, and what is loaded dynamically.
2. **Design install channels.** Stable, beta, nightly, enterprise-pinned, or managed-distribution channels should be explicit.
3. **Version compatibility intentionally.** Core runtime, plugin API, cache schema, and settings schema may need separate compatibility promises.
4. **Treat caches as versioned state.** Cache invalidation should be tied to schema and compatibility boundaries, not only app version.
5. **Plan safe migrations.** Upgrade, downgrade, rollback, and partial-update behavior should be defined before shipping breaking changes.
6. **Constrain local footprint.** Logs, caches, session state, tool registries, and downloaded integrations need bounded retention policy.
7. **Clean up orphaned state.** Old plugin versions and abandoned cache layouts need retention and garbage-collection rules.
8. **Protect user trust during rollout.** Make plugin breakage, cache resets, or session migration visible when they materially affect behavior.
9. **Test upgrade paths.** New installs, in-place upgrades, old-cache startup, plugin version mismatch, and rollback should all be exercised.
## Host Rules
- Keep runtime versioning distinct from plugin or extension compatibility.
- Prefer additive migrations, with explicit breaking boundaries when unavoidable.
- Version caches and local state independently from binary packaging.
- Make rollback behavior a first-class release concern.
- Bound local cache and log growth so the CLI does not silently accumulate unowned disk usage.
- Treat managed enterprise distribution as a different channel, not just a different flag.
- Cache keys should include compatibility-relevant install context when plugins can come from paths, subdirs, or repackaged sources.
## Scratch-Rebuild Coverage
- Coverage strength:
strong for release channels, compatibility boundaries, versioned state, rollback framing, local-footprint discipline, and the requirement that plugin and cache identity be treated as separate compatibility surfaces
- Missing for faithful reproduction:
cross-version plugin API contracts, staged rollout telemetry, orphaned-version cleanup, cache-schema migration choreography, and downgrade behavior across partially updated hosts need more operational detail
- Required additions:
document compatibility matrices for core versus plugins versus caches, cache-key rules for path or subdir installs, rollout and rollback observability requirements, and spell out how partial upgrades fail safely
## Build Order
1. Define the shipping artifact and install surfaces.
2. Define release channels and rollout policy.
3. Separate compatibility promises for runtime, plugins, caches, and settings.
4. Add versioned migrations and rollback rules.
5. Define cache identity and orphan-cleanup policy.
6. Add footprint controls for logs, caches, and downloaded integrations.
7. Add staged rollout telemetry and downgrade tests.
## Core Invariants
- Binary version, plugin API version, and cache schema version are different contracts.
- Rollback is part of release design, not a later repair.
- Users must be told when upgrades reset or invalidate meaningful local state.
- Enterprise-managed distribution is a first-class operating mode.
- Install footprint growth must be bounded and owned.
- Obsolete plugin versions and caches must have explicit retention and cleanup rules.
## Failure Modes
- New binaries booting against incompatible old caches with silent corruption.
- Plugin breakage hidden behind a “successful” core update.
- Rollbacks that leave migrated state unreadable to the previous version.
- Partial updates where helpers, plugins, and core disagree on protocol.
- Long-term disk growth from logs, caches, or downloaded runtimes with no retention policy.
- Different plugin installs sharing one cache identity and corrupting each other across upgrades.
## Minimal Viable Version
- One shipping artifact and one documented install path.
- One stable channel and one pre-release channel.
- One versioned cache schema.
- One explicit rollback posture.
- One retention rule for orphaned plugin versions or cache directories.
- One visible warning path for incompatible plugin or cache state.
## What Strong Implementations Add
- Multi-channel rollout with staged exposure and telemetry.
- Compatibility matrices across core, plugins, settings, and caches.
- Automatic migration with safe fallback or quarantine on failure.
- Orphaned-version cleanup and cache identities that incorporate install context.
- Bounded retention for session logs, caches, and downloaded assets.
- Enterprise-pinned or managed-distribution release streams.
- **Custom Distributions** as a distinct channel class, with pinned upstream commit, manifest, and distro ID visible in `--version`.
- **OSS install scripts** (`*.sh` + `*.ps1`) committed to the repo with checksum verification and unattended-install modes.
- **Foundation-level governance** (OSS license, maintainers, security disclosure, supply-chain gates like `deny.toml`).
- **Recipe/manifest static scanners** so YAML artifacts face the same gating as compiled code.
## Known Traps
- Treating a binary version number as the only compatibility signal while plugin APIs, cache schema, and managed policy have their own break surfaces.
- Shipping state or cache migrations without downgrade planning and then stranding users who roll back or switch channels.
- Assuming fresh-install test coverage proves upgrade safety for existing operators with old caches, old plugins, and customized settings.
- Reusing one cache namespace across different install sources, channels, or packaging layouts and creating subtle runtime corruption.
- Calling enterprise distribution “the same build with different flags” when policy, update cadence, or bundled capabilities differ materially.
- Fabricating or copy-pasting update-channel/version-gate key names and allowed values instead of checking current vendor docs — e.g. inventing an `autoUpdatesChannel: "disabled"` value that doesn't exist (the real values are `latest`/`stable`; updates are stopped via `DISABLE_AUTOUPDATER`, a separate control). Any config key, env var, or CLI flag you generate for a real host product must be verified against that product's current docs, not inferred from a plausible-sounding pattern.
## Common Anti-Patterns
- Treating semantic version of the binary as the only compatibility signal.
- Shipping cache migrations without downgrade planning.
- Assuming plugin authors will discover breakage without host-level checks.
- Reusing one cache namespace for plugin installs that came from materially different paths or subdirs.
- Calling enterprise distribution “the same build with different flags.”
- Ignoring install footprint because each file seems small in isolation.
## Cross-Platform Patterns (Goose)
Goose's distribution model is more explicit than the Claude Code lineage on three fronts: white-label custom distributions, OSS-style install scripts, and foundation-level governance.
### Custom Distributions — white-label as a first-class channel
Goose supports `CUSTOM_DISTROS.md`: preconfigured builds with specific providers, extensions, branding, and bundled recipes. This is not a flag on the same binary — it is a distinct shipping artifact with a narrowed capability envelope and baked-in policy.
- **Pattern:** treat custom distros as a separate channel class, parallel to stable/beta/nightly. Compatibility matrices must track distro identity because a custom distro's plugin set is frozen at build time.
- **Anti-pattern:** representing enterprise or partner builds as "stable channel with a config file." That leaks partner-specific providers into the upstream compatibility matrix and makes breakage attribution impossible.
- **Recipe:** give each custom distro a distro ID, a pinned upstream commit, a recipe/extension manifest, and its own update policy. Users must see (in `--version` output and in telemetry) that they are on a distro build, not the main stable.
### Install-script duality and OSS install surface
Goose ships `download_cli.sh` and `download_cli.ps1` as canonical OSS install paths, alongside platform package managers. The scripts are the contract — they pin channel resolution, signature verification, and binary placement.
- **Pattern:** commit install scripts into the repo root with public, stable URLs. They serve as the source-of-truth install path when package managers are unavailable (CI, air-gapped, bleeding-edge).
- **Anti-pattern:** depending on one package manager (Homebrew-only, npm-only) as the install path for a coding agent that needs to reach varied developer environments.
- **Recipe:** one script per platform family (`sh` + `ps1`), each with explicit channel flag, checksum verification, and a documented unattended-install mode for enterprise automation.
### Governance and foundation-level trust
Goose operates under the **Agentic AI Foundation (AAIF)** within the Linux Foundation (founding contributors Block, Anthropic, OpenAI; transferred April 7, 2026; 170+ member organizations including AWS, Google, Microsoft et al.; Apache-2.0 license; documented `GOVERNANCE.md`, `MAINTAINERS.md`, `SECURITY.md`). For OSS coding agents, foundation-level governance is a trust signal for enterprise distribution.
- **Pattern:** separate release engineering (binary + update channels) from governance (who can accept a maintainer PR, who signs releases, who has CVE coordination authority). Both belong in the distribution surface.
- **Anti-pattern:** treating "open source" as a single checkbox. Enterprises buying custom distros need to know the upstream governance, release signing, and vulnerability-disclosure paths.
- **Recipe:** alongside release channels, publish `GOVERNANCE.md`, `MAINTAINERS.md`, `SECURITY.md`, and `deny.toml` (supply-chain gates). The `recipe-scanner` pattern generalizes as "static analysis for shipped artifacts" — validate not only code but also the YAML recipes and plugin manifests that your distro ships.
### Update channels, disabling auto-update, and enterprise version-pinning (Claude Code, verified 2026-07-11)
Claude Code's real update-channel surface is smaller than "stable/beta/nightly" naming would suggest, and the exact keys matter because a wrong one silently no-ops.
- **`autoUpdatesChannel`** (user settings, `~/.claude/settings.json`) takes exactly two values: `"latest"` (default — most recent release) or `"stable"` (roughly a week behind, skips releases with known major regressions). There is no `"disabled"`, `"none"`, or `"off"` value — a config with one of those strings does not turn updates off, it is simply an invalid channel name. **Known trap:** at least one sibling skill in this cluster previously fabricated a `"disabled"` channel value; treat any coding-agent doc or generated config that sets `autoUpdatesChannel` to something other than `latest`/`stable` as suspect until re-verified against `code.claude.com/docs/en/settings`.
- **To actually stop auto-updates**, set the `DISABLE_AUTOUPDATER` environment variable (e.g. `"env": {"DISABLE_AUTOUPDATER": "1"}` in settings.json, or export it in the shell/container). Channel selection and the update kill-switch are two different controls — don't conflate "pick a channel" with "turn updates off."
- **`requiredMinimumVersion`** and **`requiredMaximumVersion`** are managed-settings-only fields (MDM or a system `managed-settings.json`, never user/project settings) that block startup entirely outside the declared range — the CLI exits with an instruction to install an approved version. Contrast with the older **`minimumVersion`**, a soft floor that blocks downgrades via `claude update`/auto-update but does not stop a user already on an older build from starting Claude Code.
- **Fail-open nuance (the part non-experts miss):** an invalid or malformed `requiredMinimumVersion`/`requiredMaximumVersion` value is stripped rather than enforced — a bad policy push cannot brick the fleet by accidentally locking everyone out. Design your own hard version gates the same way: validate the gate value at the point it is *set*, and make the runtime's response to a malformed gate "ignore and log," never "refuse to start."
- **Pattern:** use `requiredMinimumVersion` to enforce a security patch floor and `requiredMaximumVersion` to freeze a release for a compliance period; use `autoUpdatesChannel: "stable"` for teams that want fewer regressions rather than a hard version freeze; use `DISABLE_AUTOUPDATER` only when a separate release process (image baking, golden AMI, offline install) already owns the version.
- **Anti-pattern:** using `minimumVersion` when you need a hard block, or assuming a channel setting also disables updates. A soft floor does not stop a user on an older build from starting Claude Code, and a channel choice is not a kill-switch.
- **Recipe:** document the current pinned range and channel choice in your enterprise settings file alongside the last-verified date. Track version bumps as a first-class release-communication concern, and re-verify exact key names against current docs before generating configs for users — do not rely on memory or a prior skill's copy.
### Desktop-runtime upgrade: Electron to Tauri (Goose 2.0, April 2026)
Goose 2.0 is migrating the desktop app from Electron to Tauri. Both old (Electron) and new (Tauri) desktop clients communicate with the shared ACP daemon rather than bundling separate runtimes. The migration is a case study for custom distribution operators: the distribution artifact changes (app bundle, binary size, OS trust signing), but the protocol contract (ACP) is stable. Users on old desktop builds can still interact with the new daemon; the surface change is UI, not protocol.
- **Pattern:** when migrating desktop runtimes, stabilize the daemon protocol first. Distribution channels then ship the new UI as a separate upgrade path from the daemon, and rollback is the previous UI version, not a full revert.
- **Anti-pattern:** coupling the desktop runtime to the daemon version with a hard parity check. That forces simultaneous upgrades for all distribution tiers and eliminates the rollback option for the UI.
### Build-time supply-chain gates (deny.toml + recipe-scanner)
Goose uses `deny.toml` (cargo-deny) for license/advisory/source gating at build, and `recipe-scanner/` to statically validate the recipes that will ship with the binary.
- **Pattern:** every shipping artifact — binary, plugin, recipe, extension manifest — has a build-time static gate. Nothing reaches a release channel without passing.
- **Anti-pattern:** scanning only code. Recipes and plugin manifests are executable-ish too; ship them through static validation as well.
## Navigation
### References
- [`references/packaging-updates-and-compatible-plugins.md`](references/packaging-updates-and-compatible-plugins.md) — Packaging, update policy, release channels, and plugin compatibility
- [`references/cache-migrations-and-install-channels.md`](references/cache-migrations-and-install-channels.md) — Cache versioning, state migrations, rollback, and local footprint control
- [`references/openai-codex-install-update-and-doctor.md`](references/openai-codex-install-update-and-doctor.md) — OpenAI Codex install channels, update target checks, app-server package variants, and doctor diagnostics
### Data
- [`data/sources.json`](data/sources.json) — Primary docs and implementation references for coding-agent release and distribution design
### Related Skills
- [`../ai-coding-agents-plugins/SKILL.md`](../ai-coding-agents-plugins/SKILL.md)
- [`../ai-coding-agents-settings-policy/SKILL.md`](../ai-coding-agents-settings-policy/SKILL.md)
- [`../ai-coding-agents-sessions/SKILL.md`](../ai-coding-agents-sessions/SKILL.md)
## Fact-Checking
- Known bugs, regressions, framework/compiler/runtime footguns, and version-specific crash or workaround guidance must be verified against current primary web sources before being treated as current fact.
- Packaging and update mechanics depend heavily on the target OS, installer strategy, and enterprise controls. Preserve the release architecture, but verify the actual platform constraints before implementation.
- Cache and migration behavior must be tested on real upgraded installs, not only fresh environments.
## Learnings Loop
Before applying this skill on a non-trivial task, read `learnings.consolidated.md` in this directory (and `learnings.md` if present).
After applying it, if you encountered a pattern worth remembering, a mistake worth preventing, or a domain fact that surprised you, append one dated bullet to `learnings.md` via `agents-skills-feedback-loop/scripts/append_learning.py`. Do not modify `SKILL.md` itself.