# Architecture

This document describes the runtime architecture implemented in `mooncake-store-rs`.

## Design Goals

- Keep the public store programming model close to Mooncake
- Reuse Mooncake TE/TENT for the data path
- Avoid a dedicated master on the route hot path
- Keep metadata backends responsible for leases, segments, route policy, handoff, and `MetadataOnly` route persistence
- Make lifecycle changes, reclaim, and routing explicit in the client

## Hot-Path Invariant

Steady-state request hot paths must not depend on backend round trips.

- Redis, etcd, admin RPC, and other backend-owned control surfaces must stay off normal per-request read and write latency paths
- hot paths may use local snapshots, maintained caches, authority indirection, or exact maintained indexes instead
- `MetadataOnly` remains a bring-up and debugging mode rather than the normal performance target
- if a feature proposal would reintroduce direct backend reads or writes on every request, the design is wrong until the hot-path dependency is removed

## Component Model

| Component | Responsibility | Hot Path |
|-----------|----------------|----------|
| `StoreClient` | User-facing API, local state, batching, reclaim scheduling | Yes |
| `RouteOperations` / `RouteDirectory` | Operation-level route table facade plus lookup/CAS implementation | Yes |
| `ControlPlaneClient` | Peer-to-peer control transport for route, allocator, eviction, and migration RPC | Yes |
| `StorageOwnerState` | Local replica tracking, CLOCK eviction, route-aware reclaim | Yes on storage nodes |
| `MetadataBackend` | Leases, segments, route policy, handoff, and `MetadataOnly` route persistence | No for default `EmbeddedWrh` route lookups |
| `TentEngine` / `TentTransportFactory` | Data transfer and remote segment access | Yes |
| `LocalAllocatorState` | Local segment reservation and release | Yes for local storage |

```mermaid
graph LR
    A["Store API"] --> B["StoreClient"]
    B --> C["RouteOperations / RouteDirectory"]
    B --> D["Allocator"]
    B --> E["ControlPlaneClient"]
    B --> J["StorageOwnerState"]
    B --> F["TentEngine / Transport"]
    C --> G["MetadataBackend"]
    D --> G
    J --> C
    J --> D
    E --> H["Peer client control plane"]
    E --> J
    F --> I["Peer client segment"]

    style B fill:#e3f2fd
    style C fill:#e8f5e9
    style D fill:#fff3e0
    style E fill:#ede7f6
    style J fill:#fce4ec
    style G fill:#f3e5f5
```

## Route Control

### Default mode: `EmbeddedWrh`

In the default route mode, the client chooses route authorities with embedded weighted rendezvous hashing.

- candidates come from live client leases
- only compatible, route-capable clients are considered
- the top `route_topk` authorities are selected per key
- the highest-ranked authority is the CAS primary
- the remaining `route_topk - 1` authorities are mirrored authorities
- route reads and route CAS go to authorities through the client-owned control-plane transport
- if the mirrored set does not resolve a key, lower-ranked authorities in the same WRH ordering can still be queried

This keeps object route lookups on the authority mesh and off the metadata hot path in normal `EmbeddedWrh` deployments.

`mooncake-store-route` owns the route-control request semantics. It defines the
route control request/response envelope, dispatches inbound route-authority
requests to the local authority service, and turns outbound transport replies
back into route lookup/CAS/list results. `mooncake-store-client` owns the
control-plane transport implementation: tonic channels, control streams,
unary fallback, timeouts, and protobuf encoding. Non-route control services
such as allocator, eviction, and migration remain in `mooncake-store-client`.
Client maintenance flows that already know the affected object key, including
drain, migration, and shrink, update object routes through the same
`RouteOperations` CRUD/CAS facade as put, get, delete, and exist paths. They do
not write directly to selected route authorities.

The route crate is split into three route-specific layers:

- `shim`: public object route operation and integration shim, including `RouteOperations`, `build_route_directory`, hit reporting, and authority/membership contracts
- `table`: single-authority local route table storage, CAS, and indexes
- `mesh`: distributed route-authority protocol, including Embedded WRH selection, primary CAS, mirror/repair/fallback, local authority binding, and per-authority table registration

Each route authority maintains an exact `replica owner -> ordered object key` index. Owner maintenance
queries use cursor pagination with a fixed 256-route default and maximum page size; compatibility
maintenance visitors consume these bounded pages until the response omits `next_cursor`.

Owner maintenance consumes pages through a visitor and retains only the current authority pages.
The compatibility `Vec` API has a fixed 256-route total limit and returns an explicit error when a
continuation exists. Custom authority services keep source compatibility and fail closed until they
implement the paginated service method. `MetadataOnly` applies the same fixed compatibility limit.

Route authority policy is bootstrap-validated through metadata:

- every client starts with a local `route_control` (cluster-level, fixed at startup) and `route_topk` (fallback, overridable via tenant policy)
- the first client in a metadata keyspace writes the default cluster route policy with create-if-absent semantics
- runtimes then resolve the effective route policy from the stored metadata key for their default tenant, otherwise the default cluster policy
- later clients must match that effective policy or startup fails

This keeps route-authority fanout deterministic across the cluster instead of letting each client silently pick a different authority set size.

### Alternative mode: `MetadataOnly`

`MetadataOnly` bypasses client authorities and stores object routes directly in the metadata backend.

| Route Mode | Route Read Path | Route Write Path | Best For |
|------------|-----------------|------------------|----------|
| `EmbeddedWrh` | Authority RPC across ranked WRH authorities | Authority CAS with mirrored top-k publication | Normal deployments |
| `MetadataOnly` | Metadata backend | Metadata backend | Simpler debugging and bring-up |

## Membership Snapshot Model

`StoreClientBuilder::build(...)` publishes the client lease, prewarms a live-client snapshot, and then starts a background membership sync worker.

The shared snapshot is the membership truth used by the hot request path.

- route-authority selection reads the cached snapshot
- routed placement reads the same cached snapshot
- runtime lease lookup and preferred-storage resolution read the same cached snapshot
- successful background refresh replaces the whole snapshot
- failed refresh keeps the last successful snapshot available

This keeps `list_live_clients()` off the normal request path. Metadata still owns the durable lease set, but request-path consumers read a locally cached view that is refreshed asynchronously.

The same background worker now also maintains the tenant-root quota-policy hot cache used by write admission:

- tenant quota policy is cached per tenant root instead of being re-read from metadata for every object write
- the default tenant's root quota policy or cached absence is seeded during client build, so the first steady-state request does not need a backend lookup just to learn that default-tenant policy state
- the cache shares the same worker thread and timer as membership refresh
- the worker prunes idle tenant-policy entries and opportunistically refreshes recently used stale entries
- hot writes still refresh a missing or stale tenant policy on demand when needed

This keeps membership and tenant-policy maintenance on one metadata-cache loop without turning tenant policy into a global full-scan snapshot.

The membership snapshot is runtime cache, not protocol configuration:

- membership snapshots are refreshed in the background
- route policy is durable cluster configuration stored in metadata
- request-level tenants affect scoped object keys, not the cluster-wide route-authority policy

## Write Path

A write is split into route resolution, allocation, transfer, and route publication.

For routed batch writes, remote replica transfers are coalesced by tenant and scratch-window
capacity before route publication. Large same-tenant batches therefore pay one transfer-completion
wait per chunk instead of one wait per object.

If a routed write fails during remote transfer before the object route is published, the client
releases the prepared allocations, quarantines the failed remote storage runtime, refreshes its
membership snapshot, and retries placement when the request is not pinned to a hard required
segment. This keeps transient storage-owner transport failures from escaping into Python backup
threads as fatal exceptions.

For routed batch writes, retry placement re-ranks candidates after each membership refresh instead
of reusing only the pre-failure ranking. When a rollout removes one runtime and introduces a
successor between attempts, the retried batch can move onto the newly visible live runtime instead
of exhausting only the stale pre-refresh owner list. The reserve stage now uses the same retry
envelope: transient `no placement candidates` / `not enough writable owners` windows back off
briefly, refresh membership again, and wait for a standby successor to become active before the
batch gives up.

Delete follows a rollout-era convergence rule now. If a route delete CAS loses to a fresher
still-active route version during cleanup or handoff, the client only retries when metadata can
prove that the fresher route is a targeted hot-upgrade or standby-promotion successor for the same
replica lineage. Ordinary delete-versus-rewrite races, including same-payload rewrites, still
surface a conflict instead of deleting the fresher rewrite.

Segment-announcement metadata faults such as missing or non-contiguous published storage target
chunks are treated as stale segment state first. The client invalidates cached segment state and
may retry the write, but it does not quarantine the touched storage runtimes on that signal alone.
Remote transfer planning splits each request at both local registration limits and the storage
target chunks published in the target segment announcement. The route still records one logical
replica, but the transport only receives slices that fit inside one registered storage target
chunk, matching classic RDMA transfer-engine requirements when a segment is backed by multiple
contiguous registrations.

Classic TE P2P deployments also publish the TE segment descriptor in the Store-RS segment
announcement. The logical `segment_name` remains the allocator and route identity, while
`transport_endpoint` names the peer RPC endpoint and `transport_segment_descriptor` carries the
full TE RAM descriptor that Redis-backed TE metadata would otherwise store under
`mooncake/ram/[segment_name]`. Before `openSegment`, Store-RS preloads that descriptor into the
local TE cache so P2P opens have the same device/GID/buffer view as Redis metadata opens without
adding a backend lookup to the request path.

Replica routes keep two separate coordinates. `ReplicaRoute::offset` is the actual transport
target address used by TE/TENT and is the byte location of the stored payload in the segment
storage target map. `segment_offset` belongs to the local allocator and reclaim path. Segment
announcements publish the exact `logical_offset -> target_offset` storage chunks derived during
local registration; writers use those chunks as the only allocator-to-transport mapping source.
Scratch buffers are registered for staging only and are never published as object-addressable
storage. Local direct reads, batch reads, and drain migration translate `offset` through the
selected segment's storage target map before copying from local storage, so local and remote reads
observe the same bytes even when the transport target coordinate is not the process virtual address.

```mermaid
sequenceDiagram
    participant App
    participant Client as StoreClient
    participant Route as RouteOperations
    participant Alloc as Allocator/ControlPlane
    participant Evict as Storage Owner State
    participant Peer as Remote Storage Client
    participant TE as TE/TENT

    App->>Client: put / batch_put
    Client->>Client: resolve replication policy
    Client->>Alloc: reserve local or remote segment space
    Alloc-->>Client: reservations
    Client->>TE: write buffers into chosen segments
    TE-->>Peer: transfer payload
    Client->>Route: publish ObjectRoute
    Route-->>Client: route version / CAS result
    Client->>Evict: track local replicas
    Client->>Peer: batch track remote replica routes (best effort)
```

### Placement rules

The current implementation supports:

- local-only writes
- routed writes to remote storage nodes
- local-first placement with remote spillover
- explicit preferred segment hints
- explicit preferred storage owner hints
- multi-replica placement

The default request policy prefers local storage when available. When local capacity is insufficient, the client allocates on remote storage nodes selected by the planner and the replication policy.

### Remote storage-owner tracking

Route publication and eviction are intentionally decoupled across two owners:

- the route owner is responsible for the authoritative object route version
- the storage owner is responsible for the actual bytes and local capacity

After a write publishes a route, the writer groups replicas by remote storage owner and sends the published routes through `BatchTrackReplicaRoutes`.

This lets each storage owner update its local eviction clock from the published route directly, instead of rebuilding state from metadata during normal write traffic.
Newly published replicas enter the storage-owner clock with one write-fresh grace pass. Real read
and route-query hits still use the read-hot path, so hot data outlives merely fresh writes without
coupling boolean existence probes to eviction accounting.

## Read Path

For reads, the client first resolves the object route, then groups reads by remote segment and submits transfer requests through TE/TENT.
When the selected replica is local, the client still resolves the same `ReplicaRoute::offset` target coordinate that remote TE reads use, then maps that coordinate back to the local storage registration.
Successful route lookup APIs are also access signals: `query_route` and `get_size` report active
route hits to the storage owners best-effort, using the same local/CLOCK and control-plane
hit-report path as completed reads. Existence checks stay boolean probes and do not report hits.

```mermaid
sequenceDiagram
    participant App
    participant Client as StoreClient
    participant Route as RouteOperations
    participant Evict as Storage Owner State
    participant TE as TE/TENT
    participant Peer as Remote Storage Client

    App->>Client: get / batch_get
    Client->>Route: lookup route
    Route-->>Client: ObjectRoute
    Client->>Evict: report active route hit
    Client->>TE: open segment and submit read batch
    TE-->>Peer: fetch bytes
    TE-->>Client: completion status
    Client->>Evict: mark local hits
    Client->>Peer: batch report remote hits (best effort)
    Client-->>App: value or copied buffer
```

The read path supports:

- single get and batch get
- direct copy into caller buffers
- multi-buffer reads for fragmented targets
- registered-buffer reads for reduced copy overhead

### Read-hit reporting

Successful reads update eviction heat at the storage owner:

- local hits are reported directly into the local `StorageOwnerState`
- remote hits are grouped by replica owner and sent through `BatchReportRouteHits`

Hit reporting is best-effort. It improves eviction quality but is not part of correctness.

## Allocation and Reclaim

Allocation is split by storage ownership.

- local allocations use `LocalAllocatorState`
- remote allocations use control-plane RPC to the owning client
- remote allocator capacity errors remain owner-local results; transport or protocol failures quarantine that owner and let placement move on

Local memory supports two backing strategies:

- transport-managed memory through the TE/TENT transport
- hugepage-backed native memory allocated directly by store-rs and then registered into the transport

The Python host allocator uses shared `memfd` + `mmap`, and can also request hugepage-backed shm regions when the host kernel is configured for hugepages.

Reclaim is explicit and route-aware.

- overwrites schedule release for the old replicas
- deletes schedule reclaim after route removal
- `reclaim_grace_ms` controls scheduled delayed release behavior
- remote release uses batched allocator RPC
- queued reclaim cleanup is idempotent for duplicate local or remote release, but direct non-cleanup release still surfaces allocator errors

### Storage-owner CLOCK with route-owner CAS

Capacity pressure is resolved by the storage owner, but correctness is still enforced by the route owner.

```mermaid
sequenceDiagram
    participant Client as StoreClient
    participant Alloc as LocalAllocatorState
    participant Evict as StorageOwnerState
    participant Route as RouteOperations

    Client->>Alloc: reserve local space
    Alloc-->>Client: Allocator error
    Client->>Evict: evict_one(preferred_segment?)
    Evict->>Evict: stale/orphan pre-pass over tracked local replicas
    Evict->>Evict: pick CLOCK victim
    Evict->>Route: CAS route without victim replica
    Route-->>Evict: applied / current route
    Evict->>Alloc: release victim bytes after CAS success
    Evict-->>Client: reclaimed or exhausted
    Client->>Alloc: retry reservation
```

The important invariants are:

- a stale/orphan pre-pass runs before live CLOCK eviction and can reclaim tracked local allocations whose authoritative route already moved away from this runtime
- each stale/orphan pre-pass checks only a bounded cursor slice of tracked keys; eligible stale/orphan allocations found in that slice are reclaimed before live CLOCK victims, while later cursor slices are left for subsequent attempts
- tight eviction retry loops are rate-limited so one allocator miss cannot turn into repeated full route sweeps
- pending local reservations are still protected until publish or timeout, even during eviction pressure
- `reclaim_grace_ms` delays scheduled cleanup, but storage-owner eviction pressure can reclaim stale/orphan local allocations earlier once the authoritative route no longer references them
- a local replica is never released before the authoritative active route no longer references that local allocation
- a route-missing lookup is treated as inconclusive for allocator release; reclaiming confirmed-deleted ghost allocations requires a separate confirmed-absent proof path
- a failed CAS refreshes local eviction state instead of guessing
- a storage owner can rebuild its CLOCK from route state if best-effort tracking falls behind
- local CLOCK eviction is enabled only on clients labeled `storage=true`
- routed writers without local storage keep the spill-remote behavior

Remote allocator RPC follows the same pattern on the storage owner side. A live remote storage owner returns a real allocator error when it still cannot free capacity. The caller does not silently downgrade that case to metadata allocation.

### Background watermarks plus synchronous fallback

The local storage owner now has two reclaim modes:

- background mode: poll local allocator usage and reclaim from the high watermark down to the low watermark
- synchronous mode: when a reserve still fails, evict immediately and retry the allocation

This keeps steady-state pressure off the front path while still preserving a deterministic fallback under bursty writes.

Default local-memory thresholds are:

- high watermark: `90%`
- low watermark: `80%`
- poll interval: `100ms`

Startup also normalizes the storage role:

- `storage=true` is rejected when `storage_bytes=0`
- `storage_bytes=0` without an explicit storage label is normalized to `storage=false`

## Control Plane

The control plane is implemented with protobuf and tonic.

It handles three categories of RPC:

- route RPC: batch get, compare-and-swap, replace
- allocator RPC: batch reserve any, reserve specific, release
- eviction RPC: batch report route hits, batch track replica routes

Single-item calls are intentionally folded into the batch path so that the implementation can reuse streaming sessions and keep the control-plane logic uniform.

For route control, that batch substrate serves both the CAS primary and the mirrored remainder of the `route_topk` authority set.

## Metadata Model

Metadata backends store four persistent categories of data:

- client leases
- segment announcements and segment lifecycle state
- object routes, when metadata persistence is needed
- tenant policy and strict-quota metadata

For membership specifically, metadata is the authoritative lease store, while the client runtime keeps a prewarmed and background-refreshed snapshot for request-path reads.

Client-lease registration uses `allocate_client_lease`: the metadata backend atomically derives the next epoch from `max(active epochs for stable_id, persistent HWM) + 1`, writes the lease under that epoch, and returns the assigned `ClientRuntimeId`. Republishing the same `(stable_id, epoch)` through `upsert_client_lease` is a refresh and extends the lease TTL in place — heartbeat and lifecycle-state updates use that path. The backends implement the allocation differently: the in-memory backend holds the active-epoch set and HWM under its write lock, Redis uses a dedicated Lua script over a `by-stable` set and an HWM key, and etcd uses a txn loop over per-epoch marker keys and the HWM key. Callers never supply an epoch; the `ClientEpoch` type remains internal to serialization, handoff plans, and metadata keys.

For strict quota rollout, the metadata model now also includes tenant-root quota primitives:

- `TenantQuotaState` for committed and pending usage
- `TenantObjectAccounting` for authoritative committed object size/version
- `TenantQuotaReservation` for reserve/finalize/abort coordination

In Phase 1, these primitives exist in the shared contracts and all three metadata backends. The in-memory backend applies them under one write lock, Redis uses backend-atomic Lua reserve/finalize/abort scripts, and etcd uses multi-key compare-and-swap txn loops.

Phase 3 now wires those primitives into the single-object client path: `put` reserves tenant quota before allocation/write, publishes the route, then finalizes quota before returning success. `remove` now reserves and finalizes the negative delta at delete CAS time, so quota/accounting state tracks authoritative object visibility rather than delayed storage reclaim.

Phase 4 extends the same model to routed `batch_put`: the client sorts entries by scoped key before quota admission, reserves quota for every item before storage reservation proceeds, aborts already-acquired reservations if later admission fails, and finalizes quota only after each route CAS is authoritative. That keeps routed batch admission deterministic and prevents partial failures from leaving pending quota behind.

### Backend support

| Backend | Use Case |
|---------|----------|
| Redis | local development, e2e, route and segment persistence |
| etcd | store metadata for distributed deployments |
| in-memory | unit tests |

## Lifecycle and Elasticity

`StoreClient` also exposes lifecycle operations that are used by the compatibility facade.

| Capability | Description |
|------------|-------------|
| `activate` / `enter_standby` / `enter_draining` | Drive client lifecycle state |
| `plan_handoff` | Prepare successor handoff metadata |
| `expand_local_memory` | Add new local storage capacity |
| `drain_segment` / `retire_segment` | Drain and retire individual local segments |
| `evacuate_owned_replicas` / `evacuate_owned_replicas_via` | Rewrite live routes away from a draining client and retire emptied segments |
| remove + reclaim | Delete route state and release segment space |

These APIs are what the e2e suite uses to validate dynamic membership, elastic expansion, true client shrink, and hot-upgrade handoff.

During full client shrink, route changes for known keys are published through
the same object route CRUD/CAS facade as normal client operations. The client
does not perform a separate route-authority mirror pass before shutdown.

## Observability

The client contains a built-in typed metrics registry and a lightweight HTTP exporter.

Observability is split into three stages:

- request-path code records facts into typed families close to the state transition
- `snapshot_metrics()` builds one immutable view of registry + process facts
- the exporter renders Prometheus text from that snapshot without mutating state

This avoids continuing to grow one branchy `operation -> counters` map and keeps `/metrics` deterministic under concurrent request traffic.

### Metrics

Metrics are recorded per operation and status.

Examples include:

- route lookups
- local copy and remote transfer work
- control-plane batch operations
- bytes in and bytes out
- accumulated latency and max latency
- metadata backend operation latency, inflight calls, and typed outcomes for Redis, etcd, or another `MetadataBackend`
- tenant quota reservation / finalize / abort / reconcile outcomes
- route-authority publish latency and storage-owner read/write traffic observed from control-plane route CAS, route-hit, and replica-track handlers

The same tracker framework also covers eviction-related work such as:

- storage-owner eviction attempts
- route-hit reporting RPC
- replica-route tracking RPC
- strict tenant quota protocol transitions

### Tracing

Log-oriented tracing is built on `tracing` + `tracing-subscriber` and can be enabled from code or by environment variables.

Jaeger profiling uses the same operation boundaries as the metrics registry:

- `OperationTracker` creates semantic profiling spans for request APIs and internal stages when profiling is enabled; spans can go to OTLP/Jaeger, a local JSONL file, or both
- request API spans such as `store.put`, `store.batch_put_from`, `store.get`, and `store.batch_get_into` become the root of the in-process waterfall
- local JSONL profiling can also emit `store.api_items.v1` records for `batch_put_from` and `batch_get_into` when `MC_STORE_RS_TRACE_ITEM_METADATA=1`; these records keep per-item key hash/prefix, namespace, runtime id, SGLang TP rank, KV kind, byte count, and status in the offline artifact instead of high-cardinality metrics labels
- control-plane stages use names such as `control.route_lookup`, `control.allocate`, `control.route_publish`, and `control.replica_track`
- data-plane stages use names such as `data.transfer_write`, `data.transfer_read`, `data.local_write`, and `data.local_read`
- the metadata backend wrapper creates child spans for Redis, etcd, or another `MetadataBackend`
- spans carry `mooncake.phase`, `mooncake.flow`, `mooncake.request_id`, `mooncake.item_count`, byte counts, and target-count attributes so Jaeger traces can be correlated with metrics time series
- disabled profiling is an atomic fast path and does not build spans or touch the exporter
- `/tracing` on the metrics HTTP server can turn profiling on or off dynamically after an OTLP endpoint or JSONL file is configured
- high-throughput profiling can set a sample ratio before exporter initialization to keep the collector from becoming the bottleneck

## Python Compatibility Architecture

The Python package exposes two runtime paths over the same Rust implementation.

### Real path

`MooncakeDistributedStore.setup(...)` builds a native `StoreClient`.

That means:

- route lookups use the same `RouteOperations` facade and `RouteDirectory` implementation
- allocation uses the same local / remote allocator logic
- data transfer uses the same TE/TENT transport path
- lifecycle, reclaim, tracing, and metrics share the same implementation as Rust callers

### Dummy path

`MooncakeDistributedStore.setup_dummy(...)` connects to a standalone `mooncake-store-rs-client` process.

That path is split as follows:

- gRPC carries compatibility operations such as put/get/batch RPCs
- a Unix-domain side channel passes shm file descriptors for registered buffers
- the standalone server resolves those shm registrations and forwards operations into the native store runtime

This preserves compatibility for integrations that expect a dummy client / external server split while keeping the real store logic inside the Rust runtime.

## Code Map

| Path | Role |
|------|------|
| `crates/mooncake-store-core` | Shared contracts and store model |
| `crates/mooncake-store-rs-metadata` | Backend implementations for metadata |
| `crates/mooncake-store-route` | object route table component split into `shim` for public operation/integration facade and metadata adapter, `table` for single-authority local route tables, `mesh` for distributed route-authority protocol, plus `control`, `metrics`, and `util` |
| `crates/mooncake-store-client/src/client/mod.rs` | `StoreClient` assembly and module composition |
| `crates/mooncake-store-client/src/client/builder.rs` | builder defaults, lease publication, membership prewarm |
| `crates/mooncake-store-client/src/client/runtime_core.rs` | runtime lookup, placement, lifecycle, allocator helpers |
| `crates/mooncake-store-client/src/client/runtime_io.rs` | get/batch-get, route scans, migration reads |
| `crates/mooncake-store-client/src/client/runtime_write.rs` | put/batch-put and route publication |
| `crates/mooncake-store-client/src/client/runtime_alloc.rs` | local and remote allocation helpers |
| `crates/mooncake-store-client/src/client/membership_sync.rs` | background live-client snapshot refresh |
| `crates/mooncake-store-client/src/client/facade.rs` | Mooncake-compatible surface methods |
| `crates/mooncake-store-client/src/route_directory.rs` | route crate adapters for membership snapshots, local authority binding, and metrics |
| `crates/mooncake-store-client/src/control_plane/mod.rs` | control-plane module entry and exports |
| `crates/mooncake-store-client/src/control_plane/client.rs` | protobuf RPC client and stream-session reuse |
| `crates/mooncake-store-client/src/control_plane/server.rs` | protobuf RPC server and dispatch |
| `crates/mooncake-store-client/src/memory.rs` | local memory and segment tracking |
| `crates/mooncake-store-client/src/transport.rs` | transfer submission helpers |
| `crates/mooncake-store-rs-runtime/src/config.rs` | compatibility setup configuration shared by the Python runtime and CLI |
| `crates/mooncake-store-rs-runtime/src/runtime.rs` | real compatibility runtime construction |
| `crates/mooncake-store-rs-runtime/src/dispatcher.rs` | Python-compatible operation dispatch |
| `crates/mooncake-store-rs-runtime/src/dummy_client.rs` | dummy compatibility client and shm registration RPC |
| `crates/mooncake-store-rs-runtime/src/dummy_service.rs` | standalone dummy compatibility service |
| `crates/mooncake-store-rs-runtime/src/shm.rs` | shm region ownership, fd passing, shared mapping helpers |
| `crates/mooncake-store-rs-admin/src/admin/` | admin service, HTTP surface, and maintenance operations |
| `crates/mooncake-store-rs-admin/src/bin/mooncake-store-rs-admin.rs` | fixed Store-RS operator command |
| `crates/mooncake-store-rs-cli/src/bin/mooncake-store-rs-client.rs` | fixed Store-RS standalone runtime command |
| `crates/mooncake-store-rs-cli/src/bin/mooncake-store-rs-bench/` | Store-RS verification and benchmark command |
| `crates/mooncake-store-py/src/lib.rs` | private `mooncake._store_rs` Python bindings |
| top-level `mooncake-store-rs/CMakeLists.txt` | CMake-owned TE/TENT shim targets and Python component installation |
| `crates/mooncake-store-e2e` | runnable system validation |
| `crates/mooncake-store-test-utils` | test-only fixtures, counting / faulty backend decorators, `TestTransport` and `FaultyTransport` |

## When to Read Which Document

- Start with `README.md` for setup and a first run
- Read the [deployment guide](../../../deployment/store-rs/deployment.md) for scenarios and deployment roles
- Read the [Rust API](../../../api-reference/rust/store-rs.md) for Rust integration
- Read [configuration](../../../deployment/store-rs/configuration.md) for defaults and tuning knobs
- Read the [Python API](../../../api-reference/python/store-rs.md) for the Python layer
- Read [testing and validation](../../../deployment/store-rs/testing.md) for scenarios and fault-injection coverage
- Read `crates/mooncake-store-e2e/src/main.rs` for a complete runnable example
