Skip to main content

Steadlith

Steadlith

CI Codecov PyPI Python License

Steadlith reuses unchanged RAG chunks with content-defined identities, cache-aware planning, and transactional indexing.

Steadlith is a Python toolkit for stable, incremental retrieval-augmented generation (RAG) indexing. It combines content-defined chunking, content-addressed identities, and a dry-run planner so a small edit can be represented as a small set of index operations.

The distribution, Python module, and command are all steadlith.

The v1 chunk-identity schema is compatibility-stable and protected by golden-vector tests. Built-in five-corpus benchmarks publish churn and retrieval baselines for every bundled chunking strategy. The default offline provider performs lexical retrieval; select a learned provider when queries require semantic similarity.

Why Steadlith exists

Hashing chunks only avoids work when chunk boundaries stay stable. Offset-based chunkers can shift every downstream boundary after an insertion near the start of a document, which changes hashes even where the underlying text did not change.

Steadlith's default cdc-rabin strategy places candidate boundaries from a rolling fingerprint over normalized words. Boundaries far from a local edit should therefore remain stable. A manifest diff then classifies each chunk as add, keep, move, or delete. When embedding identity is unchanged, only uncached add content needs a new embedding; a model or embedding-parameter migration may re-embed otherwise unchanged occurrences.

Steadlith is deliberately a library and planner, not a RAG framework. The intended integration point is below orchestration libraries and above embedding/vector providers.

Supported scope

The reference path is implemented end to end:

  • deterministic normalized-word chunking with Rabin content-defined boundaries;
  • content-addressed chunks and embedding-cache keys;
  • manifests, Merkle roots, and explicit change plans;
  • a local CLI, SQLite index, and SQLite embedding cache;
  • migration with preview, recovery, and rollback;
  • versioned churn and retrieval regressions across five built-in corpora;
  • cross-platform determinism, adapter, crash-recovery, deletion, and query tests.

Sentence/paragraph snapping remains opt-in because it needs project-specific legal review. The default unsnapped strategy does not depend on it.

Installation

Steadlith requires Python 3.10 or newer.

Install the latest published release:

python -m pip install steadlith

For an isolated command-line installation, use pipx:

pipx install steadlith

For development, install from a source checkout:

git clone https://github.com/satwiksps/steadlith.git
cd steadlith
python -m pip install -e ".[dev]"

Releases are built and published by the tag-triggered workflow described in the release checklist.

Provider SDKs are optional and do not load with the core package. From a source checkout:

python -m pip install -e ".[openai]"
python -m pip install -e ".[sentence-transformers]"

Quick start

Create a local configuration and inspect a plan before applying it:

steadlith init
steadlith plan
steadlith index
steadlith status
steadlith query "your question"
steadlith verify

With no explicit paths, steadlith plan and index use the committed [sources] globs. plan is the safe starting point: it reports proposed adds, keeps, moves, and deletes without writing index state.

[!CAUTION] Paths passed to plan or index are the complete desired corpus for that run. Previously indexed documents omitted from that scope are planned as deletions. Prefer the committed [sources] globs and inspect steadlith plan before applying changes. index requires --allow-delete for a deleting plan and also requires --allow-empty before emptying a previously populated corpus.

The generated starter configuration uses deterministic unigram/bigram feature hashing. It works offline for exact-term and keyword retrieval but does not infer synonyms or semantic similarity. Use the OpenAI or sentence-transformers provider when semantic matching is required.

See the CLI reference before automating a workflow; in particular, positional paths describe a complete desired corpus rather than additions to the existing index.

Programmatic use keeps chunking separate from provider and backend concerns:

from steadlith import CDCChunker
from steadlith.config import load_config

chunker = CDCChunker.from_config(load_config("steadlith.toml"))
chunks = chunker.split("A document that changes a little at a time.")

for chunk in chunks:
    print(chunk.text)

load_config performs file I/O at the application edge; the chunker receives the parsed object and remains independent of files, providers, and backends.

The documented top-level API and JSON outputs follow the compatibility policy. Versioned chunk identities do not change silently across package releases.

Configuration

The complete sample is in examples/steadlith.toml. The default strategy is unsnapped Rabin CDC:

[chunker]
strategy = "cdc-rabin"
window_words = 48
min_tokens = 180
max_tokens = 640
snap_window_words = 24

Snapping is enabled only by selecting strategy = "cdc-rabin+snap"; it is never enabled by the plain default strategy.

Changing normalization or chunking parameters changes chunk identity. Always run steadlith plan before applying a configuration change.

Design constraints

  • chunk and content stay deterministic and free of I/O, network access, and configuration lookups.
  • The embedding model is not part of the chunk hash. Embedding cache keys add model and model-parameter identities separately.
  • Snapping may inspect only a bounded local window and is never enabled implicitly.
  • Deletes become tombstones before compaction so removed content cannot silently remain active.
  • Benchmark reporting must publish churn and retrieval-quality results together.

Documentation

Upgrading from Cairn 0.2

Steadlith 0.3 is the same project under a new package, module, command, configuration, and default state name. It preserves the 0.2 wire identities so existing indexes and cached embeddings can be adopted without recomputation.

From the directory that contains the existing configuration, run:

python -m pip uninstall cairn-rag
python -m pip install steadlith
steadlith adopt --from-config cairn.toml --config steadlith.toml
steadlith plan

adopt writes a validated Steadlith configuration while preserving the existing state paths and configured embedding identity. It does not overwrite files, follow paths outside the project, or proceed while a migration is pending. Update Python imports from cairn_rag to steadlith and use the steadlith command afterward. New releases are published only as steadlith.

When Steadlith is a fit

Steadlith is aimed at large documents or corpora where edits are small relative to the indexed content. It may offer little advantage for short documents that are normally replaced wholesale, and content-defined boundaries may retrieve differently from semantically selected boundaries. Measure both churn and retrieval quality on your own corpus.

Contributing and security

Contributions are welcome. Start with CONTRIBUTING.md, follow the CODE_OF_CONDUCT.md, and add tests for behavior changes. Report vulnerabilities privately as described in SECURITY.md.

License

Steadlith is available under the Apache License 2.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

steadlith-0.3.0.tar.gz (133.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

steadlith-0.3.0-py3-none-any.whl (110.0 kB view details)

Uploaded Python 3

File details

Details for the file steadlith-0.3.0.tar.gz.

File metadata

  • Download URL: steadlith-0.3.0.tar.gz
  • Upload date:
  • Size: 133.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for steadlith-0.3.0.tar.gz
Algorithm Hash digest
SHA256 4bce022e7661af6204619e9eda9ad0f3766e0a6db54d7c5f3f54ef550ef0769c
MD5 b35d002981919c4eadbb35aa9dd190ea
BLAKE2b-256 55cc51eedb5f40bc9584d9495fcd86f8da13a4dc5a53c49f9d58c7858addebde

See more details on using hashes here.

Provenance

The following attestation bundles were made for steadlith-0.3.0.tar.gz:

Publisher: release.yml on satwiksps/steadlith

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file steadlith-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: steadlith-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 110.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for steadlith-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 355c5193e71a440481f85d0a64ef2e64ac26adcdd6738ac2e089a9cfe4b18829
MD5 dcc7c6b839a88187befc2dc712d63205
BLAKE2b-256 c11ea62e8121a5b21f3c135a31a3e0321e6d70da275ee2511cf6d745b481d426

See more details on using hashes here.

Provenance

The following attestation bundles were made for steadlith-0.3.0-py3-none-any.whl:

Publisher: release.yml on satwiksps/steadlith

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page