Lang on Rock is a document database for what your agents know.

Markdown in, atomic commits, history and restore, and a compiled read model that finds the right document 75% of the time in 17 round trips, against 70% in 30 for plain OKF files and 30% in 20 for ChromaDB. Own engine, one binary, no SQL.

View install script
$ curl -fsSL https://raw.githubusercontent.com/langonrock/langonrock/main/install.sh | sh

Detects the platform, verifies the checksum, and drops the binary in ~/.local/bin. x64 and arm64 both covered.

Then langonrock --version to check it, or the quickstart to import your first folder.

Right concept in the top 80 – 100%
Right concept in the top 8, measured in percent of questions
Lang on Rock75%
OKF raw files70%
ChromaDB30%

Higher is better. Twenty questions that name the concept they ask about, over a 500-concept catalogue. OKF is BM25 over the raw files; ChromaDB embeds 1,000-character chunks with all-MiniLM-L6-v2. Asked by description instead, Lang on Rock and OKF find it 95% of the time and ChromaDB 70%, and on no corpus measured did Lang on Rock find it less often than either.

Tool calls0 – 30 calls
Tool calls, measured in tool calls
Lang on Rock17
OKF navigator30
ChromaDB20

Lower is better. The same twenty questions, each side on its path with the fewest calls. Lang on Rock reads the manifest once and makes one batched fetch for each of the sixteen questions that need a document. ChromaDB returns its top eight chunks with their text, one search per question. The OKF navigator reads index.md, then each answer’s file and the files it links to. On prose with no links to batch, all three need about one per question: 21, 21 and 20 on four novels.

Tokens billed0 – 130,101 tokens
Tokens billed, measured in tokens
Lang on Rock39,862
OKF navigator130,101
ChromaDB73,021

Lower is better. Twenty questions over four novels, one concept per chapter, each side on its cheapest path. Lang on Rock ranks and then reads a located window instead of the chapter, ChromaDB returns its top eight chunks with their text, and the navigator reads whole chapters. On the catalogue ChromaDB’s cheapest path bills fewer, 30,804 against 56,928, charged as if it always fetched the right chunk, and on the recipes 18,450 against 19,551.

How these were measured: OKF and Lang on Rock, ChromaDB.

What you get

Six things that change once what your agents know lives in a database, and the mechanism behind each one.

Related edits land together or not at all

A transaction carries up to 1,000 writes and deletes. Each one names the hash of the version it replaces, and if any of them is stale, nothing is published. Twenty-five new documents commit in 94 ms at 5,000 concepts.

Every commit can be taken back

History lists the retained revisions, and restore publishes an old one as a new commit, guarded by the revision you expect to replace. Ten revisions are kept by default. A pruned revision is gone.

A returned write is on disk

Every file is flushed before HEAD is swapped, so a normal return is a durable commit. A failure after the swap is reported as indeterminate, with the revision to check, rather than guessed at. Tested by killing processes, not by cutting power.

Pay for the section, not the document

Ask for the schema of a table by its own Markdown heading, hand find a phrase, or follow a search hit’s pos offset to the densest passage. A table’s schema costs 213 tokens, and a located window in a novel 513, whatever the document’s size.

Editing a body does not cost you the cache

Identical documents compile to identical bytes, so an edit that keeps a concept’s description and links changes no row of the manifest, and the agent’s cached prompt prefix survives it. A row that does change invalidates the cached prefix that holds it.

Your Markdown comes back out exactly

Import tracks what each folder looked like, so a re-import never overwrites a database edit and a file changed on both sides fails instead of picking a winner. Export writes the current revision back out, frontmatter and line endings intact.

The whole lifecycle, four commands long

Import a folder once, read it the way an agent does, commit a change against the version you read, and take it back. Each step uses what the one before it returned.

  1. Import

    Point Lang on Rock at a folder where every subdirectory is a bundle of Markdown. It becomes the tenant’s first commit, and the database remembers what each file looked like, so importing the folder again never overwrites an edit made since. A file changed on both sides fails the whole import instead of picking a winner.

    $ langonrock import sources/acme --data ./data --tenant acme

    The folder is where documents come from, not where they live. Nothing writes back to it, and export writes the current revision to a new directory with its frontmatter and line endings intact.

  2. Read

    An agent reads the manifest first, one row per concept with its id, its summary, its links and whether it is still current, then asks for the one section it chose, every id in a single call. The scheme picks where the database runs, and open(dsn) returns the same interface for all three.

    $ langonrock get orders --section schema --data ./data --tenant acme
    okf:///var/data?tenant=acme
    Embedded, direct file access.
    okf+unix:///tmp/okf.sock?tenant=acme
    Local daemon, warm indexes, no cold start.
    okf+https://host:7777?token=…
    Remote, tenant resolved from the token.
  3. Commit

    A batch is JSON. Each change names its bundle, its path and the hash of the version it replaces, which reading the source returned, or leaves the hash out to say the document is new. If one hash is stale, nothing in the batch is published, so two writers cannot quietly undo each other.

    $ langonrock transact --data ./data --tenant acme --from batch.json

    The commit is visible to manifest, search and get as soon as it returns. It writes a complete snapshot, so its cost grows with the tenant: 25 new documents take 94 ms at 5,000 concepts.

  4. Restore

    History lists the retained revisions, newest first. Restore publishes an old one as a new commit, and only if the revision you name as current still is, so it cannot undo a change you never saw.

    $ langonrock restore "$REVISION" --expected-revision "$CURRENT" --data ./data --tenant acme

    Nothing is rewritten. The commit you restored past stays in history until collection prunes it, and ten revisions are kept by default.

Search takes the same path. Retrieval is BM25 over each concept’s names, manifest row and body, plus a one-hop expansion across the links, capped so that a hub concept cannot drag in half the manifest. There is no model anywhere in it, so the same query returns the same set tomorrow. Asked a question that names a concept, it ranks that concept in its top eight 75% of the time, against 70% for the same ranker over the raw files and 30% for ChromaDB’s embeddings. A query returns in 1.65 ms at 20,000 concepts.

What a commit promises, and where it stops

The engine is small enough to state in full: a directory per tenant, immutable files named by their hash, and one pointer that moves.

A normal return means the commit is on disk. Every new file is written and flushed first, then HEAD is replaced and flushed again, and that replacement is the commit. A writer killed halfway leaves files no revision points at, which no reader sees and collection removes. A failure after the swap comes back as indeterminate, with the revision to inspect, and a corrupt HEAD fails closed instead of falling back to an older revision.

A reader pins the revision it opened, so a search ranks and fetches against one state even while a commit lands beside it. Writers wait for each other on a kernel lock, and a writer that loses the race is refused rather than merged.

It is a local engine for documents. There is no SQL or query language, no replication, no transaction across tenants and no promise on a network filesystem. Crash recovery was tested by killing processes, not by cutting power, and the test suite passes on macOS and Linux but not yet on Windows. Every commit writes a complete snapshot, so each revision kept adds disk until collection prunes it.

The full failure contract, surface by surface.

A tenant on diskdata/tenants/acme/
HEAD
The committed revision. Replacing this file is the commit.
snapshots/
The compiled read model of each revision, named by its hash.
sources/
The exact Markdown: frontmatter, paths, navigation files.
revisions/
One immutable record per commit, pointing at its parent.
imports/
What each imported folder looked like the last time.
staging/
Writes still being prepared. No reader ever sees them.
writer.lock
Held by the kernel, so one writer publishes at a time.
retention.lock
Readers take it briefly to pin a revision, collection to delete one.

What reading costs, and where it loses

Twenty fixed questions per corpus on one machine, every side billed for delivering the same answers. OKF is its reference consumption pattern, navigating with no wrong turns. ChromaDB is chromadb 1.5.9 with its default all-MiniLM-L6-v2 embeddings, run through Lang on Rock’s own harness on whichever of its paths is cheapest for the figure quoted.

On the 500-concept catalogue Lang on Rock answers in 17 round trips, against 30 for the OKF navigator and 20 for ChromaDB, because the agent reads the manifest once and makes one batched fetch per question. It ranks the concept a question names in its top eight 75% of the time, against 70% for the raw files and 30% for ChromaDB. Tokens are where ChromaDB wins on this corpus: its cheapest path bills 30,804 against Lang on Rock’s 56,928 and the navigator’s 116,357, charged as if it always fetched the right chunk.

The documents decide the token bill. On twenty-eight RFCs Lang on Rock bills 13,995 tokens in 16 round trips, against 27,629 for ChromaDB and 756,168 for the navigator. On four novels it bills 39,862 by reading located passages instead of chapters, against 73,021 and 130,101, and on the Bible at one concept per book 39,395, against 77,469 and 1,278,420. ChromaDB bills fewer on Mrs Beeton’s recipes, 18,450 against 19,551, as it does on the catalogue. On prose with no links to batch, round trips even out at about one per question for all three.

On no corpus did Lang on Rock find the right concept less often than either. Asked by name, it found it for every question over the recipes and over the RFCs, against 90% for both the raw files and ChromaDB on the recipes and 95% for both on the RFCs. Asked by description, it found it for 80% of the recipe questions, against 55% and 50%.

Nothing in it embeds anything. A 5,000-concept catalogue is searchable 0.38 s after Lang on Rock starts compiling it, against 89 s for ChromaDB to embed it, and its compiled snapshot takes 5.4 MiB against the 67.5 MiB ChromaDB writes. BM25 over the raw files is faster at both: searchable in 0.31 s, and 0.24 ms a query against Lang on Rock’s 0.52 ms, because Lang on Rock also locates the passage in its top hits. ChromaDB takes 72 ms a query, embedding the question included.

A synthetic catalogue and four public-domain corpora, a deliberately crude chars / 4 token estimate, one machine. No session pays for a miss: each is billed as if its first answer were the right one, which flatters whoever ranks worst. Treat it as an order of magnitude and measure your own documents. The OKF and Lang on Rock method, and the ChromaDB runs.

People get an editor, not a manifest

The compiled read model is for agents. langoneditor is the half you look at, a desktop app for macOS, Windows and Linux. Point it at a folder of Markdown and it works, or point it at a Lang on Rock server and it searches that server’s own index. The binary ships inside it, so there is nothing else to install.

It derives no ids, resolves no links and reproduces no lint rules: it asks the server and shows the answer, so the two cannot drift apart. A save goes through the same source routes as any other client, one document at a time, and names the version it replaces, so an edit made elsewhere is never silently overwritten.

  • The bundle tree

    Every bundle and concept in the tenant, as they sit on disk.

  • Markdown, with a form for the frontmatter

    Prose stays prose. The fields that have to validate get fields.

  • The link graph

    What a concept points at, and what points back at it.

  • Archives and spreadsheets

    Move a bundle in or out without touching the store by hand.

One binary, server optional

One binary for macOS and Linux on x64 and arm64, a data directory, and an MIT licence. Embedded, there is no server to provision and nothing that has to stay running between reads. From source it is Bun 1.4.2 or newer, bun install, and a C compiler for the small native adapter that takes the OS locks and flushes files to disk.

View install script
$ curl -fsSL https://raw.githubusercontent.com/langonrock/langonrock/main/install.sh | sh

Detects the platform, verifies the checksum, and drops the binary in ~/.local/bin. x64 and arm64 both covered.

Then langonrock --version to check it, or the quickstart to import your first folder.