SPIKE: run standalone vm-agent in Cloudflare Sandbox#1544
SPIKE: run standalone vm-agent in Cloudflare Sandbox#1544simple-agent-manager[bot] wants to merge 36 commits into
Conversation
Spike resumed — recovered lost fix + root-caused the real agent-start blocker (2026-07-08)Picked up where the prior session left off. The prior session's "cannot push" was a misdiagnosis (it inspected the What was actually wrong (and it was NOT the binary)The recurring Root cause: The binary always existed, was valid ( The fix
Verified on staging (new binary, fresh cf-container launch)
Final remaining blocker (narrow, control-plane wiring)The agent's 3 generated messages don't reach the chat because the standalone message reporter has no auth token:
Commits on this branch
Still draft / |
The boot-time message reporter is created without an auth token (server.go ~428), and standalone mode never runs bootstrap's setTokenAllReporters, so the reporter POSTed chat messages with no token -> "no auth token" and the agent's output never persisted to the chat session. getOrCreateReporter's fast path returned the existing tokenless reporter without ever setting a token. Refresh the reporter's token from the workspace runtime (workspaceCallbackToken) on every getOrCreateReporter access. By the time the agent session is created the workspace callback token is present in the runtime, so the reporter can authenticate its message POSTs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The cf-vm-agent/start endpoint inserted the workspace without installationId, so /:id/git-token returned 404 "Workspace has no GitHub installation" and the agent ran without git access (couldn't list remote branches / clone). Inherit the project's GitHub App installation on the workspace so it can mint a repo-scoped git token. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The node-ready callback re-dispatches pending workspaces via createWorkspaceOnNode, which omits `lightweight`. For a standalone cf-container node the VM agent's boot runtime already has the workspace with lightweight=true, so the re-dispatch hits a 409 profile conflict and marks the workspace `error`. The messages endpoint then rejects the agent's output with "Workspace is error, not active", so chat never persists. cf-container workspaces are provisioned by their own launch flow and must never be re-dispatched through the normal node-ready path. Exclude vm_location='cf-container' from the pending-workspace re-dispatch query. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In standalone (cf-container) mode the per-session GH_TOKEN is injected into the agent environment, but git has no credential helper configured (the devcontainer helper setup in bootstrap is skipped and targets docker-host addresses that don't apply). So the agent's `git ls-remote`/clone prompt for a username and fail: "could not read Username for 'https://github.com'". Install a small GitHub-scoped credential helper that serves the injected GH_TOKEN, and register it via `git config --system credential.helper` at standalone startup. Non-fatal on failure. Behavioral tests cover the github host, non-github host rejection, missing-token, and non-get actions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
✅ Full stack working end-to-end (2026-07-08)A standalone vm-agent in a Cloudflare Container now completes a real chat session with tool calls and working git credentials. Verified on staging with a fresh cf-container launch: Prompt: "Run: Result (persisted to the chat session, 13 messages):
Four control-plane/wiring gaps fixed to get here (each surfaced only after the previous)
Plus the earlier agent-start fix ( Full commit list on this branch
Still draft / |
CF container productionized-path validation - 2026-07-08Branch Commit summary:
Local gates passed after the productionized runtime wiring:
Additional post-Sonar hardening validation:
Specialist review summary:
Staging verification:
The same staging evidence was appended to SAM idea Per the spike constraint, this PR remains draft, labeled |
|



Summary
Productionizes the Cloudflare Container instant-session path in PR #1544 while keeping the PR draft-only for human staging review.
This branch turns the proven spike into the user-facing flow:
runtime(vmorcf-container) to agent profiles and skills, including D1 migration0089and shared API/web types.POST /api/projects/:projectId/sessions/startinstant-session launcher.cf-vm-agent/startspike launcher.Draft/merge policy: do not merge. The PR intentionally remains draft and labeled
needs-human-reviewuntil Raphaël tests or explicitly clears it.Validation
pnpm lintpnpm typecheckpnpm test.claude/rules/47-control-loop-io-budget.md)Additional validation:
pnpm buildpnpm --filter @simple-agent-manager/api exec vitest run tests/unit/cf-container-runtime-contract.test.ts tests/unit/services/agent-profiles.test.tspnpm --filter @simple-agent-manager/web exec vitest run tests/unit/pages/project-chat.test.tsx tests/unit/components/agent-profiles.test.tsxpnpm --filter @simple-agent-manager/web exec playwright test tests/playwright/project-chat-composer-audit.spec.ts- 21 tests passed across iPhone SE, iPhone 14, and desktop.pnpm quality:observability-noise- no significant log noise detected; D1 subcheck skipped becauseOBSERVABILITY_DB_IDwas not configured, Workers telemetry skipped with 403.No sweep/cron/alarm candidate-selection behavior was changed; the checked item is N/A because this PR does not add or alter a control-loop candidate query.
Staging Verification (REQUIRED for all code changes - merge-blocking)
All checkboxes below are mandatory for any PR that changes runtime code (
.ts,.tsx,.go, etc.). WriteN/A: docs-onlyONLY if the PR contains zero runtime code changes. See.claude/rules/13-staging-verification.md.Deploy Stagingworkflow triggered manually and passed for this branchapp.sammy.party(staging) using test credentials and actively tested the applicationStaging Verification Evidence
Deploy-staging run
28980055879passed: deploy job green in 7m38s and smoke-tests green in 2m1s.Live staging verification used
https://api.sammy.partyandhttps://app.sammy.partywith the primary Playwright smoke user on project01KTKXZ4ZZAT6MJFXRW1ZTQ7RB(serverspresentation2025/hono). A temporary explicit cf-container profile01KX1Y8TRGH01BA0ZXM3ZHBSC7was created for the test and deleted afterward.The instant-session API returned 201 in 16,674 ms for session
291d3716-4a74-4158-b744-c825649f326d, workspace01KX1Y90YX0450Q081DP9MH752, node01KX1Y90SCV0X04N58V7W65KPR, and ACP session01KX1Y9A9P2884SAX3TX15DHTX. Runtime decision was{ runtime: 'cf-container', reason: 'explicit-cf-container' }.Measured timings: setup 10,831 ms, install 7,879 ms, agentReady/heartbeat wait 174 ms, workspaceCreate 642 ms, acpSessionCreate 642 ms, acpSessionStart 288 ms.
Browser verification observed the expected notification/session WebSockets plus the workspace ACP proxy WebSocket at
wss://ws-01kx1y90yx0450q081dp9mh752.sammy.party/agent/ws?.... A direct browser WebSocket open to the workspace ACP proxy path succeeded in 2,191 ms.Transcript verification found 4 persisted messages (
user,user,assistant,assistant); assistant chunksSA+M_CF_CONTAINER_SMOKE_OKcombined toSAM_CF_CONTAINER_SMOKE_OK. The final staging screenshot showed the assistant marker rendered in the live UI.Account-map verification: node status
running, healthStatushealthy, vmLocationcf-container, cloudProvidercloudflare, vmSizestandard-1, lastHeartbeatAt2026-07-08T22:42:25.962Z; workspace statusrunningwith populatednodeId.Evidence was also posted in PR comment #1544 (comment) and appended to SAM idea
01KWY8E8W1J4F3AC3QAETT2RAT.UI Compliance Checklist (Required for UI changes)
.codex/tmp/playwright-screenshots/(see.claude/rules/17-ui-visual-testing.md)UI evidence:
tests/playwright/project-chat-composer-audit.spec.tspassed 21 tests across iPhone SE, iPhone 14, and desktop. The live staging chat screenshot for session291d3716-4a74-4158-b744-c825649f326dshowed the streamed assistant marker without layout overlap or console errors.End-to-End Verification (Required for multi-component changes)
.claude/rules/10-e2e-verification.md)Data Flow Trace
apps/api/src/db/migrations/0089_agent_profile_runtime.sql, schema/types inapps/api/src/db/schema.ts, shared profile field mapping inapps/api/src/services/profile-fields.ts, profile services inapps/api/src/services/agent-profiles.ts, and web profile controls inapps/web/src/components/agent-profiles/ProfileFormDialog.tsx.apps/api/src/services/workspace-runtime.ts, combining sandbox availability, explicit profile/skill runtime, and user/platform credential source.apps/web/src/hooks/useProjectChatState.ts, callsapps/web/src/lib/api/sessions.ts:startInstantChatSession, and posts toapps/api/src/routes/chat-start.ts.apps/api/src/routes/chat-start.tsauthenticates project/repo access, resolves runtime, and callsapps/api/src/services/instant-session.ts:launchInstantSessionfor cf-container sessions.apps/api/src/services/instant-session.tscreates the Sandbox, virtual node, workspace, ACP session, and start event, reusing helpers fromapps/api/src/services/sandbox.tsand the existing workspace/session/project-data services.Untested Gaps
The complete cf-container happy path was manually verified on staging with a real container, workspace WebSocket proxy, ACP session, and persisted transcript. Automated coverage exercises the runtime contract, agent-profile persistence, API service launch sequencing with mocked boundaries, and web chat/profile UI; Cloudflare Sandbox cold-start behavior remains live-infrastructure-only.
Post-Mortem (Required for bug fix PRs)
N/A: not a bug fix. This is productionization of an existing feasibility spike.
What broke
N/A: not a bug fix.
Root cause
N/A: not a bug fix.
Class of bug
N/A: not a bug fix.
Why it wasn't caught
N/A: not a bug fix.
Process fix included in this PR
N/A: not a bug fix.
Post-mortem file
N/A: not a bug fix.
Specialist Review Evidence (Required for agent-authored PRs)
If local subagents were used during Phase 5, list every reviewer below. Do NOT merge until every row shows PASS or ADDRESSED. If any reviewer could not complete (timeout, workspace killed, error), you MUST add the
needs-human-reviewlabel and stop - do not self-merge. See.claude/rules/25-review-merge-gate.md.needs-human-reviewlabel added and merge deferred to humanThe specialist table is complete. The PR still intentionally has
needs-human-reviewbecause the user explicitly requested staging-first human testing and no production merge.Exceptions (If any)
needs-human-reviewafter all agent-side work.Agent Preflight (Required)
Classification
External References
N/A: no external API contract was changed. Cloudflare Sandbox/Container behavior had already been validated by the existing spike in this PR; this pass productionized SAM's own API, UI, runtime resolver, and staging verification flow.
Codebase Impact Analysis
Affected paths span
apps/api(D1 migration, profile/skill schema, runtime resolver, chat-start route, instant-session and sandbox services),apps/web(chat launch hook, sessions API helper, profile runtime controls, composer runtime messaging),packages/sharedprofile/runtime types, and task tracking undertasks/active. The change also removes the admin-only cf-container launcher fromapps/api/src/routes/admin-sandbox.ts.Documentation & Specs
Task-tracking documentation was updated in
tasks/active/2026-07-08-cf-container-vm-agent-standalone-spike.mdwith implementation status, validation notes, staging evidence, PR/idea links, and the do-not-merge handoff. No public www documentation was updated because this is a draft PR pending Raphaël's staging review.Constitution & Risk Check
Checked Constitution Principle XI / no hardcoded values, auth/project-boundary risks, container/runtime gating, migration safety, and UI verification obligations. Main risks are live Cloudflare Sandbox behavior, ephemeral cf-container runtime expectations, and draft human-review gating; those are covered by
SANDBOX_ENABLED, explicit runtime resolution tests, staging verification, and the retainedneeds-human-reviewlabel.