diff --git a/AGENTS.md b/AGENTS.md index 44ae58b..715dab0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,6 +4,15 @@ Docker image packaging [opencode](https://opencode.ai) into a production-ready dev container. Image variants are published to Docker Hub via Gitea Actions CI. Not a library or application — this is infrastructure (Dockerfiles, entrypoint scripts, docker-compose, documentation). +> **pi is deprecated here (since v1.17.2), removed in v2.0.0.** The +> `INSTALL_PI` build arg, the `with-pi` / `omos-with-pi` / `pi-only` +> variants, the `base-pi-only` published tag, and all `~/.pi`-related +> wiring are slated for removal. pi now ships from its own repo +> (`joakimp/pi-devbox`). Do not add new pi functionality here. Full +> removal plan + the `NPM_CONFIG_PREFIX` relocation: see +> `docs/CLEANUP-v2.0.0.md`. The pi-related descriptions below remain +> accurate only until the v2.0.0 removal lands. + ## File roles - `Dockerfile.base` — variant-independent layers (apt, locales, AWS CLI, Node.js, mempalace, gitea-mcp, user setup, chromadb prewarm, ENVs, entrypoints). Published as `joakimp/opencode-devbox:base-`. Rebuilt only when its content hash changes. diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ff345b..f436c5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,77 @@ Tags follow `v{opencode_version}[letter]` — bare tag for the first build on a ## Unreleased +## v1.17.2 — 2026-06-10 + +First container build on **opencode-ai `1.17.2`** (from `1.16.2`). This +release also **deprecates all pi support** ahead of its removal in v2.0.0, +and hardens the mempalace install. + +### Bumped: opencode-ai 1.16.2 → 1.17.2 + +`OPENCODE_VERSION` ARG in `Dockerfile.variant`. Bare `v1.17.2` tag per the +`v{opencode_version}` scheme. + +### Deprecated: pi support (removed in v2.0.0) + +pi has been decoupled into its own self-contained image, +[`joakimp/pi-devbox`](https://gitea.jordbo.se/joakimp/pi-devbox) (v1.0.0+, +which no longer FROMs `base-pi-only`). The pi paths in opencode-devbox are +now dead weight and are **deprecated as of v1.17.2, scheduled for removal in +v2.0.0**: + +- The `INSTALL_PI` build arg and all `PI_*` args. +- The `with-pi`, `omos-with-pi`, and `pi-only` build variants. +- The `base-pi-only[-vX.Y.Z]` tag published (to the `joakimp/pi-devbox` + repo) from this repo's CI. +- All `~/.pi`-related entrypoint wiring (pi-toolkit / pi-extensions deploy, + settings.json bootstrap, mempalace pi-bridge symlink, pi-fork / pi-obsmem + registration). + +What this release does: + +- Building with `INSTALL_PI=true` now prints a **build-time deprecation + warning** to stderr. +- README, DOCKER_HUB.md, and AGENTS.md mark the pi variants deprecated and + point to `joakimp/pi-devbox`. +- The full removal plan is documented in `docs/CLEANUP-v2.0.0.md`. + +**Migration:** pull `joakimp/pi-devbox:latest` directly instead of any +`*-with-pi` / `pi-only` opencode-devbox tag. opencode-only users are +unaffected by this release. + +#### ⚠ Heads-up for v2.0.0: global npm prefix relocation + +Today `NPM_CONFIG_PREFIX` points at the pi-specific `~/.pi/npm-global` +(backed by the `devbox-pi-config` named volume), so `npm install -g` as the +developer user persists across recreates. **v2.0.0 will move the prefix to a +neutral opencode path** (e.g. `~/.config/opencode/npm-global`). Consequences +for existing opencode users at the v2.0.0 upgrade: + +- Previously global-installed npm tools remain on disk in the old volume but + **drop off `PATH`** until migrated. +- The new prefix path is not currently a named volume, so persistence needs a + compose/volume update. + +v2.0.0 will ship a **one-time migration shim** (copies old prefix contents to +the new path on first run) and an updated volume mapping. This notice is the +one-release-cycle advance warning. + +### Hardened: mempalace install pinned + diary_write schema workaround + +- `MEMPALACE_VERSION` is now an explicit ARG (default `3.4.0`) in + `Dockerfile.base`; the install uses `mempalace==${MEMPALACE_VERSION}` + instead of an unpinned `uv tool install mempalace`. An unpinned install is + what silently swept in the broken `diary_write` schema. Mirrors pi-devbox. +- Added an idempotent, self-deactivating post-install patch that strips the + **top-level `anyOf`** from `mempalace_diary_write`'s `input_schema`. + Mempalace 3.3.x/3.4.0 advertise `anyOf:[{required:[entry]},{required:[content]}]` + at the schema root, which the Anthropic tools API rejects outright + (`input_schema does not support oneOf, allOf, or anyOf at the top level`), + breaking pi/Claude tool registration at session start. The handler still + accepts `content` server-side. Upstream: MemPalace/mempalace#1728, PR #1735. + Remove once a fixed mempalace release is pinned. + ### Fixed: smoke-test pi-extensions readiness race (test-only, no image change) `scripts/smoke-test.sh`'s entrypoint-deploy wait loop gated only on @@ -17,10 +88,7 @@ see fewer than 4 files under parallel build load. Observed on v1.16.2 run 370: `smoke-with-pi` saw `<4` while `smoke-omos-with-pi` / `smoke-pi-only` (identical pi-extensions `357fcc6`) both saw 8, skipping `build-variant-with-pi`. The wait loop now blocks until the *last*-deployed artifact (the `mempalace.ts` bridge -symlink) exists **and** the extension count has settled ≥ 4 (up to 45s). Affects -only when smoke samples the container — image bytes are unchanged, so this does -not warrant a new tag; it lands in the next release and is exercised by -`validate.yml` on this push. +symlink) exists **and** the extension count has settled ≥ 4 (up to 45s). ## v1.16.2 — 2026-06-08 diff --git a/DOCKER_HUB.md b/DOCKER_HUB.md index 5953511..1d68156 100644 --- a/DOCKER_HUB.md +++ b/DOCKER_HUB.md @@ -10,15 +10,16 @@ Designed for teams who want a reproducible coding-agent setup that runs the same |---|---| | `latest` / `vX.Y.Z` | Base image — opencode, Node.js, AWS CLI, dev tools | | `latest-omos` / `vX.Y.Z-omos` | Base + [oh-my-opencode-slim](https://github.com/alvinunreal/oh-my-opencode-slim) multi-agent orchestration and Bun | -| `latest-with-pi` / `vX.Y.Z-with-pi` | Base + [pi](https://github.com/earendil-works/pi) as alternative/complementary harness (shares the mempalace install with opencode) | -| `latest-omos-with-pi` / `vX.Y.Z-omos-with-pi` | OMOS + pi together | +| `latest-with-pi` / `vX.Y.Z-with-pi` | **DEPRECATED (removed in v2.0.0)** — Base + [pi](https://github.com/earendil-works/pi). Use [`joakimp/pi-devbox`](https://hub.docker.com/r/joakimp/pi-devbox) instead | +| `latest-omos-with-pi` / `vX.Y.Z-omos-with-pi` | **DEPRECATED (removed in v2.0.0)** — OMOS + pi together | All variants support `linux/amd64` and `linux/arm64`. -> A fifth, pi-without-opencode build is produced from the same `Dockerfile.variant` -> (`INSTALL_OPENCODE=false`) but is **not** published under this repo — it ships as -> the separate [`joakimp/pi-devbox`](https://hub.docker.com/r/joakimp/pi-devbox) -> image so an "opencode-devbox" tag never lacks opencode. +> **Looking for pi?** The `*-with-pi` / `pi-only` builds and the `base-pi-only` +> tag are **deprecated since v1.17.2 and will be removed in v2.0.0**. pi now +> ships as its own self-contained image: +> [`joakimp/pi-devbox`](https://hub.docker.com/r/joakimp/pi-devbox). Pull that +> directly instead of any pi-bearing opencode-devbox tag. ## Quick Start diff --git a/Dockerfile.base b/Dockerfile.base index f16f6bd..8ae25fa 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -259,14 +259,50 @@ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64" # Always installed in the base (variant-independent). Set # INSTALL_MEMPALACE=false at base-build time to shave ~300 MB. ARG INSTALL_MEMPALACE=true +# Pin mempalace explicitly (mirrors pi-devbox). An unpinned +# `uv tool install mempalace` is what silently swept in the broken +# diary_write top-level-anyOf schema (3.3.x/3.4.0) that breaks the +# Anthropic tools API; pinning makes every bump a deliberate, reviewable +# diff. Bump this in lockstep with pi-devbox's MEMPALACE_VERSION. +ARG MEMPALACE_VERSION=3.4.0 ENV UV_TOOL_DIR=/opt/uv-tools ENV UV_TOOL_BIN_DIR=/usr/local/bin RUN if [ "${INSTALL_MEMPALACE}" = "true" ]; then \ mkdir -p /opt/uv-tools && \ - uv tool install --no-cache mempalace && \ + uv tool install --no-cache "mempalace==${MEMPALACE_VERSION}" && \ /opt/uv-tools/mempalace/bin/python -c "import mempalace; print('mempalace', mempalace.__version__ if hasattr(mempalace, '__version__') else 'installed')" ; \ fi +# ── workaround: strip top-level anyOf from mempalace_diary_write schema ── +# Mempalace 3.3.x/3.4.0 advertise diary_write's input_schema with a +# top-level `anyOf: [{required:[entry]}, {required:[content]}]` to express +# "either entry or content must be supplied". Anthropic's tools API rejects +# top-level anyOf/oneOf/allOf, so pi/Claude fail at session start with +# `tools..custom.input_schema: input_schema does not support oneOf, +# allOf, or anyOf at the top level`. +# +# Patch the advertised schema to require ["agent_name", "entry"] and remove +# the anyOf block. The handler keeps accepting `content` server-side as a +# kwarg alias so existing callers still work. +# +# Idempotent and self-deactivating: once upstream releases the fix the +# regex no longer matches and this RUN is a silent no-op. +# Upstream tracking: +# https://github.com/MemPalace/mempalace/issues/1728 +# https://github.com/MemPalace/mempalace/pull/1735 +# TODO: remove this RUN once a mempalace release containing PR #1735 is on +# PyPI and installed by the line above. +RUN if [ "${INSTALL_MEMPALACE}" = "true" ]; then \ + MP_FILE="$(find /opt/uv-tools/mempalace -path '*/mempalace/mcp_server.py' | head -n1)" && \ + if [ -z "$MP_FILE" ]; then echo "mempalace mcp_server.py not found" >&2; exit 1; fi && \ + perl -0777 -i -pe 's/(?:[ \t]*\#[^\n]*\n)*[ \t]*"required":\s*\[\s*"agent_name"\s*\]\s*,\s*\n[ \t]*"anyOf":\s*\[\s*\n[ \t]*\{\s*"required":\s*\[\s*"entry"\s*\]\s*\}\s*,\s*\n[ \t]*\{\s*"required":\s*\[\s*"content"\s*\]\s*\}\s*,?\s*\n[ \t]*\]\s*,\s*\n/ "required": ["agent_name", "entry"],\n/s' "$MP_FILE" && \ + if grep -q '"required": \["agent_name", "entry"\]' "$MP_FILE"; then \ + echo "mempalace diary_write anyOf workaround: applied (or already clean)"; \ + else \ + echo "WARN: mempalace diary_write anyOf workaround did not match expected schema — upstream may have changed shape" >&2; \ + fi ; \ + fi + # ── mempalace-toolkit — bash wrappers for session/docs mining ──────── ARG INSTALL_MEMPALACE_TOOLKIT=true ARG MEMPALACE_TOOLKIT_REF=main diff --git a/Dockerfile.variant b/Dockerfile.variant index bddcac4..830380a 100644 --- a/Dockerfile.variant +++ b/Dockerfile.variant @@ -10,14 +10,19 @@ # ───────────────── ──────────────── ──────────── ────────── # base true false false # omos true true false -# with-pi true false true -# omos-with-pi true true true -# pi-only false false true +# with-pi *DEPR* true false true +# omos-with-pi*DEPR* true true true +# pi-only *DEPR* false false true # -# The `pi-only` variant is the single source of truth for the pi-devbox -# image (pi + companions, no opencode). It exists so pi-devbox can FROM it -# without inheriting opencode, while the pi install logic stays defined -# here in one place. +# DEPRECATION (since v1.17.2): the three pi-bearing variants (with-pi, +# omos-with-pi, pi-only) and the INSTALL_PI build path are DEPRECATED and +# will be REMOVED in v2.0.0. pi now ships from its own self-contained image: +# joakimp/pi-devbox:latest (https://gitea.jordbo.se/joakimp/pi-devbox). +# See docs/CLEANUP-v2.0.0.md for the removal plan. +# +# Until v2.0.0 the `pi-only` variant remains the source of truth for the +# legacy pi build (pi + companions, no opencode); pi-devbox v1.0.0+ no +# longer FROMs it. # # Pass `--build-arg BASE_IMAGE=:base-` to select the base. # The CI workflow computes the base hash from Dockerfile.base + rootfs/ @@ -42,7 +47,7 @@ ARG USER_NAME=developer # edit, so the cache-hit class of bug that bit pi-devbox v0.74.0.. # v0.75.5 cannot apply here. ARG INSTALL_OPENCODE=true -ARG OPENCODE_VERSION=1.16.2 +ARG OPENCODE_VERSION=1.17.2 RUN if [ "${INSTALL_OPENCODE}" = "true" ]; then \ NPM_CONFIG_PREFIX=/usr npm install -g opencode-ai@${OPENCODE_VERSION} && \ opencode --version ; \ @@ -81,6 +86,13 @@ ARG PI_OBSMEM_REPO=https://github.com/elpapi42/pi-observational-memory.git ARG PI_OBSMEM_REF=master RUN if [ "${INSTALL_PI}" = "true" ]; then \ set -e && \ + printf '%s\n' \ + "===========================================================" \ + "DEPRECATION WARNING: INSTALL_PI is deprecated in opencode-devbox" \ + "(since v1.17.2) and will be REMOVED in v2.0.0. Use the dedicated" \ + "image joakimp/pi-devbox:latest instead." \ + "See https://gitea.jordbo.se/joakimp/pi-devbox" \ + "===========================================================" >&2 && \ git_clone_retry() { \ url="$1"; ref="$2"; dest="$3"; \ for i in 1 2 3 4 5; do \ diff --git a/README.md b/README.md index ea061b2..6377d19 100644 --- a/README.md +++ b/README.md @@ -420,7 +420,8 @@ docker compose build --build-arg NVIM_VERSION=0.12.1 # pin to a specific versi | `INSTALL_MEMPALACE` | `true` | [MemPalace](https://github.com/MemPalace/mempalace) local AI memory system (~300 MB — disable to shrink image if you don't need MCP memory) | | `INSTALL_MEMPALACE_TOOLKIT` | `true` | [mempalace-toolkit](https://gitea.jordbo.se/joakimp/mempalace-toolkit) bash wrappers (`mempalace-session`, `mempalace-docs`). Cloned at build time from `MEMPALACE_TOOLKIT_REF` (default `main`). Requires `INSTALL_MEMPALACE=true`. | | `INSTALL_OMOS` | `false` | [oh-my-opencode-slim](https://github.com/alvinunreal/oh-my-opencode-slim) multi-agent orchestration (installs Bun and plugin) | -| `INSTALL_OPENCODE` | `true` | Install opencode. Set `false` to build a pi-only image (still includes Bun if `INSTALL_OMOS=true`; for a fully stripped pi-only image see the `pi-devbox` repo). | +| `INSTALL_PI` | `false` | **DEPRECATED (removed in v2.0.0)** — install pi alongside opencode. Use [`joakimp/pi-devbox`](https://gitea.jordbo.se/joakimp/pi-devbox) instead. | +| `INSTALL_OPENCODE` | `true` | Install opencode. Set `false` to build a pi-only image (still includes Bun if `INSTALL_OMOS=true`; for a fully stripped pi-only image see the `pi-devbox` repo). **Note: the pi-only path is deprecated and removed in v2.0.0.** | | `INSTALL_PI` | `false` | Install [pi](https://github.com/earendil-works/pi) as alternative/complementary harness. Both clones [pi-toolkit](https://gitea.jordbo.se/joakimp/pi-toolkit) (~5 MB) and [pi-extensions](https://gitea.jordbo.se/joakimp/pi-extensions) (~1 MB) into `/opt/`; entrypoint deploys them on container start. ~150 MB total image growth. | | `PI_VERSION` | `latest` | npm version of `@earendil-works/pi-coding-agent`. Floats by default (image rebuild = pi update). | | `PI_TOOLKIT_REF`, `PI_EXTENSIONS_REF` | `main` | Git refs for the toolkit/extensions clones. Pin to a tag/commit for reproducibility. | @@ -487,6 +488,19 @@ All six agents should respond if your provider authentication is working. ## pi (alternative/complementary harness) +> **⚠ DEPRECATED since v1.17.2 — removed in v2.0.0.** pi support in +> opencode-devbox (the `INSTALL_PI` build arg, the `*-with-pi` / +> `omos-with-pi` / `pi-only` variants, and the `base-pi-only` tag) is +> deprecated. pi now ships as its own self-contained image: +> **[`joakimp/pi-devbox`](https://gitea.jordbo.se/joakimp/pi-devbox)** — pull +> that directly. The section below documents the legacy path until removal. +> +> *Migration note for v2.0.0:* the global npm prefix +> (`NPM_CONFIG_PREFIX`) will move off the pi-specific `~/.pi/npm-global` +> path to a neutral opencode path. Globally `npm install -g`'d tools may +> need their volume/PATH refreshed; the v2.0.0 release notes will carry a +> one-time migration shim and details. + [pi](https://github.com/earendil-works/pi) is a lightweight TUI coding-agent that can run alongside opencode in the same container. Both harnesses share the mempalace install and palace data — wing/diary entries created by one are visible to the other. ### Setup diff --git a/docs/CLEANUP-v2.0.0.md b/docs/CLEANUP-v2.0.0.md new file mode 100644 index 0000000..26f8bf8 --- /dev/null +++ b/docs/CLEANUP-v2.0.0.md @@ -0,0 +1,221 @@ +# PR-5: Retire pi from opencode-devbox + +After pi-devbox has shipped v1.0.0 as a fully independent image (with +its own base + variant Dockerfiles, CI, smoke tests, and docs), the +pi-related paths in opencode-devbox become dead weight. This PR +removes them. + +## Pre-conditions before merging + +This PR should land **only after** all of the following are stable: + +1. `pi-devbox v1.0.0` published, smoke tests passing, in active use + for at least one release cycle. +2. Anyone consuming `joakimp/pi-devbox:base-pi-only` directly (e.g. + forks pinned to it) has been notified and migrated. +3. The deprecation warning (PR-1 of this work — see below) has been + live for at least one release cycle so consumers have visible + notice. + +## Files / sections to remove from opencode-devbox + +### `Dockerfile.variant` + +Remove these blocks entirely: + +- The `INSTALL_PI` / `PI_VERSION` / `PI_TOOLKIT_REF` / + `PI_EXTENSIONS_REF` / `PI_FORK_REPO` / `PI_FORK_REF` / + `PI_OBSMEM_REPO` / `PI_OBSMEM_REF` build-args. +- The `RUN if [ "${INSTALL_PI}" = "true" ]; then ...` block (entire + block — git_clone_retry, git_fetch_ref, npm install + pi-coding-agent, the four /opt/pi-* clones, the npm installs in + /opt/pi-fork and /opt/pi-observational-memory, and the four + rev-parse echoes). +- All comments referencing pi-only as "the single source of truth for + the pi-devbox image" (the variant matrix table, the explanatory + paragraph, and the "rationale" comments at the top of the file + about pi-only existing for pi-devbox to FROM). + +Update the variant matrix table at the top of `Dockerfile.variant`: + +``` + variant INSTALL_OPENCODE INSTALL_OMOS + ───────────────── ──────────────── ──────────── + base true false + omos true true +``` + +(only two variants now; pi-only and the with-pi/omos-with-pi axis are +gone). + +### `entrypoint-user.sh` + +Remove: + +- The pi-toolkit and pi-extensions install hooks (the section that + runs `(cd /opt/pi-toolkit && ./install.sh --yes)` etc.). +- The `~/.pi/agent/settings.json` seeding from + `/opt/pi-toolkit/settings.example.json`. +- Any other pi-conditional blocks (search for `INSTALL_PI`, `pi-toolkit`, + `pi-extensions`, `~/.pi/`). + +Verify that the AWS Bedrock auth bootstrap (the pi-toolkit AWS env +loader) is not relied on by opencode users. If it is, lift it out of +the pi-toolkit dependency (it's small and self-contained). + +### `Dockerfile.base` + +Remove: + +- The `mkdir -p /home/${USER_NAME}/.pi/agent/extensions` line in the + standard-directories block. Replace with the equivalent opencode- + specific paths if any aren't already present (`~/.config/opencode` + is already there). +- `NPM_CONFIG_PREFIX=/home/${USER_NAME}/.pi/npm-global` — change to + `/home/${USER_NAME}/.config/opencode/npm-global` or a more neutral + path. Update the corresponding `PATH` env var. + +Also update the long base-image header comment to remove the +"variants for pi-devbox" rationale. + +### CI (`.gitea/workflows/docker-publish-split.yml` or equivalent) + +Remove: + +- The `pi-only` variant build job. +- The `with-pi` and `omos-with-pi` variant build jobs (they're + redundant with the standalone pi-devbox now). +- The `base-pi-only` tag publish step (which pushes to + `joakimp/pi-devbox:base-pi-only` from this repo). +- The `resolve-pi-version` job step (no longer needed). +- Smoke-test invocations with `--variant pi-only`, `--variant with-pi`, + `--variant omos-with-pi`. + +Remaining variants in CI: `base`, `omos`. The "with-pi" axis is +fully retired. + +### `scripts/smoke-test.sh` + +Remove: + +- The `--variant pi-only`, `--variant with-pi`, `--variant + omos-with-pi` branches. +- pi-related assertions: `pi --version`, the + `~/.pi/agent/extensions/*.ts ≥ 4` check, the mempalace.ts bridge + gate (mempalace itself stays, but its bridge into pi is no longer + this image's concern). + +Remaining variant axis in smoke tests: `base`, `omos`. + +### `README.md` (and `AGENTS.md`, `DOCKER_HUB.md`) + +- Remove the pi-only variant from the "Image variants" table. +- Remove the with-pi / omos-with-pi variants if they were documented. +- Remove all sections about pi-toolkit, pi-extensions, pi-fork, + pi-observational-memory, ~/.pi paths, and pi-related env vars. +- Remove the "this image also produces base-pi-only for pi-devbox" + notes. +- Add a single-paragraph **"Looking for pi?"** section pointing to + `joakimp/pi-devbox`. + +### `Dockerfile` references in `pi-devbox` repo (cleanup of cross-repo coupling) + +This isn't a change to opencode-devbox, but it's part of the same +deprecation: + +- Once pi-devbox v1.0.0 is the single source of truth, remove + pi-devbox/Dockerfile (the 5-line shim with the long + `joakimp/pi-devbox:base-pi-only` rationale comment). It's replaced + by `Dockerfile.base` + `Dockerfile.variant` produced by PR-1 of + this work. + +## Two-step deprecation path (recommended) + +Rather than a single big-bang removal, use a deprecation cycle: + +### Step 1 — pre-PR (lands at the same time as pi-devbox v1.0.0) + +Add a deprecation warning to opencode-devbox: + +1. **Build-time message** — when `INSTALL_PI=true`, + `INSTALL_PI_DEPRECATED=warn` is the default; the variant build + prints to stderr: + ``` + =========================================================== + DEPRECATION WARNING: INSTALL_PI is deprecated in opencode-devbox + and will be removed in v2.0.0. Use joakimp/pi-devbox:latest + instead. See https://gitea.jordbo.se/joakimp/pi-devbox + =========================================================== + ``` +2. **CHANGELOG** entry on opencode-devbox: "INSTALL_PI build-arg path + deprecated; will be removed in v2.0.0." +3. **README and DOCKER_HUB** updates: mark `pi-only`, `with-pi`, + `omos-with-pi` variants as deprecated, point to pi-devbox. +4. The `base-pi-only` tag continues to be published but with a + notice in the description: "Internal artifact for pi-devbox. + Deprecated; pull joakimp/pi-devbox:latest directly." + +### Step 2 — removal PR (this document) + +Lands one release cycle (or one calendar month, whichever is later) +after step 1. Removes everything listed in the per-file sections +above. Tagged as opencode-devbox v2.0.0 (the major bump signals the +breaking change). + +## Risk assessment + +### What could go wrong + +- **Someone is consuming `base-pi-only` directly** without going + through pi-devbox. The deprecation warning + one-cycle delay should + surface this. +- **Mempalace bridge in pi-extensions** — this stays in pi-devbox; no + impact on opencode-devbox. +- **Shared base assumptions** — opencode-devbox's + `~/.pi/npm-global` NPM_CONFIG_PREFIX was a pi-specific design. In + the cleanup we move it to a neutral path. Existing opencode-devbox + users get a one-time migration: their `npm install -g` packages + installed at the old path stop being on PATH. Document this in the + v2.0.0 changelog and add a one-liner that copies the old prefix + contents to the new one if the old one exists. + +### What's safe + +- The base apt set, the Go-binary installs, MemPalace, the SSH + ControlMaster setup, the entrypoint UID/GID dance — all of these + stay. They're not pi-specific. +- The `omos` variant — fully unaffected. +- Existing opencode-only users — no change to their workflow. + +## Verification + +After PR-5 lands, the following should be true: + +- `grep -ri "INSTALL_PI\|pi-toolkit\|pi-extensions\|pi-fork\|pi-observational-memory\|base-pi-only" .` in opencode-devbox returns no matches. +- `docker history joakimp/opencode-devbox:latest` shows no pi-related layers. +- The opencode-devbox CI matrix builds only `base` and `omos` variants. +- pi-devbox CI is unaffected (it's a different repo). +- Both repos build cleanly in their own CI without referencing the other. + +## Estimated effort + +- Step 1 (deprecation warnings): ~2 hours. +- Step 2 (removal): ~4 hours including local testing of opencode-only + build paths. +- One release cycle of monitoring between them. + +Total: ~1 working day of focused effort, spread over a calendar month. + +## Order in the broader plan + +1. PR-1 on pi-devbox — copy base + variant Dockerfiles, strip + opencode/omos paths, tag v1.0.0. +2. PR-2 on pi-devbox — add pandoc, graphviz, imagemagick, tldr, yq. +3. PR-3 on pi-devbox — add `:latest-studio` variant. +4. (Optional) PR-4 on pi-devbox — add `:latest-studio-tex` variant. +5. PR-pre on opencode-devbox — deprecation warnings (step 1 above). +6. **PR-5 on opencode-devbox — actual removal (this document, step 2).** + +PRs 1–4 are independent and can land in any order on pi-devbox. PR-pre +should land alongside or shortly after pi-devbox v1.0.0 (PR-1) so +consumers know to migrate. PR-5 lands one release cycle after PR-pre.