State and failures¶
Every workflow on the public workflows page ends in one of two things: a result, or one classified refusal. This page names who owns the state a request reads, what a refusal looks like, how many attempts precede it, and the resource ceilings that hold under load.
State and ownership¶
| Resource | Authority | Brama state | Freshness and recovery |
|---|---|---|---|
| Client bearer and binding | Dedicated central token item and service document | Digest in process memory | Restart after a policy or token change |
| Request-sign identity | Exact central item or agent capability | Secret in scoped memory only | Re-redeemed per request or after restart |
| Provider credential | Skarbiec or entitlements resource | Secret in scoped memory only | Re-redeemed at final use |
| Subscription inventory | Live entitlements router | Per-agent cache, 60 seconds | When the live lookup fails, trusted startup metadata is the only other source read; nothing else is consulted in its place |
| Route registry | Operator-owned registry document | Parsed map of alias to its one route | An unknown top-level field is refused by the deserializer and the whole document is rejected; every alias then reports routes_file_invalid |
| Retirement | Brama journal | Append-only retire record | Last matching record wins |
| Task quality | Brama journal | Append-only quality record | Latest active record per agent, task and model wins |
| Public model metadata | models.dev | memory and a replaceable cache file in Brama's state directory | A stale or partial catalogue is visible in health output and is never credential authority |
| Performance telemetry | Brama process | bounded map and a replaceable perf.json in Brama's state directory | Diagnostic only; never business authority |
| Donated-subscription metadata | Brama overlay | owner-only atomic JSON rewrite | The credential itself stays in entitlements authority |
| Plan usage, its source, and the newest check verdict | The provider's own usage report, plus the answer headers of real traffic | owner-only atomic ledger holding each reading's instant | Refreshed by the free usage report sweep and by traffic; the last good reading is served, marked stale after a failed read or an elapsed reset, until a newer one replaces it; a ledger that cannot be parsed yields no readings, and the next sweep rewrites it |
| Operator credential refresh | Brama journal | Append-only subscription_refresh record naming provider, reason, verdict and how many grants were tried | Audit only; never consulted by routing, and never holds credential material |
Journal credentials, encrypted secret overlays, and raw provider responses are
prohibited. The journal schema is append-only; an incompatible interpretation
requires a release migration contract. The registry document is rewritten only
by an owner-only atomic replacement, whether the writer is
PUT /v1/admin/routes, DELETE /v1/admin/routes, or
brama routes migrate.
Brama's state directory is BRAMA_STATE_DIR, else .brama under the
service account's home. When neither is declared and no home resolves, Brama
still starts and serves, and every reader and writer of that state refuses
with the home's cause instead of stopping the process: a request that asks for
its one signed answer is answered HTTP 500 with this request's one signed answer
has no place to be kept: <cause>; the journal, the donated-subscription
overlay, the model metadata cache and onboarding progress refuse their
operation naming the same cause; and performance telemetry logs one
perf_stats_unplaced warning with the cause at the first dispatch, then keeps
the numbers in memory only.
Failure contract¶
Public errors use this envelope, where attempts counts the provider calls
this request actually made; a refusal Brama made before any dispatch asked no
provider and carries no attempts key:
{
"error": {
"message": "bounded human-readable detail",
"type": "stable_class",
"code": "stable_code",
"retryable": false,
"attempts": <provider calls made>
}
}
| HTTP | Code | Meaning | Caller action |
|---|---|---|---|
| 400 | invalid_request | malformed JSON, route, selector, or limit | Correct the request; do not retry it unchanged |
| 401 | unauthenticated | bearer or HMAC missing or invalid | Repair or rotate the exact identity |
| 403 | forbidden | a valid identity lacks model, agent, or path authority; the message names the client and the cause: the refused model with the models the credential is scoped to, the path a model-scoped credential may not reach, the bound agent against the signing one, or the organization the authority does not admit the user to. A workload credential refused a model is also told the capability it lacks, call:brama#<model>, that call:brama (no route) issues every route, and the stado credentials token mint command that issues it | Correct the grant or the request; sending a different identity is not a repair |
| 404 | subscription_not_found | an owned lifecycle target does not exist | Refresh inventory or correct the ID |
| 409 | state_conflict | the requested mutation conflicts with current state | Read current state before retrying |
| 426 | secure_transport_required | neither loopback nor a trusted HTTPS peer | Use the approved HTTPS ingress |
| 429 | provider_rate_limited | bounded provider quota and rate attempts are exhausted | Wait, or name an explicit authorized target |
| 429 | subscription_unavailable | no usable agent credential within the bound, and at least one was actually tried | Repair the intended subscription or wait |
| 502 | provider_failure | the provider returned a permanent or malformed failure | Inspect the provider classification; retry only if the envelope says so |
| 503 | alias_unserviceable | a declared alias cannot serve; details carry state and route | Repair the alias in the registry; this is the caller's answer for that alias |
| 503 | credential_unauthorized | redemption was refused, or no capability, read grant, or installation trust material could produce a credential at all | Repair the authorization chain; waiting does not reach it |
| 503 | subscription_reauthorization_required | every credential within the bound was refused by the provider; retryable, and the refusal wakes the gateway's own maintenance | Retry once the pass ends: the gateway renews the grant or signs the member in through Weles by itself |
| 503 | dependency_unavailable | a required catalogue, broker, vault, or provider is unavailable, or the transport did not carry a provider request; the message retains its cause | Restore the named dependency |
| 500 | internal_error | Brama failed outside a classified dependency | Operator investigation is required |
An alias the registry never declared is answered 404, and that body's
details carry state and route as well, so one diagnosis reads the same
whether the alias is unknown or known and unserviceable. In both cases the
alias has exactly one route, and the refusal from it is what the caller
receives.
A response states retryable explicitly. Error message text is diagnostic, not
the machine contract. Credential rotation inside one route never exceeds the
attempt count the envelope reports. The full code list, with examples, is in
Errors.
Cancellation and retry¶
- Buffered and streaming requests run until the provider answers, refuses, or the connection fails. Brama adds no elapsed-time cutoff before the first streamed byte or between later reads.
- Catalogue reads, provider model discovery and OAuth refresh also have no Brama elapsed-time cutoff. Provider responses are read whole; the resource behavior below describes their handling.
- Inference and OAuth transport failures retain their underlying causes. Removing a gateway clock does not turn a refused connection, TLS failure, provider refusal or incomplete stream into a successful answer.
- An OAuth response read failure names the token endpoint, HTTP status and bytes received. Even a partial 401 or 403 remains a transport failure, not evidence that the provider disowned the grant; its recorded credential state stays unchanged. Only a complete response reaches refusal classification.
- Direct routes perform one provider attempt.
- Explicit subscription routes perform at most two provider attempts, both on the one route the request named.
- Selectors try every model candidate in order, each on at most two credentials, and skip the routes of a provider whose whole pool refused.
- Brama does not retry arbitrary 5xx or malformed results automatically.
- Dropping the client connection cancels the in-process future where the HTTP stack propagates cancellation; Brama has no durable job to resume.
- A stream that has committed is never retried, on any credential, for any failure class.
- A caller must treat an ambiguous provider outcome as potentially billable and must not replay it automatically unless the returned code is retryable.
Resource behavior¶
- provider answers, OAuth answers and credentials are read whole; a size limit is a provider's own and comes back as its refusal;
max_tokensis the caller's or, when omitted, the model's own limit;- model and credential attempts are finite;
- the perf registry keeps one entry per route that was ever served;
- catalogue and subscription caches have explicit TTLs;
- the provider usage report pass spends no plan quota: one read per active
subscription that has no reading, a reset window, a reading naming no reset or
a failed last read, single-flighted per subscription, no retry inside a pass,
and it runs in each of the serving process's own maintenance passes (one at start,
one at each moment the ledger states something becomes due, one after a refusal for
want of a signed-in subscription) and when
brama maintainasks; - the completion probe is bounded to what an operator asks for: one attempt
against one named subscription per request to
POST /v1/admin/subscriptions/:agent_id/:subscription_id/probe, no retry, no rotation to another credential, refused outright for a subscription inside a recorded block, and never triggered by a timer — the shipped configuration performs no quota-consuming request on any schedule; - the credential refresh pass makes one refresh attempt per active subscription per maintenance pass, single-flighted per subscription, no retry inside a pass, a definitively refused credential left alone until a sign-in through Weles replaces it; a pass starts at a moment the ledger states (a grant's stated expiry, a plan window's stated reset, a block's stated end), never on a period of Brama's own;
- no unbounded background retry, queue, or provider worker exists;
- append-only journal growth is operator-monitored until a versioned compaction contract exists.
Evolution and completion¶
Public changes follow RELEASE.md. Provider integrations
follow INTEGRATIONS.md. Every supported outcome maps
to examples/ and approved evidence in
TESTING.md. Obsolete fields and aliases are removed once
callers have moved; Brama keeps no hidden compatibility path and no second
authority for the same decision. An operator whose registry document still
carries retired top-level fields brings it to the current shape with
brama routes migrate, which is idempotent and
prints the document it committed.
Where to go next¶
- Authorization and observability — configuration rules, secret handling, and what a routing event records.
- Errors — the full public error reference.
- Runbook — operator procedures for the failures above.