Docs / architecture.md · mirrored from the repo
Namaste Ji — Architecture & Design Notes
Status: design / brainstorm. Nothing here is built yet. This is the agreed direction, captured so decisions aren’t lost. Treat it as living — update as we go. Business research, roadmap, and planning live in Notion (hub “Namaste Ji 🌅”); this file is the technical counterpart.
1. Product vision — an agent-operated product
Namaste Ji is designed to be run by agents, with the founder in the loop for strategy and review:
- Creative agents run agentic workflows to research → generate → review → prepare content/data (greetings, devotional imagery, vernacular copy, festival assets).
- Engineering agents consume that content + creative strategy to drive development.
- The founder reviews creative strategy and approves at human-in-the-loop gates.
First principle: the content pipeline is itself a product surface.
2. Guiding principles
- Everything on Cloudflare by default. Reach for an external tool only when CF genuinely can’t do the job — and document why when you do.
- Architect for the low-end device (cache-first sharing, strict
.nomedia). - Vernacular-first, English-second.
- Control plane and execution plane are separate concerns (see below).
- Single source of truth — no component keeps its own private copy of catalog or control state.
3. The two planes
We deliberately split the system into a headless execution plane and a human-facing control plane.
The creative half of the execution plane (the agent org, the brief contract, the content lifecycle state machine, evaluation, ingest) and the back office that supervises it are detailed in CREATIVE-PLANE.md. The downstream delivery plane (catalog → users: ranking, the share-loop, freshness, edge logistics, timeless vs time-bound) is DISTRIBUTION.md.
flowchart TB
subgraph CP["Control plane — Back office (separate hosted app)"]
Console["Ops Console (Workers + Pages)<br/>monitor · approve · start/stop"]
CtlDO["Control DO<br/>global + per-stage mode · kill switch · audit"]
end
subgraph EP["Execution plane — headless on Cloudflare"]
direction LR
R["Research<br/>agent"] --> G["Generate<br/>agent"] --> V["Review<br/>agent"] --> H{"Gate<br/>auto or manual?"}
end
Catalog[("Content Catalog<br/>D1 · R2 · Vectorize")]
Eng["Engineering<br/>agents"] --> AppAPI["App / API<br/>(Workers)"]
AIG["AI Gateway<br/>cost · logs · cache"]
Console <-->|start / resume| EP
Console <--> CtlDO
CtlDO -->|mode per stage| H
H -->|approved| Catalog
H -.->|needs human| Console
Catalog --> Eng
R -.-> AIG
G -.-> AIG
V -.-> AIG
EP -->|observability stream| Console
Execution plane (headless)
Stays autonomous; contains all agent/business logic.
| Concern | Cloudflare primitive |
|---|---|
| Durable multi-step orchestration | Workflows (retries, state, DAG, sleeps) |
| Stateful agents | Agents SDK (agents, Durable Objects) |
| Inference (all of it) | Workers AI + AI Gateway (cost/cache/logs) |
| Content catalog | D1 (metadata) · R2 (assets) · Vectorize (embeddings) |
| Config / feeds | KV |
| Async fan-out | Queues |
| Scheduling | Cron Triggers + Agents scheduled tasks |
| Research / scraping | Browser Rendering |
Control plane (the back office — its own hosted app)
A separately deployed app (apps/console, working name Ops Console / Mission
Control). It is UI + a thin control API + the authoritative mode state — and must
not contain agent or business logic (the rule that killed n8n). It handles:
- Monitoring running workflows + the live agent topology.
- Human-in-the-loop approvals (resolve paused workflow gates).
- Starting / stopping workflows.
- Switching parts between autonomous and manual.
Autonomous ↔ manual: a policy engine, not UI checkboxes
A single authoritative Control Durable Object holds:
globalMode: auto | manual | paused+ a hard kill switch;stageMode[stage]: auto | manualper gate;- thresholds (e.g. auto-approve only if the Review agent’s score ≥ X; otherwise escalate to manual even in auto mode).
Every workflow gate does one RPC to the Control DO (“what’s my mode for this stage?”) → auto-approve or pause-and-wait. The DO broadcasts mode changes over WebSocket, so console and running workflows stay in sync. Guardrails: kill switch, rate caps, escalate-on-low-confidence so “fully autonomous” can’t silently ship bad content.
4. Observability — how we visualize it at runtime
Three native layers (plus the static diagram above for design-time):
- Built-in dashboards (zero build): Workflows dashboard (per-instance step
timelines, retries, durations;
workflowsAdaptiveGroupsGraphQL dataset, 31-day retention;wranglerCLI) and the AI Gateway dashboard (per-call prompt/response, tokens, cost, latency). - Live event stream:
agents/observabilitysubscribe()over typed channels —agents:rpc(agent-to-agent calls),agents:workflow(start/paused/approved/ rejected/resumed/terminated),agents:message(tool:result, tool:approval),agents:state,agents:schedule,agents:lifecycle,agents:mcp. - Mission Control canvas: the Ops Console renders agent state + a live graph using
useAgent/ read-only “spectator” connections. This is the n8n-canvas replacement.
5. Auth & identity
Two trust domains, one identity core. One canonical users + roles model in D1;
two different front doors.
| Back office | Consumer app | |
|---|---|---|
| Users | ~tens (team + service accounts) | potentially millions, free |
| Threat model | privileged access | public signup |
| Cost driver | negligible | per-MAU pricing can bankrupt a free app |
| Approach | Cloudflare Access (perimeter) + app-level RBAC in D1 | self-host on Workers |
- Back office (internal): Cloudflare Access gates the building (SSO via Google/OIDC,
MFA, group policies — Cloudflare can now be its own IdP), free, zero-code. Fine-grained
roles (
admin / creative-lead / engineer / reviewer / viewer) live in our D1. Rule: coarse in Access, fine in app. WorkOS AuthKit is the managed alternative if we ever want hosted login + IdP/SCIM features (free ≤ 1M MAU; email-OTP, social, SSO) — but Access already covers an internal tool, so default stays Access. - Consumer (external): Cloudflare has no first-party B2C identity product (Access is workforce-only) — a real CF gap. WorkOS was evaluated and ruled out for the consumer app: AuthKit deliberately has no SMS/phone OTP (it steers to email magic-auth / TOTP / passkeys), and our audience is phone-first (below). So consumer auth = self-host on Workers with Better Auth — it’s D1-native (pass the binding directly), runs on Workers, ships a phone-number OTP plugin with pluggable OTP delivery (wire any SMS provider — e.g. MSG91 for India, Twilio as fallback) and social login. This gives OTP + social, everything-CF, and no per-MAU fee at next-billion scale. Managed B2C with SMS OTP (Firebase Auth / Supabase Auth / Clerk / Stytch) is the faster-to-validate fallback, accepting per-MAU cost + migration risk. Lean: Better Auth on Workers.
- Onboarding (grounded in market research): primary audience is 35+, Tier-2/3,
Android, vernacular → phone + OTP = primary, Google Sign-In = secondary
(client secret already in
secrets/), email/password = skip. (This is exactly why WorkOS’s no-SMS-OTP stance is disqualifying for consumer.) - RBAC: keep it role-based and simple now (full model designed in BACK-OFFICE.md §9 / BO-10); only go attribute/policy-based if needed.
6. Data residency & compliance (radar, not now)
Consumer PII for Indian users pulls in India’s DPDP Act + data-residency
expectations. Cloudflare can do jurisdiction-restricted storage (DO/D1 placement), so
it’s tractable — but it should inform the users table + catalog storage choices when
we design them.
7. Decisions log
| # | Decision | Rationale |
|---|---|---|
| D1 | Backend = everything Cloudflare; external tools only if CF can’t | One account/bill/deploy; colocated with data |
| D2 | n8n dropped | Redundant with Workflows; agents (not humans) are the operators |
| D3 | Agent core on Workflows + Agents SDK; all inference via AI Gateway | Durable, observable, cost-controlled |
| D4 | Back office is a separate hosted app (apps/console) | Different cadence, auth, threat model than execution plane |
| D5 | Autonomous/manual via a Control DO policy engine | Authoritative, strongly consistent, broadcastable |
| D6 | Cloudflare Access + D1 RBAC for back office | Free, right fit for an internal tool |
| D7 | Self-host consumer auth on Workers (Better Auth), phone-OTP + social | Per-MAU pricing kills a free next-billion app; WorkOS ruled out — no SMS OTP; Better Auth is D1-native with a phone-OTP plugin |
| D8 | Content catalog is the shared spine (D1 + R2 + Vectorize) | Both agent types + the app read/write it |
8. Open questions
Self-host vs managed for consumer auth.→ Leaning self-host Better Auth on Workers (phone-OTP + social, D1-native, no per-MAU fee); WorkOS ruled out (no SMS OTP). Confirm SMS provider (MSG91 vs Twilio) when the consumer surface starts.- Frontend stack (native Android vs cross-platform).
- Content sourcing/licensing pipeline (in-house vs partnerships).
Image optimization on CF (Images vs R2 + transforms).→ Resolved: default to Cloudflare Images (CREATIVE-PLANE.md, CP-7).
9. Suggested build order
- Content catalog data model (D1 schema + R2 layout + Vectorize index) — the spine.
- Control DO interface (modes + decision + audit events).
- First creative Workflow (research → generate → review → gate) against the catalog.
- Ops Console (monitor + approvals) on top of 1–2.
- Auth (Access for console; consumer auth when the app surface exists).