lodestone-client
lodestone-client is the current-only asynchronous Rust client for the
Lodestone API request/reply protocol and canonical subscription gRPC
stream. It depends on the generated leaf lodestone-wire DTO crate and
does not expose internal Core RPC, storage, authority, Elasticsearch, RESP, or
server types.
Cargo consumers declare only an exact lodestone-client version from
crates.io. The same-version lodestone-wire package is an exact transitive
dependency; a consumer does not need a direct wire dependency, Git pin, path
patch, or custom registry.
Construct one CellTransport per exact cell and operation class, then attach
lightweight CollectionSession values containing a validated connection
profile and caller-owned CredentialProvider. Sessions for different
Collections share the bounded transport only when endpoints, TLS server name
and trust, cluster/schema identity, operation class, and pool limits match
exactly. Credential material remains session-local and request-scoped. A
bounded transport LRU may retain only verified non-secret metadata, which each
session rechecks against its complete profile before use. Create CallOptions, then pass
those options to CollectionSession::connect. Client remains the ordinary
Collection-session spelling used by generated methods. CallOptions::new converts its duration to one absolute
deadline immediately; clones retain that exact deadline. Connection verifies
TLS and ALPN, authenticates, discovers the exact schema and stream, and
validates the cluster, Collection, expected principal, configuration generation,
and binding revision before returning. Reuse the same options for a caller workflow when
discovery, binding, preparation, submission, and resolution share one budget.
Endpoints rotate in profile order; a read may move to the next endpoint only
within its bounded retry policy. Mutations retry only before the submission
boundary.
State helpers accept a semantic StateIndex, enforce the 254-byte key bound,
and provide get, colocated mget, absolute-expiry set, and delete.
Callers retain a durable StateActionId for writes. The helpers perform
prepare/submit/resolve and return StateWriteOutcome, preserving retired,
reset, and indeterminate outcomes rather than claiming success. Secret
material is never Clone, Debug, serialized, or included in errors, and is
overwritten on drop.
append_exact, mutate_document_exact, and reconcile_index_exact share one
recovery contract. ExactWorkflowRecoveryV2 retains the first absolute effect
deadline, caller action/request digest, exact cluster/Collection/index scope,
prepared locator, monotonic revision, and closed phase. The executor persists
submission_started before a submit RPC, so a restart resolves the original
locator instead of treating a missing response as proof of no effect.
Replicated applications inject an Arc<dyn ExactWorkflowRecoveryStore> with
with_recovery_store. Its load and single-key compare_exchange must be
linearizable and durable; a conflict returns the observed V2 value. The
caller-selected workflow key is stable and collision-resistant, stays outside
the recovery value, and must not contain credentials or raw requests. Deleting
or reassigning a key while an effect is unresolved destroys the caller's
recovery guarantee. FilesystemExactWorkflowRecoveryStore provides the same
contract over the sealed local journal. Format-1 recovery values and local
journal directories require a fresh start. Callers without a store must persist
the returned V2 value and pass it back with with_recovery.
Once submission may have happened, the helpers resolve the original locator
and never prepare a replacement action. reconcile_index_exact creates only an
absent exact definition and reports a conflict instead of updating an existing
index.
This package is an unreleased development artifact. It has no protocol downgrade or compatibility mode.
Document-bulk and retained-append callers derive the request batch_id with
the re-exported
bulk_batch_id(&Identity, &Resource, &[Digest]).
It rejects malformed, zero, duplicate, or over-bound action identities and
preserves caller order. There is no append-specific alias or predecessor hash.
The direct hyper-util and tower dependencies reuse versions already in
Core's dependency closure. Only TokioIo and service_fn are enabled so the
subscription channel can use the crate's TLS-1.3-only rustls connector instead
of a broader transport default. No native/system dependency is added.