
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.
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.
- Because of Jarvis, you can now look up a definition, search one project's index by its prefix, and ask up to 50 questions in one call, each with cited evidence, a clear miss, or its own error, with a real hit kept even when it shares a line, a neighboring definition kept as its own hit, and with what he measured while building that call written down.
- Because of ordinary being, a filtered view now shows the documents it was meant to show, a count can require a minimum score, asking whether a query is valid reads the field types the way a search does, and the catalog count matches the documents you can actually search.
- Because of samuel mbabhazi, Day or Night follows you from page to page, a failed build names the operating-system error underneath, and a watched folder no longer starts a new pass because an ignored file changed.
- Because of Mohamed Al-Aweshi, the single-file index command stops before writing when you point it at a folder and points you at autoindex, instead of creating an empty index and crashing.
- Because of Mario Marcolongo, the homepage now points an agent to the agent guide, the API description, and the endpoint docs.
People who spoke up. These 12 told us what broke, wrote a field report, or translated a page.
- Nikan Wystaf noticed three autoindex crashes on a 16 GB Windows machine with no pagefile and told us, and now Windows keeps a second memory ceiling, taken from the commit space the process can still reach, rather than from the RAM sticker alone.
- Because of jongin, you can read the install and the agent setup in Korean.
- redwolf2019 brought the Simplified Chinese README back in line with the English one, repaired a recipes link that had started saying not found, and corrected an agent guide that listed thirteen tools while the server then offered twenty.
- Wolf Schmitz noticed that macOS 27 was throwing away every PDF because the reader was not allowed to start, and told us, and now that reader starts, the run says so when it truly cannot, and the spreadsheet reader is treated the same way.
- Mathieu Lecarme noticed that the single-file index command, pointed at a folder, created an empty index and then crashed, and told us, and Mohamed's fix above is the answer.
- lakshya goyal (zero) noticed that choosing Night snapped back to Day on the next page and told us, and now the choice sticks.
- camen-collab noticed an autoindex run that stalled partway and left the node unable to answer searches, and told us, and now a refresh has a bound so it cannot wait forever and take searches down with it.
- Gilang Pratama noticed a final check that sat at zero while another corpus was publishing, and told us, and now that check gets a turn between writes, and a page that timed out is not counted as empty.
- Simon noticed that editing a file in a very wide dataset made the next update drop that file, and told us, and now those edits stay.
- Highlander noticed that one embedding of the wrong width came back as a retryable server error, and told us, and now that item is a clear 400 so a client does not retry what cannot succeed.
- Vincenzo Lombardo noticed a query that a validity check accepted and a search rejected, text in a field that holds integers, and told us, and now the check reads the field types and agrees with search.
- Ng Kam Woh prepared a plan-and-act reference corpus and wrote the path down for the next person, including that the installer checked its checksum, that the pin recorded the licence and the files, and that the manifest check needs Rust, and that pack is not part of this release.
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.
- Matthieu Foillard signed on for an Atoma reference corpus prepared for Corpus Hub, and that pack is not part of this release.
- MJ Hwang signed on and set the terms for attributing their MIT-licensed llm-relay project, under the name MJ Hwang, if Corpus Hub lists it.
- Qiu signed on, and three fixes they opened, for null JSON payloads, trailing-slash checks, and the installer test fixtures, are still open and are not in this release.
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.
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.
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.
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.
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.
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:
- LobeHub
- skills.sh — install with
npx skills add xerj-org/xerj - Trendshift
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.
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.
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.
- Join the community, the field report
- Contributing
- Issues
- Discord
- GitHub
- X