Skip to main content

Module lfs_adapter

Module lfs_adapter 

Source
Expand description

The LFS batch/transfer adapter (wave 9) — the storage-side logic of the LFS protocol’s batch/checking and byte paths, as a substrate surface under the lfs feature (ADR-022 §1–2; lfs.md §1–2; the substrate-side piece of ADR-025’s LFS-surface member). The alkgit core has no native LFS op set (git-lfs speaks HTTP only) — the door is the alkhttp lfs feature (family infrastructure); this surface is what that door consumes, front-door-blind: it carries the storage-side mapping and never touches HTTP.

§The adapter/door split (the wave’s spec-level call, pinned here

for the gate)

ADR-025’s neutral record names the door-side batch mapping as riding alkblobs directly; the row assertion is the composition-owned piece only this surface carries. Drawn exactly:

The door’s side (never here): the JSON batch protocol parsing and the HTTP route surface; the auth plumbing (alkhttp ADR-073’s Basic-userinfo tolerance on the batch); the anonymous-public anon identity synthesis (the adapter refuses an absent identity — the door synthesizes the identity, the grant short-circuits on the public-repo flag); href/token minting (LfsHrefMint is the mint-input carrier — the door mints the absolute URLs with per-action Authorization; the adapter never mints a URL or a door token); HTTP Range-header parsing and the 206/416 responses; the object-size ceiling choice (the budget per assembly, the door’s LfsAdapterConfig::max_object_bytes); and the batch request’s transfers negotiation (the adapter carries no negotiation input and answers basic — the door reads the client’s list and refuses a request that excludes basic before the batch reaches the adapter; the wave-9 gate’s recorded door duty, lfs.md §1’s pinned shape).

The adapter’s side (this surface): the batch’s per-object existence answered over the ops control plane — blobs/stat through an OperationContext built with the caller’s identity and the wired ownership provider (the POC-L door’s DirectOps binding shape as a substrate surface); the response objects’ shapes ({oid, size, authenticated} + the per-object action grant-carriers); the row assertion at check time (the moment the server learns the pair — lfs.md §3, over the LfsRows surface); the byte paths: the pre-keyed put (upload) and the ranged fetch with per-window slice-digest verification (download); the wired-provider requirement (never the static fallback).

What rides alkblobs directly (no substrate surface): the JSON batch protocol itself is the door’s; the facade seam (Store::put_as(GitObjectSha256, len, stream) / read_range) is the in-process embedder alternative with no ops plane at all — deliberately not re-exposed here (the embedder binds SubstrateAssembly::blobs directly; the adapter is the ops-plane surface). The wire ops (blobs/put / blobs/fetch, the channel data plane) remain the fleet/remote consumer’s form — the DirectOps-vs-loopback binding choice sits door-side.

§The pinned protocol facts (lfs.md §1, riding the shapes)

  • hash_algo answers sha256 only: a batch carrying any other declared algorithm is refused (LfsAdapterError::HashAlgo — the door’s 409). verify is not served: no batch path produces a verify action.
  • Transfer is basic; the download action’s mint input is the whole media oid (range negotiation never rides the batch — the client’s Range rides the transfer GET).
  • The upload key is formable in advance (ADR-022 §1: under Algorithm::GitObjectSha256 the oid is the digest — the key is [0x04] + oid bytes): existence is a direct blobs/stat on the formed key (the translate-then-stat is direct; there is no mapping row, and no have use — that is the replication diff verb).

§The byte paths (ADR-022 §2)

  • Upload — the pre-keyed put. The offer carries the claimed oid and the batch’s size; a size-less offer is a protocol error (LfsAdapterError::SizelessOffer — LFS clients always send size; the door refuses before the body). The put rides the put handler’s contract minus the channel: the one-read tee (a sha256 pass alongside a bounded pipe the facade put consumes concurrently via put_as(GitObjectSha256, Some(len), …)), the claim cross-check before the facade’s EOF — a body the derivation contradicts kills the put pre-commit (LfsAdapterError::MislabeledBody: no stored content, no held pin — the zero-residue discipline the put’s stage hygiene carries on both tiers) — then the custody hand-over through the OpsContext verbs: fleet (mint_fleet, then the immediate confirm — the upload is complete, so the token’s ticket retires at the confirmation and the mint boundary’s admission cap stays live per upload, ADR-022 §5; the fleet pin row’s TTL is the durable protection — a dropped unconfirmed ticket would hold an admission slot until process end, the wave-9 gate’s fix) or non-fleet (mint_custodial + confirm, the LFS pattern POC-L validated; a mint refusal at the admission cap is LfsAdapterError::MintRefused, answering the already-committed put honestly). The reference row is asserted at upload time too (batch check or upload — lfs.md §3).
  • Download — the ranged fetch. Every download serves verified windows: the requested range (or the whole entry) is split internally at LfsAdapterConfig::window_bytes and each window rides Store::read_range, whose ADR-006 slice digest is checked mid-flight — a window’s bytes are yielded only after the independently computed sha256 of exactly the returned window bytes matches the read’s slice digest; a mismatch aborts the stream mid-flight (the caller re-fetches — the ranged arm’s answer is the mid-flight-verified shape). The resolved span is budget-gated by LfsAdapterConfig::max_object_bytes — every form the adapter will actually produce counts (the range-less whole serve, the open-ended resume, any resolved span; bytes=0- is a whole download and refuses over the ceiling — the wave-9 gate’s fix, the whole-arm budget’s bypass closed). Verification, stated precisely (the gate’s fix): a whole-span download additionally rides the end-to-end oid digest check — the windows’ bytes accumulate into one sha256 pass, and the finished digest is compared against the key’s derivation digest (the identity family’s digest is the raw content’s hash, so the comparison is the oid verification the large tier’s reads carry no re-derivation for) before the last window yields. A partial span’s windows carry the length + slice checks only — the store interior’s ADR-006 digests, not an oid conclusion. The pinned window-splitting call (drawn against lfs.md’s “the door owns window splitting”, flagged for the gate): that fact governs the door binding the ops byte-path (the loopback/remote forms, where fetch_max_total_bytes bounds the op’s ranged arm). This side of the HTTP boundary the adapter owns the arithmetic: a download call splits internally at window_bytes per verified window; the door’s HTTP work is Range parsing and the budget, not window counting.

§The wired ownership provider (alkcall ADR-048’s posture, composed)

The adapter takes the ownership provider as a required constructor argument — there is no Option, no static path, and every context it builds wires ownership: Some(provider): the static Identity.resources fallback is unreachable through this surface (the POC-L gateway-gap regression’s posture; the battery pins it — an identity carrying a static resources claim is refused unless the wired provider grants). The shipped provider is LfsGrantProvider: alkgit’s registry composed onto the ops ACL — the same per-repo grants the git surface composes (ADR-011’s posture), served through the cached read provider’s sync resolve. alkcall ADR-048’s loud default guards the gateway dispatch spine (the wire path); here the guard is the constructor requirement plus the battery. The anon composition is door-side (above).

Structs§

LfsActions
The per-object action grants (the LFS shape: upload rides the absent objects’ answers for an upload batch, download the present ones for a download batch; at most one side is populated per response object).
LfsAdapter
The batch/transfer adapter — the storage-side surface the alkhttp lfs door consumes (ADR-022 §1–3, lfs.md §1–2 — the adapter/door split is the module doc). Construct over the object pool, the rows surface, the wired ownership provider (required — see the module doc), and the config knobs.
LfsAdapterConfig
The batch/transfer adapter’s knobs (the door budgets the ceiling; the adapter splits at the window). Defaults are the POC-L datums: the 32 MiB split window and the fetch_max_total_bytes-shaped 64 MiB object ceiling (raised per assembly to trade opens for windows — lfs.md §2).
LfsBatchObject
One batch request object: the pointer’s oid and its mandatory size (the batch’s size is mandatory — LFS clients always send it; the door refuses the size-less form before this surface).
LfsBatchRequest
The batch/checking request as the door hands it over (post-JSON, post-auth plumbing — the identity resolved, the operation mapped).
LfsBatchResponse
The batch/checking response — the transfer is basic and the served algorithm is sha256 (the pinned protocol facts; the door serializes the JSON shape).
LfsDownload
The download’s verified-window stream — an AsyncRead fed by a pump that splits the requested range at the configured window size and yields each window only after its mid-flight slice-digest check passes (the module doc’s byte-path section) — ADR-022 §2 as amended (the download byte path’s verification posture). A failed window check or a failed read surfaces as an io error at the yield point (already-delivered windows stand; the caller aborts and re-fetches). The pump ends at EOF; a zero-length whole read is an empty stream (the entry’s zero-length entry served).
LfsGrantProvider
The wired ownership provider — alkgit’s registry composed onto the ops ACL (the batch’s authorization posture: lfs.md §1 — the per-repo grant governs batch access, the ADR-011 posture composed onto the ops ACL). The alkblobs ops specs gate on blob-namespace resources whose id is the payload’s namespace — the repo id; this provider answers with the same authorize policy function the git surface composes: read granted (or anonymous-public — the door’s synthesized anon identity rides the public-repo flag here), write per the grant monotonicity (manage ⊃ write ⊃ read). Unknown repos deny by default — the unknown ≡ unauthorized posture. Served through the cached read provider’s sync resolve (the hot path — no await, no round trip; a stale cache delays revocation until the next refresh, the same posture the git serving path takes).
LfsHrefMint
The action-grant carrier the response objects hold — the mint inputs, never a URL: the door mints the absolute href and the per-action Authorization from these (front-door-blind — no URL or door token is formed here).
LfsObjectAnswer
One batch response object — the pinned shape {oid, size, authenticated} plus the optional per-object error/actions branches. authenticated is true whenever the object is answered: the request rode the wired ownership provider’s grant (the ops ACL path), so every served action is server-authorized — the anonymous-public composition (the door’s synthesized anon identity on a public repo’s read) answers the same way.
LfsObjectError
A per-object error, carried in the response object (the LFS per-object error shape — the object’s error field; the HTTP mapping stays the door’s).
LfsRange
The byte range a download call serves: [offset, offset + len) with len = None meaning to the entry’s end (the door maps the HTTP bytes=a-b / bytes=a- forms onto the explicit count).

Enums§

LfsAdapterError
The adapter’s error surface (thiserror family; message-only — the engine source types stay off the surface, the row store’s StorageError text is carried). The whole-batch failures (forbidden, hash-algo) and the transfer-path failures are errors; per-object failures ride the batch response’s error objects, not this surface.
LfsBatchOperation
The batch API’s operation half (the door maps the wire’s "upload" / "download" onto it).