chore(deps): integrate four non-trivial Dependabot bumps (ACP SDK, Node 26, sandbox, Starlight) - #1842
Open
simple-agent-manager[bot] wants to merge 13 commits into
Open
chore(deps): integrate four non-trivial Dependabot bumps (ACP SDK, Node 26, sandbox, Starlight)#1842simple-agent-manager[bot] wants to merge 13 commits into
simple-agent-manager[bot] wants to merge 13 commits into
Conversation
Bumps library/node from 22-bookworm-slim to 26-bookworm-slim. --- updated-dependencies: - dependency-name: library/node dependency-version: 26-bookworm-slim dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps cloudflare/sandbox from 0.12.1 to 0.12.5. --- updated-dependencies: - dependency-name: cloudflare/sandbox dependency-version: 0.12.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@agentclientprotocol/sdk](https://github.com/agentclientprotocol/typescript-sdk) from 0.25.0 to 1.3.0. - [Release notes](https://github.com/agentclientprotocol/typescript-sdk/releases) - [Changelog](https://github.com/agentclientprotocol/typescript-sdk/blob/main/CHANGELOG.md) - [Commits](agentclientprotocol/typescript-sdk@v0.25.0...v1.3.0) --- updated-dependencies: - dependency-name: "@agentclientprotocol/sdk" dependency-version: 1.3.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@astrojs/starlight](https://github.com/withastro/starlight/tree/HEAD/packages/starlight) from 0.40.0 to 0.41.7. - [Release notes](https://github.com/withastro/starlight/releases) - [Changelog](https://github.com/withastro/starlight/blob/main/packages/starlight/CHANGELOG.md) - [Commits](https://github.com/withastro/starlight/commits/@astrojs/starlight@0.41.7/packages/starlight) --- updated-dependencies: - dependency-name: "@astrojs/starlight" dependency-version: 0.41.7 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Brings #1801, #1790, #1792, #1796 in as one reviewable unit and fixes what each Dependabot commit left half-done. #1801 @agentclientprotocol/sdk 0.25.0 -> 1.3.0: REMOVED instead of bumped. An exhaustive sweep (all file types, tsconfig paths/types, vite/vitest/eslint configs, every workspace package.json, Go modules) found zero importers. packages/acp-client hand-rolls its ACP payload types in src/hooks/useAcpMessagePayloads.ts and src/transport/types.ts, and transport/websocket.ts deliberately types the ACP payload as `unknown`. The canonical wire contract lives in the Go VM agent. Carrying a 1.3.0 dep whose deprecated ClientSideConnection/ndJsonStream surface implies an integration that does not exist is worse than carrying none. AGENTS.md claimed the SDK "defines the ACP wire protocol types" — corrected to describe reality. #1790 node 22 -> 26-bookworm-slim: taken, comment desync fixed. None of the seven globally-installed agent CLIs declares an engines.node upper bound, so no EBADENGINE is possible; the digest resolves to node 26.7.0 and bookworm is still published for 26. #1792 cloudflare/sandbox 0.12.1 -> 0.12.5: Dependabot moved only the image. The npm client stayed at ^0.12.1 while the Dockerfile comment still asserted they MUST match. Pinned @cloudflare/sandbox to exactly 0.12.5 — an exact pin, because a range lets the client drift from the digest-pinned image on any unrelated install. #1796 @astrojs/starlight 0.40.0 -> 0.41.7: root cause of all five red checks was peer astro@^7.0.2 vs pinned astro@6.4.8. The newer peer graph pulls @astrojs/mdx@7.0.5, which imports `chunkToString` from astro/runtime/server/index.js — absent in Astro 6. Upgraded astro to 7.2.2 (pinned in exactly one place, apps/www). Astro 7's rolldown pipeline then resolves dynamic imports inside processed <script> blocks, so the mermaid lazy-loader in BlogPost.astro needed is:inline; /scripts/blog-mermaid.js is an esbuild output emitted to public/ at build time, i.e. a runtime URL rather than a resolvable module. Build is clean: 181 pages + Pagefind + sitemap. Also corrects a bad @types/node resolution combo the lockfile text-merge produced across the two npm PRs. Process fix: the existing Docker governance test asserted digest pinning only, so it passed straight through BOTH stale-comment bugs. Adds two tests to scripts/quality/dependency-governance.test.ts — reviewed-source-tag comments must match their FROM tag, and @cloudflare/sandbox must be an exact pin equal to the image tag. Both verified discriminating: each goes red on the exact pre-fix state Dependabot produced.
Addresses findings from the local test-engineer and cloudflare-specialist reviews of the first pass. HIGH (test-engineer): reviewedSourceTag() used .exec() so it captured only the FIRST reviewed-source-tag comment in a file, and the assertion then did a file-wide `fromRefs.toContain(declared)`. On a multi-stage Dockerfile a stale comment on stage 2 was invisible, and worse, stage 1 still matching made the whole assertion pass. Replaced with reviewedSourcePairs(), which pairs every FROM with its NEAREST PRECEDING comment. Verified discriminating against a synthetic two-stage file: the old file-wide check passes the drift, the new one catches it at the exact line. MEDIUM (test-engineer): .github/workflows/devcontainer-cache-experiments.yml embeds two heredoc Dockerfiles using the same reviewed-source-tag convention, but walk() only matches files literally named Dockerfile*, so they were never checked. reviewedSourcePairs() now operates on text rather than paths and the test feeds it workflow files too. Verified discriminating by drifting the heredoc comment. Inside workflows only stanzas that opted into the convention are asserted, since workflow FROM lines otherwise legitimately have no comment. MEDIUM (cloudflare-specialist): the sandbox pin check hardcoded apps/api/package.json as the only place to look. tasks/active/2026-07-23-codex- guided-setup-terminal.md already plans a second @cloudflare/sandbox declaration in apps/web for the /xterm client, which would have reintroduced exactly the drift this guard exists to prevent. Now walks every workspace manifest and checks dependencies/devDependencies/optionalDependencies. Verified discriminating by adding a caret range in apps/web. LOW (test-engineer): a prerelease image tag failed with "must FROM cloudflare/sandbox:<tag>", misreporting a version-format rejection as a missing FROM. Split into a defined-check and a format-check with an explanatory message. Also added a vacuity guard: the comment-sync test asserts it actually inspected at least five stanzas, so a future walk()/parser regression cannot make it pass by finding nothing. Docs (doc-sync-validator): CLAUDE.md gets a Recent Changes entry — the SDK removal and the two new enforced invariants are the kind of institutional knowledge that section exists to preserve. apps/www/AGENTS.md gets the Astro 7 rolldown dynamic-import trap and the Starlight/Astro major-coupling rule so the next agent does not rediscover them through a failed build.
Contributor
… blocker The ACP session verified end-to-end on staging (prompt -> Read tool call -> correct answer, rendered in-browser, zero console errors), and the regression sweep passed at both viewports. The cf-container/Instant turn could NOT run: staging has CF_CONTAINER_ENABLED='false' on its GitHub Environment (set 2026-08-11), so resolveWorkspaceRuntime forces VM and chat-start 409s. That is pre-existing and unrelated to this branch. Rather than skip the check, both images were built and executed locally in Docker; what remains unproven is a live agent turn through the deployed container. Recorded as a gap instead of rationalised as a pass. Also records that apps/www is not staging-deployable -- deploy-www.yml runs with environment: production on push to main -- so merging this PR will deploy the marketing site on Astro 7.
…ivial-d0kabv # Conflicts: # packages/acp-client/package.json
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Integrates the four non-trivial Dependabot PRs as one reviewable, verified unit:
#1801 (
@agentclientprotocol/sdk0.25.0 → 1.3.0), #1790 (library/node22 → 26-bookworm-slim),#1792 (
cloudflare/sandbox0.12.1 → 0.12.5), #1796 (@astrojs/starlight0.40.0 → 0.41.7).All four head commits are merged with
--no-ff, so their SHAs stay reachable and GitHub willauto-close each PR when this lands via a merge commit.
Each Dependabot commit was incomplete. This PR finishes them:
#1801 — removed the SDK rather than bumping it
An exhaustive sweep (
.ts .tsx .js .mjs .cjs .json .go .py .sh .astro .vue, every config file,tsconfig
paths/types,declare module,/// <reference types>, barrel re-exports, everynon-
node_modulespackage.json, andpackages/vm-agent/go.mod) found zero importers of@agentclientprotocol/sdk.packages/acp-clienthand-rolls its ACP payload shapes insrc/hooks/useAcpMessagePayloads.tsand its VM-agent control messages insrc/transport/types.ts;src/transport/websocket.tsdeliberately types the ACP payload asunknownand forwards it. Thecanonical wire contract lives in the Go VM agent, which has no dependency on this npm package.
The dep was added by spec-007 (
specs/007-multi-agent-acp/tasks.mdT002/T019/T020) intending to useClientSideConnectionover a custom WebSocket transport; that intent was never implemented.Upstream, the real API break was 0.27.0 (fluent
agent()/client()rewrite; legacyClientSideConnection/AgentSideConnectiondeprecated but not removed) — 1.0.0 was a stabilizationtag, and ACP v2 in 1.3.0 is opt-in behind the
./experimental/v2subpath. So the bump isbehaviourally inert because nothing imports it, not because the API is compatible.
Decision: carrying a 1.3.0 dependency whose deprecated
ClientSideConnection/ndJsonStreamsurface implies an integration that does not exist is worse than carrying none (CLAUDE.md, "No dead
code"). Removed, and corrected
packages/acp-client/AGENTS.md, which claimed the SDK "defines theACP wire protocol types" — it defines nothing in this repo.
#1790 — Node 26 taken; stale review comment fixed
No globally-installed agent CLI in
apps/api/Dockerfile.vm-agent-containerdeclares anengines.nodeupper bound (claude-agent-acp>=22,claude-code>=22.0.0,codex>=16,gemini-cli>=20;codex-acp,opencode-ai,@ampcode/clideclare none), sonpm install -gcannot fail
EBADENGINE. The pinned digest resolves toNODE_VERSION=26.7.0and bookworm is stillpublished for 26.
container-entrypoints/patch-acp-amp.pyis pure Python under uv-managed CPython3.12, and
container-entrypoints/vm-agent-bootstrap.shis POSIXshthat never invokes node. Theonly native module (
@lydell/node-pty-linux-x64, via gemini-cli) is N-API, so theNODE_MODULE_VERSION127 → 147 jump is ABI-safe.Dependabot rewrote only the
FROMdigest, leaving line 1 assertingnode:22-bookworm-slim. Fixed.#1792 — the image moved without its SDK
apps/api/Dockerfile.sandboxstates the invariant in its own comment: the reviewed tag "MUST matchthe
@cloudflare/sandboxnpm package version". Dependabot bumped only the digest, leavingapps/api/package.jsonat^0.12.1and the comment at0.12.1. The container-server binary in theimage and the npm client speak the same versioned HTTP API (
getSandbox()/exec()/readFile()), sodrift is a runtime protocol mismatch no type check or unit test can observe.
Pinned
@cloudflare/sandboxto exactly0.12.5— exact, not^, because a range lets the clientdrift from the digest-pinned image on any unrelated
pnpm install.#1796 — kept; root cause was a missing Astro major
@astrojs/starlight@0.41.7declares peerastro@^7.0.2;apps/wwwpinnedastro@6.4.8. The newerpeer graph resolves
@astrojs/mdx@7.0.5, which importschunkToStringfromastro/runtime/server/index.js— a symbol Astro 6 does not export. Because Type Check / Test /Workspace Quality Surfaces / Durable Object Workers all depend on
@simple-agent-manager/www#buildin turbo, that one root cause produced all five red checks.
Upgraded
astro6.4.8 → 7.2.2 (pinned in exactly one place,apps/www/package.json). Astro 7'srolldown pipeline then resolves dynamic imports inside processed
<script>blocks, so the mermaidlazy-loader in
apps/www/src/layouts/BlogPost.astroneededis:inline—/scripts/blog-mermaid.jsis an esbuild artifact emitted intopublic/at build time, i.e. a runtimeURL rather than a resolvable module. Build is clean: 181 pages + Pagefind index + sitemap.
Lockfile
The two npm PRs'
pnpm-lock.yamltext-merge produced a wrong@types/noderesolution combo;pnpm installcorrected it.Process fix
scripts/quality/dependency-governance.test.tsasserted Docker digest pinning only, so it passedstraight through both stale-comment bugs and said nothing about image↔SDK drift. Two tests added:
FROMtag;@cloudflare/sandboxmust be an exact pin equal to theDockerfile.sandboximage tag.Both verified discriminating — each was run red against the exact pre-fix state Dependabot
produced, then restored.
Validation
pnpm lint— 13/13 packagespnpm typecheck— 19/19 taskspnpm test— 21/21 tasks (apps/web alone: 260 files / 3126 tests)pnpm build9/9;pnpm format:checkratchet;pnpm quality:type-boundaries(0 blocking);pnpm quality:scripts:test38 files / 473 tests;and
quality:dependency-governance,workspace-test-surfaces,direct-dependency-evidence,stale-artifacts,file-sizes,source-contract-tests,agent-install-manifest,wrangler-bindings,repo-visibilityall passalarm candidate selection is touched. The diff is dependency versions, one Astro template
directive, one docs correction, and two governance tests.
Staging Verification (REQUIRED for all code changes — merge-blocking)
32009397965, 08:14:13Z→08:29:22Z,headSha== this branch's909ba28d7api.sammy.party/api/auth/token-login, drove the real project chat UIStaging Verification Evidence
Deploy provenance (checked before trusting any result). Deploy
headShaequals thisbranch's HEAD
909ba28d7d0b22e8acc8482aeebfb3ed23334561. The deploy log shows the containerimages were genuinely rebuilt from
node:26-bookworm-slim@sha256:cd565714d4daandcloudflare/sandbox:0.12.5— 4 image pushes, zero EBADENGINE / npm errors. I confirmedfrom
deploy-reusable.ymlthatwrangler deployreally does rebuild the[[containers]]images and that staging sets
skip_agent: false; without that, an Instant session would haverun the OLD image and produced a false green.
#1801 — ACP agent session: VERIFIED end-to-end on staging. Real conversation on a VM
runtime profile, session
7517db17-bc4d-4bff-b11c-0d4ef57428d2:Prompt → response → real
Readtool call → correct answer, andrendered=trueconfirmsthe answer painted in the browser through
packages/acp-clientwith the SDK removed, withzero console errors. Tool-call evidence comes from the durable API transcript's
toolMetadata, not from page text — whole-pageinnerTextis unusable here because the appchrome contains a "Search…Ctrl+K" button that false-positives naive matching.
Regression sweep: PASS.
/dashboard,/projects,/settings,/nodesat 1280×800 and375×667 — all render real content with correct headings, no document-level overflow, zero
console errors at both viewports. One 5px clipped overshoot on mobile
/settings(
MAIN.sam-main-content380>375); this PR contains zeroapps/web/source changes, so itcannot originate here — filed as SAM idea
01M07E845VMG8A1MZZCK98G3TZ.Cleanup done. Node
01M07EHK49165026PHT7DHEQ12and workspace01M07EP268FC74B9X9SGH9RVDQboth deleted; re-queried D1 afterwards and staging is back to zero non-destroyed nodes and
zero live workspaces. The Hetzner 10-server cap is shared with production.
What is NOT verified, and why
#1790 / #1792 — the cf-container agent turn could not run on staging. Instant sessions are
disabled there:
CF_CONTAINER_ENABLED='false'on the staging GitHub Environment (set2026-08-11).
resolveWorkspaceRuntime(apps/api/src/services/workspace-runtime.ts:61) gateson
(CF_CONTAINER_ENABLED ?? SANDBOX_ENABLED) !== 'true', sochat-start(
apps/api/src/routes/chat-start.ts:150) returns 409 "Selected profile resolves to VMruntime".
SANDBOX_ENABLED='true'cannot rescue it —??only falls back on null/undefined.I confirmed the Instant profile really was selected (chip
aria-pressed=true; profiles APIreports
runtime=cf-container), so this is the server refusing, not a mis-click. This ispre-existing and unrelated to this PR; enabling it means reversing a deliberate decision on
shared staging, which is an infrastructure call for the merge approver, not mine. It also
contradicts the project policy that
CF_CONTAINER_ENABLEDshould default true.Substitute evidence, gathered locally with Docker rather than skipped:
Dockerfile.vm-agent-containerbuilds on Node 26 — exit 0, zero EBADENGINE. The pinneddigest resolves to node v26.7.0 / npm 11.19.0.
Every agent binary executes in that image:
claude2.1.207,claude-agent-acp0.58.1,codex0.144.6,codex-acp1.1.2,gemini0.50.0,opencode1.17.18,amp,vibe/vibe-acp2.19.1,acp-amp,gh2.97.0 — names cross-checked againstpackages/shared/src/agent-install-manifest.json.Dockerfile.sandboxbuilds; the container server self-reports"serviceVersion":"0.12.5",matching the exact-pinned npm client. The image↔SDK invariant is confirmed by observation,
not only by the new test.
undici 8
fetchexercised directly in the pinned Node 26 image (this was the singleresidual risk metadata could not rule out — Node 26 ships undici 8, changing global
fetchfor seven HTTP-heavy agent CLIs):
DNS, TLS, request and response parsing, and streaming body reads all work. The
401fromAnthropic is the informative one: it is an authentication rejection, not a transport failure,
so the complete request/response cycle to the exact API the agents call succeeded.
What remains genuinely unproven is a live agent turn through the deployed container — i.e.
the full agent harness running under SAM's own orchestration on Node 26, rather than the image
and its runtime being exercised piece by piece as above.
#1796 — the docs site is not staging-deployable by design.
apps/wwwis not part ofdeploy-staging.yml; it has its owndeploy-www.yml, triggered by push tomaintouchingapps/www/**and running withenvironment: production. Staging's www accordingly stillserves the old build (
<meta generator>reportsAstro v6.4.8 / Starlight v0.40.0), which isexpected rather than a defect. I did not dispatch that workflow from this branch, because
it would publish unreviewed changes straight to the live public site.
Docs verification was therefore done against the real Astro 7 build output, at 375 and 1280:
181 pages build;
/,/docs/overview/,/docs/quickstart/,/blog/,/docs/guides/instant-sessions/,/docs/reference/configuration/all serve 200 with correct<title>/<h1>and 3.6k–36k chars of real text;pagefind.jsserves 200 (the Starlightfeature most likely to break on a major); zero document-level overflow. The two clipped
elements on mobile
/(SECTION.hero688>375,DIV.node-grid424>375) are identical onorigin/mainunder Astro 6 — I built main in a throwaway worktree to check rather thanassume. Only the scoped-CSS hash differs, as expected when Astro regenerates scopes.
UI Compliance Checklist (Required for UI changes)
to
apps/web/,packages/ui/,packages/terminal/, none of which this PR touches. The onlytemplate change is
is:inlineon a<script>inapps/www, which changes bundling, notlayout. Docs/blog rendering verified on staging instead (see evidence above).
End-to-End Verification (Required for multi-component changes)
Data Flow Trace
The load-bearing path is the Instant (cf-container) agent session, because it is the one thing that
exercises both bumped images:
apps/web→POST /api/projects/:id/sessions/.../messagesapps/api/src/services/sandbox.ts(await import('@cloudflare/sandbox'),getSandbox) — thisis the npm client whose version chore(deps): bump cloudflare/sandbox from 0.12.1 to 0.12.5 in /apps/api #1792 must keep aligned with the image
SandboxDO/VmAgentContainercontainer bindings inapps/api/wrangler.tomlboot the imagesbuilt from
apps/api/Dockerfile.sandboxandapps/api/Dockerfile.vm-agent-container— the twoimages bumped by chore(deps): bump cloudflare/sandbox from 0.12.1 to 0.12.5 in /apps/api #1792 and chore(deps): bump library/node from 22-bookworm-slim to 26-bookworm-slim in /apps/api #1790
container-entrypoints/vm-agent-bootstrap.shexecs the baked Govm-agentbinarynpm install -gin that image — running on theNode 26 runtime from chore(deps): bump library/node from 22-bookworm-slim to 26-bookworm-slim in /apps/api #1790
packages/acp-client/src/transport/websocket.ts, which types the payload asunknownand hands itto
src/hooks/useAcpMessagePayloads.ts— the hand-rolled types that prove chore(deps): bump @agentclientprotocol/sdk from 0.25.0 to 1.3.0 #1801's SDK is deadpackages/acp-clientcomponents in the project chatSteps 2–6 cannot be proven by any unit test. Steps 6–7 (ACP over the wire → acp-client rendering)
are verified by the staging ACP session above. Steps 3–5 through the deployed container remain
unverified because Instant is disabled on staging; see "What is NOT verified".
Untested Gaps
The Docker images are built in the deploy pipeline, not in CI or locally, so no automated test can
observe Node 26 actually executing an agent CLI. That gap is only partially closed: the ACP half is covered by the staging session above, and the
image half by the local Docker builds. The live-agent-turn-through-the-deployed-container gap is
stated openly in "What is NOT verified" rather than papered over.
Post-Mortem (Required for bug fix PRs)
What broke
Two Dependabot bumps landed a Dockerfile in a self-contradictory state: the
FROMline pointed at anew image while the "reviewed source tag" comment beside it still named the old one. In #1792 that
was worse than cosmetic — the comment asserts an invariant ("MUST match the
@cloudflare/sandboxnpmpackage version") that the commit itself broke, leaving a digest-pinned 0.12.5 container server
paired with a
^0.12.1npm client.Root cause
Dependabot rewrites only the machine-readable
FROMdigest. It has no concept of the human-readablecomment that records what a human actually reviewed, and it opens the image bump and the npm-package
bump as two independent PRs with no link between them.
Class of bug
An invariant asserted in a comment but enforced nowhere. Prose that states "X MUST match Y" is
documentation, not a guard; it degrades silently the moment an automated tool touches one side. The
adjacent class is a paired-artifact bump where the two halves live in different files and are updated
by independent processes.
Why it wasn't caught
scripts/quality/dependency-governance.test.tsalready had a Docker test, which made the area lookcovered. It asserted digest pinning only — a property both bumps satisfied — so it passed green
through both defects. A test that cannot observe the failure it is adjacent to reads as coverage
while providing none.
Process fix included in this PR
scripts/quality/dependency-governance.test.ts— two new tests, both verified to fail on the exactpre-fix state:
comment from prose to an enforced invariant, for every Dockerfile, not just the two here.
cross-file invariant the comment claimed, and additionally requires an exact pin so a semver range
cannot reintroduce drift on an unrelated install.
Post-mortem file
tasks/active/2026-08-17-integrate-four-nontrivial-dependabot-prs.md(section "Process gap that lettwo of these ship half-done").
Specialist Review Evidence (Required for agent-authored PRs)
needs-human-reviewlabel added and merge deferred to humanastropinned in one place; both governance tests discriminating; one root cause behind all five red checks on #1796; checklist↔diff correspondence with no scope creep). No CRITICAL/HIGH. Two LOW notes, both superseded by909ba28d7.909ba28d7. HIGH: the comment-sync helper used.exec()(first match only) plus a file-widetoContain, so on a multi-stage Dockerfile a stale stage-2 comment was invisible and masked by stage 1 matching; replaced with nearest-preceding-comment pairing. MEDIUM: two heredoc Dockerfiles in.github/workflows/devcontainer-cache-experiments.ymluse the same convention but were outside the path walk; now covered. LOW: position-agnostic regex (fixed by the pairing) and a misleading prerelease error message. Also independently re-verified my three original discrimination claims.apps/api/package.json, andtasks/active/2026-07-23-codex-guided-setup-terminal.mdalready plans a second@cloudflare/sandboxdeclaration inapps/web— now walks every workspace manifest (909ba28d7). MEDIUM: Node 26 is Current, not LTS — surfaced above as an explicit decision for the merge approver rather than silently resolved. MEDIUM: Dependabotgroups:cannot tie the image to the npm SDK because groups are per-ecosystem; documented in CLAUDE.md that the governance test is the tripwire instead. Verified both digests against Docker Hub manifest lists, peer deps clean, and confirmed no new DO migration is needed.AGENTS.mdrewrite is accurate line-by-line against source and that leavingspecs/006-*/specs/007-*untouched is correct per rule 01. Found no stale version claim in any doc. Both recommendations taken in909ba28d7: a CLAUDE.md Recent Changes entry, andapps/www/AGENTS.mdgotchas for the Astro 7 rolldown dynamic-import trap and the Starlight↔Astro major coupling.Not run, with reason:
go-specialist(no Go source changed),ui-ux-specialist(rule 17 scopes toapps/web/,packages/ui/,packages/terminal/— untouched),security-auditor(no auth,credential, or token code),
env-validator(no environment variables added, removed, or renamed),constitution-validator(no business logic, URLs, timeouts, or limits introduced).Exceptions (If any)
image; the blast radius is production agent sessions. He asked for this to be made "provably good
to go, integrated, tested in staging" and will give the merge go-ahead himself. There is also an
open decision for him on Node 26 (Current) vs Node 24 (Active LTS) — see chore(deps): bump library/node from 22-bookworm-slim to 26-bookworm-slim in /apps/api #1790 above.
Agent Preflight (Required)
Classification
External References
Consulted the official documentation and primary registries for every version boundary before
changing any code (Context7 was not required — these are release notes and registry metadata, read
from source):
ClientSideConnection/Stream/ndJsonStreamstill exist in 1.3.0:https://github.com/agentclientprotocol/typescript-sdk/releases and
https://raw.githubusercontent.com/agentclientprotocol/typescript-sdk/main/MIGRATION_0.26_0.27.md
https://unpkg.com/@agentclientprotocol/sdk@1.3.0/dist/acp.d.ts
https://raw.githubusercontent.com/nodejs/Release/main/schedule.json
https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V26.md
engines.nodefor all seven bundled agent CLIs: https://registry.npmjs.orgnode:26-bookworm-slimexists, that bookworm was not droppedfor 26, and that the PR digest is byte-identical: https://hub.docker.com/_/node
astro@^7.0.2) read from the installed package manifest, andAstro 7 availability from https://www.npmjs.com/package/astro
Codebase Impact Analysis
apps/api/Dockerfile.vm-agent-container— Node base image 22 → 26; backs theVmAgentContainercontainer binding in
apps/api/wrangler.toml.apps/api/Dockerfile.sandbox—cloudflare/sandboxbase image 0.12.1 → 0.12.5; backsSandboxDO.apps/api/package.json—@cloudflare/sandbox^0.12.1→ exact0.12.5; consumed byapps/api/src/services/sandbox.ts,apps/api/src/env.ts, and re-exported asSandboxDOfromapps/api/src/index.ts. Aliased inapps/api/vitest.workers.config.ts.packages/acp-client/package.json— removed the unused@agentclientprotocol/sdk; consumedtransitively by
apps/web.packages/acp-client/AGENTS.md— corrected a false claim about where ACP types are defined.apps/www/package.json,apps/www/src/layouts/BlogPost.astro— Astro 6 → 7 and theis:inlinedirective required by Astro 7's rolldown pipeline.
scripts/quality/dependency-governance.test.ts— two new governance tests (the process fix).pnpm-lock.yaml— regenerated; also repaired a bad@types/noderesolution from the text-merge.tasks/active/2026-08-17-integrate-four-nontrivial-dependabot-prs.md— task record.specs/006-multi-agent-support/andspecs/007-multi-agent-acp/stillreference
@agentclientprotocol/sdk. Per.claude/rules/01-doc-sync.md, spec files are historicalrecords and must not be edited outside their own active spec context.
Documentation & Specs
packages/acp-client/AGENTS.md— rewrote the "Gotchas" claim that@agentclientprotocol/sdk"defines the ACP wire protocol types". It defines nothing here; thereplacement cites the real locations (
src/hooks/useAcpMessagePayloads.ts,src/transport/types.ts,src/transport/websocket.ts) per the "cite code paths in behavioraldocs" requirement.
apps/api/Dockerfile.vm-agent-containerandapps/api/Dockerfile.sandbox— reviewed-source-tagcomments brought back in sync with their
FROMlines, and now enforced by test rather than trust.tasks/active/2026-08-17-integrate-four-nontrivial-dependabot-prs.md— full research record,checklist, and acceptance criteria.
apps/www/src/content/docs/docs/change needed: no public doc states an Astro, Starlight, Node,or sandbox version, and no user-facing behaviour changed.
Constitution & Risk Check
literals added are dependency pins and test assertions about those pins, which is configuration
data, not business-logic configuration.
@agentclientprotocol/sdkinsteadof bumping an unused dependency across a major.
.claude/rules/01-doc-sync.md— docs corrected in the same commit as the code; spec files leftuntouched per the spec-edit-scope rule.
.claude/rules/02-quality-gates.md— bug-fix PRs require a process fix; two governance testsadded and both proven discriminating against the pre-fix state.
.claude/rules/13-staging-verification.md/30-never-ship-broken-features.md— the Dockerimages are built only in the deploy pipeline, so a real Instant session completing a real agent
turn on staging is the only admissible evidence for chore(deps): bump library/node from 22-bookworm-slim to 26-bookworm-slim in /apps/api #1790 and chore(deps): bump cloudflare/sandbox from 0.12.1 to 0.12.5 in /apps/api #1792. See the staging section above.
half is now enforced by test. The first half is the open Node 24-vs-26 decision flagged for the
merge approver rather than silently resolved.
Key risks/tradeoffs. The residual risk is Node 26's undici 8 major changing global
fetchforthe bundled agent CLIs; package metadata cannot detect it (every constraint is a lower bound, so the
image builds green regardless), which is why verification is empirical. Removing the ACP SDK is the
lowest-risk action available for #1801 precisely because nothing imports it — the change cannot alter
runtime behaviour. The Astro 7 upgrade is the largest real code change here, but it is confined to
apps/www, a static site with no runtime coupling to the control plane.