Version: Current
Historical release snapshot. These docs are frozen. Read current docs.
Architecture
acumen is one Go binary with one listener. Three request shapes arrive at it and one routing path answers all of them; everything else is a view onto that path.
One listener, two planes
Section titled “One listener, two planes”127.0.0.1:4020 serves the model plane (/v1/*) and the operator surface
(/api/*, /console, /ide) from the same process. Nothing binds a public
address. The public origin https://ai.tcp.systems is the edge, and the edge
forwards only the model plane; the operator routes answer 404 there. That
split is why a virtual key can be public while an admin key can exist at all.
Three doors, one decision
Section titled “Three doors, one decision”POST /v1/chat/completions (OpenAI), POST /v1/messages (Anthropic) and
POST /v1/responses (OpenAI Responses) all resolve to the same order:
authenticate the key, resolve the model alias, pick candidates from the offer
table, then call seats in order until one answers.
The door decides the envelope, not the behaviour. An Anthropic-shaped request
that is answered by an Anthropic seat still returns an OpenAI-shaped body,
because the reply is converted on the way out. A client that expects
content[] blocks will not understand it. See the API reference
for the exact shapes.
A failure is a routing event
Section titled “A failure is a routing event”A seat that fails is cooled down rather than removed, and the same request
continues on the next candidate. The same deployment is never retried, so a
vendor that fails fast costs one attempt, not two. When every candidate fails
the answer is 502 with a code from the error reference,
and the cooldown window is the plan default rather than the vendor’s
Retry-After.
State lives in PostgreSQL
Section titled “State lives in PostgreSQL”Seats, keys, the grant ledger, the attempt ledger and console sessions are
tables, not files. The process re-reads the seat set every 30 seconds
(cmd/acumen/main.go:85), which is why adding a provider is a write plus a
wait, not a restart. This is also why a rollback of the binary is safe: the
state survives it.
What that costs
Section titled “What that costs”- A seat change is not instant; the reload window is a real delay.
- A vendor’s own rate-limit advice is ignored, so a long pause is not honoured.
- The operator surface has no network boundary of its own. It is loopback-only by construction, and putting it behind anything else is a decision that needs its own record.
The decisions behind these choices are in Decisions.