Claude Code Cloud Architecture — Research Findings (2026-04-24)
Claude Code Cloud Architecture — Research Findings (2026-04-24)
Deep dive on Claude Code’s remote/cloud architecture for a 100% cloud-native Ascend GTM agent workflow. Every claim cites a live April 2026 doc URL.
Three execution models — when to use which
| Model | Runtime | Use for |
|---|---|---|
| Claude Code on the Web (docs) | Anthropic-managed VMs, 4 vCPU / 16 GB RAM / 30 GB disk, Ubuntu 24.04 | Open-ended dev tasks, parallel task execution (--remote fires N sessions), overnight builds |
| Routines (docs) | Same Anthropic VMs, scheduled/API/GitHub-triggered | Unattended automation — nightly PR audit, Sentry → draft-PR, PR-opened auto-review |
| Remote Control (docs) | Local CLI mirrored to web/mobile | Steering in-flight work from phone — NOT for laptop-off scenarios |
| Agent SDK (docs) | Self-hosted library (Python/TS) | Custom Workers / Lambda functions using Claude as a tool — e.g., “a CF Worker that auto-triages Sentry alerts” |
Key clarification for Ascend: Remote Control ≠ cloud session. Remote Control is “my laptop runs CC, I drive it from my phone.” Useful for oversight, not for the “close laptop, agent keeps working” case. That case = Web (with --remote) or Routines.
Web runtime — confirmed specs
From https://code.claude.com/docs/en/claude-code-on-the-web:
| Property | Value |
|---|---|
| CPU / RAM / disk | 4 vCPU / 16 GB / 30 GB |
| OS | Ubuntu 24.04 |
| Session persistence | Across browser close; expires after inactivity (~24-48 h) |
| Environment caching | ~7 day TTL; setup script runs on cache miss only |
| Pre-installed runtimes | Python 3.x + toolchain (pip/poetry/uv/black/mypy/pytest/ruff), Node 20/21/22 (npm/yarn/pnpm/bun¹), Ruby 3.1-3.3, PHP 8.4, Java 21, Go, Rust, C/C++, Docker, Postgres 16, Redis 7 |
| Utilities | git, jq, yq, ripgrep, tmux, vim, nano |
gh CLI | NOT pre-installed — add via setup script |
wrangler CLI | NOT pre-installed — add via setup script |
| Network | 4 access levels (None / Trusted / Full / Custom) |
¹ Bun is broken behind the security proxy — use npm/yarn/pnpm.
Repo-vs-user config — what carries over
Confirmed against the “What’s available in cloud sessions” table at the URL above:
| Config | Carries to cloud? | Fix |
|---|---|---|
Repo CLAUDE.md, .claude/settings.json, .claude/rules/, .claude/skills/, .claude/agents/, .claude/commands/ | ✅ Yes — part of clone | |
Repo .mcp.json | ✅ Yes | |
Plugins in repo .claude/settings.json enabledPlugins | ✅ Installed at session start from marketplaces | |
User ~/.claude/CLAUDE.md | ❌ No | Move to repo .claude/CLAUDE.md |
User ~/.claude/mcp.json / stdio MCPs added via claude mcp add | ❌ No | Move to repo .mcp.json |
User-scope enabledPlugins | ❌ No | Declare in repo .claude/settings.json |
| Static API tokens / secrets | ❌ No — no dedicated secrets store exists yet (per docs) | Paste into environment variables in claude.ai/code UI — visible to anyone who can edit that env |
| Interactive auth (AWS SSO, browser-based login) | ❌ No | Use scoped tokens stored in env vars |
Routines — full spec
From https://code.claude.com/docs/en/routines:
Trigger types (combinable on one routine):
- Schedule — preset frequency (hourly/daily/weekdays/weekly) or one-off. Minimum 1-hour interval. Custom cron via
/schedule updateCLI. - API — per-routine HTTPS endpoint + bearer token. POST
{text: ...}body. Token shown once, must store externally. - GitHub —
pull_request.*orrelease.*event matchers with filters (author, title, branch, labels, is-draft, is-merged, regex).
Caps (research preview): per-account daily run cap (variable, visible at claude.ai/code/routines or claude.ai/settings/usage). Extra Usage setting enables overage billing.
One-offs don’t count against the daily cap. Scheduled recurring runs + API fires + GitHub events do.
Webhook caps during preview: GitHub events have per-routine and per-account hourly caps; events beyond the limit are dropped until the window resets.
The GitHub proxy (security model)
All git operations in cloud sessions go through a dedicated proxy that:
- Uses a scoped credential inside the sandbox (not your real token)
- Restricts
git pushto the current working branch only — prevents routine-spawned sessions from overwritingmain - Translates the scoped credential to your real token outside the sandbox
- Keeps your PAT / GitHub App token out of any code execution context
Implication: cloud sessions can’t accidentally force-push to main even if the agent model went rogue — the proxy enforces branch scoping at the network layer.
--remote, --teleport, --resume, --remote-control — canonical semantics
| Flag | What it does |
|---|---|
claude --remote "task" | Creates a new cloud session, runs task, returns session URL |
claude --teleport <id> | Pulls a cloud session into local CLI with full history + branch checkout |
claude --resume | Reopens a local session from local history (NOT a cloud pull) |
claude --remote-control | Exposes a local CLI session for monitoring/steering from web/mobile. Unrelated to cloud sessions. |
/tasks (in-session) | Lists active background sessions; press t to teleport into one |
One-way handoff from CLI: --remote pushes to cloud, --teleport pulls from cloud. The CLI doesn’t push a running local session to the cloud — use the Desktop app’s “Continue in” menu for that direction.
Anti-patterns (what NOT to do)
- Don’t rely on user-scope
~/.claude/*config for cloud parity. If it’s not in the repo, it doesn’t exist in the cloud VM. - Don’t put long-lived secrets in cloud environment variables (no rotation, visible to env editors). Use short-lived tokens OR wait for the dedicated secrets store.
- Don’t use bun in cloud sessions — breaks through the security proxy. npm/yarn/pnpm only.
- Don’t assume Routine sessions persist memory across firings — each GitHub event / API fire = new stateless session. If state needed, persist to D1/KV.
- Don’t build custom webhook routers on your own infra when Routines’ API trigger gives you one per routine for free.
- Don’t use Remote Control expecting the laptop to be off — it mirrors a local session. Laptop off = session dead.
- Don’t grant Full network access to Routines that only need package installs — Trusted covers all common registries + GitHub + CF + cloud SDKs.
Decision matrix — Ascend use cases
| Ascend use case | Tool | Rationale |
|---|---|---|
| Overnight implementation of Phase 2 Tasks 2.5-2.8 | claude --remote | Open-ended, parallel subagents, benefits from full VM |
| Daily “review all open PRs and nudge stale ones” | Routine — Scheduled | Unattended, predictable cadence |
| ”Sentry fires → investigate + draft PR” | Routine — API trigger | External system fires → agent responds, no polling |
| PR opened by a teammate → run Ultraplan review | Routine — GitHub pull_request.opened | Event-driven, stateless |
| Ops checking on overnight job from iPhone | Web session → iOS app | Monitor + steer without laptop |
| Manager steering an in-flight build while on the road | Remote Control (requires laptop online) OR web monitor (more robust) | RC needs local CLI alive; web doesn’t |
| CF Worker that auto-triages Sentry alerts programmatically | Agent SDK (self-hosted in Worker) | Narrow, in-line, no human loop |
| n8n’s 83 workflows that fire from Telegram/webhooks | Routine API triggers | Replaces the n8n Cloud webhook → V5 gateway hop with a native path |
Recommended starting configuration for Ascend
repo: .claude/ CLAUDE.md # Non-Stop Protocol (currently at ~/.claude/CLAUDE.md — move here) settings.json # enabledPlugins, hooks, SessionStart, PreToolUse hooks/ # dangerous-command-blocker.py, etc. — copy from ~/.claude/hooks/ rules/ # api-integrations.md, parallelization.md, print-pdf.md skills/ # repo-relevant skills only .mcp.json # ascend-gateway (hosted), hindsight, cloudflare (hosted), github (hosted) .github/ workflows/ ci.yml # existing typecheck + test (unchanged) routine-smoke.yml # new — validate routine config on PR
cloud environment at claude.ai/code: name: ascend-gtm-ops-prod network: Trusted env vars: (25 from ~/.zprofile — one-time paste) setup script: installs wrangler + gh + any missing tooling
routines: 1. "Nightly PR audit" — schedule 03:00 UTC, scans open PRs, posts summary 2. "CI failure auto-fix" — GitHub trigger, pull_request.synchronize with failing checks 3. "Sentry triage" — API trigger, called by a CF Worker on error threshold 4. "Weekly tech-debt re-evaluation" — schedule Mondays 06:00 UTCSession limits — what Ascend should plan for
- Context window: 1M tokens (with auto-compaction ~95% capacity; tunable via
CLAUDE_AUTOCOMPACT_PCT_OVERRIDEenv var) - Max concurrent cloud sessions: not publicly documented, but each
--remoteconsumes a session slot; in practice/tasksshows up to ~10 cleanly - Rate limits: shared across CLI + Web + Routines within the same account. Parallel runs consume proportionately
- Compute billing: no separate VM charge; token usage = standard API billing
- Setup script execution time: no explicit cap, but runs before Claude Code launches; keep under ~5 min for good UX
Plugin marketplace — what’s relevant for Ascend
Currently installed plugins (from ~/.claude/plugins/installed_plugins.json):
n8n-mcp-skills@n8n-mcp-skillsclaude-reflect@claude-reflect-marketplace
Ando marketplace, Anthropic skills, and others exist but aren’t installed. Recommendation: enumerate the ones actually used in past 30 days, declare them in repo .claude/settings.json enabledPlugins, drop the rest.
Zero Data Retention compatibility
From the docs: “Organizations with Zero Data Retention enabled cannot use /web-setup or other cloud session features.”
If Ascend (or a specific tenant like Kahuna or a PFP portfolio co) requires ZDR, cloud sessions are off the table for that tenant. Route their work to local CLI.
Anti-pattern alert — current ~/.claude/CLAUDE.md content
The Non-Stop Execution Protocol I just added to ~/.claude/CLAUDE.md is at user scope — it does NOT carry to cloud sessions. This is the #1 migration item: if we want cloud sessions to respect the Non-Stop Protocol, the exact text must live in the repo’s .claude/CLAUDE.md. Otherwise cloud sessions stop at turn boundaries exactly like before.