Architecture
The map of the core codebase: what lives where, why it lives there, and what a change may not do. The boundaries are not aesthetic — each one exists because breaking it would be invisible in a diff and visible in production.
The four planes
Every request moves through four trust levels. Each boundary is a place where a credential is checked.
Edge
aetherin-middleware (Vercel)Public entry point: auth gate, CORS, size limits, circuit breaker, security headers, request id.
Host Edge
Caddy on the box (optional)TLS termination; /aether/api → core, /aether/gateway/* routes.
Core
aetherin-server-coreSplits into a hot data plane and a high-impact control plane (see below).
Platform
internal only, never exposedKernel, plugins, providers, store, sealed secrets, discovery worker, pricing engine, policies.
Why the planes are separated
A defect in the data plane costs latency and money; a defect in the control plane costs credentials, other tenants' data, or the deployment. They have different failure costs, different review depths, and different availability requirements — so they must not share a package where a change to one is indistinguishable from a change to the other.
Data plane vs control plane
Data plane
high volume, hot path
- →Chat, embeddings, usage, budgets
- →Credential: API key
- →No cookie, no CSRF
- →Owns its benchmarks — the hot path
Control plane
low volume, high impact
- →Keys, providers, models, orgs, team, admin, pricing, billing
- →Credential: session + CSRF proof, role-gated
- →Where role checks, CSRF proofs and the audit trail live
Package map
| Package | What it owns |
|---|---|
| pkg/pluginsdk | The public plugin contract — semver-frozen, no internal imports. |
| internal/kernel | The microkernel: transport, plugin host, config, events, secrets, storage. Stdlib-only. |
| internal/platform | Cross-cutting runtime: origin policy, CSRF proof, SSRF target policy, CORS, request-id propagation. |
| internal/api | The HTTP boundary: handlers, DTOs, authorization, CSRF, error envelope, route registration. |
| internal/providers | Upstream adapters (OpenAI, Anthropic, Gemini, …). |
| internal/store | Persistence: Postgres + the in-memory fakes. |
| plugins/ring0 | Kernel plugins: healthz (real), config, eventbus, registry, secrets, storage, transport. |
| plugins/ring1 | Product plugins: auth, metering, providerregistry, ratelimit, router. |
The rules
- ▸internal/kernel imports nothing outside itself and pkg/pluginsdk.
- ▸pkg/pluginsdk imports nothing from internal/.
- ▸internal/platform imports no product package.
- ▸A plugin never imports another plugin.
- ▸The direct Go dependency set is frozen — adding one is an architectural decision.
- ▸The request fast path does not allocate per chunk.
- ▸Metering and logging never block a streaming response.
Storage
Postgres
Primary store — users, orgs, keys, usage events, billing.
Redis
Rate-limit counters, budget counters, session/cache state.