PLAN — Aquila POC
Aquila — Task & Reminder Agent for every Indian business owner. Personal AI bots at ₹250/month, one container per bot, running on deklo's mini-PC network. The eagle that works while you sleep. (Named after the constellation — see
DECISIONS.mdD001.)
Window: 3–4 days · Owner: Bhavya (orchestrated build) · Audience: Sriram, Rohan
Status: executing (Day 1) · Decision log: DECISIONS.md
1. POC goal (what "done" means)
Demonstrate to Sriram and Rohan, with measurements, that:
- One mini-PC-class box runs 8–15 per-user AI bots in isolated containers at acceptable latency.
- The economics work at ₹250/month — per-bot inference + infra cost measured, verdict modeled at ₹250/₹299 pricing and 10/15/20 bots per 16GB node.
- A non-technical owner can actually use it — phone-number microsite, one Telegram OTP, bots that message them, zero technical setup.
- The whole thing is portable — plain Docker today, K8s-mappable shapes for Rohan's platform
tomorrow, domain-agnostic for the
<phone>.aquila.comend state.
Success metrics (locked, D009): ≥10 live bots on the 8GB slice · idle ≤250MB/bot · p95 first-token <4s · 12h soak with routines firing · measured ₹/bot/month · 5-minute scripted demo.
2. Architecture
aquila.exaflair.com <phone>.aquila.exaflair.com
(static site: homepage + /docs) (per-user microsites + app)
│ │
Hostinger CNAME → Vercel Hostinger A *.aquila → relay VPS
(CI deploys from main) Caddy on-demand TLS → tunnel
│ │
│ ┌─────────────────┘
│ ▼
┌──────────────────── POC laptop (8GB budget · plain Docker · no k3s) ────────────────────┐
│ │
│ manager (FastAPI) ──── docker.sock ────► bot containers ×N (core/) │
│ · phone identity + OTP sessions · persona.md + chat loop + SQLite memory (FTS5) │
│ · bot CRUD, workspace (Jinja) · APScheduler routines │
│ · cost rollup dashboard · tools: web_search, web_fetch, imap_read │
│ · wildcard Host routing · talks ONLY to gateway for LLM │
│ │
│ gateway (LiteLLM proxy) ──► OpenCode Go → OpenRouter free (POC chain) │
│ · per-bot virtual keys + ₹ budgets + spend log (the metering story) │
│ │
│ channels/telegram ── ONE Aquila bot: OTP contact-share login · chat multiplex · │
│ routine delivery · QR/deep links │
│ │
│ searxng (self-hosted search) ── used by core/ web_search tool │
└──────────────────────────────────────────────────────────────────────────────────────────┘
Identity flow: <phone>.aquila.exaflair.com welcome page → Telegram deep link / QR →
native contact-share proves number ownership → OTP/session → workspace + bots live; bots reach
the user in Telegram.
Safety posture (locked): detect → summarize in Hinglish → deliver on Telegram → draft the reply for the human to send. Bots never send email, pay, file, or act on the owner's behalf.
3. Repo layout
core/ WS1 — per-bot runtime container (Python 3.11, FastAPI, uvicorn)
gateway/ WS2 — LiteLLM config + per-bot key/budget API + spend export
manager/ WS3 — control plane API + microsites (Jinja2, vanilla JS, no JS build)
channels/telegram/ WS4 — Aquila Telegram bot service
deploy/ compose stack, relay/Caddy configs, k8s mapping notes (orchestrator)
site/ WS5 — homepage source (night-sky theme)
brand/ tokens.css, tokens.json, BRAND.md
docs/ plan·decisions·killer-apps·economics·demo-script (*.md → /docs on the site)
scripts/ build.mjs (→ public/), check.mjs (CI gate)
e2e/ smoke tests + density harness (orchestrator)
.github/workflows/ deploy.yml (copied pattern from ~/exa/design-context)
opencode.json + .opencode/agent/ workstream agent definitions (DeepSeek V4.x Flash, max effort)
Deployment of the static site: main → CI → Vercel project aquila → aquila.exaflair.com
(homepage + /docs). PRs get preview deployments with sticky comments. Same VERCEL_TOKEN team
secret as design-context.
4. Interfaces (frozen — details in AGENTS.md)
- core ↔ gateway: OpenAI-compatible
/v1/chat/completions(SSE streaming) via LiteLLM proxy. Bot presentsBOT_LLM_KEY(virtual key). Model aliasaquila-default. - core ↔ manager: core exposes HTTP on
:8080—/health,/persona(GET/PUT),/chat(SSE),/routine/{name}/run. Manager spawns containers with env +/datavolume. - telegram ↔ manager: telegram service calls manager API to resolve user→bot and fetch OTP challenges; manager calls telegram service to send routine deliveries.
- manager ↔ docker: Docker SDK via socket; container naming
aquila-bot-<bot_id>. - wildcard routing: manager resolves
Host: <phone>.aquila.exaflair.com→ user workspace.
5. Day-by-day
Day 1 — foundations (docs-first, then parallel workstreams)
- Repo + DECISIONS.md + PLAN.md + AGENTS.md + CI + scaffolds (orchestrator, before agents)
- WS1: core v1 — persona load, chat loop (SSE via gateway), SQLite memory,
/health - WS2: gateway up — LiteLLM proxy, virtual key API, budget enforcement, spend log
- WS5: homepage v1 — night-sky landing (vestra-structure: hero, how-it-works, personas, pricing)
- Orchestrator: compose stack skeleton, e2e smoke script, relay runbook
- Integration checkpoint 1 (achieved 2026-09-16): one bot chatting through the gateway live — bot container → gateway (auth/budget/metering) → OpenRouter free model, SSE streaming, spend rows attributed. Stack: manager+gateway+gateway-admin+searxng+bot on this machine.
- Pending env: Telegram bot token (WS4 live), test Gmail app password (VEGA live), OpenRouter top-up (~$5) for the paid DeepSeek primary — see D033.
Day 2 — the product surface
- WS3: manager v1 — phone identity, OTP sessions, bot CRUD (docker spawn), workspace UI
- WS4: telegram — OTP contact-share flow, chat routing, routine delivery template
- WS1: personas ×3 (VEGA, NOVA, PULSAR) + routines + IMAP tool + search/fetch tools
- WS5:
/docsrendering, copy pass fromdocs/killer-apps.md - Integration checkpoint 2: welcome page → OTP → bot created → chat in Telegram
Day 3 — density + economics + hardening
- Density test: scale to ≥10 bots on the 8GB slice, measure RAM/CPU/latency
- Economics: usage profile → ₹/bot/month from gateway spend logs; model 10/15/20 bots per node
- Hardening: restart policies, resource limits, log rotation, isolation sanity
- Soak start (12h), demo data seeding
Day 4 — demo + handoff
- Soak results; fix what it flags
- Demo script rehearsed + recorded; economics one-pager
- Handoff docs: k8s mapping notes for Rohan, relay runbook, WhatsApp-bridge TODO notes
- Retro + DECISIONS.md wrap-up
6. Workstreams & review (locked, D010)
| WS | Owns | Agent model |
|---|---|---|
| WS1 | core/ |
DeepSeek V4.x Flash, max effort |
| WS2 | gateway/ |
" |
| WS3 | manager/ |
" |
| WS4 | channels/telegram/ |
" |
| WS5 | site/, brand/, docs/ rendering |
" |
| WS6 | orchestration, deploy/, e2e/, economics, reviews |
main session |
Cadence: each WS works on ws/<name> branch → orchestrator review + smoke test → merge to main.
Twice-daily integration checkpoints. DECISIONS.md appended on every decision.
Model note: agents configured in opencode.json / .opencode/agent/*.md; orchestrator launches
them with the Task tool. Restart opencode after config changes (config loads once at startup).
7. Provisioning checklist (Bhavya)
- Laptop access — SSH + sudo + Docker (compose plugin). Keep the Aquila stack isolated from k3s;
resource budget ~8GB (
deploy/compose.ymlsets per-container limits summing under it). - Relay for wildcard (public demo) — either Rohan fixes bengaluru-svc ufw (#66) or provision a
fresh small VPS (~₹500/mo, 1GB is plenty). Runbook:
deploy/relay/README.md. - Hostinger DNS records —
aquilaCNAME →cname.vercel-dns.com;*.aquilaA → relay IP. - GitHub remote + secrets — create repo, add
VERCEL_TOKEN(team-scoped, same as design-context). - Tokens — Telegram bot token (@BotFather), OpenRouter key, test Gmail + app password.
- OpenCode Go — orchestrator auto-detects API access for the gateway upstream; OpenRouter free is the fallback/primary if not.
8. Risks & mitigations
| Risk | Mitigation |
|---|---|
| OpenCode Go has no programmatic API | Chain is config, not code — OpenRouter free becomes primary (D005) |
| Relay dependency delays public demo | Tailscale/LAN demo path is always working; relay is additive |
| Density misses target | Python-slim images, no Chromium, shared SearXNG; measure honestly on D3 and report |
| Free-tier rate limits during demo | Gateway queues + budgets; warm keys; demo script rehearsed |
| 3–4 day overrun | Scope ladder below |
Scope ladder: P0 = one bot + OTP + Telegram + density numbers · P1 = 3 personas + cost dashboard
- public wildcard · P2 = homepage polish + QR bridges + WhatsApp-bridge investigation notes.
9. Economics model (to be filled by D3 measurements)
Per 16GB node / month: hardware amortized (₹35k/36mo ≈ ₹972) + power (~₹150) + ISP share
(host's existing line; incremental ~₹0–1,800) + host fee (₹400) ≈ ₹1,550–3,350
Per bot at N bots/node: infra ₹/N + inference (measured) + margin
Price points to verdict: ₹250 vs ₹299 at N = 10 / 15 / 20
The POC's single most important number: measured ₹ inference/bot/month at the defined usage profile (30 msgs/day + 1 routine/day) — this decides whether ₹250 is viable or the free/cheap tiers must carry routine work.