contract store · 10-store.md · 11-snapshot.md · 12-time.md · 13-replica.md · 14-drain.md · 15-endpoint.md · 16-collect.md · 17-merge.md · 18-pull.md · guide · card
Bucket endpoints and leases
The [sync] endpoint decides how each request reaches the bucket: its scheme, its region and the credentials that sign it.
The adapter speaks the S3 object API to AWS S3, R2 and compatible services, and reads a filesystem bucket directly.
endpoint
Bucket endpoint schemes, transport, request addressing and signing, credentials and backend response handling.
schemestest[sync] endpointmapsfile://<directory>to a filesystem bucket ands3://<region>to regional AWS S3.r2://<account-id>selects that account’s R2 endpoint at regionauto.https://<host>uses[sync] region, defaultus-east-1.unsupported-schemetestAny other scheme, or an S3 or R2 endpoint in a build without thes3-syncfeature, raisesSyncEndpointUnsupported, naming the endpoint.Why
because an unreachable bucket refuses when it opens, before a push uploads anythingplaintexttestAnhttp://endpoint opens on a loopback host alone; any other host raisesSyncEndpointInsecure, naming it.Why
because plaintext objects and signed requests are readable and replayable by anyone on the pathaddressingtestS3 and R2 address<endpoint>/<bucket>/<key>path-style, percent-encoding each key segment, and sign every request with AWS Signature Version 4 for services3at the endpoint’s region.credentialstest[sync] access_key_id,secret_access_keyand the optionalsession_tokeneach bindsecret://<name>, hydrated aswhole-value-reference, orenv://NAME, read whole from the process environment, as the bucket opens.credential-unboundtestAn S3 or R2[sync]omittingaccess_key_idorsecret_access_key, supplying a non-reference credential, or naming an unset variable raisesSyncCredentialUnbound, naming the key.Why
because a literal key inconfig.tomlsits in plaintext on every disk and backuprole-credentialstest[sync] credentials = "role"on ans3://orhttps://endpoint signs with workload-role credentials in place of both keys, from the ECS container credential endpoint, then STS web identity, then IMDSv2.Why
because a workload role supplies short-lived keys in place of long-lived stored onesrole-conflicttestcredentials = "role"beside a key credentialcredentialsbinds, or on an R2 endpoint, raisesSyncCredentialConflict, naming the endpoint.Why
because two credential sources for one bucket leave unstated which identity signed a writerole-refreshtestRole credentials refresh 300 s before their stated expiry and never sign once expired; a failed refresh keeps still-valid credentials and retries at the next request.conditional-answerstestA412or409means a failed condition; a404namingNoSuchKeydoes so for anIf-Matchput.501means an unsupported method;403means forbidden credentials. Both followinconclusive.missing-buckettestA404naming a code other thanNoSuchKey,NoSuchBucketincluded, is neither an absent object nor a failed condition: the request fails as transport, naming the code.Why
because a missing bucket otherwise reads as empty, a free lease or a lost compare-and-settransporttestAn incomplete S3 get, head, list page, delete or unconditional put retries within 3 attempts. Connections allow 5 s; responses allow 2 s, 4 s, then 10 s. Conditional puts attempt once.Why
because a resent conditional put whose answer was lost reads its own write as a failed conditionthrottledtestS3 requests retry within 5 attempts after429or503, or500except on conditional puts. Each retry waits a uniform draw below a ceiling doubling from 100 ms to 5 s.Why
because a throttled request never applied, and jitter spreads throttled clientslist-pagestestA list follows continuation tokens until the backend reports completion, returning every key under the prefix in sorted order.
probe
Testing conditional writes with a sentinel object and selecting the backend’s coordination mode.
inconclusivetestAn unsupported-method response, a forbidden response or a transport error raisesSyncProbeInconclusiveand counts as capability not demonstrated.unproventestDeclaringcasagainst a backend the probe did not demonstrate raisesSyncCoordinationUnprovenand stops the push.sentineltestThe probe creates a sentinel under_contextful/cas-probe/, demonstratescaswhen a second create and a staleIf-Matchfail while a currentIf-Matchreplaces it, then deletes it.network-volumetestA filesystem bucket on a mount type outside apfs, hfs, ext4, xfs, btrfs, zfs, tmpfs and overlay resolvessingle-writerwithout a sentinel, naming the mount type; a declaredcasthere meetsunproven.Why
because a sentinel run from one client of a network share cannot observe another client
lease
Exclusive pipeline and compaction writer leases, their commit fences, and cursor commits in the commit log.
ttltestA writer lease grants ownership for 10 min.renewaltesttestThe process holding a compaction lease renews it every 200 s byIf-Matchreplace on its ETag;sync compactrenews while it pulls, folds and pushes.operator-renewtestsync lease renew <table>renews the compaction lease this node holds, forsync compact --held.clock-skewtestBucket leasing assumes the clocks of two machines differ by 30 s or less, and every expiry judgment reads the judging machine’s monotonic clock.Why
because correctness rests on the commit fence, and the skew bound only sets how early a holder stops committingheldtestIf a run finds an unexpired lease, the engine raisesLeaseHeld, names the holder and expiry, and skips the run. The engine retries the run at the next reconciliation tick.stale-fencetesttesttheoremIf a commit-log create, pointer replacement or catalogUPDATEloses its condition to a higher commit fence, the operation raisesLeaseFenced. The associated run or snapshot stays unreadable.not-heldtestReleasing a lease another node holds, or one a later acquisition of the same node fenced past, raisesLeaseNotHeldand leaves the object untouched.cursor-kindtestA cursor whose kind takes no lease reachingcursors/raisesLeaseCursorKindMismatch.local-nodetestA bucket lease attempted under the node idlocalraisesLeaseNodeIdLocal, logging the variable that sets a node id; that machine keeps the machine lease.Why
P3acquiretestAcquisition creates the lease object underIf-None-Matchor replaces an expired or released object underIf-Matchon its ETag. The acquired commit fence is one above the object’s commit fence.pointer-fencetesttesttheoremTaking a table’s compaction lease raises the fence stored in its bucket pointer, so a publish carrying a lower fence loses its condition.network-volumetestA compaction lease on a bucket resolvingsingle-writerundernetwork-volumemeetsunproven, naming the mount type. Acquisition writes no lease object or pointer fence.Why
because a conditional put holding on one machine only lets two machines each take the leasecommit-logtestUnder a machine lease, a run commits by creating the nextcursors/<pipeline-id>/<node-id>/<seq>.json. Acquisition creates an entry carrying its fence. A manifest markedloggedbecomes readable when that log records the manifest.
unsettled: Which process carries out renewal for a pipeline lease? owner: store affects: store.lease