Skip to main content

Module origin

Module origin 

Source
Expand description

Where a persisted AI request came from: the client that produced it, the inbound wire protocol it spoke, and how strongly the client is evidenced.

All three halves are closed enums so ai_requests.client_kind, ai_requests.wire_protocol and ai_requests.client_attestation are CHECK-constrained columns, never free text. This module is the normative specification of client attribution; the hosted gateway documentation restates it for operators.

§Evidence tiers

classify answers “which client sent this request?” by walking a ladder of evidence, strongest first. The winning tier sets client_kind and client_attestation; everything the wire carried is kept in ClientEvidence so a classification can be audited or corrected later.

tierheader / signaltrust
host-tokenbridge principal with x-systemprompt-client-attestation: host-token; the bridge verified a per-host HMAC token on its loopback and stamped x-systemprompt-client itselfcryptographic on the device, channel-bound to the bridge
bridge-secretbridge principal with x-systemprompt-client-attestation: bridge-secret; the caller presented the raw loopback secret, so the host is taken from the lower tierschannel verified, host not
declaredx-systemprompt-client: <kind> from any principal (or passed through on the secret path)client-asserted, closed vocabulary
native-markera structural marker of one harness in the body (NativeMarker): Claude Code’s billing entrypoint or metadata.user_id grammars, Codex turn metadatastructural, unforged in practice
user-agentthe exact first product token of User-Agent (ua_product)weakest tier kept
nonenothing matched; client_kind is otherhonest fallback

internal and unknown are never produced from live gateway traffic: internal pairs with server-side producers and unknown with rows written before attribution existed.

A conflict between tiers (a host token naming opencode under a claude-cli User-Agent) is never rejected: the strongest tier wins and the evidence row records the rest. Two inputs are rejected with 400 instead: an x-systemprompt-client value outside the vocabulary, and an x-systemprompt-client-attestation header from anything but the bridge.

The one wire vocabulary is ClientKind::as_str. The bridge’s own host ids (codex-cli) are baked into HMAC labels and rendered host configs, so they stay bridge-internal and map through ClientKind::from_bridge_host_id / ClientKind::bridge_host_id.

Copyright (c) systemprompt.io — Business Source License 1.1. See https://systemprompt.io for licensing details.

Structs§

ClassificationInput
Raw inputs to classify. principal_is_bridge is the only fact that comes from authentication rather than the request itself.
Classified
conflicting is set when a weaker signal named a different client than the winning tier; the caller logs it, nothing rejects it.
ClientEvidence
Which tier named client_kind, and what the wire carried.
RequestOrigin
Client, wire protocol and attestation of one request, carried together so a producer cannot record one without the others.
StainlessHeaders
The x-stainless-* headers every Stainless-generated SDK sends.

Enums§

ClassificationRejection
A request the gateway refuses with 400. The evidence gathered before the rejection rides along so the rejected row still records what was sent.
ClientAttestation
How strongly the recorded client is evidenced; see the module head for the ladder. Ordered strongest-first so Ord matches precedence.
ClientKind
The client that produced an AI request.
InboundWireProtocol
The protocol a request arrived on. Internal pairs with ClientKind::Internal; Unknown pairs with ClientKind::Unknown.
NativeMarker
A structural marker of one harness found in the request body.
OriginParseError

Functions§

classify
native_marker
ua_product