Skip to main content

Crate flint_lean

Crate flint_lean 

Source
Expand description

flint-lean: the checkout/publish syncer core (plan of record: docs/plans/flint-lean-plan.md v2).

Lean is a SEPARATE front end from the hub: no NFS, no daemon in the data path. An agent pod gets a full local checkout on an emptyDir (real ext4/APFS POSIX), and a syncer publishes snapshots to the bucket through a barrier. Durability is RPO-shaped (the flush floor); coherence is snapshot-level (the subtree manifest CAS is the atomic commit point). This module reuses tier::store (ObjectStore, GenerationStamps, conditional puts, the epoch cell) as a library and deliberately does NOT reuse the hub’s flush/arbitration machinery — the plan pins that: the hub’s 412 arbitration is LOCAL-WINS-overwrite (tier/flush.rs), which is exactly wrong under HITL second writers.

The protocol here is the shipped shape lean/PROTOCOL.md writes out, from its model lean/formal/LeanP1.tla (the shape since the simplification of 2026-09-25: P1, P2, M1). PROTOCOL.md has every rule with the invariant it holds up and the model world that fails without it; the load-bearing ones, in brief:

  • Every write lands at a fresh immutable handle (files/<path>@<flush>), and the pointer CAS is the only commit — a writer’s and the gateway’s alike. Nothing overwrites a handle.
  • The gateway commits each UI verb itself (P2): a save PUTs a fresh handle, then ONE pointer CAS that lands only over the version the UI read (else 412); a rename or a delete is one CAS. It never takes the writers’ lease. The request cell (inbox, .flint/lean/inbox) carries only the two verb requests, “please publish” and “please pull” — no entries, no removals, no window.
  • The barrier: consume (the cheap path: the scan trigger) → scan → upload → claim the lease → verify the uploads (R4a) → install, a three-way merge onto the CURRENT document with the baseline as the merge base (mine wins modify/modify; R7 records theirs; a delete over theirs applies, theirs kept, M3) → collect → finish (the baseline follows what landed).
  • What a commit stops citing is retired, not deleted: logged at the CAS and reaped only once G old (M1), so a reader that loaded less than G ago can still fetch it. The orphan sweep runs only under the lease (R4b) and spares a save in flight (G3).
  • Takeover rotation: a successor rewrites the document before serving, so a deposed holder’s pointer CAS 412s; the worker-facing verbs are epoch-validated per request.
  • Restart matrix: marker present ⇒ never re-materialize (a re-checkout would resurrect unpublished deletes); reload the persisted baseline, rescan, self-recognize the lease via the persisted incarnation id (emptyDir-scoped — a replacement pod gets a fresh identity and takes the takeover path).
  • Deletion basis: a path is delete-eligible only if absent in two consecutive scans AND present in our own baseline (the rename-vs-walk guard).

Re-exports§

pub use gauges::status_report;
pub use gauges::Gauges;
pub use gauges::StatusReport;

Modules§

barrier
The publish barrier (plan §2.1, seven steps) — the machine lean/formal/LeanSubtree.tla checks. Order is load-bearing: consume → scan → intent/window → uploads → manifest CAS (merge) → GC deletes LAST → baseline rewrite.
checkout
Checkout + the restart matrix (plan §2.1).
chunk
Content-defined chunking of the manifest’s key stream (docs/plans/flint-lean-chunked-manifest-design.md §3).
chunkcache
A local copy of manifest chunks, kept by content address (latency plan 2026-10-23, lever A: docs/plans/flint-lean-latency-plan-2026-10-23.md).
conformance
Does this store actually enforce the conditions lean writes under?
control
The .flint/ control namespace (boundary-verbs plan §2.0, D0/D11): the agent’s side of the file protocol.
docview
A manifest document seen chunk by chunk (latency plan 2026-10-23, lever G, §12).
gauges
.flint-sync/gauges.json — the Phase-3 observability minimum (§2.6; review ledger OF-6).
inbox
The request cell: ONE CAS document per workspace carrying the two verb requests a party outside the pod can make (plan §2.5) — “please publish” and “please pull”.
lease
The subtree lease, held for ONE BARRIER’s commit section (design 2026-09-13, docs/plans/flint-lean-writer-lease-and-gated-assessment.md §4), with a FIFO ticket so W writers wait at most W barriers.
manifest
The lean subtree manifest: one JSON document, CAS-written, the atomic commit point every reader trusts (checkout, sync, DR).
metrics
/metrics (D15, §8 Q5) — Prometheus exposition rendered from the SAME struct gauges.json is written from.
news
The news poll (latency plan 2026-10-23, lever B).
reader
Read access (per-user access design §4.4): the floor tick of a syncer that follows the workspace and never writes to the bucket.
scan
The barrier’s scan-diff (plan §2.1 step 2).
sentinel
The boundary verbs: .flint/publish and .flint/sync (plan §2.1, §2.2 — D1, D2, D3, D3.1, D12).
state
Durable emptyDir bookkeeping (plan §2.1 “restart matrix”).
sync
The sync verb (v1, HITL — decided §9 Q4), plus the scoped form the .flint/sync sentinel invokes (boundary-verbs plan §2.2, D4). Harness- or sentinel-invoked, never background.
trace
The protocol event trace (FLINT_SYNC_EVENT_TRACE=1, or spec.eventTrace on a deployed workspace).
tracked
Collections that remember which keys changed since they were loaded, so the baseline persists what a save changed rather than the whole document (lever D, docs/plans/flint-lean-latency-plan-2026-10-23.md).
uds
The UDS door (§2.5, Phase 5) — .flint-sync/ctl.sock.
untracked
Finding 10: an upload whose commit never came.
verbs
The one-shot verbs, and which of them holds the publish fence for its whole run.

Structs§

LeanConfig
Syncer
Everything a syncer operation needs: store + config + durable state.

Enums§

Access
What this syncer may do to the bucket (per-user access design §4.4).
LeanError
SentinelMode
Sentinel posture knob (D0.4). auto = verbs on unless the pre-existing-.flint/ pre-flight trips; force accepts consumption of pre-existing sentinel-named files.

Constants§

CHUNK_CACHE_DIR
The chunk cache’s directory inside the state dir (chunkcache).
CHUNK_FETCH_PARALLELISM
Chunk GETs a manifest load keeps in flight (LeanConfig:: chunk_fetch_parallelism). A chunk is about 1 MiB, so this many is 16 MiB in flight; the bodies are all held until the document is assembled anyway, as they were when they were fetched one at a time.
CONTROL_DIR
The workspace-local control namespace (boundary-verbs plan D0): the agent’s side of the file protocol. Reserved exactly as the gateway reserves .flint/ on the HTTP side (flint-lean-gateway’s path_ok) — the scan skips it, classify never makes it delete-eligible, and checkout never materializes a files/.flint/... citation into it.
EXIT_REFUSED
Process exit code for LeanError::Refused (sysexits EX_CONFIG). Mirrored as SYNCER_EXIT_REFUSED in the CSI node plugin, which does not depend on this crate; drill leg S22 is where the two are checked against each other.
LEAN_DIR
Reserved control namespace inside the subtree prefix. Never scanned, never part of a checkout, never GC’d by the barrier.
MAX_FLUSH_LEN
The longest flush id a handle carries: the gateway’s ui-<secs>-<uuid> with a u64 of seconds (a barrier’s is a bare uuid; an ingress copy’s, ingress-<etag>, adopts an object whose bare key already fit).
MAX_KEY_BYTES
The longest key the stores lean runs on take: 1,024 bytes of UTF-8 on S3 (KeyTooLongError) and on GCS.
SENTINEL_PROTOCOL
Protocol version advertised in .flint/capabilities.json.
STATE_DIR
The syncer’s durable bookkeeping directory inside the workspace (emptyDir-scoped: survives container restarts, dies with the pod).
SYNCER_VERSION
This binary’s version, echoed to the agent (capabilities.json) and to the operator (the lease cell’s echo, §2.6). Both mixed-version holes — agent↔syncer and operator↔syncer — are detected by comparing what is RUNNING against what was asked for, and neither comparison exists without a version on the running side.
WHOLE_PUT_MAX
Default whole-object publish ceiling; larger files go through the multipart compose path (tier/flush.rs uses the same 64 MiB split).

Functions§

now_unix
Seconds since the epoch, saturating at 0 on a clock before it.
ui_flush
The gateway’s flush id for a UI write’s handle: ui-<added_unix>-<uuid>. The time is the order a consume reads off two UI handles of one path (design 2026-09-19, R7’s “later”): a citation that moved to a LATER gateway write supersedes an entry, one that moved to an earlier one leaves it live. One gateway’s clock orders its own writes exactly; two replicas’ clocks are the residual, and a tie or an inversion between them costs a surfaced conflict, never a silent drop.
ui_flush_added
The added_unix a UI flush id carries; None for any other flush.

Type Aliases§

LeanResult