Storage modes
A knowledge model points its passages back at source files.
Where those source files live is the storage mode —
chosen at build time and recorded inside the .rlat.
The three modes
| Mode | Source lives in | Pick when |
|---|---|---|
| bundled | inside the .rlat (zstd-framed) |
shipping a self-contained artefact (HuggingFace Hub, archive, offline) |
| local (default) | the filesystem, at --source-root |
you are indexing a corpus on disk that you will edit |
| remote | HTTP(S) URLs with an SHA-pinned manifest | source lives at canonical URLs (e.g. a tagged GitHub release) |
You pick the mode at build time with --store-mode. To
switch modes later, run rlat convert <km> --to {bundled|local|remote}
— it reshapes the storage mode in place without re-running the
encoder. The band, registry, and ANN index are all preserved.
Drift means a source file changed since the knowledge
model was built, so an indexed passage no longer matches the bytes
on disk. Every rlat search hit carries a per-passage
drift status of verified, drifted, or
missing.
Bundled
rlat build ./my-corpus -o my-corpus.rlat --store-mode bundled
Source files are zstd-compressed individually inside the
.rlat. The result is one self-contained file. Drop it
on HuggingFace Hub, mail it as an attachment, ship it in CI —
there is nothing else to fetch.
| Pro | Con |
|---|---|
| One file, fully reproducible | Largest on disk (full source plus bands) |
| Works offline | No live edits — rebuild to re-ingest |
Drift can only happen by tampering with the .rlat itself | Bigger to push around |
When rlat search returns a hit from a bundled model,
drift_status is almost always verified. A
drifted or missing row means the
.rlat was edited after build — investigate.
Local (default)
# build (default --store-mode local)
rlat build ./my-corpus -o my-corpus.rlat
# query — source-root defaults to where you built from
rlat search my-corpus.rlat "..."
rlat search my-corpus.rlat "..." --source-root /different/path
The .rlat records
(source_file, char_offset, char_length) triples and
re-resolves them on disk at query time. The corpus stays in your
filesystem; the .rlat just indexes it.
| Pro | Con |
|---|---|
Smallest .rlat (no source bytes) | The source-root path is part of the runtime contract |
| Live edits — drift detection tells you what changed | Move or delete a file and that hit shows up as missing |
Cheap to rebuild incrementally (rlat refresh) | Source is not portable with the .rlat |
Stays live as you edit (rlat watch) | Watch needs the [watch] extra (pip install rlat[watch]) |
To see only hits whose source still matches the build:
rlat search my-corpus.rlat "..." --verified-only
To re-ingest drifted files in place, use rlat refresh.
To keep the archive live as you edit, use rlat watch —
the same incremental pipeline, debounced by filesystem events.
rlat watch --once is the synchronous CI / pre-commit
shape.
Remote
rlat build ./my-corpus -o my-corpus.rlat \
--store-mode remote --remote-url-base https://example.com/corpus/v1
The .rlat carries a manifest (manifest.json
at the top of the ZIP) mapping each source_file to a
{url, sha256} pair recorded at build time. The URL is
<remote-url-base>/<source_file>
(forward-slash-joined). The first time a query touches a passage,
the source file downloads to a per-knowledge-model on-disk cache
(default ~/.cache/rlat/remote/<km-sha>/) and its
SHA is pin-verified against the manifest. Later reads hit the cache.
The cache is keyed on (source_file, expected_sha), so a
re-pinned file can never serve stale bytes.
| Pro | Con |
|---|---|
| Source is centrally hosted — multiple consumers share it | First query is slower (downloads on a cache miss) |
| SHA pin means a swapped-out URL fails loud, not silent | Needs network on first access |
Survives git rm of local files | Cache verification on every read |
The default download timeout is 30 seconds per file — a stalled
upstream cannot hang rlat search indefinitely. An
SHA-pin mismatch raises an actionable error pointing at the cache
file to delete; if upstream genuinely moved, re-run
rlat build --remote-url-base ... to regenerate against
the current content.
rlat freshness my-corpus.rlat # read-only: are upstream SHAs still what we pinned?
rlat freshness walks every manifest entry, downloads
the upstream bytes, hashes them, and reports per-entry status
(verified / drifted / missing).
It is a read-only drift check — it never changes the archive — and
suitable for CI gating: it exits non-zero when any drift is detected.
When freshness reports drift, run rlat sync — the
delta-apply: it buckets passages on a stable passage_id,
re-encodes only the updated and added passages, and writes atomically.
The manifest, band, and registry stay internally consistent end to
end. rlat refresh is the local-mode sibling — the same
incremental delta-apply, run against the filesystem instead of the
manifest.
Cross-mode rules
-
rlat comparealways uses the base band, regardless of mode. Two knowledge models built in different modes can be compared as long as their base bands were produced by the same pinned encoder revision. -
Switching modes is
rlat convert <km> --to {bundled|local|remote}— it reshapes the storage mode in place, with embeddings, drift hashes, and the ANN index preserved; nothing is re-encoded. See the CLI reference for the per-transition flag requirements. - Drift is per-passage, not per-file: editing one line in a 5,000-line file marks only the passages whose character range actually changed.
Hosted on a Fabric UDF
To share a .rlat with a team — a single hosted copy,
no per-user download — the .rlat lives in OneLake and
queries go through a Microsoft Fabric User Data Function:
rlat fabric add team=https://<udf-endpoint-url>
rlat search fabric://team/team-docs "..."
This is not a fourth --store-mode. The
.rlat itself stays in any of the three modes above;
Fabric hosting layers on top. The UDF reads the .rlat
from OneLake, runs retrieval server-side, and returns hits over
HTTPS. Authentication is Microsoft Entra (device-code by default,
service-principal fallback).
| Pro | Con |
|---|---|
One .rlat, queryable by everyone on the workspace | Maintainer pays the Fabric capacity-unit cost per call |
Re-upload the .rlat and the next query sees fresh content | Requires a Fabric workspace plus a UDF item |
| First-call cold start of a few seconds; warm calls sub-second (see the Fabric page for the measured latency profile) | Fabric UDFs run Python 3.11.9 only |
Picking a mode
If you are not sure:
- Building a knowledge model for yourself, against your own working repo — use
local. You get drift detection and cheap incremental rebuilds as the corpus evolves. - Publishing for others to download — use
bundledif the corpus is self-contained (consumers get a single file); useremoteif the source belongs at canonical URLs (e.g. a tagged GitHub release — the manifest pins SHAs so a moved or rewritten upstream fails loud). - Shipping in CI, a Docker image, or an air-gapped install — use
bundled. - Sharing with a team where each user works in Claude Code or a local IDE — host it on Fabric. The maintainer publishes one UDF, each user runs
rlat fabric addand queries viafabric://.
The technical layout — ZIP internals, NPZ band format, manifest schema — is documented in the internal store specification.