Architecture Overview
System topology, component relationships, and data flows.
Diagrams
Current truth: the supported, demo-ready topology in this checkout is the local Docker Compose stack with one shared sandbox, explicit
runtime apply, and the web/TUI/gateway clients. The Azure and sandbox-pool diagrams below are useful design context, but they describe preview or longer-term topology rather than tomorrow's primary path.
Current Demo Topology
flowchart TB
subgraph host["Local Docker Compose demo"]
web["web :3000"]
docs["docs :3001"]
api["api :8787"]
worker["worker"]
postgres["postgres :5432"]
sandbox["sandbox :4096 + noVNC"]
runtime["runtime/staged + runtime/applied"]
gateways["gateway profiles"]
end
web --> api
docs --> web
gateways --> api
api --> postgres
worker --> postgres
api --> sandbox
worker --> sandbox
api --> runtime
runtime --> sandbox
Preview / Longer-Term Diagrams
The following diagrams are still helpful for roadmap context, but treat them as preview architecture rather than the default deployment you should stand up for a demo.
Dispatch & Sandbox Pool Detail (Preview)
Runtime Boundary
The runtime bundle is the handoff between provider configuration in Postgres and the sandboxed opencode process. Desired provider state is staged, then promoted with bun orginabox runtime apply, and only the applied bundle is consumed by the sandbox.
See the dedicated Runtime Bundle page for the full staged/applied flow and bundle layout.
Component Topology
┌─────────────────────────────────────────────────────────┐
│ User Interfaces │
│ TUI (oiab chat) Web UI (:3000) Docs (:3001) │
└──────────────────────┬──────────────────────────────────┘
│ REST / SSE
┌──────────────────────▼──────────────────────────────────┐
│ orginabox-api (:8787) │
│ Hono REST server Auth middleware Route modules │
└──────────────────────┬──────────────────────────────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌───────▼──────┐ ┌─────▼─────┐ ┌────▼─────────────────┐
│ PostgreSQL │ │ Job Queue│ │ Channel Gateways │
│ + pgvector │ │ LISTEN/ │ │ Slack / Teams / │
│ + pg_trgm │ │ NOTIFY │ │ Email │
└───────────────┘ └─────┬─────┘ └──────────────────────┘
│
┌─────────▼──────────┐
│ orginabox-worker │
│ (job drainer) │
└─────────┬──────────┘
│ SDK calls
┌─────────▼──────────┐
│ opencode sandbox │
│ (:4096) shared │
│ Ubuntu VM │
│ Xvfb + noVNC │
│ Chromium │
│ Plugin host │
└────────────────────┘
Preview notes:
- The checked-in Azure modules do not yet provision the sandbox/runtime service.
- The remote sandbox pool and multi-VM dispatch path are still experimental design/partial work in this repo.
- For a reliable demo, use the single shared sandbox shown above.
Package Map
| Package | Purpose |
|---|---|
packages/core | CLI, TUI, HTTP server, job drainer, RBAC, audit, embeddings, keyring |
packages/db | Drizzle schema (20 tables), migrations, DB utilities |
packages/shared | Cross-package types, logger, env parser, embeddings factory |
packages/analytics | Usage event aggregation, cost digest |
packages/sandbox | Docker image (Ubuntu 24.04 + opencode + noVNC) |
packages/web | Next.js 15 dashboard |
packages/docs | Fumadocs documentation site |
packages/plugins/* | opencode plugins (memory, orchestrator, dispatch, team, reflection, browser, …) |
packages/gateway/* | Channel adapters (Slack, Teams, Email). Telegram/Discord adapters exist in the repo but are disabled by default and not part of the supported surface. |
Request Flow (Inbound Message)
1. Message arrives at gateway (Slack/Teams/etc.)
2. Gateway calls resolveChannelUser() → finds or creates user
3. Gateway enqueues { kind: "agent-turn", payload }
4. NOTIFY fires → worker drainer wakes
5. Drainer claims job (SELECT FOR UPDATE SKIP LOCKED)
6. Handler calls client.session.promptAsync()
7. SSE stream fires events → gateway edits/appends response
8. session.status = idle → reflection plugin fires
9. Trajectory + reflection stored; skill proposed if pattern detected
Multi-Tenancy
All tables carry a tenant_id UUID column that references tenants.id. A NULL tenant_id indicates legacy single-operator mode. All existing single-operator flows continue to work unchanged.
The auth middleware sets ctx.tenant from the JWT tid claim. Route handlers scope all DB queries by tenant_id.
Security Layers
- Network: all inter-service communication is within the Docker network; only ports 8787 (API), 3000 (web), 3001 (docs), and gateway ports are exposed
- Auth: JWT HMAC-SHA256 (access 15min, refresh 7d); falls back to
ORGINABOX_API_KEYbearer - Keyring: AES-256-GCM; master key in Azure Key Vault (prod) or
~/.orginabox/.keyring(local) - Sandbox isolation: agents run in an Ubuntu VM; no direct host filesystem access
- RBAC: per-action permission checks on all API routes
- Audit: every action logged with tenant + user context
See Security Architecture for details.
