Skip to content

Cloud-Only Audit — 2026-04-24

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.

TL;DR

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

✅ Already cloud-native — zero laptop dependency

SurfaceRuntimeURL
V5 Gateway WorkerCloudflare Workersascend-gateway-v5.ascendgtm.workers.dev
Context Worker (Phase 2)Cloudflare Workerspending resource provisioning (auth’d in CLAUDE.md)
TokenManager (OAuth refresh)Cloudflare Durable ObjectsTOKEN_MANAGER binding
ascend-gateway-dbCloudflare D1error_ledger, kv_audit, decision_log
ASCEND_KVCloudflare KV3c4d67dc67d040c4a40db5deb02db0f3
ascend-gateway-backupCloudflare R2Weekly KV → R2 snapshot
ctx_v5_facts (Phase 2)Cloudflare VectorizePending wrangler vectorize create
Workers AI embeddingsCloudflare Workers AI@cf/baai/bge-small-en-v1.5
CF Queues (Phase 2)Cloudflare Queuesctx-ingest-gong, ctx-ingest-salesforce + DLQs
5 CF Cron TriggersCloudflare Cronsystem health, canary, token health, cleanup, autoresearch
hindsight.ascendgtm.netSelf-hosted on cloud + Cloudflare proxylong-term memory
hindsight-auth.ascendgtm.netCloudflare Worker (hindsight-oauth-proxy)OAuth bridge
ascendgtm.netCloudflare Pagesmarketing site
All DNSCloudflareascendgtm.net, subdomains
mmurawala.app.n8n.cloudn8n Cloud (managed)workflow consumer
All source codeGitHub (mishaal-cloud/*)origin truth
All CIGitHub 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 integrationsV5 Worker via OAuth + KV-resolved tokenscloud

⚠️ Laptop-dependent TODAY — the migration targets

#SurfaceWhere it lives todayImpact if laptop offCloud destination
1Claude Code CLI runtimeclaude installed on MacAgent cannot runClaude Code on the Web (claude.ai/code) — Anthropic-managed VMs (4 vCPU / 16 GB / 30 GB)
2Hooksdangerous-command-blocker.py, parallelization-nudge.sh, research-first-claim-detector.sh + 7 more~/.claude/hooks/Guardrails gone in cloudCommit to repo .claude/hooks/ + reference in .claude/settings.json
3Skills (300+ ads/marketing/data/product skills + all custom)~/.claude/skills/No skill access in cloudCommit repo-relevant skills to .claude/skills/; plugin skills declared via .claude/settings.json enabledPlugins
4Rulesapi-integrations.md, n8n-workflows.md, parallelization.md, print-pdf.md~/.claude/rules/Rules silently disabledCommit to repo .claude/rules/
5Global CLAUDE.md (incl. the new Non-Stop Protocol)~/.claude/CLAUDE.mdNon-Stop Protocol not loadedMove protocol to repo .claude/CLAUDE.md + per-repo CLAUDE.md files
625+ secrets~/.zprofileCloud session can’t auth to anythingOne-time paste into cloud environment variables at claude.ai/code; wrangler secrets already handle Worker-side
7n8n-mcp stdio servernode ~/.gemini/antigravity/scratch/n8n-mcp-source/dist/mcp/index.jsAgent can’t touch n8nUse the n8n Cloud HTTP API directly (already available — $N8N_CLOUD_API_KEY); drop the stdio MCP
8cloudflare MCP via npxStdio — npx @anthropic-ai/cloudflare-mcp@latestAgent can’t provision CF resourcesCloud VM’s pre-installed wrangler + gh via setup script; CF API calls through ascend-gateway MCP
9github MCP via npxStdioAgent can’t do PR/issue workCloud VM has gh CLI pre-installed (verified in live docs); auth via GitHub App or /web-setup
10Playwright tunnelLocal tunnel on localhost:8931, auto-started at session startNo browser automationDrop — Claude Code web has built-in browser; CF Browser Rendering for production scraping
119 local git worktrees/Users/mishaalmurawala/dev/ascend-gtm-ops/.claude/worktrees/Lost work if laptop diesCloud sessions use --remote; fresh clone per session; commits push to GitHub
12Local scheduled tasks (token-health-monitor, docs-freshness-check, error-pattern-digest, backup-verification)~/.claude/scheduled-tasks/Scheduled runs skip when laptop offConvert to Claude Code Routines at claude.ai/code/routines — run on Anthropic-managed infra

❓ Historical / already decommissioned

SurfaceStatusAction
ascend-agent-vps (Hetzner 5.78.117.196)DECOMMISSIONED per V5 global CLAUDE.mdNone — already gone
Mac bridge :8889DECOMMISSIONEDAlready gone
Tailscale (100.125.246.94)Listed in ~/CLAUDE.md as legacy network; no V5 traffic uses itDocument as unused; remove from CLAUDE.md
Old n8n self-hostedReplaced by n8n CloudAlready handled

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_KEY
  • CLOUDFLARE_API_TOKEN, CLOUDFLARE_TUNNEL_TOKEN
  • HETZNER_API_TOKEN
  • ASCEND_GATEWAY_KEY, ASCEND_ADMIN_KEY, ASCEND_TENANT_BEARER
  • GOOGLE_ADS_CUSTOMER_ID, GOOGLE_ADS_LOGIN_CUSTOMER_ID
  • N8N_CLOUD_API_KEY
  • VERCEL_TOKEN, VERCEL_TEAM_ID, VERCEL_ASCENDGTM_PROJECT
  • OPENAI_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

┌─────────────────────────────────────────┐
│ 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)

Phase A — Move agent config to the repo (~30 min)

No CF resource creation. Pure git work.

  1. Copy ~/.claude/CLAUDE.md content.claude/CLAUDE.md in ascend-gtm-ops repo.
    Specifically: the Non-Stop Execution Protocol I added must live in the repo for cloud sessions to load it.
  2. Copy ~/.claude/rules/*.claude/rules/ in the repo. Commit.
  3. Copy ~/.claude/hooks/*.claude/hooks/ in the repo; update .claude/settings.json to reference them. Commit.
  4. Declare plugins in .claude/settings.jsonenabledPlugins list so cloud sessions install them on startup (pulls from the marketplaces you currently use — ando-marketplace, anthropic-skills, n8n-mcp-skills, claude-reflect).
  5. 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)

Your browser, not mine.

  1. Go to claude.ai/code. Confirm the plan tier includes Code on the Web (Pro/Max/Team/Enterprise with premium seat).

  2. Install the Claude GitHub App on mishaal-cloud/ascend-gtm-ops (+ any other repos). Or run /web-setup in your local CLI to sync the gh token.

  3. 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).

  4. Paste the setup script into the environment:

    #!/bin/bash
    set -e
    npm install -g wrangler
    apt update && apt install -y gh
  5. Save. First session boot caches the script output; every subsequent session starts in ~5 seconds.

Phase C — Drop the local MCPs (~15 min)

Once the V5 gateway MCP is reachable from cloud sessions, the stdio MCPs become redundant.

  1. Drop n8n-mcp (stdio) — the gateway already exposes n8n via call_api with N8N_CLOUD_API_KEY. Any n8n operation the agent needs goes through the gateway.
  2. Drop cloudflare MCP (npx stdio) — cloud VM has wrangler via setup script; any CF API call the agent needs either uses wrangler directly, the gateway’s call_api, or a dedicated script.
  3. Drop github MCP (npx stdio) — cloud VM has gh CLI via setup script + auth’d via GitHub App.
  4. 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)

Replace the ~/.claude/scheduled-tasks/ entries with Anthropic-hosted Routines.

  1. token-health-monitorRoutine at claude.ai/code/routines — schedule nightly, repo = ascend-gtm-ops, prompt = the existing SKILL.md body, connectors = ascend-gateway MCP + Hindsight.
  2. error-pattern-digest → Routine — schedule daily 6am UTC, prompt from SKILL.md.
  3. docs-freshness-check → Routine — schedule weekly Monday 4am UTC.
  4. backup-verification → Routine — schedule weekly Sunday 3am UTC.
  5. Delete ~/.claude/scheduled-tasks/ locally after verification.

Phase E — First fully-cloud validation (~10 min)

Prove the loop.

  1. From browser: go to claude.ai/code, open session on mishaal-cloud/ascend-gtm-ops, tell it “run the test suite and report results.” Confirm npm test passes in the cloud VM using the repo’s config.
  2. Close the browser tab. Check /tasks on the iOS app — session still visible, still running.
  3. From a fresh terminal (any machine, or claude --teleport from your laptop): pull the session into CLI, confirm conversation history + branch check out.
  4. Log the cloud VM’s check-tools output to docs/architecture/cloud-vm-toolset-2026-04-24.md for reference.

Phase F — Drop Tailscale + clean up CLAUDE.md (~15 min)

  1. Remove Tailscale mention from ~/CLAUDE.md — not used by V5.
  2. Remove VPS section (already decommissioned) from ~/CLAUDE.md.
  3. Commit .claude/ changes in a PR titled chore(cloud-only): migrate agent config into repo + drop local dependencies.

What could still require a laptop (and why that’s fine)

Two narrow cases remain laptop-only — both by choice, not dependency:

  1. 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 does wrangler deploy --env preview and hits the preview URL — same dev loop, cloud-native.
  2. 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)

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.json gets 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

Four things I cannot decide solo:

  1. Plan tier confirmation. Is your Anthropic plan Pro, Max, Team, or Enterprise? Code on the Web requires Pro+. Routines require Pro+.
  2. GitHub App install vs /web-setup. Per-repo explicit install (more secure, required for Auto-fix) or sync existing gh token (fastest, scoped to your token’s repos)?
  3. Any tenant other than ascend + kahuna that needs cloud-environment access? Each tenant effectively needs env var seeding once.
  4. 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)

After migration, all of these must be true:

  • claude.ai/code opens a session on ascend-gtm-ops, runs npm test, reports 567/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 /tasks and 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 --remote task 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).
  • ~/.zprofile no longer needs to be sourced for the agent to function.