Think2earn · Architecture · 2026-06-30

Current architecture vs target architecture

A self-contained view of where the product runs today and where we are building toward — same product surface, different control-plane shape, stronger session and artifact durability.

Current (production) Target (north star)

At a glance

Layer Current Target
Public URL chat.think2earn.com Same domain; static UI + API split
Edge Cloudflare Tunnel → always-on EC2 :8080 Cloudflare DNS + email; API via Lambda URL or ALB; UI on S3 + CloudFront (or Pages)
Control plane Single EC2 host (Node/Express + SPA) Serverless API (Lambda); no always-on app server
Default chat Bedrock ConverseStream tool loop on EC2 Same pattern; runs in Lambda
Long / agent work AgentCore Runtime for jobs; chat stays on EC2 Bedrock AgentCore Runtime + Claude Agent SDK (Bedrock IAM) for agent + plan micro-VM lanes
Turn journal In-memory on EC2 (~30 min TTL; lost on restart) DynamoDB (durable; survives deploy and scale-out)
Thread session Per-user Runtime session for agent chat; requestId for cancel/resume Per-thread agentSessionId + S3 SessionStore for agent transcripts
Artifacts S3 + DynamoDB library assets; dock via GET /artifacts Same store + inline placeholders, publish host pub.think2earn.com, global artifact events
Auth / billing Cognito + app JWT; Stripe credits Unchanged
Deploy Manual SSM tarball → EC2 build + restart CI → Lambda + static asset pipeline; EC2 decommissioned for API

Current Production architecture

Verified against live prod (chat.think2earn.com, EC2 i-076d244b62ec4d8e8, account 995772916887, us-east-1). One long-lived control-plane host fronts the entire web product.

flowchart TB
  subgraph users [Users]
    Browser[Browser]
  end

  subgraph edge [Cloudflare]
    CF_DNS[DNS]
    CF_Tunnel[Tunnel to origin]
  end

  subgraph ec2 [Control plane EC2]
    Cloudflared[cloudflared daemon]
    NodeApp[Node Express API plus Vite SPA]
    TurnMem[In-memory turn journal]
    LocalTerm[local_terminal shell on host]
    IAMHost[Think2earnHostRole]
  end

  subgraph aws_data [AWS data]
    DDB[(DynamoDB 16 tables)]
    S3[(S3 artifact bucket)]
    SSM[SSM secrets]
  end

  subgraph bedrock [Bedrock and AgentCore]
    Converse[Bedrock ConverseStream]
    CI[Code Interpreter]
    BrowserAC[Browser CDP]
    Memory[AgentCore Memory]
    Gateway[Gateway Exa MCP]
    Runtime[AgentCore Runtime microVM jobs only]
  end

  subgraph external [External]
    Cognito[Cognito]
    Stripe[Stripe]
  end

  Browser --> CF_DNS --> CF_Tunnel --> Cloudflared --> NodeApp
  NodeApp --> TurnMem
  NodeApp --> DDB
  NodeApp --> S3
  NodeApp --> SSM
  NodeApp --> IAMHost
  IAMHost --> Converse
  IAMHost --> CI
  IAMHost --> BrowserAC
  IAMHost --> Memory
  IAMHost --> Gateway
  IAMHost --> Runtime
  NodeApp --> LocalTerm
  NodeApp --> Cognito
  NodeApp --> Stripe
      

Request paths (today)

Default chat (simple mode)

  • Browser POST → SSE on EC2
  • Bedrock ConverseStream + native tool loop
  • Tools: run_code, browse_web, web_search, update_plan
  • Tool services called from host via AgentCore SDK
  • Artifacts persisted to S3 on tool completion

Long jobs (Path B)

  • Composer → Agent task (hours)
  • POST /workspaces/:id/task
  • InvokeAgentRuntime → hermes_chat Runtime
  • Think2earn Agent binary in microVM
  • Results + artifacts back to DynamoDB / S3

Characteristics

Target North-star architecture

AWS-first: burn credits on Bedrock and AgentCore, keep Cloudflare for DNS and transactional email, eliminate the always-on EC2 API host, and externalize every piece of session state the UI depends on.

flowchart TB
  subgraph users [Users]
    Browser[Browser]
  end

  subgraph edge [Cloudflare]
    CF_DNS[DNS]
    CF_Email[Transactional email]
  end

  subgraph static [Static delivery]
    CF_CDN[CloudFront or Pages]
    SPA[Vite SPA bundle]
  end

  subgraph api [Serverless API]
    Lambda[Lambda API]
    DDB_Journal[(DynamoDB turn journal)]
    DDB_Core[(DynamoDB core tables)]
    SSE_Turn[POST chats messages SSE]
    SSE_Global[GET events stream or poll]
  end

  subgraph storage [Object storage]
    S3_Art[S3 artifacts and workspaces]
    S3_Sess[S3 SessionStore transcripts]
    PubCDN[pub.think2earn.com published HTML]
  end

  subgraph agent_compute [Isolated agent compute]
    Runtime[AgentCore Runtime microVM]
    AgentSDK[Claude Agent SDK Bedrock IAM]
    Sweep[Post-turn workspace sweep to S3]
  end

  subgraph bedrock [Bedrock and AgentCore services]
    Converse[Bedrock ConverseStream simple chat]
    CI[Code Interpreter]
    BrowserAC[Browser]
    Memory[Memory]
    Gateway[Gateway Exa]
  end

  subgraph external [External unchanged]
    Cognito[Cognito]
    Stripe[Stripe]
  end

  Browser --> CF_DNS
  Browser --> CF_CDN --> SPA
  Browser --> SSE_Turn
  Browser --> SSE_Global
  CF_DNS --> Lambda
  SSE_Turn --> Lambda
  SSE_Global --> Lambda
  Lambda --> DDB_Journal
  Lambda --> DDB_Core
  Lambda --> S3_Art
  Lambda --> Converse
  Lambda --> CI
  Lambda --> BrowserAC
  Lambda --> Memory
  Lambda --> Gateway
  Lambda --> Runtime
  Runtime --> AgentSDK
  AgentSDK --> Converse
  AgentSDK --> Sweep --> S3_Art
  AgentSDK --> S3_Sess
  S3_Art --> PubCDN
  Lambda --> Cognito
  Lambda --> Stripe
  CF_Email -.-> Lambda
      

Request paths (target)

Default chat (simple mode)

  • Static SPA → Lambda SSE
  • Same Bedrock ConverseStream tool loop
  • Events journaled to DynamoDB per turn
  • Reload / reattach reads journal + active-turn
  • No change to default model or tool gating

Agent / plan / long work

  • InvokeAgentRuntime with agentSessionId per thread
  • Claude Agent SDK in microVM (CLAUDE_CODE_USE_BEDROCK=1)
  • NDJSON stream → same SSE event vocabulary
  • SessionStore on S3; resume across Runtime recycling
  • HTML and files swept to S3 → artifact dock + publish

Product surfaces (target UI)

Characteristics

What changes (current → target)

Control plane

Today: One EC2 runs API + SPA + in-memory journal + optional host subprocess agent.
Target: Lambda (or equivalent) for API/SSE only; SPA on CDN; EC2 retired for app traffic.

Session & reconnect

Today: requestId + in-memory journal; per-user Runtime session for agent mode.
Target: Per-thread agentSessionId; DynamoDB journal; S3 SessionStore for agent transcripts.

Agent runtime

Today: Think2earn Agent binary in Runtime for jobs; chat default stays on EC2 Bedrock loop.
Target: Claude Agent SDK container in same Runtime ARN for agent/plan lanes; JSONL contract unchanged for the UI.

Artifacts & HTML

Today: S3 + signed URLs; dock preview; no publish host or inline placeholders.
Target: Placeholder chips, version badges, publish pipeline, global artifact index.

Edge & ops

Today: Cloudflare Tunnel to EC2; manual SSM deploy.
Target: Cloudflare DNS + email; automated Lambda + static deploy; tunnel removed when API migrates.

What stays the same

Explicitly out of scope (for now)

Compute paths compared

Workload Current Target
Quick chat + tools EC2 → Bedrock ConverseStream; AgentCore CI/Browser/Gateway from host Lambda → same Bedrock loop; same AgentCore services from Lambda role
Plan clarify (light) Code Interpreter sandbox on host-driven loop Same; optional promotion rules unchanged
Plan execute (heavy) Checkpoint S3 → Runtime microVM → Think2earn Agent Checkpoint S3 → Runtime → Claude Agent SDK
Multi-hour agent task Runtime hermes_chat via job dispatch Runtime with SDK; same invoke contract
User shell / terminal local_terminal on EC2 host Dropped for v1 migration; agent work in Runtime only
SSE relay EC2 holds connection until turn completes (E8: bills after disconnect) Lambda with same detached-turn semantics; journal in DynamoDB

Data & state

State Current store Target store
Conversations, messages, users, billing DynamoDB DynamoDB (unchanged)
Turn journal (SSE replay) EC2 memory, 30 min TTL DynamoDB per requestId
Thread context doc (goal, plan, checklist) Not persisted DynamoDB CONTEXTDOC + version snapshots
agentSessionId Not on conversation DynamoDB conversation field
Agent transcript files Inside warm microVM only S3 SessionStore mirror
Artifacts (images, HTML, files, plans) S3 + library_assets; GET /artifacts Same + artifactPlaceholderFallback + published prefix
Secrets SSM + env files on EC2 SSM / Lambda env (same params)

Edge & clients

flowchart LR
  subgraph today [Current edge]
    U1[User] --> CF1[Cloudflare Tunnel]
    CF1 --> EC2[EC2 serves API and SPA]
  end

  subgraph future [Target edge]
    U2[User] --> CF2[Cloudflare DNS]
    U2 --> CDN[CloudFront or Pages SPA]
    U2 --> API2[Lambda API URL]
    CF2 --> API2
  end