Expand description
brazen — the engine behind the bz command, and the pure, fully-tested core
of a stateless LLM adapter.
cargo install brazen builds the bz binary (this crate’s [[bin]]); the
library is that binary’s engine, published alongside it in case it is useful as
a dependency. Its API is not yet a stability contract — pin an exact version
if you build on it.
This crate holds the canonical model (the single source of truth every
provider/protocol projects to and from) and the traits behind which all
impurity (network, clock, credentials, browser) is injected. The bz binary
and src/native/ own the native impls; the library reaches 100% coverage on its
own because nothing here touches IO — a boundary tests/purity.rs keeps real now
that the bin and the library share one crate.
Beyond the canonical model and error model (the dependency root), this crate
defines the seams the rest of the pipeline plugs into: the Protocol,
Auth, Transport, CredStore, and Clock traits, the data records they
exchange (WireRequest, Provider, Cred, …), and the Registry that
dispatches by id without ever matching a vendor name (§4 of the architecture).
It also holds the pure pipeline — input resolution, canonical-in parsing, and
the output projections + pump loop (§5). Concrete protocol/auth/transport
impls land via their own tasks; the shared test doubles live in [testing].
Structs§
- Ambient
Spec - An ambient credential source as row DATA (auth §5.5):
pathis the source LOCATOR thebzimpl reads — a~/$HOME-expanded filesystem path for a file format, an environment-variable NAME forapi_key_env— andformatselects the pure parser that maps its bytes to aCred. Neither lives in core code, so deleting the row’sambientblock deletes the capability (severability). - Args
- The injected process inputs handed to
run: the program arguments (excludingargv[0]), a snapshot of the environment, and the one bit of terminal state the pure lib can’t observe — whether stdin is an interactive tty (§5.5).mainbuilds it fromstd::env/isatty; tests build it from literals — sorunis exercised end-to-end without touching the real process state (arch §6.5, §9.6). - Cached
Models - One provider’s cache document (§5.1): the ORDERED list plus
last_used, the local observation of which id this provider last served a 2xx for. Two DIFFERENT facts in one file, never two representations of one:modelsis MEMBERSHIP (which ids this row can serve — read by partial matching and by routing’s ownership tier, config §7),last_usedis RECENCY (which of them to default to on an empty seed, §4 rung 2). The pointer is never a permutation of the list — §5.4’s “append, never reorder” stands. - Canonical
Error - A normalized error, carried in-band as
Event::Error(§3.3). It stores only what cannot be computed:retryableand the exit code are queries overkind, never fields that could drift. - Canonical
Request - The single canonical request. A field set on the wire is used as-is; a field
it omits defaults (
getConfigValuefills it later — §6.1).extrais the long-tail valve: an unmodelled top-level key is forwarded verbatim. - CountIo
- The injected seams + writers for one
bz --count-tokens— the sibling ofListIo, with areader(the count op CONSUMES a request, unlike the listing verb). Reuses the data-planeTransport/CredStore/ModelCache/Clock: the model seed is placed against the same cache (READ-only — no write), and the one round-trip goes through the sameAuth::apply.stdoutgets the count; any error goes tostderr. - EnvSnapshot
- A snapshot of the process environment, injected by
main. A newtype over aBTreeMapso the projection is deterministic and pure (config §3.4). - Envelope
Head - What Brazen reads off a delegate’s response head (spec §5.2): the status every
transport already carries, the ONE response header it already keeps —
retry-after, verbatim (arch §3.3) — and where the BODY starts in the buffer, so bytes that arrived alongside the head stream on as the first chunk instead of being buffered to end. Widening the header set stays additive. - Exec
Spec - The wire request + the three delivery facts it carries (
wire.rs): the HTTPMethod, the subprocessExecSpec, and theEnvelopeits pipes carry. A subprocess target aWireRequestmay name instead of an HTTP one (claude-code spec §3.1): the native transport spawnsprogram args…, writeswire.bodyto the child’s stdin, and streams the child’s stdout as the response body. Data on the one struct already crossing the transport seam — likeMethod/Timeouts, never a newsendparameter.Envelopesays what the child’s pipes CARRY, which is the only thing the two subprocess uses differ in. - Header
Spec - The auth-header shape as data (auth §2): the only thing that names the auth
header, so
ApiKey/Bearershare one data-driven header write. - Host
- The five impure data-plane seams, bundled (arch §1, §6.5) — the sibling of the
verbs’
ListIo/LoginIoIO bundles. Every round-trip the generation path makes goes through exactly these: theTransport(the oneurequser), the credential store, the model cache, the clock (auth-refresh expiry), and the fail-open replay stash (ingress §5 — read/written only by the--in/--servemasquerade shell;generatenever touches it). The writers stay separate from theHostbecauserunborrowsstdout/stderrmutably AND simultaneously when it builds the sink — a seam reference is shared, a writer reference is exclusive, so they cannot live in one struct. - Ingress
Error - A
decode_requestfailure. ALWAYSErrorKind::ParseInput(ingress.md §2) — the kind is a query over this type, never a stored field — framed in the CLIENT dialect’s error envelope at the edge (§9).messagenames the offending key/shape, per the adapt-or-reject ladder’s rung 4 (§3). - ListIo
- The injected seams + writers for one
bz --list-models(model-discovery §2), the sibling ofLoginIo. The verb writes its listing tostdoutand any error tostderr, reuses the data-planeTransport/CredStore/Clockfor the one GET (auth/refresh and all, through the sameAuth::applyseam), and is the WHOLESALE writer of thecache— itputs the decoded list the generation path later reads, which that path then appends learned ids to on success (§5, §5.4). - LoginIo
- The injected control-plane seams + RNG for one
bz --login(auth §7.2). - Message
- A transcript message.
contentis ALWAYS aVec<Content>; a bare wire string decodes tovec. Deserialize is hand-rolled inrequest_de: auserturn bearing anytool_resultdecodes asRole::Tool(§2.2, the Anthropic packing normalized). - Model
- One available model, the canonical projection of a provider list entry (§3).
Ordered position in the returned
VecIS the provider’s suggested order — the single source the heuristics read, so there is no rank field.defaultis CARRIED, not invented: a dialect that flags one sets it; today none does, so it isfalseand §4’s first-in-list rule governs — the seam stays so a provider that DOES flag one needs no code change. - Models
Override - The
[provider.models]per-row model-discovery override (config §4.4, model-discovery §3.2): thebz --list-modelsGET’s path/query and the response list keys, OVERRIDING the protocol’s defaultModelsShape(§3.1). Every key is optional — an omitted one inherits the protocol default — and the whole block is optional (absent ⇒ pure protocol default).deny_unknown_fieldsmakes a typo’d key aMalformedFile(config §2.3), likeoauth.stripis NOT here: it is protocol-only (Google’s leadingmodels/), never row-overridable.querymirrorsauthorize_params(aVec<(k, v)>URL-encoded by the same codec, auth §7.4); theskip_serializing_ifkeeps an omitted key out of a--dump-configround-trip and off the TOML serializer’s no-Nonepath. - OAuth
Config - The OAuth auth-row as data (auth §7.1): endpoints,
client_id,scope, and the auth-mode-dependentbeta_headers(e.g.anthropic-beta: oauth-…). The provider NAME is deliberately absent — it lives once, as the row key /store_key. The pure OAuth builders take&OAuthConfig, so no vendor policy is compiled into the core. Like the[[provider]]row (config §2.3),deny_unknown_fieldsmakes a typo’d or MISPLACED key aMalformedFilerather than a silent drop — a TOP-LEVEL row key (e.g.unsupported_body_keys) typed under[provider.oauth]would otherwise vanish and the strip never fire (bl-9649). - Provider
- A resolved provider row (arch §4.2). Pure data:
nameis a table key never matched on in the pipeline;protocol/authare registry keys;model_aliasesdrives the computed alias→wire-id lookup. Sparse user/file rows fold onto the embedded defaults before a completeProvideris resolved (config §3.2). - Providers
Io - The injected seams + writers for one
bz --list-providers(config §6.1), the deliberately-thin sibling ofListIo. There is noTransport, noClock, and noModelCache: the verb reads the merged config, the credential store, and any row’sambientfile, and that is the whole of its reach. - Redirect
Spec - The loopback redirect endpoint as data (auth §10.1). The default reproduces
today’s literal —
127.0.0.1(RFC 8252), an ephemeral port (None⇒:0), and/callback— so deleting the block restores it (severability). A provider whose registered redirect differs (OpenAI:localhost:1455/auth/callback) names it here as data; the socket still binds the IPv4 loopback127.0.0.1. - Replay
Stash - The stash directory, rooted at the injected XDG cache root. Payloads are opaque bytes to this module — the canonical-JSON block(s) for one turn.
- Resolved
Config - The one config the pipeline runs on (config §7).
modelis the alias- resolved WIRE id, soProviderCtx.modelis final andencodehas no model logic (arch §4.1). Each gen scalar already carries the routed row’sbody_defaultsbeneath flag/env/file (folded at resolve, config §4.1). - Secret
- A plaintext secret whose
Debug/Displayredact and whose only plaintext reads areexpose()(the single audited site) andSerialize(reached only byCredStore::putwriting the 0600 file) — auth §5.3. - ServeIo
- The injected seams + writers for one
bz --serve(ingress §7) — the sibling ofListIo/LoginIo. The data-plane seams carrySynchere because the connection threads share them (each thread rebuilds the ordinaryHostview);bindyields the listener;stashis the §5 replay stash. - Timeouts
- The per-request transport budgets (config §4.3), in WHOLE SECONDS; each
Noneleaves that bound unset (the transport’s own default). ureq’s three phase budgets — the seam’s internal vocabulary, NOT the config surface: the resolved config carries ONEtimeout(the silence budget), andResolvedConfig::timeouts()FANS it onto all three here (all equal, or allNone), so the collapse to one knob is a surface fact and the fan is observable at this seam (arch §13.15). Carried on theWireRequest— the one thing crossing the seam — so config- sourced policy reaches the impure transport without widening thesendsignature. The one number lives in config (floordata/defaults.toml), never as magic in the bin (severability — policy in config, not core). - Transport
Response - The peeked HTTP status (read even under
--raw, for exit-code correctness) plus the blocking, incremental body stream (arch §4.1). - Transport
Spec - The
[provider.transport]delegate block (transport spec §4.2): the operator’s own HTTP/TLS implementation, spawned per request and spoken to over the stdio HTTP envelope (spec §5).programis aPATHname or an absolute path;argsare passed VERBATIM — the operator’s vocabulary, never inspected here, so no client identity is compiled into Brazen.deny_unknown_fieldsmakes a typo’d key aMalformedFile(config §2.3), like[provider.models]; the whole block folds withOption::oracross layers (replaced, never merged). - Usage
- Token accounting (§3.2). Every field is
Option: a provider that never reports a counter leaves itNone(0would be a lie), never fabricated. Token-explicit names — these count tokens (Anthropicinput_tokens/…, OpenAIprompt_tokens/…) — frozen with the rest of thev=1vocabulary. - Wire
Request - The wire request + the three delivery facts it carries (
wire.rs): the HTTPMethod, the subprocessExecSpec, and theEnvelopeits pipes carry. The HTTP request that flows encode → auth → transport (arch §4.1).encodebuilds the body + non-auth headers;Auth::applyadds the auth headers in place;Transport::sendconsumes it. Header names match case-insensitively so an auth overwrite never duplicates a header.methodisPostfor every generation request (the default —encodebuilds POSTs vianew) andGetfor thelist-modelsverb’s GET (§6).timeoutsis the per-request transport policy (config §4):encodeleaves it at theDefault(all unset) andrunstamps the resolved config onto it beforesend, so a config-driven bound reaches the impure transport without a widersendsignature.execdeclares a SUBPROCESS target (claude-code spec §3):None= HTTP (every prior dialect, byte-identical);Someroutes the native transport to the spawn —url/method/headersare inert on that path.
Enums§
- Ambient
Format - Which foreign credential format an
AmbientSpecnames (auth §5.5). A closed enum, not a JSON-pointer DSL: each shape needs a parser anyway, so one variant per known source is less mechanism than a speculative mapping language. The variant ALSO tells thebzdiscoverimpl where to read: a file (ClaudeCode) or a process env var (ApiKeyEnv). - AuthId
- Which auth model a provider uses (arch §4.2, §4.4). A registry key.
ApiKeyandBearerdiffer only inHeaderScheme; both ship, plusOAuth2andNone.Noneis a keyless row (e.g. local Ollama): no credential is read and no auth header is written, so it carries noapi_header— a resolve invariant mirroring the way anOAuth2row carries anoauthblock. - Content
- A piece of content.
Textis expressible as a bare string or a{"type":"text",…}object; other variants are tagged objects.Thinking/RedactedThinkingpayloads and the two server-tool variants (CR-4) round-trip verbatim — provider-executed blocks carried untouched, mirroring theRedactedThinkingrule. - Content
Kind - What kind of content block is opening (§3.2). Externally tagged so it
renders
{"text":{}}/{"tool_use":{…}}exactly as the §5.2 sample shows. - Cred
- The stored secret bundle for one provider (auth §5.1). The variant IS the
token-kind discriminant;
expires_atis ABSOLUTE unix-seconds; there is nois_validflag (freshness is thenow + SKEW >= expires_atquery) and no provider name (the file path is the name). - Delta
- A streamed content fragment (§3.2). Externally tagged so a newtype variant
renders
{"text_delta":"Hel"}. Tool arguments rideJsonDeltaas text fragments, never a parsedValue. - Document
Source - A document source — the
Imageanalogue for PDFs/files,kind-tagged exactly likeImageSource; a dialect that can’t express a source rejects at encode (providers §9). - Envelope
- The wire request + the three delivery facts it carries (
wire.rs): the HTTPMethod, the subprocessExecSpec, and theEnvelopeits pipes carry. What a spawned child’s stdin/stdout carry (transport spec §4.1) — the ONE discriminator between the two subprocess uses, soWireRequestnever grows a second exec field and a row can never be both by construction. - Error
Kind - The taxonomy every failure normalizes to (§3.3).
Providercarries the HTTP status soretryable/exit derive without a second table.Otheris the forward-compat escape hatch (§3.2v=1contract): an error event carries novhandshake, so a future kind cannot be version-gated — instead an unrecognized snake_casekinddecodes here verbatim (mirroringFinishReason::Other) so a 0.1.0-pinned consumer degrades instead of failing. Serde is hand-rolled (below) to route the unknown tag, not derived. - Event
- Finish
Reason - Why generation stopped (§3.2). Carried flattened into
Event::Finish, keyed onreason. Refusal is aFinish, never anError.Otherpreserves any unknown reason string so decode never panics on a new value. - Header
Scheme - How the secret is written into the header value (auth §2). Two arms cover
every shipped wire convention; a
matchon it is value formatting, not vendor dispatch. - Image
Source - Ingress
Id - The closed set of ingress dialects — the registry key, mirroring
ProtocolId(arch §4.4). A dialect is always named EXPLICITLY (the--inflag, or under--servethe route path); structural sniffing stays forbidden (ingress.md §2). - Method
- The wire request + the three delivery facts it carries (
wire.rs): the HTTPMethod, the subprocessExecSpec, and theEnvelopeits pipes carry. The HTTP verb aWireRequestcarries (model-discovery §6): every generation request is aPost(the default —encodeis unchanged), thelist-modelsverb’s GET aGet. Data on the one struct already crossing the transport seam (mirrorstimeouts), not a newsendparameter — the impureHttpTransportreads it to pick the verb,MockTransportrecords it. - OutMode
- The output projection (arch §5.1):
--textdefault,--json→Ndjson,--raw→Raw. The single enum behind bothPartialConfig.outputandResolvedConfig.output— one home for “which projection” (config §7). - Output
Format - A PORTABLE structured-output intent — one canonical knob every structured-output-
capable dialect spells differently, lifted out of
extraso each adapter owns its projection (the same rule asToolChoice/reasoning). Internally tagged ontype({"type":"json"}/{"type":"json_schema",...}), so it rides the wire and config the same way.name/strictfeed only the dialects whose wire has them (OpenAI); Anthropic/Google/Ollama read onlyschema(providers.md §6). - Protocol
Id - Which wire dialect a provider speaks (arch §4.2). A registry key, never a
matchtarget; the explicitrenamekeeps the config spelling (openai_chat) stable regardless of the Rust identifier. - Reasoning
Effort - A PORTABLE reasoning-effort intent — one canonical knob every reasoning-capable
dialect spells differently, lifted out of
extraso each adapter owns its projection (the same rule asToolChoice/parallel_tool_calls). serde lowercase, so"low"/"medium"/"high"on the wire and in config (providers.md §6). - Role
- Route
- Which control plane the
bzshim should wire (§5.10.1). Computed by the ONE authoritative [parse_args], so the coverage-excluded shim never hand-rolls an argv scan and can never disagree with the lib on flag-vs-prompt: a value whose text looks like a control flag (--system=--login) is the value, and any word after--is the prompt, so neither is ever mistaken for a route. - Service
Tier - A PORTABLE PROCESSING-LANE intent — the FIFTH lifted knob (providers.md §6.2):
spend the provider’s priority lane on this request, or demand the standard one.
An ENUM, not a bool: “which lane” is a value, and a bool would be the lossy
“is this fact present” projection of it (AGENTS.md) — OpenAI speaks
default|flex|priority, Anthropicauto|standard_only, and a further rung (Flex) is additive later under#[non_exhaustive]. serde lowercase, so"priority"/"standard"on the wire and in config;None= absent, the key omitted and the provider’s own default lane taken (the empty-set path). - Tool
- A declared tool — an OPEN SET (brazen enumerates none, registers none). The
enum distinguishes only NORMALIZE vs CARRY, and the harness declares which by
the shape it hands over: a wire object with no
typekey isCustom, one with atypekey isProvider(hand-rolled serde inrequest_de, keyed ontype). - Tool
Choice - All four tool-use intents, lifted explicitly rather than left in
extra.
Constants§
- EVENT_
SCHEMA_ VERSION - Event-schema version stamped into the first
MessageStart(§3.2). The one handshake a harness pins to; a backward-incompatible change to theEventvocabulary bumps it (an additive kind/event does NOT — see the module doc). - VERSION
- The crate’s own version (
Cargo.toml’s[package] version, via Cargo’s compile-time env var). Re-exported at the crate root asbrazen::VERSIONso a downstream that linksbrazenreads the linked crate’s version DIRECTLY — the linked crate is the source of truth — instead of mirroring the pin by parsing a manifest. The sibling [VERSION_LINE] is thebzCLI’s rendering of this same fact;concat!takes only literals, so both derive fromenv!("CARGO_PKG_VERSION")rather than one from the other.
Traits§
- Bind
- The bind seam: the resolved
[ingress].listenaddress becomes a listener. The shim wires the OS TCP bind; tests wire in-memory queues. - Browser
Launcher - Open
urlin the user’s browser (auth §7.2). Real implCommand::spawns thebrowser_argv; the fake records the argv and never execs. - Clock
- The one injected time source in the data plane (auth §5.4): unix seconds. The
library never calls
SystemTime::now;bzwiresSystemClock, tests wireFakeClock. - Code
Receiver - Capture the loopback redirect (auth §7.2, §10.1).
bindbinds the listener on127.0.0.1at the requestedport(None⇒ an OS-assigned ephemeral port, RFC 8252 §7.3) and returns the ACTUALLY-bound port, whichbrowser_flowsubstitutes into theredirect_uri— single-sourcing the port through the receiver whether fixed or ephemeral.await_querythen blocks until the redirect arrives and returns its rawcode=…&state=…query, whichparse_callbackvalidates. - Cred
Store - Persist and retrieve one secret bundle per provider (auth §5.2, §5.5).
getreturnsNonefor a missing cred (the no-creds path), never an error; refresh isOAuth2::applyusing get+put (freshness is a query); list/delete are control-plane.discoveris the third primitive (auth §5.5): read a foreign credential source named by anAmbientSpec— a file (Claude Code’s~/.claude/…) or a process env var (a vendor key alias) — into a brazenCred. The IO — a file read with$HOMEexpansion, or an env read — lives in thebzimpl; the format parse is the pureparse_ambient; a store with no ambient backing returnsNone. - Listener
- The accept seam (ingress §7): blocks for the next connection;
Noneends the loop. The native impl accepts forever (SIGINT/SIGTERM end the process, the repo’s default-disposition signal convention); test doubles script a finite queue, which is what keeps the loop’s shutdown testable. - Model
Cache - The per-provider model-list cache (model-discovery §5.1) — filesystem state, so
like
CredStoreit lives behind an injected trait; the pure lib never touches the disk. A SIBLING ofCredStore, not folded into it: a secret and a regenerable model list are different facts with different files. Thebzbin backs it with one JSON file per provider under$XDG_CACHE_HOME/brazen/models/<provider>.json(the{"models":[{id,default}]}shapelist-models --jsonemits, reused); the in-memory double lives intesting. - Pacer
- Pace the device-flow poll loop (auth §7.3): the real bin sleeps
secs; the test fake records the interval and returns instantly — so the whole flow runs offline with no real time. A control-plane concern only, kept off the data-planeClock. - Serve
Conn - One accepted client connection: a blocking byte stream both ways.
Sendso the accept loop can hand it to its connection thread (ingress §7). - Transport
- The single network seam (arch §4.1). Object-safe;
Send + Syncso an impl is shareable. Exactly one round-trip per process — a caller wanting N concurrent requests spawns Nbz.
Functions§
- browser_
argv - The argv to open
urlin the user’s default browser on the build target (arch §7.3). A thin pass of the compile-time OS to the pureargv_for; the caller (bz --login --browser)Command::spawns the result. - count_
tokens - Run
bz --count-tokensand return the POSIX exit code (§5.10.1). Reads the request fromreader(stdin /--input) or the positional prompt, resolves provider/model as the data plane does, does ONE round-trip, and prints{"input_tokens": N}under--jsonelse the bareN. A failure is written to stderr and mapped to its exit (usage 64 / no-input 66 / config 78 / auth 77 / non-2xx 69-70 / malformed body 70). - decode_
request - Client-dialect request bytes → the canonical request (ingress.md §2). Pure; the
dialect dispatches by a total match on the closed enum — the ingress mirror of
Registry::protocol(arch §4.4), never a match on a vendor name. - envelope_
error - A malformed envelope as the seam’s
Transporterror (→69). The message names a REASON and never echoes head bytes: a broken — or hostile — delegate that echoed the request back must not be able to makebzprint the credential (spec §6). - envelope_
head - Parse the response head out of however much of the delegate’s stdout has arrived
(spec §5.2).
Ok(None)= still incomplete, read more;Ok(Some(head))= parsed, withhead.body_startsplitting the buffer;Err= malformed or oversized (spec §6, → exit 69). Caller-owned buffer, so the codec stays a pure function of the bytes so far — no hidden state, and every arm is reachable from a table test. - envelope_
request - Render the request the delegate must perform (spec §5.1): an absolute-form
request line (RFC 9112 §3.2.2 — what a proxy receives, so the child needs no
second URL channel), then
wire.headersVERBATIM in order, then the body. - generate
- Generate against a resolved config (arch §1): drive ONE round-trip and yield the
canonical event stream, terminated by a single
End. THE pure typed core —runwraps it in byte I/O, an embedder consumes the events directly. The model SEED is resolved against the per-provider cache here (a local file read viahost.cache, model-discovery §5.2), then the request is encoded, authenticated, and sent over the oneTransport. Every failure is an in-bandEvent::Error, so the call is total. This is the normalized-in / canonical-out composition — [send_encoded] (the request half) then [canonical_events] (the response half); the--raw=outvariant reusessend_encodedunder aRawSink(arch §5.4, §13.14). - list_
models - Run
bz --list-modelsand return the POSIX exit code (model-discovery §2). Reuses the full flag parser +into_resolved(None, …)to pick the provider (an explicit--provider, else the row owning a configuredmodel; neither →NoProvider/78), does ONE GET tomodels_path, and prints —--jsonthe{"models":[…]}object, else the ids one per line with(default)on the default. The listing goes to stdout; any failure is written to stderr and mapped to its exit (config 78 / auth 77 / non-2xx 69-70 / a malformed body 70 — the same run-level table). - list_
providers - Run
bz --list-providersand return the POSIX exit code (config §6.1). Reuses the full flag parser and the SAME fold a run does —flags.or(env).or(file).or(defaults())— then completes EVERY row instead of routing to one, so the built-in floor is visible. Rows print inprovidersorder, which IS routing priority (arch §4.3.1): the head is the row a barebz "q"reaches. Always exit 0 on a config that completes; a malformed file / bad env scalar / incomplete row is the usual 78. - login
- Run
bz --loginand return the POSIX exit code (auth §7). Resolves the provider’sOAuthConfig, runs the selected flow, and persists the resultingCred::OAuth2. Any failure is written to STDERR and mapped to its exit (login failure → 77, unresolvable / no-oauth / no-device-endpoint provider → 78, bad flag → 64). - parse_
ambient - Map a foreign credential source’s bytes to a brazen
Cred(auth §5.5) — the pure half of discovery, so thebzimpl does only the IO.Nonefor malformed or incomplete input (the no-creds path, likeget). Theclaude_codecase readsclaudeAiOauthinto aCred::OAuth2:expiresAtis MILLISECONDS, divided to absolute unix-seconds once here (the single home for that unit mismatch), andscopesjoin into thescopestring (Nonewhen empty);account_idisNone(Anthropic binds no account id). Theapi_key_envcase is the env var’s value as a rawCred::ApiKey(trimmed; empty/non-UTF-8 ⇒None). - query_
from_ request_ line - Extract the query string from an HTTP request line, e.g.
GET /callback?code=x&state=y HTTP/1.1→code=x&state=y(auth §7.4). PURE, so the bin’s loopback receiver reads the line over the socket and defers the parse here;Nonewhen the request-target carries no?query. - route
- Read the routing decision from argv (§5.10.1). A parse error (an unknown flag, two
combined control ops) routes to
Route::Run, whose lib entry re-parses and surfaces the same error as the authoritative 64 — so routing owns no error path. - run
- The binary in one call (arch §1). Resolves config, reads the request (positional
XOR stdin), encodes, authenticates, sends one round-trip, decodes the framed
response into canonical events, and projects them through the mode’s sink —
returning the POSIX exit code (
mainmaterializes theExitCode). - serve
- Run
bz --serveand return the POSIX exit code (ingress §7). Pre-loop failures are fatal and stderr-only, exactly like every control op: flag parse 64, config (no/invalid[ingress]table) 78, a bind failure 69. Once the loop runs, every failure is a per-connection concern answered in the client dialect (§9) — the process stays up.
Type Aliases§
- Bytes
- One transport body chunk. An alias, so the framers’
Vec<u8>and the body stream speak the same type.