Alias¶
What the model names callers use actually mean. An alias is a
deployment-owned name that resolves to a canonical provider/model route.
Callers ship against aliases so routes, providers, and subscription-backed
selection can change without a client release; an alias never unlocks a
credential its caller does not own.
The model-name vocabulary¶
A request's model field must be one of exactly six things:
- an alias the deployment declares (
wisent-backend,smol, …); - the delegation alias
best; - a decision alias —
decision-modelorbest-decision-model, onPOST /v1/decisionsand nowhere else, see decision; - a media alias —
image-model,video-modelorvoice-model, each on its own endpoint and nowhere else, see media; - a canonical
provider/modelroute (openai/gpt-4o-mini); - a selector (
any,any-vision-capable,task:<task-name>) — signed agents only, see entitlement.
Nothing else is guessed. A bare vendor model name is refused before any provider is considered:
$ model="gpt-4o" → 400
{"error":{"code":"invalid_request","message":"model must be a canonical
provider/model route or a supported selector", ...}}
Declared aliases¶
BRAMA_MODEL_ALIASES (assembled by the launcher from the sealed policy
document, extended per request by the routes file) maps alias names to
canonical routes. Seven aliases are required in managed deployments because
callers ship against them:
| Alias | Shape promise |
|---|---|
wisent-backend |
chat — the Wisent App backend's alias, spelled as the client's name and nothing more. The shape is the endpoint the caller posts to, and the one route behind the alias is the routes entry in the route table; neither is spelled into the name |
model-review |
chat — the model-review probe's own alias. It was wisent-backend/evaluation, which named a consumer that never called it |
wisent-backend/embeddings |
embeddings only — never handed a chat model |
wisent-backend/moderation |
moderation only |
weles |
chat — the Weles workload's own alias, spelled as the client's name; which model answers it is the route table's decision |
best |
delegation to subscription dispatch |
decision-model |
typed decisions only — one canonical route that can answer them, never a chat completion and never best. Known by name, required of nobody |
best-decision-model |
typed decisions, delegated — a route or best, which hands the choice to subscription dispatch. Known by name, required of nobody |
The two decision aliases are the same kind of promise as the embedding one,
in the other direction: a caller that asks either of them for a typed answer
is never routed to something that cannot produce one, and
POST /v1/chat/completions refuses them by name — "`decision-model` is a
decision alias: it answers typed questions on POST /v1/decisions, not chat
completions". Neither is required at startup, so a deployment that serves no
decisions changes no policy to take the release.
Any further name is the operator's to invent and is accepted on the
general-purpose chat shape without a gateway release. A route containing *
or stray whitespace fails startup. A route naming a provider whose capability
was never issued on this host does not fail startup: the gateway starts,
serves the aliases that are serviceable, and logs
alias_provider_capability_absent — "no provider capability was issued for
this route; the alias will not serve" (src/core/server.rs).
An alias that cannot serve says so¶
A declared alias is never silently dropped. The gateway judges every alias it knows into one of the following states, and every surface reports the same word:
| state | meaning | repair |
|---|---|---|
serving | at least one declared route names a provider this gateway holds a credential for, or delegates to best | none |
no_route | the alias is known — required by the contract or named by a caller's allowlist — but no route is declared for it | declare a route with PUT /v1/admin/routes or in the launcher's model_aliases policy |
capability_absent | every declared route names a provider whose capability was never issued on this host | issue the provider capability, or point the alias at a route the host can reach, such as best |
capability_check_failed | the credential authority could not establish a usable provider route | repair the operation named in reason; an execution, decoding or vault refusal is not proof that no credential was configured |
routes_file_invalid | the route registry file exists and cannot be read, so nothing in it serves | repair the file named by BRAMA_INFERENCE_ROUTES_FILE |
Managed route inspection retains the exact route resolve resource, execution or decoding error, process exit status and diagnostic output. A vault row's problem and an incomplete coordinate are refusals, not missing providers. Failed inspections are not cached as absent routes. The next inspection can observe recovery without restarting Brama. Standalone credential-store read errors likewise remain failures rather than selecting managed credentials.
PUT /v1/admin/routes returns 503 with the inspection cause before changing the registry. Onboarding stops before its billable request rather than switching from an unreadable direct-provider check to subscription dispatch. Brama Desktop's Routing inspector displays the same state and reason; permitted direct routes remain visible as unavailable in GET /v1/models when their inspection fails.
Real refusal qualification: run cargo test --test credential-administration -- --ignored --exact route_refusal::route_authority_failure_remains_visible_and_preserves_registry against an isolated gateway and its real Skarbiec authority. Supply TEST_SOURCE_REVISION, GATEWAY_SOURCE_REVISION, BRAMA_ADMIN_URL, BRAMA_ADMIN_BEARER, EXPECTED_ALIAS, EXPECTED_ROUTE, EXPECTED_ROUTE_OPERATION and EXPECTED_ROUTE_CAUSE from that fixture. The alias must already name the expected direct route and fail authority inspection; the test refuses a healthy or different fixture before attempting a route write. It checks alias and catalogue diagnostics, the rejected write, the unchanged persisted registry, and repeated inspection without caching the failure as absence. It submits no inference and installs no credential; the catalogue read can initiate Brama's normal background discovery against the fixture's real dependencies. It retains revision-bound HTTP evidence under target/real-tests/route-authority. Execute separately for each actual failing operation; a missing fixture or an unexecuted run is not a pass.
Where the verdict is read:
GET /v1/modelslists a declared alias the caller may use even when it cannot serve, asavailable: falsewithunavailable_reasoncarrying the sentence above. A caller that checks the catalog before calling — Jeden does — therefore reportsmodel `weles` is unavailable: alias `weles` routes to … but this gateway holds no provider credential for …instead ofnot in the Brama catalog.- A completion request naming a declared alias that cannot serve is refused
with
503, codealias_unserviceable, the same sentence asmessage, anddetails.state,details.route. It is not refused as a malformed model name. An alias this gateway does not declare at all is404, and itsdetailscarry the samestateandroutepair. GET /v1/aliasesis the operator's view: every alias with state, route, reason, whether the contract requires it, and whether the presenting bearer may use it.brama aliasesprints the same table from an operator shell and names the route registry file it read;--strictexits non-zero when any alias cannot serve.- Brama Desktop's Routing screen carries a Gateway column and a Not serving facet, and its inspector shows the reason verbatim; an alias the gateway requires but has no route for appears there with an Add route action even though the registry has no row for it.
In standalone desktop mode an absent BRAMA_MODEL_ALIASES means {}; in
managed mode a bare brama serve fails closed with the exact sentence in the
runbook.
best is delegation¶
best (and any alias whose route delegates to best) resolves through
subscription dispatch, where the caller's signed HMAC identity selects the
subscription that pays. Brama deliberately holds no direct credential for it.
A destination naming best inside the routes file passes through untouched
rather than being resolved as a local deployment
(src/core/inference_routes.rs).
When the alias table points best at a route no subscription pays for — a local
inference route such as local-openai/chat-primary, or a provider route this
deployment pays for itself — that route answers the request directly, or refuses it with its
own error; the subscription pool is not walked first, so its sign-in state neither delays
nor refuses the request. The routing log names this mode best-declared-route.
A route of a subscription provider (claude-code, codex,
kimi) stays the caller's first choice in subscription dispatch, with the
caller's other ranked routes behind it.
A request containing an image_url content part restricts
best to the caller's active models whose catalogue advertises image
input. This happens before a configured preference is promoted, on both the
buffered and streaming paths. A text-only preference cannot override it.
If none qualifies, the request is refused with
no active vision-capable stateless provider model for signed agent.
Selection does not add a subscription, change the caller's allowlist, or use
another identity. A workload must already be authorized to request best.
Dynamic routes: the routes file¶
is reloaded per request and its routes extend the launch aliases. The document has exactly three known top-level fields —schema_version (the number
one), deployments, and routes, which maps each alias to its
single destination:
{
"deployments": [
{"name": "qwen3-8b", "adapters": [{"name": "chat"}],
"endpoint": {"host": "127.0.0.1", "port": 8000}}
],
"routes": {"wisent-backend": "openai/gpt-4o-mini"}
}
Guards, each failing closed with its own sentence
(src/core/inference_routes.rs):
inference routes must be a regular non-symlink fileinference routes must be owned by the Brama userinference routes must not be accessible by group or other(mode0o077bits must be clear)- an unknown top-level field: the deserializer refuses it by name and the whole document is rejected
- a repeated destination:
inference route '<alias>' repeats destination '<destination>' - a bare deployment name resolves to
local-openai/<name>only when its endpoint host is loopback or Tailscale IPv4 (100.64.0.0/10) and its port is nonzero; otherwiseinference deployment '<name>' has no safe local or Tailscale endpoint.
PUT /v1/admin/routes ({"alias", "primary"}) persists
operator route changes into the same file atomically (staging file, 0600,
validate, rename), and
brama routes migrate moves a
registry file written before this contract onto the shape above in one
idempotent operation. Without a configured routes file the update is refused:
409 {"error":{"code":"state_conflict",
"message":"runtime route registry is not configured", ...}}
Lifecycle¶
Launch aliases live for the process lifetime; restart after policy changes. Routes-file aliases change whenever the file does — the snapshot is re-read per request, so an update is visible to the next request without a restart.
Not to be confused with¶
- A selector.
any,any-vision-capable, andtask:<name>are not names for one route; they rank candidates per caller identity (entitlement). - A canonical route.
provider/modelnames one provider directly and is paid by the deployment's own capability, never by a subscription.