Route registry¶
The route registry is the one file that decides where an alias is served.
Its path is the required BRAMA_INFERENCE_ROUTES_FILE declaration;
a missing path refuses launcher startup. The gateway re-reads it per
request, so a committed edit takes effect on the next completion without a
restart. It is owner-only, it is written atomically, and it is validated whole
before it is used or replaced.
Document shape¶
The document has exactly three known top-level fields:
schema_version— the number one. A legacy document that omits it is read as that version.deployments— the named deployment table a route may refer to by bare name.routes— the map from an alias to its single destination.
An unknown top-level field is refused by the deserializer, and the whole document is rejected with the deserializer's own sentence naming the field. Nothing in the document names more than one destination for an alias: there is no ordered list of spare routes for an alias to be tried in turn, and a top-level field that once carried such a list is now simply an unknown field and rejects the file. When the single destination refuses a request, that refusal is what the caller receives.
The example below is a complete registry; its schema_version
is the number one, spelled here in prose because the value is a bare number:
{
"deployments": [],
"routes": {
"wisent-backend": "anthropic/claude-sonnet-4-5",
"wisent-backend/evaluation": "anthropic/claude-sonnet-4-5",
"wisent-backend/embeddings": "openai/text-embedding-3-large",
"best": "local-weles"
}
}
A zero-byte or whitespace-only file means an empty registry. Every alias in
routes resolves to the destination written next to it and to
nothing else; a bare name is resolved through deployments.
Validation guards¶
The file is checked before it is read as configuration and again before any
replacement is committed. Any one of these rejects the complete document, and
the aliases it would have served report
routes_file_invalid rather than resolving to something else:
- the path must be a regular file, not a symlink;
- it must be owned by the Brama user;
- its mode must not be readable by group or other;
- it must be valid UTF-8 JSON with no duplicate object keys and no unknown top-level field;
- two routes must not repeat a destination — one destination belongs to one alias;
- deployment names must be unique, and every deployment must carry an endpoint that is either a safe loopback address or a Tailscale IPv4 address; anything else rejects the document;
- provider and model shapes must be ones this build supports.
An alias whose destination exists but whose capability is not present
reports capability_absent; a declared alias with no entry in
routes reports no_route; a healthy one reports
serving. A completion naming a declared alias that cannot serve
answers 503 alias_unserviceable with
details.state and details.route, and an unknown alias
answers 404 whose details also carry
state and route. See
Errors.
Writing the registry¶
PUT /v1/admin/routes takes exactly two fields:
{
"alias": "wisent-backend/moderation",
"primary": "anthropic/claude-sonnet-4-5"
}
An unknown field is refused with the deserializer's own sentence. There is
no field for a second destination in the request body and none in the
response. DELETE /v1/admin/routes takes
{"alias"}. Both answer
{"ok":true,"routes":<document>}, the
whole committed document as it now stands on disk.
brama routes set and
brama routes rm perform the same two
operations from an operator shell, through the same validation and the same
atomic owner-only replacement, for a host whose gateway is not running or has
no console bearer.
Both writers check the shape the alias promises: an embedding alias takes an
embedding route, a moderation alias a moderation route, a
decision alias a route that can answer typed
questions — and decision-model refuses best, because delegation
is what best-decision-model is for.
Every registry write follows the same sequence: the new document is built in memory, validated whole, serialized into a staging file created 0600 in the destination directory, flushed, and then renamed over the destination. A reader either sees the previous document or the new one, never a partial file, and the file never widens beyond owner-only. A validation refusal happens before the staging file is renamed, so the destination keeps the document it had. HTTP API documents the admin routes in full.
Reading what is registered¶
GET /v1/aliases returns one row per alias with
alias, state, route,
reason, required, and authorized. The
route field is the single destination, and
reason is the sentence explaining a state that is not
serving. brama aliases
prints alias, state, and route from the same source.
Migrating an existing file¶
brama routes migrate is
the one command that moves an operator's existing registry to this shape
without editing anything by hand. It reads the configured registry document,
keeps only the known top-level fields
(schema_version, deployments, routes),
validates the result against every guard above, and commits it with the same
atomic owner-only replacement every other registry write uses: 0600 staging
file, then rename. It then prints the resulting document. Running it a second
time on an already-migrated file produces the same document and the same
output, so it is safe to run from a script or twice in a row.
Use it when a file written against an older shape now carries a top-level field this build does not know and the gateway therefore rejects the document. The migration is the supported path from that file to a document the deserializer accepts.
Adopting an existing registry¶
brama adopt, the first-use
--adopt-* options, and Brama Desktop's
Review existing setup… sheet use one Brama-owned
preview/apply operation. The accepted source is an exact route registry
document of the shape above, not a guessed provider export. Every field,
alias, destination, deployment name, adapter, and endpoint is validated before
any mutation.
The review resolves bare deployment names through the source deployment
table, lists unreferenced deployments and keeps them, and classifies each
alias with exactly one reviewed route. Direct provider routes are importable
only when this process already has the corresponding acquisition route.
best is importable only when the selected agent has a
subscription identity discoverable through Brama's existing Skarbiec boundary.
Discovery does not redeem the credential, activate a subscription, or perform
inference.
Selection is explicit. An identical alias is left unchanged, which makes a repeated import idempotent. An existing alias is kept unless the operator explicitly asks to replace that reviewed alias; a deployment-name conflict is never replaced, because an unselected existing alias may depend on it. Unselected and unreferenced state is preserved. Apply merges in memory, revalidates the whole destination, then replaces the owner-only file atomically. The source file and the credential stores are left unchanged. Results report the exact imported, unchanged, conflicting, and rejected aliases through the CLI, HTTP, and desktop surfaces.