REN-302 (parent REN-284). The k8s-go adapter test fails with Claude ACP server command is not available: claude-agent-acp.
What changed
agent-runtime-go and agent-runtime-ops: install @agentclientprotocol/claude-agent-acp@0.73.0 globally (lands in /usr/bin). 0.73.0 is the pin in Paperclip's packages/adapters/claude-local/package.json.
Beyond the card, please review: Paperclip ships that package with its own patch (patches/@agentclientprotocol__claude-agent-acp@0.73.0.patch: isolated context, task-tool allow-list, usage metadata). It is vendored unchanged in ci/images/agent-runtime-common/ and applied with git apply. Without it the pod's ACP server would load workspace project settings/MCP servers and not allow Paperclip's task tools.
go image: go and gofmt symlinked into /usr/local/bin, so they resolve with the default PATH, not only via image ENV. Ops tools and golangci-lint were already in /usr/local/bin.
Both builds now fail unless every tool resolves under env -i PATH=<default>.
Kaniko context is ci/images (was the variant dir) so both Containerfiles can COPY the shared patch.
Not bumped by Renovate: bump together with Paperclip and replace the patch (README note).
How verified
Locally: npm install -g @agentclientprotocol/claude-agent-acp@0.73.0 and git apply of the patch succeed.
The images have not been built yet: the pipeline runs on push to master only. Build result and digests go on REN-302 after merge.
Effect on the cluster
None directly. The build moves the v1 tag the sandbox plugin pulls; new sandbox pods get the added binary. No running pod restarts, no Home Assistant impact.
Revert
Revert this PR's commit; the next pipeline run rebuilds v1 without it. Or point back to the previous date tag.
REN-302 (parent REN-284). The `k8s-go` adapter test fails with `Claude ACP server command is not available: claude-agent-acp`.
## What changed
- `agent-runtime-go` and `agent-runtime-ops`: install `@agentclientprotocol/claude-agent-acp@0.73.0` globally (lands in `/usr/bin`). 0.73.0 is the pin in Paperclip's `packages/adapters/claude-local/package.json`.
- **Beyond the card, please review:** Paperclip ships that package with its own patch (`patches/@agentclientprotocol__claude-agent-acp@0.73.0.patch`: isolated context, task-tool allow-list, usage metadata). It is vendored unchanged in `ci/images/agent-runtime-common/` and applied with `git apply`. Without it the pod's ACP server would load workspace project settings/MCP servers and not allow Paperclip's task tools.
- go image: `go` and `gofmt` symlinked into `/usr/local/bin`, so they resolve with the default PATH, not only via image `ENV`. Ops tools and golangci-lint were already in `/usr/local/bin`.
- Both builds now fail unless every tool resolves under `env -i PATH=<default>`.
- Kaniko context is `ci/images` (was the variant dir) so both Containerfiles can COPY the shared patch.
- Not bumped by Renovate: bump together with Paperclip and replace the patch (README note).
## How verified
- Locally: `npm install -g @agentclientprotocol/claude-agent-acp@0.73.0` and `git apply` of the patch succeed.
- The images have not been built yet: the pipeline runs on push to master only. Build result and digests go on REN-302 after merge.
## Effect on the cluster
None directly. The build moves the `v1` tag the sandbox plugin pulls; new sandbox pods get the added binary. No running pod restarts, no Home Assistant impact.
## Revert
Revert this PR's commit; the next pipeline run rebuilds `v1` without it. Or point back to the previous date tag.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The k8s-go adapter test failed with 'Claude ACP server command is not
available: claude-agent-acp'. Both agent-runtime images now install
@agentclientprotocol/claude-agent-acp@0.73.0, the version Paperclip pins,
with Paperclip's patch for it applied (vendored in agent-runtime-common/).
go and gofmt are also linked into /usr/local/bin, so every tool is found
with the default PATH, not only with the image ENV. The build checks that
with env -i. Kaniko context is now ci/images so both images can COPY the
shared patch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Defect: Paperclip pins the ACP server's SDK with a pnpm override: @agentclientprotocol/claude-agent-acp@0.73.0>@anthropic-ai/claude-agent-sdk: 0.3.280 (/app/package.json). npm install -g ignores that and resolves 0.3.257, the exact dep in claude-agent-acp 0.73.0. Checked locally: npm install -g --prefix … @agentclientprotocol/claude-agent-acp@0.73.0 gives SDK 0.3.257. So the pod runs a different SDK than Paperclip nightly.
Fix (tested locally): install into a fixed prefix from a package.json with the override, patch it, and link the bin:
npm install --omit=dev → npm ls shows claude-agent-sdk@0.3.280 overridden, git apply of the patch OK, the bin starts. Put the prefix under e.g. /opt/claude-agent-acp, link node_modules/.bin/claude-agent-acp into /usr/local/bin. Keep the env -i PATH check. Add the SDK pin to the comment and README bump note.
Passed: version 0.73.0 = Paperclip pin; vendored patch byte-identical to /app/patches/…0.73.0.patch (sha256 ff14cb36…); patch applies to the npm tarball; agent-runtime-common/** matches the ci/images/agent-runtime-*/** trigger; no other context-relative COPY breaks with --context .; a failing build check stops kaniko before it pushes v1.
Changes requested on `9049a6b2`.
**Defect:** Paperclip pins the ACP server's SDK with a pnpm override: `@agentclientprotocol/claude-agent-acp@0.73.0>@anthropic-ai/claude-agent-sdk: 0.3.280` (`/app/package.json`). `npm install -g` ignores that and resolves 0.3.257, the exact dep in claude-agent-acp 0.73.0. Checked locally: `npm install -g --prefix … @agentclientprotocol/claude-agent-acp@0.73.0` gives SDK 0.3.257. So the pod runs a different SDK than Paperclip nightly.
**Fix (tested locally):** install into a fixed prefix from a package.json with the override, patch it, and link the bin:
```
{"private":true,"dependencies":{"@agentclientprotocol/claude-agent-acp":"0.73.0"},"overrides":{"@anthropic-ai/claude-agent-sdk":"0.3.280"}}
```
`npm install --omit=dev` → `npm ls` shows `claude-agent-sdk@0.3.280 overridden`, `git apply` of the patch OK, the bin starts. Put the prefix under e.g. `/opt/claude-agent-acp`, link `node_modules/.bin/claude-agent-acp` into `/usr/local/bin`. Keep the `env -i` PATH check. Add the SDK pin to the comment and README bump note.
**Passed:** version 0.73.0 = Paperclip pin; vendored patch byte-identical to `/app/patches/…0.73.0.patch` (sha256 ff14cb36…); patch applies to the npm tarball; `agent-runtime-common/**` matches the `ci/images/agent-runtime-*/**` trigger; no other context-relative COPY breaks with `--context .`; a failing build check stops kaniko before it pushes `v1`.
npm install -g ignored Paperclip's pnpm override and pulled
claude-agent-sdk 0.3.257. Install from a package.json with the override
(0.3.280) into /opt/claude-agent-acp and link the bin into /usr/local/bin.
The build fails if the SDK version is not 0.3.280.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Approve ed6903ae88. Checked: override file pins claude-agent-sdk 0.3.280; reproduced the RUN step locally: npm install -> npm ls shows 0.3.280 overridden, grep gate passes, patch (sha256 ff14cb36) applies and reverse-checks, bin via symlink answers ACP initialize under env -i. Both Containerfiles identical in the install block; env -i PATH check covers claude-agent-acp in both.
Approve ed6903ae883ad7d60977dda6d48265a360c4158c. Checked: override file pins claude-agent-sdk 0.3.280; reproduced the RUN step locally: npm install -> npm ls shows 0.3.280 overridden, grep gate passes, patch (sha256 ff14cb36) applies and reverse-checks, bin via symlink answers ACP initialize under env -i. Both Containerfiles identical in the install block; env -i PATH check covers claude-agent-acp in both.
Ghost
merged commit 2a34573823 into master2026-09-27 21:41:31 +00:00
🤖Automated review — model CLI default (complexity: complex), commit ed6903ae883ad7d60977dda6d48265a360c4158c.
Advisory review by the review-bot pipeline. It never approves; a human merges. Push new commits to get a fresh review.
Summary
Adds claude-agent-acp@0.73.0 (with Paperclip's vendored patch and Claude Agent SDK override) to both agent-runtime-go and agent-runtime-ops images, symlinks go/gofmt into /usr/local/bin, widens the kaniko build context so both Containerfiles can share ci/images/agent-runtime-common/, and adds default-PATH verification checks. The mechanics are sound (fail-closed on version mismatch, correct USER root/1000 bracketing, correct path-filter globbing for the new shared directory), and I found no blocking defects. Two non-blocking gaps worth a look before/soon after merge, below.
🟡 Suggestions
Registry layer dedup regression (ci/images/agent-runtime-go/Containerfile:37-43, ci/images/agent-runtime-ops/Containerfile:36-42): the new RUN npm install ... layer isn't made byte-stable. The sibling ci/images/claude/Containerfile:20-48 documents and fixes exactly this problem (issues #351/#336): npm writes fresh mtimes on every install, so a rebuild of the sameclaude-agent-acp version still produces a different layer digest and orphans a new copy in the registry instead of deduping. That Containerfile normalizes file mtimes with touch -h -t ... and removes /root/.npm explicitly (npm cache clean --force alone doesn't clear all cache residue). The new blocks here only call npm cache clean --force, so any future rebuild triggered by an unrelated change to these Containerfiles (e.g. a Renovate bump of the golang/golangci-lint base stages, which live in the same path-filtered files) will churn the registry even though the ACP tool itself didn't change.
Unpinned transitive dependencies for a root-privileged install (ci/images/agent-runtime-common/claude-agent-acp.package.json, used at agent-runtime-go/Containerfile:154-160 / agent-runtime-ops/Containerfile:194-200): package.json pins only the two top-level packages (claude-agent-acp@0.73.0, SDK override 0.3.280); no lockfile is committed, so npm install resolves and runs the install-time scripts of every transitive dependency at whatever version is current on the registry at build time, running as USER root. This is inconsistent with the pinning discipline the same Containerfile's header comment states as policy ("pinned by tag AND digest... a curl+sha256 pin... would break on every Renovate bump") for the base images. Since this dependency is explicitly not Renovate-managed and only bumped by hand together with Paperclip, committing the generated package-lock.json (or using npm ci) would make rebuilds reproducible and reduce the supply-chain surface of running arbitrary postinstall scripts as root. (Note: ci/images/claude/Containerfile has the same npm install -g pattern without a lockfile, so this isn't a new class of risk for the repo — just worth tightening while touching this area.)
🟢 Nits
The ~15-line comment + RUN block for installing claude-agent-acp is duplicated verbatim between agent-runtime-go/Containerfile and agent-runtime-ops/Containerfile. Given the PR body already flags that bumps must be done "by hand... together with Paperclip," a future bump means editing both files identically — easy to let them drift. Not worth a build-system change for two files, but worth a second pair of eyes when it's next bumped.
I could not verify byte-for-byte that ci/images/agent-runtime-common/claude-agent-acp-0.73.0.patch matches Paperclip's patches/@agentclientprotocol__claude-agent-acp@0.73.0.patch unchanged, since that source isn't in this checkout and I have no network access to fetch either package. The vendored hunks are internally consistent (fail-closed defaults when PAPERCLIP_ACPX_ISOLATED_CONTEXT=1 but the MCP bridge doesn't match), and the failure mode if the patch doesn't apply cleanly is a hard build failure via the && chain — not a silent skip — so this is a low-risk unknown, but it's the one part of this PR I couldn't independently confirm.
Tests
No unit tests apply to this Dockerfile/CI change. The added build-time checks are the right kind of test for this: both Containerfiles' final RUN steps verify go, gofmt, golangci-lint/kubectl/flux/kustomize/helm, and claude-agent-acp all resolve under a clean default PATH (env -i PATH=...), and the install step itself hard-fails (&& chain) if npm ls doesn't confirm the SDK override version. That matches the PR's stated goal ("both builds now fail unless every tool resolves under env -i PATH=<default>"). The PR body is upfront that the actual kaniko build hasn't been run yet (only npm install -g + git apply tested locally, not inside the target image) — worth watching the first build-agent-runtime run to confirm git and node/npm are actually present in ghcr.io/paperclipai/agent-runtime-claude, which I could not verify from this checkout.
Recommendation
Looks reasonable — no blocking issues; comments above are optional.
🤖 **Automated review** — model `CLI default` (complexity: complex), commit `ed6903ae883ad7d60977dda6d48265a360c4158c`.
> Advisory review by the `review-bot` pipeline. It never approves; a human merges. Push new commits to get a fresh review.
---
## Summary
Adds `claude-agent-acp@0.73.0` (with Paperclip's vendored patch and Claude Agent SDK override) to both `agent-runtime-go` and `agent-runtime-ops` images, symlinks `go`/`gofmt` into `/usr/local/bin`, widens the kaniko build context so both Containerfiles can share `ci/images/agent-runtime-common/`, and adds default-PATH verification checks. The mechanics are sound (fail-closed on version mismatch, correct USER root/1000 bracketing, correct path-filter globbing for the new shared directory), and I found no blocking defects. Two non-blocking gaps worth a look before/soon after merge, below.
## 🟡 Suggestions
- **Registry layer dedup regression** (`ci/images/agent-runtime-go/Containerfile:37-43`, `ci/images/agent-runtime-ops/Containerfile:36-42`): the new `RUN npm install ...` layer isn't made byte-stable. The sibling `ci/images/claude/Containerfile:20-48` documents and fixes exactly this problem (issues #351/#336): npm writes fresh mtimes on every install, so a rebuild of the *same* `claude-agent-acp` version still produces a different layer digest and orphans a new copy in the registry instead of deduping. That Containerfile normalizes file mtimes with `touch -h -t ...` and removes `/root/.npm` explicitly (`npm cache clean --force` alone doesn't clear all cache residue). The new blocks here only call `npm cache clean --force`, so any future rebuild triggered by an unrelated change to these Containerfiles (e.g. a Renovate bump of the golang/golangci-lint base stages, which live in the same path-filtered files) will churn the registry even though the ACP tool itself didn't change.
- **Unpinned transitive dependencies for a root-privileged install** (`ci/images/agent-runtime-common/claude-agent-acp.package.json`, used at `agent-runtime-go/Containerfile:154-160` / `agent-runtime-ops/Containerfile:194-200`): `package.json` pins only the two top-level packages (`claude-agent-acp@0.73.0`, SDK override `0.3.280`); no lockfile is committed, so `npm install` resolves and runs the install-time scripts of every transitive dependency at whatever version is current on the registry at build time, running as `USER root`. This is inconsistent with the pinning discipline the same Containerfile's header comment states as policy ("pinned by tag AND digest... a curl+sha256 pin... would break on every Renovate bump") for the base images. Since this dependency is explicitly *not* Renovate-managed and only bumped by hand together with Paperclip, committing the generated `package-lock.json` (or using `npm ci`) would make rebuilds reproducible and reduce the supply-chain surface of running arbitrary postinstall scripts as root. (Note: `ci/images/claude/Containerfile` has the same `npm install -g` pattern without a lockfile, so this isn't a new class of risk for the repo — just worth tightening while touching this area.)
## 🟢 Nits
- The ~15-line comment + `RUN` block for installing `claude-agent-acp` is duplicated verbatim between `agent-runtime-go/Containerfile` and `agent-runtime-ops/Containerfile`. Given the PR body already flags that bumps must be done "by hand... together with Paperclip," a future bump means editing both files identically — easy to let them drift. Not worth a build-system change for two files, but worth a second pair of eyes when it's next bumped.
- I could not verify byte-for-byte that `ci/images/agent-runtime-common/claude-agent-acp-0.73.0.patch` matches Paperclip's `patches/@agentclientprotocol__claude-agent-acp@0.73.0.patch` unchanged, since that source isn't in this checkout and I have no network access to fetch either package. The vendored hunks are internally consistent (fail-closed defaults when `PAPERCLIP_ACPX_ISOLATED_CONTEXT=1` but the MCP bridge doesn't match), and the failure mode if the patch doesn't apply cleanly is a hard build failure via the `&&` chain — not a silent skip — so this is a low-risk unknown, but it's the one part of this PR I couldn't independently confirm.
## Tests
No unit tests apply to this Dockerfile/CI change. The added build-time checks are the right kind of test for this: both Containerfiles' final `RUN` steps verify `go`, `gofmt`, `golangci-lint`/`kubectl`/`flux`/`kustomize`/`helm`, and `claude-agent-acp` all resolve under a clean default `PATH` (`env -i PATH=...`), and the install step itself hard-fails (`&&` chain) if `npm ls` doesn't confirm the SDK override version. That matches the PR's stated goal ("both builds now fail unless every tool resolves under `env -i PATH=<default>`"). The PR body is upfront that the actual kaniko build hasn't been run yet (only `npm install -g` + `git apply` tested locally, not inside the target image) — worth watching the first `build-agent-runtime` run to confirm `git` and `node`/`npm` are actually present in `ghcr.io/paperclipai/agent-runtime-claude`, which I could not verify from this checkout.
## Recommendation
Looks reasonable — no blocking issues; comments above are optional.
<!-- pr-review:sha=ed6903ae883ad7d60977dda6d48265a360c4158c -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
REN-302 (parent REN-284). The
k8s-goadapter test fails withClaude ACP server command is not available: claude-agent-acp.What changed
agent-runtime-goandagent-runtime-ops: install@agentclientprotocol/claude-agent-acp@0.73.0globally (lands in/usr/bin). 0.73.0 is the pin in Paperclip'spackages/adapters/claude-local/package.json.patches/@agentclientprotocol__claude-agent-acp@0.73.0.patch: isolated context, task-tool allow-list, usage metadata). It is vendored unchanged inci/images/agent-runtime-common/and applied withgit apply. Without it the pod's ACP server would load workspace project settings/MCP servers and not allow Paperclip's task tools.goandgofmtsymlinked into/usr/local/bin, so they resolve with the default PATH, not only via imageENV. Ops tools and golangci-lint were already in/usr/local/bin.env -i PATH=<default>.ci/images(was the variant dir) so both Containerfiles can COPY the shared patch.How verified
npm install -g @agentclientprotocol/claude-agent-acp@0.73.0andgit applyof the patch succeed.Effect on the cluster
None directly. The build moves the
v1tag the sandbox plugin pulls; new sandbox pods get the added binary. No running pod restarts, no Home Assistant impact.Revert
Revert this PR's commit; the next pipeline run rebuilds
v1without it. Or point back to the previous date tag.🤖 Generated with Claude Code
Changes requested on
9049a6b2.Defect: Paperclip pins the ACP server's SDK with a pnpm override:
@agentclientprotocol/claude-agent-acp@0.73.0>@anthropic-ai/claude-agent-sdk: 0.3.280(/app/package.json).npm install -gignores that and resolves 0.3.257, the exact dep in claude-agent-acp 0.73.0. Checked locally:npm install -g --prefix … @agentclientprotocol/claude-agent-acp@0.73.0gives SDK 0.3.257. So the pod runs a different SDK than Paperclip nightly.Fix (tested locally): install into a fixed prefix from a package.json with the override, patch it, and link the bin:
npm install --omit=dev→npm lsshowsclaude-agent-sdk@0.3.280 overridden,git applyof the patch OK, the bin starts. Put the prefix under e.g./opt/claude-agent-acp, linknode_modules/.bin/claude-agent-acpinto/usr/local/bin. Keep theenv -iPATH check. Add the SDK pin to the comment and README bump note.Passed: version 0.73.0 = Paperclip pin; vendored patch byte-identical to
/app/patches/…0.73.0.patch(sha256 ff14cb36…); patch applies to the npm tarball;agent-runtime-common/**matches theci/images/agent-runtime-*/**trigger; no other context-relative COPY breaks with--context .; a failing build check stops kaniko before it pushesv1.Approve
ed6903ae88. Checked: override file pins claude-agent-sdk 0.3.280; reproduced the RUN step locally: npm install -> npm ls shows 0.3.280 overridden, grep gate passes, patch (sha256 ff14cb36) applies and reverse-checks, bin via symlink answers ACP initialize under env -i. Both Containerfiles identical in the install block; env -i PATH check covers claude-agent-acp in both.🤖 Automated review — model
CLI default(complexity: complex), commited6903ae883ad7d60977dda6d48265a360c4158c.Summary
Adds
claude-agent-acp@0.73.0(with Paperclip's vendored patch and Claude Agent SDK override) to bothagent-runtime-goandagent-runtime-opsimages, symlinksgo/gofmtinto/usr/local/bin, widens the kaniko build context so both Containerfiles can shareci/images/agent-runtime-common/, and adds default-PATH verification checks. The mechanics are sound (fail-closed on version mismatch, correct USER root/1000 bracketing, correct path-filter globbing for the new shared directory), and I found no blocking defects. Two non-blocking gaps worth a look before/soon after merge, below.🟡 Suggestions
ci/images/agent-runtime-go/Containerfile:37-43,ci/images/agent-runtime-ops/Containerfile:36-42): the newRUN npm install ...layer isn't made byte-stable. The siblingci/images/claude/Containerfile:20-48documents and fixes exactly this problem (issues #351/#336): npm writes fresh mtimes on every install, so a rebuild of the sameclaude-agent-acpversion still produces a different layer digest and orphans a new copy in the registry instead of deduping. That Containerfile normalizes file mtimes withtouch -h -t ...and removes/root/.npmexplicitly (npm cache clean --forcealone doesn't clear all cache residue). The new blocks here only callnpm cache clean --force, so any future rebuild triggered by an unrelated change to these Containerfiles (e.g. a Renovate bump of the golang/golangci-lint base stages, which live in the same path-filtered files) will churn the registry even though the ACP tool itself didn't change.ci/images/agent-runtime-common/claude-agent-acp.package.json, used atagent-runtime-go/Containerfile:154-160/agent-runtime-ops/Containerfile:194-200):package.jsonpins only the two top-level packages (claude-agent-acp@0.73.0, SDK override0.3.280); no lockfile is committed, sonpm installresolves and runs the install-time scripts of every transitive dependency at whatever version is current on the registry at build time, running asUSER root. This is inconsistent with the pinning discipline the same Containerfile's header comment states as policy ("pinned by tag AND digest... a curl+sha256 pin... would break on every Renovate bump") for the base images. Since this dependency is explicitly not Renovate-managed and only bumped by hand together with Paperclip, committing the generatedpackage-lock.json(or usingnpm ci) would make rebuilds reproducible and reduce the supply-chain surface of running arbitrary postinstall scripts as root. (Note:ci/images/claude/Containerfilehas the samenpm install -gpattern without a lockfile, so this isn't a new class of risk for the repo — just worth tightening while touching this area.)🟢 Nits
RUNblock for installingclaude-agent-acpis duplicated verbatim betweenagent-runtime-go/Containerfileandagent-runtime-ops/Containerfile. Given the PR body already flags that bumps must be done "by hand... together with Paperclip," a future bump means editing both files identically — easy to let them drift. Not worth a build-system change for two files, but worth a second pair of eyes when it's next bumped.ci/images/agent-runtime-common/claude-agent-acp-0.73.0.patchmatches Paperclip'spatches/@agentclientprotocol__claude-agent-acp@0.73.0.patchunchanged, since that source isn't in this checkout and I have no network access to fetch either package. The vendored hunks are internally consistent (fail-closed defaults whenPAPERCLIP_ACPX_ISOLATED_CONTEXT=1but the MCP bridge doesn't match), and the failure mode if the patch doesn't apply cleanly is a hard build failure via the&&chain — not a silent skip — so this is a low-risk unknown, but it's the one part of this PR I couldn't independently confirm.Tests
No unit tests apply to this Dockerfile/CI change. The added build-time checks are the right kind of test for this: both Containerfiles' final
RUNsteps verifygo,gofmt,golangci-lint/kubectl/flux/kustomize/helm, andclaude-agent-acpall resolve under a clean defaultPATH(env -i PATH=...), and the install step itself hard-fails (&&chain) ifnpm lsdoesn't confirm the SDK override version. That matches the PR's stated goal ("both builds now fail unless every tool resolves underenv -i PATH=<default>"). The PR body is upfront that the actual kaniko build hasn't been run yet (onlynpm install -g+git applytested locally, not inside the target image) — worth watching the firstbuild-agent-runtimerun to confirmgitandnode/npmare actually present inghcr.io/paperclipai/agent-runtime-claude, which I could not verify from this checkout.Recommendation
Looks reasonable — no blocking issues; comments above are optional.