Pristine.Client.foundation/1 builds the recommended production client profile.
It wires the Foundation retry, rate-limit, circuit-breaker, telemetry, and
admission-control adapters into one provider-agnostic runtime client.
Build A Foundation Client
This direct default_auth example is standalone compatibility. Governed
execution must use governed_authority instead of env-backed default_auth,
direct headers, or direct base URL inputs.
client =
Pristine.Client.foundation(
base_url: "https://api.example.com",
transport: Pristine.Adapters.Transport.Finch,
transport_opts: [finch: MyApp.Finch],
serializer: Pristine.Adapters.Serializer.JSON,
default_auth: [Pristine.Adapters.Auth.Bearer.new("example-api-token")],
telemetry: [namespace: [:my_sdk]]
)authority =
Pristine.GovernedAuthority.new!(
base_url: "https://api.example.com",
base_url_ref: "base-url://example/workspace-123",
credential_handle_ref: "credential-handle://example/workspace-123",
credential_lease_ref: "credential-lease://example/one-effect",
target_ref: "target://example/production",
request_scope_ref: "request-scope://example/widgets/list",
header_policy_ref: "header-policy://example/default",
materialization_kind: "bearer",
bearer_token_ref: "bearer-token://example/one-effect",
redaction_ref: "redaction://headers",
headers: %{"x-authority-target" => "target://example/production"},
credential_headers: %{"authorization" => "Bearer authority-materialized-token"},
allowed_header_names: ["authorization", "x-authority-target"]
)
client =
Pristine.Client.foundation(
governed_authority: authority,
transport: Pristine.Adapters.Transport.Finch,
transport_opts: [finch: MyApp.Finch],
serializer: Pristine.Adapters.Serializer.JSON,
telemetry: [namespace: [:my_sdk]]
)Feature Flags
Pristine.Client.foundation/1 forwards the same top-level Foundation feature
switches used by Pristine.Profiles.Foundation:
retryrate_limitcircuit_breakertelemetryadmission_control
Each feature accepts false, true, an adapter module, or an option list.
Reporter Helpers
Pristine.Profiles.Foundation still exposes the telemetry reporter helpers used
by production runtimes:
events = Pristine.Profiles.Foundation.default_telemetry_events([:my_sdk])
child_spec =
Pristine.Profiles.Foundation.reporter_child_spec(
handler_id: "my-sdk-reporter",
events: Map.values(events)
)When you already have a Foundation client, pass its internal context to the reporter helpers:
handler_id =
Pristine.Profiles.Foundation.attach_reporter(
client.context,
handler_id: "my-sdk-reporter"
)
events = Pristine.Profiles.Foundation.reporter_events(client.context)
:ok = Pristine.Profiles.Foundation.detach_reporter(handler_id)Registry lifetime (Pristine 0.3.1 / Foundation 0.2.2)
Default breaker, rate-limit and semaphore ETS registries belong to Foundation's
supervised registry owner. Short-lived HTTP workers no longer create competing
default tables or transfer them to Erlang :init on exit. Foundation recovers
stale default caches after owner restart; that restart resets resilience state.
Explicit registries are caller-owned and need no heir. Create shared explicit registries in a long-lived supervised process and pass them via adapter options. A deleted anonymous registry is an error, not a reason to silently bypass its limits with a replacement table. Named registry creation follows Foundation's normal named-registry behavior. This ownership fix does not add transport queue bounds or physical HTTP cancellation guarantees.