Optional caller-started bounded discovery cache; no timers or background refresh.
start_link/1 accepts :name (GenServer name), :max_sources (64, 1–4,096),
:max_in_flight (8, 1–256) and :clock (Unix seconds, default system clock).
Source identity includes all configuration and trust roots. A full cache
returns :cache_overloaded; it never silently evicts revocation tombstones.
Pending waiters are bounded to 32 per in-flight capacity slot.
resolve/4 accepts :algorithms (all HTTP algorithms by default), :timeout
and :clock. It fetches on expiry/miss, single-flight per source, returns
{:ok, Discovery.Resolution} or {:error, Discovery.Error}, and never serves
stale keys after failure. Unknown keys in a fresh set do not trigger refetch.
In thumbprint mode, source revocations and tombstones reject before fetching.
In directory ID mode, they filter computed thumbprints after discovery; a
matching directory ID cannot override or become a revocation identity.
refresh/2 explicitly fetches even during negative freshness, immediately
replacing the old snapshot on success. Failures retain the last observed
snapshot without extending its freshness. If it is stale, calls within
negative_ttl return :source_unavailable without another connection.
CIMD failures are never cached, as required by CIMD-02 Section 5.2.
No-store/no-cache snapshots serve only current waiters and are never retained.
remove/3 persistently denies a thumbprint for that source, including across
refresh and invalidation. invalidate/2 discards freshness and cancels pending
fetches, retaining tombstones. Both return :ok or a bounded error. Removing
the source's denial requires a caller-created new cache/configuration.
Refresh returns {:ok, KeySet} or a bounded error. Last-waiter cancellation
kills the socket-owning fetcher; cache termination also cancels all fetches.
Summary
Functions
Returns a specification to start this module under a supervisor.
Discard a snapshot and pending work, preserving explicit removals.
Explicitly replace a source snapshot on success. Failures retain the last observed snapshot without extending its freshness; stale keys are never served.
Deny a thumbprint persistently for this cache and source.
Resolve a source-selected key ID; misses/expiry fetch under caller limits.
Start the explicitly caller-owned cache.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec invalidate(GenServer.server(), RequestSeal.Discovery.Source.t()) :: :ok | {:error, RequestSeal.Discovery.Error.t()}
Discard a snapshot and pending work, preserving explicit removals.
@spec refresh(GenServer.server(), RequestSeal.Discovery.Source.t()) :: {:ok, RequestSeal.Discovery.KeySet.t()} | {:error, RequestSeal.Discovery.Error.t()}
Explicitly replace a source snapshot on success. Failures retain the last observed snapshot without extending its freshness; stale keys are never served.
@spec remove(GenServer.server(), RequestSeal.Discovery.Source.t(), binary()) :: :ok | {:error, RequestSeal.Discovery.Error.t()}
Deny a thumbprint persistently for this cache and source.
@spec resolve( GenServer.server(), RequestSeal.Discovery.Source.t(), binary(), keyword() ) :: {:ok, RequestSeal.Discovery.Resolution.t()} | {:error, RequestSeal.Discovery.Error.t()}
Resolve a source-selected key ID; misses/expiry fetch under caller limits.
@spec start_link(keyword()) :: GenServer.on_start() | {:error, RequestSeal.Discovery.Error.t()}
Start the explicitly caller-owned cache.