BBramaDocs
Browse documentation

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:

  1. an alias the deployment declares (wisent-backend, smol, …);
  2. the delegation alias best;
  3. a decision alias — decision-model or best-decision-model, on POST /v1/decisions and nowhere else, see decision;
  4. a media alias — image-model, video-model or voice-model, each on its own endpoint and nowhere else, see media;
  5. a canonical provider/model route (openai/gpt-4o-mini);
  6. 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:

statemeaningrepair
servingat least one declared route names a provider this gateway holds a credential for, or delegates to bestnone
no_routethe alias is known — required by the contract or named by a caller's allowlist — but no route is declared for itdeclare a route with PUT /v1/admin/routes or in the launcher's model_aliases policy
capability_absentevery declared route names a provider whose capability was never issued on this hostissue the provider capability, or point the alias at a route the host can reach, such as best
capability_check_failedthe credential authority could not establish a usable provider routerepair the operation named in reason; an execution, decoding or vault refusal is not proof that no credential was configured
routes_file_invalidthe route registry file exists and cannot be read, so nothing in it servesrepair 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/models lists a declared alias the caller may use even when it cannot serve, as available: false with unavailable_reason carrying the sentence above. A caller that checks the catalog before calling — Jeden does — therefore reports model `weles` is unavailable: alias `weles` routes to … but this gateway holds no provider credential for … instead of not in the Brama catalog.
  • A completion request naming a declared alias that cannot serve is refused with 503, code alias_unserviceable, the same sentence as message, and details.state, details.route. It is not refused as a malformed model name. An alias this gateway does not declare at all is 404, and its details carry the same state and route pair.
  • GET /v1/aliases is the operator's view: every alias with state, route, reason, whether the contract requires it, and whether the presenting bearer may use it.
  • brama aliases prints the same table from an operator shell and names the route registry file it read; --strict exits 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 file
  • inference routes must be owned by the Brama user
  • inference routes must not be accessible by group or other (mode 0o077 bits 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; otherwise inference 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, and task:<name> are not names for one route; they rank candidates per caller identity (entitlement).
  • A canonical route. provider/model names one provider directly and is paid by the deployment's own capability, never by a subscription.