← ALL POSTS · /BLOG

Cover art: eight large squares for the 8 GiB tier, the first two yellow for the 2 GiB memtable budget, beside eight small squares for the 8 MiB document ceiling and one outlined square for JSON streamed past 64 MiB
PUBLIC LAUNCH · V1.0.0-RC.99 · 2026-10-24

RC.99: SMART, RESOURCE-AWARE AUTOINDEX
AND MORE HARNESS TOOLS.

rc.99 is yours: 116 merged changes, and the 20 community members behind them. We wrote this for you. If you run XERJ on your own machine, if you told us when something broke, or if you are new here, this release is for you.

It is the 98th tagged release. 97 tags exist through rc.98, because rc.79 was never tagged. It lands just over 100 days since rc.1. The window since rc.98 is those 116 merged pull requests. The maintaining team landed the rest of them. The 20 are the community contributors and reporters named below. A laptop stays usable while it indexes, questions come back with the evidence, and a restarted cluster still knows who owns a document. Two hard limits stay open: a machine that has truly run out of memory, and clustering.

01 · THANK YOU

The 20 people behind it

These are the 20. We grouped them the way the work arrived. 5 built something you can use in this release. 12 spoke up, in a report, a field report, or a translation. 3 signed on with us, and the packs, the listing, and the fixes they brought are not in this release. The maintaining team is not in this count.

People who built it. These 5 wrote code that is in rc.99.

People who spoke up. These 12 told us what broke, wrote a field report, or translated a page.

People newly welcomed. These 3 signed the contributor agreement. What they brought besides that signature is not in this release, and we are glad they are here.

02 · THE MACHINE

A laptop that stays usable while it indexes

A laptop and a large server do not get the same budget. From 16 GiB of memory up to 64 GiB, the automatic cap is 8 GiB. Larger hosts step to 16 GiB and 32 GiB. On the 8 GiB step, recent writes share a 2 GiB budget. Under 16 GiB the cap is half of RAM. An 8 GiB machine used to be given 8 GiB, which is the whole machine. It now gets 4 GiB. A merge on that smaller budget takes smaller bites, and one merge still runs, because merging is what frees memory. On Windows, Nikan Wystaf's write-up of three crashes on a 16 GB machine with no pagefile is why there is a second ceiling, taken from the commit space the process can still reach, rather than from the RAM sticker alone.

8 GiB
step from 16 GiB to 64 GiB
Hosts at 16 GiB and above. Under 16 GiB the cap is half of RAM.
2 GiB
budget for recent writes
On the 8 GiB step. When this fills, the index flushes instead of refusing every write.
8 MiB
one JSON document
Past this, that document is skipped. Its neighbours still index.
64 MiB
JSON read from disk
An uncompressed file past the old whole-file cap is streamed. Gzip stays in memory.

When that write budget is full, autoindex used to sit on “try again” until it gave up, and a search in the same moment stalled. The index now flushes, largest table first. A search publishes those writes before it scans them.

An idle node whose memory sits flat no longer spends the rest of its life trying to drain. Once the resident set has stopped falling, the drain lets go. If memory climbs again, it engages again. A phase that is making no progress says so, instead of inventing an arrival time.

One oversized JSON document is skipped, and the file is named. A bulk that would exhaust the process is refused before it is parsed. Embeddings are stored packed, so a long JSONL corpus does not keep a tree of numbers in memory until the next flush. You still read them back as a normal array. The default embedder is lexical feature-hashing. Neural embeddings run only if the node was started that way, and when the server has timed a probe, autoindex prints how long the neural part should take before the run starts. Changing that mode later does not rewrite documents already stored.

A killed corpus index finds its journal and resumes, instead of starting over under a new name. A pipeline bound to an index still runs after a restart. A refresh at the end of a run no longer waits behind one slow merge. Because camen-collab told us about a run that stalled and left searches unanswered, a refresh now has a bound, so it cannot wait forever and take searches down with it. A disk that is nearly full says so in one sentence, with the path and what to do.

The awkward files are indexed too. Wolf Schmitz is why PDF and spreadsheet workers start on macOS 27, where the old memory cap on the worker was refused by the operating system. Hand-written SQL schema is indexed as code, so the table and routine definitions are searchable. A file that is a dump of rows is still treated as rows. Graph mode picks up files you added, when they fit a dataset that already exists, and removes files you deleted, naming them. A file that needs a brand-new dataset stays out until you rebuild with --fresh. A semantic run that embeds through a proxy resumes after a failure and does not re-embed documents already written, when the model, the endpoint, and the vector width are unchanged.

If the operating system refuses a worker thread, or a body is too large to parse, the process stays up. The job that could not start is an error. The hard problem is still open: a machine that is actually out of memory, including a WSL2 virtual machine that dies under that pressure, is not solved here.

03 · THE HARNESS

Cited evidence, in one call

Because of Jarvis, an agent can hand over a file of up to 50 identifiers or questions and get them back in that order, from one search. Each item is cited evidence, an explicit empty result, or an error of its own. Exact identifiers need a keyword field. A token budget, if you set one, keeps the outcome and at least one citation for each hit, or it refuses in the open. This is retrieval. It does not write an answer, and it does not claim a confidence score.

The same work looks up a definition from a symbol and, if you want, a project prefix, a kind, and a language. No match is an empty list, which is a success. Search accepts the same kind of prefix: a project name searches that project's indices. With neither a prefix nor an index, both still search the default autoindex set. A hit can name the line that matched, not only the start of the passage, so a citation can point at the line.

A question with several words now ranks a passage that covers the question above a one-word symbol that matches a single token. A one-word lookup is unchanged. You can mark a corpus as your own code. An unidentified licence is still named on each hit. A licence the detector actually recognized still carries its warning.

The README documents setup for 26 agents that can register the local server, including DeepSeek Harness. Two rows have been run: OpenCode, and Cline's command-line client against v1.0.0-rc.98. The Cline IDE's configure button was not part of that run. DeepSeek Harness has a profile bundle in the repository. That row is untested. XERJ is not in a DeepSeek directory.

04 · A CLUSTER THAT CAN RESTART

The owner of a document survives a reboot

A single node is unchanged. The maintaining team built the restart behavior in this section. With clustering turned on, creating an index agrees the plan through the log, and a document write goes to the node that owns that shard. A copy is placed on the replicas chosen at create, and you are answered when a majority of those copies have confirmed. The primary counts. If a replica misses the acknowledgement, it leaves the in-sync set before you are answered. The primary alone, when two replicas were placed, is still a failure: the write is on the primary, and the caller is told the copies did not confirm.

Restart used to forget the plan. The node now keeps a log on disk and replays it before it serves, so the next write finds the owner again. A member that joins late copies that log. A member that has fallen too far behind receives the compacted command history, then the live documents, including documents inserted, updated, or deleted while it was down, and then rejoins the in-sync set. Bulk writes, single-document updates, and update-by-query run on the owner. A bulk is split by owner. A script runs where the current document is. If you cap how many documents an update-by-query may touch, that cap is for the whole index, spent across owners, not granted again on every shard.

Clustering is not finished. A write still needs the primary. There is no promotion if that primary is gone. Delete-by-query, and the native ingest path, still write on the node that received the request. Pipelines are not copied. Changing who is a member does not move existing copies. A search of one index asks every owner. Aggregations and the other multi-phase options are not merged across owners. The saved snapshot is the command history, not the documents themselves.

x86_64 builds run on CPUs without AVX2. The floor is the older SSE4.2 baseline. A CPU without that still cannot run the binary. The fast path for one distance kernel is used when the CPU has it, and it matches the scalar result bit for bit.

05 · THE COUNT

The 98th tagged release

The version number and the tag list are different counts. There is no v1.0.0-rc.79 tag. Tags from rc.1 through rc.98 number 97. rc.99 is the 98th tagged release. It lands just over 100 days since rc.1. The changelog is dated 2026-10-24. The window since rc.98 is 116 merged pull requests. The 20 people named above are the community in that window. The maintaining team landed the rest.

06 · WHERE XERJ IS LISTED

The README, and three live pages

The per-client setup is under Supported agents. DeepSeek Harness stays untested, and XERJ is not in a DeepSeek directory. The profile bundle is in the repository.

These pages are live:

07 · FULL CHANGELOG

Every pull request, in one place

The narrative above leaves the ticket numbers out. The source of truth for this cut is the changelog section dated 2026-10-24. Two issues named there stay open.

08 · UPGRADE

Install v1.0.0-rc.99

Before you upgrade. Back up your data folder first. Opening it with rc.99 changes nothing, but once rc.99 writes a field name with an uppercase letter (like page_Id), the folder moves to format 3 and rc.98 can no longer open it. Run xerj autoindex --fresh again on your log and .sql indices to get the new matching and the code indexing.

The installers download a GitHub release and check its SHA-256. Pin this release with XERJ_VERSION. On Linux, macOS, and Windows Git Bash, MSYS, and Cygwin:

$ curl -fsSL https://xerj.org/get | XERJ_VERSION=v1.0.0-rc.99 sh
$ export PATH="$HOME/.local/bin:$PATH"
$ xerj --version

That sh installer writes ~/.local/bin (xerj.exe on Windows) and does not edit your shell profile. PowerShell writes a different directory and adds it to the user PATH. Open a new terminal after it:

> $env:XERJ_VERSION='v1.0.0-rc.99'; irm https://xerj.org/get.ps1 | iex

Re-run the installer you used last time. The two do not share a directory. xerj --version should print v1.0.0-rc.99. The longer matrix, the manual checksum block, and the musl-versus-gnu choice are on the install page.

09 · COME IN

There is room for you

If this release helped you, or if it got in your way, tell us in your own words. A short field report is how you join: what you pointed XERJ at, what you used it for, and your honest verdict. A report that says where it frustrated you is the one we learn from. You can also send a fix, open an issue, or come say hello where we already are.