What we run, where
The system splits into always-on per customer (Maestro is awake, listening, ready to act) and on-demand (every specialist spins up a fresh Sapiom µVM when called, tears down after). Five external platforms carry the load. This page is what lives where, why, and how the pieces connect on signup and during the first build.
now Built on Stripe Projects
The whole stack is being built using Stripe Projects — Implementation 2. Stripe Projects provisions the managed equivalents of the top five hand-wired services below; everything else is shared or unchanged across both implementations.
| Capability | Hand-wired · Impl 1 | Stripe Projects · Impl 2 |
|---|---|---|
| Database | Render Postgres | Neon |
| µVM compute | Sapiom / Blaxel | Daytona |
| Auth | Custom magic link · Cloudflare Email | WorkOS |
| Secrets vault | Infisical | Stripe Secret Store |
| Scheduler · jobs | Render Cron Jobs | Inngest |
| LLM gateway | OpenRouter | OpenRouter shared |
| Source control | GitHub | GitHub shared |
| Service hosting | Render | Render unchanged |
| Edge · DNS · CDN · email | Cloudflare | Cloudflare unchanged |
| Object store | Cloudflare R2 | Cloudflare R2 unchanged |
| Observability | Sentry · Better Stack | Sentry · Better Stack unchanged |
scope The build target is Implementation 2 — Stripe Projects (summary above). The detailed walkthrough below still describes the Implementation 1 hand-wired topology; each Stripe Projects service maps onto the hand-wired one it replaces per the table above. The full side-by-side component map lives on the build page.
1 · At a glance
Five platforms carry the work. Each column shows what runs there.
Long-running services
- Maestro (multi-tenant) always
- Dashboard (Next.js) always
- Postgres always
- Cron Jobs always
- Built artifacts per app
Edge + storage + email
- DNS · wildcard cert
- CDN · DDoS
- R2 (binary assets) always
- Email Service (magic links)
µVM compute
- Specialist µVMs on demand
- Node-only base image
- Async webhook back to Maestro
LLM gateway
- Claude
- OpenAI
- Grok
- one key, one bill
Source of truth
tenwhy-brains/<cust>· private, per customertenwhy-tools/<name>· one per tool (CLI + Skill)- Platform monorepo
2 · Always-on (per customer)
Four things run continuously for every signed-up customer. They are not "spun up on demand" — they're awake all the time, even when the customer is asleep.
| Component | What it does | Where |
|---|---|---|
| Maestro | Holds the customer's session. Interviews on first visit. Decides every action the workforce takes. Multi-tenant — one Maestro server hosts every customer's session; state lives in Postgres + brain repo so the server itself is stateless. | always Render · web service |
| Dashboard | Next.js. The customer's UI. Renders the chat with Maestro on the left, the
generative widget canvas on the right (driven by Maestro's dashboard.json via
json-render.dev). |
always Render · web service |
| Postgres | Sessions, customer accounts, the tool catalog, agent task queues, audit logs.
RLS on customer_id (decision #12). |
always Render · managed DB |
| Scheduler | Cron jobs that fire shift events into Maestro (Lou daily, Ray weekly, Sal 24/7, etc.). The scheduler doesn't call specialists directly — it wakes Maestro, who decides. | always Render · cron jobs |
3 · On-demand (the workforce)
Every specialist (Max, Vic, Sac, Jon, Tom, Roy, Moz, Sid, Sal, Ray, Lou, Nic) is dormant by default. When Maestro decides to call one, a fresh Sapiom µVM boots, the tool runs, the µVM tears down. Nothing about the specialist persists between jobs except the artifacts it commits.
µVM life cycle
| Phase | What happens |
|---|---|
| Boot | Sapiom spawns a Node-only µVM. Base image has Node 20, git, curl, jq. ~1–2 s cold start. |
| Identify | µVM is started with a short-lived bootstrap token, scoped to one job. Used once, to identify itself to Infisical. |
| Fetch secrets | µVM hits Infisical with its bootstrap token, pulls exactly the secrets the specific tool needs (e.g. GitHub installation token for the brain repo). |
| Load tool | The tool comes from a prebaked image (or a shallow clone / R2 pull) — not a full git clone tenwhy-tools/<name> per boot, which would put GitHub availability and clone latency on the hot path. Loads the Skill into the agent's prompt, makes the CLI runnable. |
| Run | Specialist works: reads inputs, calls the LLM (via OpenRouter), invokes the CLI, writes outputs. Mutating/billable actions are only proposed (executed later by the platform broker). |
| Deliver | Returns its envelope + artifacts + proposed brain updates; bulky output → R2 (scoped). The platform finalizes — validates, writes Postgres, renders + commits the canonical audit to the brain (decision #28). |
| Webhook | POSTs result + summary to Maestro's webhook endpoint. Includes a job ID + HMAC signature so Maestro can verify authenticity. |
| Teardown | µVM exits. Billing stops. |
Node-only ⇒ service The base image is deliberately Node-only (decision S13). The rule that keeps it that way: anything non-Node is a service behind an HTTP boundary, never a package in the image — scraping (Scrapling), and likewise browser screenshots, headless PDF rendering, or any future binary dependency. The µVM stays small and fast; the heavy runtime lives in its own service the tool calls.
4 · Three data stores, one purpose each
Nothing lives in two stores. Each piece of data has exactly one home.
| Store | Contents | Why here |
|---|---|---|
| Render Postgres | Customer accounts · sessions · tool catalog · agent task queues · audit log | Operational state. Frequent small writes. RLS scoping. Joinable. |
GitHub · tenwhy-brains/<cust> |
The customer's "brain" — 8 HTML docs from Maestro + folders per specialist | Portable, versioned for free, clean per-agent commit attribution. |
| Cloudflare R2 | Binary assets — images, video, audio from Vic and other media-shaped tools | Cheap storage, zero egress, CDN-backed URLs. Postgres pointers reference the keys. |
5 · The signup sequence
What happens when a brand-new customer hits tenwhy.com and signs up.
- Visitor lands at tenwhy.com Marketing site (static-ish). Submits email to start.
- Magic-link email Custom auth: signed token → store in Postgres with 15-min TTL → send link via Cloudflare Email Service.
-
Customer clicks link
Token verified, session cookie set (HTTP-only). Customer record + slug provisioned. Subdomain claimed:
<slug>.tenwhy.com. -
Brain repo created
A private repo at
tenwhy-brains/<slug>is created via the GitHub API. The customer's GitHub identity is not used; the platform PAT does it. - Maestro session opens Customer lands on their dashboard. Maestro greets them, starts the interview. Chat goes to the multi-tenant Maestro service; replies stream back via the OpenRouter gateway.
-
Brain begins to fill
As the conversation produces facts, Maestro commits HTML documents to
/maestro/in the brain repo:business.html,customer.html, etc. The dashboard's right pane re-renders live. - Interview ends · workforce is empty No specialists exist yet. Maestro proposes hires based on what the customer needs.
6 · The first build — todo app, end to end
Customer says "I want a todo app." What happens next, from Maestro's first move to a live URL.
- Maestro proposes hiring Nic Posts an Approve card to the dashboard. Customer clicks Approve.
-
Maestro fires a µVM
POST to Sapiom API:
{ tool: "tenwhy-tools/nic", spec: {…}, webhook: "https://maestro.tenwhy.com/v1/jobs/<id>" }. Sapiom returns a job ID immediately. Maestro is free to handle other customers. -
µVM boots and prepares
Node base image. Bootstrap token → Infisical → fetches GitHub installation token + Render API key (both scoped, short-lived). Clones
tenwhy-tools/nic. -
Nic builds the app
Reads the brain (
business.html,audience.html, etc.) for context. Generates a Next.js app via the LLM (OpenRouter). Writes the code to a fresh repo:tenwhy-builds/<cust>-todo-<short>. -
Deploy to Render
Nic calls Render's API: create web service from the new repo, set env vars (data API key, slug, etc.), trigger deploy. Render builds + deploys. URL:
<cust>-todo-<short>.onrender.com. -
Nic commits to the brain
Updates
/nic/builds.htmlin the brain repo: lists this build, URL, repo, status, timestamp. Updatesdashboard.jsonin Postgres so the dashboard shows a "Your todo app" widget. -
Nic webhooks Maestro
POSTs
{ status: "ok", artifact: { type: "render-service", url: "…" }, log: "…" }to Maestro's webhook. HMAC-signed for verification. µVM exits. - Maestro tells the customer Next chat turn: "Your todo app is live at cust-todo-x12.onrender.com." Dashboard widget appears. Done.
7 · Auth and secrets — the security model
Two layers: customer-facing auth (humans into the dashboard) and service-to-service auth (Maestro → Sapiom, µVM → vault, µVM → GitHub/Render).
| Surface | Mechanism |
|---|---|
| Customer login | Magic link · token in Postgres (15 min TTL) · email via Cloudflare Email Service · HTTP-only session cookie after click |
| Dashboard API calls | Session cookie · CSRF token · per-customer rate limit |
| Maestro → Sapiom | Long-lived Sapiom API key (in Infisical, fetched once at Maestro boot) |
| µVM → Infisical | Bootstrap token (one-time, per job, injected by Maestro at µVM-create call). µVM exchanges it for scoped secrets. |
| µVM → GitHub | GitHub App installation token (1 hour TTL, scoped to one repo) |
| µVM → Render API | Scoped Render API key (in Infisical, granted only when the tool is one that can deploy) |
| µVM → Maestro webhook | HMAC-SHA256 signed with a per-job secret. Maestro verifies before accepting result. |
| µVM → OpenRouter | Scoped OpenRouter key with per-job spend limit |
runtime ≠ CI This is the runtime security
boundary — and it, not agent-cli-kit verify, is what stops a misbehaving tool.
verify checks a CLI's shape in CI; the boundary is enforced here:
per-job scoped credentials with a read/write split (read for plan,
write for apply), network-enforced egress allow-listing (open
verification on the build page), a brain-path allowlist on
commits, and signed tool releases. Conformance is quality; the sandbox is security
(design #32).
8 · Stack decisions locked in this session
Ten decisions made today — each one a constraint on everything downstream.
| # | Decision |
|---|---|
| S1 | Always-on per customer = Maestro warm + scheduler + DB + dashboard. Specialists on-demand. |
| S2 | Maestro is the only orchestrator. Scheduler fires events into Maestro; Maestro decides whether to wake a specialist. |
| S3 | Three output channels: deployables → Render service per artifact · text/data → brain repo · binaries → Cloudflare R2. |
| S4 | Maestro host = multi-tenant Render service. Stateless; session state in Postgres + brain. |
| S5 | Built artifacts (todo apps, sites, etc.) host = one Render service per artifact. Default URL *.onrender.com; optional custom domain. |
| S6 | Database = Render Postgres (already in the PRD). |
| S7 | Object store = Cloudflare R2. |
| S8 | Scheduler = Render Cron Jobs. Each cron hits a Maestro webhook with a shift signal. |
| S9 | µVM communication = async + webhook. Maestro posts job, µVM hits Maestro webhook when done. HMAC-signed. |
| S10 | Customer auth = custom magic link + Cloudflare Email Service. No third-party auth vendor. |
| S11 | Frontend = Next.js on Render. |
| S12 | LLM gateway = OpenRouter. One key, one bill, four providers (Claude · OpenAI · Grok · Google). |
| S13 | µVM base image = Node-only. All tool CLIs must be Node-based. |
| S14 | Secrets management = Infisical (vault). µVM fetches scoped, short-lived creds at runtime via bootstrap token. |
| S15 | Vault product = Infisical (start managed, option to self-host later). |
| S16 | DNS + CDN + edge = Cloudflare in front of Render. Wildcard cert for *.tenwhy.com. |
| S17 | Observability = Sentry (errors) + Better Stack (logs · uptime · alerts). |
| S18 | URLs = subdomain per customer (<slug>.tenwhy.com) + *.onrender.com per artifact with optional custom-domain wiring. |
9 · Still open — for a later session
Each now has a decided approach (below). None block starting v0.1.
| Area | Question |
|---|---|
| CI/CD | Decided. Maestro/dashboard deploy via Render's GitHub hook. Each tenwhy-tools/<name> repo runs a GitHub Action on push — agent-cli-kit verify (contract conformance) + Skill lint + CLI tests + the harness-seam check. Green is the gate to publish into the catalog: the automated half of the factory's Reviewer. |
| Backups / DR | Decided. Postgres → Render automated snapshots + periodic logical dumps to R2. R2 → cross-region bucket replication. Brain repos → GitHub is canonical (already durable) + a periodic mirror. Secrets → the vault is the source of truth. Plus a quarterly restore drill so recovery is exercised, not assumed. |
| Rate limiting | Decided. Cloudflare in front for DDoS; a per-customer token-bucket (Postgres, or Upstash if it gets hot) on Maestro's webhook + the dashboard API, keyed by the same customer_id as RLS. |
| Cost ceiling per customer | Resolved (design #31) — enforced ahead of the fact: a preflight monthly-cap check before dispatch + provider-side hard limits on both impls; self-reported cost_usd is reconciliation only. Better Stack alerting still wanted. |