Cloud-Only Audit — 2026-04-24
Cloud-Only Audit — 2026-04-24
Section titled “Cloud-Only Audit — 2026-04-24”Goal: make the entire Ascend GTM V5 system + the agent workflow runnable from a 10-year-old laptop with nothing local beyond a browser. Every compute + state surface on cloud infrastructure. No hardware dependency on any specific machine.
The V5 system itself is already ~100% cloud-native. Every production workload (gateway, context plane, tokens, scheduling, webhooks, embeddings, cron) runs on Cloudflare. Every integration (Slack, Gmail, ads platforms, CRMs, AWS, LLM providers) runs through the gateway — no local proxying.
The only laptop-dependent surface is the Claude Code agent workflow itself. That surface has a clean migration path via Claude Code on the Web + Routines (shipped April 2026 — live docs verified). Once migrated, you close the laptop and every loop — development, scheduled jobs, PR review, incident response — keeps running on Anthropic’s managed VMs.
Total laptop-dependent items requiring migration: 12. All have a cloud destination already documented. No new infrastructure required beyond Anthropic’s managed cloud and one CF environment-variable seed pass.
Inventory: What runs WHERE today
Section titled “Inventory: What runs WHERE today”✅ Already cloud-native — zero laptop dependency
Section titled “✅ Already cloud-native — zero laptop dependency”| Surface | Runtime | URL |
|---|---|---|
| V5 Gateway Worker | Cloudflare Workers | ascend-gateway-v5.ascendgtm.workers.dev |
| Context Worker (Phase 2) | Cloudflare Workers | pending resource provisioning (auth’d in CLAUDE.md) |
| TokenManager (OAuth refresh) | Cloudflare Durable Objects | TOKEN_MANAGER binding |
ascend-gateway-db | Cloudflare D1 | error_ledger, kv_audit, decision_log |
ASCEND_KV | Cloudflare KV | 3c4d67dc67d040c4a40db5deb02db0f3 |
ascend-gateway-backup | Cloudflare R2 | Weekly KV → R2 snapshot |
ctx_v5_facts (Phase 2) | Cloudflare Vectorize | Pending wrangler vectorize create |
| Workers AI embeddings | Cloudflare Workers AI | @cf/baai/bge-small-en-v1.5 |
| CF Queues (Phase 2) | Cloudflare Queues | ctx-ingest-gong, ctx-ingest-salesforce + DLQs |
| 5 CF Cron Triggers | Cloudflare Cron | system health, canary, token health, cleanup, autoresearch |
hindsight.ascendgtm.net | Self-hosted on cloud + Cloudflare proxy | long-term memory |
hindsight-auth.ascendgtm.net | Cloudflare Worker (hindsight-oauth-proxy) | OAuth bridge |
ascendgtm.net | Cloudflare Pages | marketing site |
| All DNS | Cloudflare | ascendgtm.net, subdomains |
mmurawala.app.n8n.cloud | n8n Cloud (managed) | workflow consumer |
| All source code | GitHub (mishaal-cloud/*) | origin truth |
| All CI | GitHub Actions (gateway-worker, context-worker-typecheck, bet2-history-verify) | cloud runners |
| All webhook receivers (Slack Events, Teams, Cal.com) | V5 Worker handlers (slack-events.ts, teams-webhook.ts, calcom-webhook.ts) | cloud |
| All 24+ external integrations | V5 Worker via OAuth + KV-resolved tokens | cloud |
⚠️ Laptop-dependent TODAY — the migration targets
Section titled “⚠️ Laptop-dependent TODAY — the migration targets”| # | Surface | Where it lives today | Impact if laptop off | Cloud destination |
|---|---|---|---|---|
| 1 | Claude Code CLI runtime | claude installed on Mac | Agent cannot run | Claude Code on the Web (claude.ai/code) — Anthropic-managed VMs (4 vCPU / 16 GB / 30 GB) |
| 2 | Hooks — dangerous-command-blocker.py, parallelization-nudge.sh, research-first-claim-detector.sh + 7 more | ~/.claude/hooks/ | Guardrails gone in cloud | Commit to repo .claude/hooks/ + reference in .claude/settings.json |
| 3 | Skills (300+ ads/marketing/data/product skills + all custom) | ~/.claude/skills/ | No skill access in cloud | Commit repo-relevant skills to .claude/skills/; plugin skills declared via .claude/settings.json enabledPlugins |
| 4 | Rules — api-integrations.md, n8n-workflows.md, parallelization.md, print-pdf.md | ~/.claude/rules/ | Rules silently disabled | Commit to repo .claude/rules/ |
| 5 | Global CLAUDE.md (incl. the new Non-Stop Protocol) | ~/.claude/CLAUDE.md | Non-Stop Protocol not loaded | Move protocol to repo .claude/CLAUDE.md + per-repo CLAUDE.md files |
| 6 | 25+ secrets | ~/.zprofile | Cloud session can’t auth to anything | One-time paste into cloud environment variables at claude.ai/code; wrangler secrets already handle Worker-side |
| 7 | n8n-mcp stdio server | node ~/.gemini/antigravity/scratch/n8n-mcp-source/dist/mcp/index.js | Agent can’t touch n8n | Use the n8n Cloud HTTP API directly (already available — $N8N_CLOUD_API_KEY); drop the stdio MCP |
| 8 | cloudflare MCP via npx | Stdio — npx @anthropic-ai/cloudflare-mcp@latest | Agent can’t provision CF resources | Cloud VM’s pre-installed wrangler + gh via setup script; CF API calls through ascend-gateway MCP |
| 9 | github MCP via npx | Stdio | Agent can’t do PR/issue work | Cloud VM has gh CLI pre-installed (verified in live docs); auth via GitHub App or /web-setup |
| 10 | Playwright tunnel | Local tunnel on localhost:8931, auto-started at session start | No browser automation | Drop — Claude Code web has built-in browser; CF Browser Rendering for production scraping |
| 11 | 9 local git worktrees | /Users/mishaalmurawala/dev/ascend-gtm-ops/.claude/worktrees/ | Lost work if laptop dies | Cloud sessions use --remote; fresh clone per session; commits push to GitHub |
| 12 | Local scheduled tasks (token-health-monitor, docs-freshness-check, error-pattern-digest, backup-verification) | ~/.claude/scheduled-tasks/ | Scheduled runs skip when laptop off | Convert to Claude Code Routines at claude.ai/code/routines — run on Anthropic-managed infra |
❓ Historical / already decommissioned
Section titled “❓ Historical / already decommissioned”| Surface | Status | Action |
|---|---|---|
ascend-agent-vps (Hetzner 5.78.117.196) | DECOMMISSIONED per V5 global CLAUDE.md | None — already gone |
Mac bridge :8889 | DECOMMISSIONED | Already gone |
Tailscale (100.125.246.94) | Listed in ~/CLAUDE.md as legacy network; no V5 traffic uses it | Document as unused; remove from CLAUDE.md |
| Old n8n self-hosted | Replaced by n8n Cloud | Already handled |
Secrets inventory — what needs to move
Section titled “Secrets inventory — what needs to move”Enumerated from ~/.zprofile (values redacted):
Cloud-side secrets — already stored as wrangler secret put on the V5 Worker:
ANTHROPIC_API_KEY,GEMINI_API_KEY,DEEPSEEK_API_KEY,OPENROUTER_API_KEY,GROQ_API_KEY,CEREBRAS_API_KEYCLOUDFLARE_API_TOKEN,CLOUDFLARE_TUNNEL_TOKENHETZNER_API_TOKENASCEND_GATEWAY_KEY,ASCEND_ADMIN_KEY,ASCEND_TENANT_BEARERGOOGLE_ADS_CUSTOMER_ID,GOOGLE_ADS_LOGIN_CUSTOMER_IDN8N_CLOUD_API_KEYVERCEL_TOKEN,VERCEL_TEAM_ID,VERCEL_ASCENDGTM_PROJECTOPENAI_API_KEY
Action: paste these (minus any that are truly dev-only) into the cloud environment variables at claude.ai/code under the ascend-gtm-ops environment, once. After that, cloud sessions have everything they need.
⚠️ Cloud environment vars are visible to anyone who can edit that environment. Per Anthropic docs, no dedicated secrets store exists yet. For shared teams, scope access accordingly. For a solo op (you), this is fine.
Architecture: the cloud-only end state
Section titled “Architecture: the cloud-only end state” ┌─────────────────────────────────────────┐ │ Any browser, any device │ │ (laptop / iPad / phone / library PC) │ └────────────┬────────────────────────────┘ │ │ HTTPS ▼ ┌─────────────────────────────────────────┐ │ claude.ai/code │ │ (Anthropic-managed VMs — 4 vCPU/16 GB) │ │ • Repo clone per session │ │ • Pre-installed: node, wrangler, gh, │ │ git, tmux, docker, postgres, etc. │ │ • Env vars from cloud env config │ │ • Hooks/Skills/Rules from .claude/ │ └──┬──────────────────┬─────────────────┬─┘ │ MCP (HTTP) │ GitHub │ Direct Anthropic API │ │ │ ▼ ▼ ▼ ┌─────────────────────────┐ ┌────────────┐ ┌─────────────────┐ │ V5 Gateway Worker │ │ GitHub │ │ Claude Models │ │ (CF Workers) │ │ (repos, │ │ (Anthropic) │ │ • 28 tools │ │ PRs, CI) │ └─────────────────┘ │ • KV, D1, R2, DO, AI │ └────────────┘ │ • Service Binding → │ │ Context Worker │ │ • Crons: 5 scheduled │ └──┬──────────────────────┘ │ │ all external integrations │ (OAuth-proxied via KV) ▼ ┌─────────────────────────────────────────────────────────────┐ │ HubSpot · Salesforce · Google Ads · GA4 · GSC · Gmail · │ │ Meta Ads · LinkedIn · Microsoft Ads · DealCloud · Gamma · │ │ SEMrush · Perplexity · AWS Bedrock/SES/Textract · Slack · │ │ Cal.com · n8n Cloud · Hindsight · OpenRouter · Gemini · │ │ DeepSeek · Groq · Cerebras │ └─────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐ │ Claude Code Routines (Anthropic-managed — runs 24/7) │ │ • Schedule: nightly PR audit, weekly digest refresh │ │ • API-triggered: Sentry alert → draft PR │ │ • GitHub: on PR opened → auto-review │ └──────────────────────────────────────────────────────────────┘Invariant: the box labeled “Any browser, any device” is the ONLY surface the user touches. No process runs on that device beyond Chrome. Everything else — development, execution, scheduled work, webhooks, CI — is on Cloudflare, Anthropic, or GitHub’s infrastructure.
Migration plan (ordered by dependency)
Section titled “Migration plan (ordered by dependency)”Phase A — Move agent config to the repo (~30 min)
Section titled “Phase A — Move agent config to the repo (~30 min)”No CF resource creation. Pure git work.
- Copy
~/.claude/CLAUDE.mdcontent →.claude/CLAUDE.mdin ascend-gtm-ops repo.
Specifically: the Non-Stop Execution Protocol I added must live in the repo for cloud sessions to load it. - Copy
~/.claude/rules/*→.claude/rules/in the repo. Commit. - Copy
~/.claude/hooks/*→.claude/hooks/in the repo; update.claude/settings.jsonto reference them. Commit. - Declare plugins in
.claude/settings.json→enabledPluginslist so cloud sessions install them on startup (pulls from the marketplaces you currently use — ando-marketplace, anthropic-skills, n8n-mcp-skills, claude-reflect). - Copy repo-relevant skills from
~/.claude/skills/→.claude/skills/. Skip skills that are clearly for other repos. Commit.
Phase B — Seed cloud environment + secrets (~10 min)
Section titled “Phase B — Seed cloud environment + secrets (~10 min)”Your browser, not mine.
-
Go to claude.ai/code. Confirm the plan tier includes Code on the Web (Pro/Max/Team/Enterprise with premium seat).
-
Install the Claude GitHub App on
mishaal-cloud/ascend-gtm-ops(+ any other repos). Or run/web-setupin your local CLI to sync theghtoken. -
Create an environment named
ascend-gtm-ops-prod. Paste the secret block from Secrets inventory into the environment-variables field. Set network access to Trusted (default covers npm/GitHub/CF/pypi/everything we need). -
Paste the setup script into the environment:
#!/bin/bashset -enpm install -g wranglerapt update && apt install -y gh -
Save. First session boot caches the script output; every subsequent session starts in ~5 seconds.
Phase C — Drop the local MCPs (~15 min)
Section titled “Phase C — Drop the local MCPs (~15 min)”Once the V5 gateway MCP is reachable from cloud sessions, the stdio MCPs become redundant.
- Drop
n8n-mcp(stdio) — the gateway already exposes n8n viacall_apiwithN8N_CLOUD_API_KEY. Any n8n operation the agent needs goes through the gateway. - Drop
cloudflareMCP (npx stdio) — cloud VM haswranglervia setup script; any CF API call the agent needs either useswranglerdirectly, the gateway’scall_api, or a dedicated script. - Drop
githubMCP (npx stdio) — cloud VM hasghCLI via setup script + auth’d via GitHub App. - Drop Playwright tunnel — Claude Code web has built-in browser (“Chrome”); production browser work uses CF Browser Rendering.
Phase D — Convert scheduled tasks to Routines (~20 min)
Section titled “Phase D — Convert scheduled tasks to Routines (~20 min)”Replace the ~/.claude/scheduled-tasks/ entries with Anthropic-hosted Routines.
token-health-monitor→ Routine atclaude.ai/code/routines— schedule nightly, repo = ascend-gtm-ops, prompt = the existing SKILL.md body, connectors = ascend-gateway MCP + Hindsight.error-pattern-digest→ Routine — schedule daily 6am UTC, prompt from SKILL.md.docs-freshness-check→ Routine — schedule weekly Monday 4am UTC.backup-verification→ Routine — schedule weekly Sunday 3am UTC.- Delete
~/.claude/scheduled-tasks/locally after verification.
Phase E — First fully-cloud validation (~10 min)
Section titled “Phase E — First fully-cloud validation (~10 min)”Prove the loop.
- From browser: go to
claude.ai/code, open session onmishaal-cloud/ascend-gtm-ops, tell it “run the test suite and report results.” Confirmnpm testpasses in the cloud VM using the repo’s config. - Close the browser tab. Check
/taskson the iOS app — session still visible, still running. - From a fresh terminal (any machine, or
claude --teleportfrom your laptop): pull the session into CLI, confirm conversation history + branch check out. - Log the cloud VM’s
check-toolsoutput todocs/architecture/cloud-vm-toolset-2026-04-24.mdfor reference.
Phase F — Drop Tailscale + clean up CLAUDE.md (~15 min)
Section titled “Phase F — Drop Tailscale + clean up CLAUDE.md (~15 min)”- Remove Tailscale mention from
~/CLAUDE.md— not used by V5. - Remove VPS section (already decommissioned) from
~/CLAUDE.md. - Commit
.claude/changes in a PR titledchore(cloud-only): migrate agent config into repo + drop local dependencies.
What could still require a laptop (and why that’s fine)
Section titled “What could still require a laptop (and why that’s fine)”Two narrow cases remain laptop-only — both by choice, not dependency:
- Wrangler dev mode (
wrangler dev) for live reload of Worker code. The cloud VM can run it too; local is faster feedback. If you want to kill this too: the cloud session doeswrangler deploy --env previewand hits the preview URL — same dev loop, cloud-native. - MCPs with non-HTTP transports that you might want in the future (some niche plugins). Avoid them. Every MCP we rely on is either HTTP (ascend-gateway, hindsight) or replaceable by cloud VM CLI (gh, wrangler, n8n).
Neither is a real laptop dependency — they’re preferences. The system works without them.
Permanent fixes (not band-aids)
Section titled “Permanent fixes (not band-aids)”Per your directive, every item in the migration plan is a structural change to the repo or cloud config, not a wrapper:
- Hooks move to repo — not a symlink, not a copy-if-missing; the file literally lives in git so every agent in every environment gets the same guardrails.
- Secrets live in claude.ai/code environment vars, NOT scripts that read from
~/.zprofile. No shell-profile assumption. - Routines replace local cron, not run alongside. After migration,
~/.claude/scheduled-tasks/is deleted outright. - MCP stdio servers dropped, not “disabled.”
claude.jsongets the stdio entries removed entirely; any MCP left is HTTP/SSE with a public endpoint. - Worktrees not used in cloud sessions. Cloud VMs fresh-clone per session. Delete the 9 worktrees locally after the cutover; they’re git branches anyway, recoverable from origin.
Outstanding questions for you
Section titled “Outstanding questions for you”Four things I cannot decide solo:
- Plan tier confirmation. Is your Anthropic plan Pro, Max, Team, or Enterprise? Code on the Web requires Pro+. Routines require Pro+.
- GitHub App install vs
/web-setup. Per-repo explicit install (more secure, required for Auto-fix) or sync existingghtoken (fastest, scoped to your token’s repos)? - Any tenant other than
ascend+kahunathat needs cloud-environment access? Each tenant effectively needs env var seeding once. - Retention choice for the 9 local worktrees — archive-tag-then-delete, or delete outright? Git branches on origin already have everything.
Success criteria (how we know it worked)
Section titled “Success criteria (how we know it worked)”After migration, all of these must be true:
-
claude.ai/codeopens a session onascend-gtm-ops, runsnpm test, reports567/567 pass. - Cloud session can push a commit + open a PR without any laptop CLI involved.
- Closing the browser tab does not interrupt the session.
- iOS Claude app shows the session in
/tasksand can be interacted with from phone. - A Routine fires nightly and appears as a completed session in the dashboard the next morning.
- Laptop can be powered OFF for 24 hours — returning, all scheduled runs completed, any in-flight
claude --remotetask has its PR open on GitHub. - The local CLI still works too (zero regression) — cloud is additive, not replacement.
-
ls ~/.claude/scheduled-tasks/returns empty (migration #19 complete). -
~/.zprofileno longer needs to be sourced for the agent to function.