Download Latest Version semlith-v0.51.1-x86_64-pc-windows-msvc.zip (24.5 MB)
Home / v0.25.0
Name Modified Size InfoDownloads / Week
Parent folder
semlith-v0.25.0-aarch64-apple-darwin.tar.gz 2026-09-20 23.0 MB
semlith-v0.25.0-aarch64-unknown-linux-gnu.tar.gz 2026-09-20 22.5 MB
semlith-v0.25.0-x86_64-pc-windows-msvc.zip 2026-09-20 20.5 MB
semlith-v0.25.0-x86_64-unknown-linux-gnu.tar.gz 2026-09-20 23.6 MB
SHA256SUMS 2026-09-20 448 Bytes
README.md 2026-09-20 7.2 kB
Semlith 0.25.0 source code.tar.gz 2026-09-20 2.4 MB
Semlith 0.25.0 source code.zip 2026-09-20 2.6 MB
Totals: 8 Items   94.6 MB 0

The right span, measured

The sealed thirty, scored once by the release binary at completion, median of three runs with zero spread, beside the previous release's binary on the same split and the same corpus:

0.23.0 0.25.0 0.25.0, SEMLITH_RERANK=on
hit@8 28 / 30 29 / 30 29 / 30
hit@3 27 / 30 27 / 30 28 / 30
hit@1 25 / 30 24 / 30 24 / 30

Identifiers are 12 of 12 in the top three and wrong-yes is 0, both asserted by the run rather than read off it. The gate this release was held to — hit@8 at least 27, hit@3 at least 26 — is met by the shipped default and was not re-baselined. The aim stated at planning was 30 of 30 at k=8; it came one question short, and that question is concept-portal-parity, whose answer is spanned in AGENTS.md and which the ranking still does not return.

hit@1 is one question below the previous release. It is stated rather than gated because on a concept question it measures the span file: several chunks answer correctly and only the spanned ones score.

The audit, which is most of the number

Before any ranking change, every question that missed at k=8 and every near-miss whose first hit was unspanned was read by hand: twenty-four in all. Eleven were answered correctly by a chunk no span covered — docs/models.md says "a query about a picture goes through CLIP's own text encoder" for the question that asks exactly that, and src/lock.rs's module doc states the advisory lock for the question about two indexers — and thirteen spans were added. Nine were real ranking failures and gained nothing. Four could be read either way and gained nothing, because a span added to buy a hit is a hit bought from the measuring stick.

Each decision is recorded on the question with the number of spans it added, and the harness fails if a question marked correct-but-unspanned gained none. The sealed thirty were redrawn from the audited set with a new seed, and the draw now lives in the harness with a test that fails if split.yaml is not what the seed produces.

Rescoring, and why it is off

There is a rescoring stage now: a local 37 M-parameter cross-encoder, int8, Apache-2.0, pinned by digest, that reads the query and a candidate together — which fusion never does, since fusion compares positions — and whose order is fused with the fused one, so a candidate has to be liked by both.

It is off unless SEMLITH_RERANK=on, and the reason is the measurement beside it: a search over one store takes 8.2 ms, and 132.2 ms with the stage over twelve candidates. What that buys on the development seventy-seven is two questions at k=1 and one at k=3. Worth having when one answer matters more than a tenth of a second; not worth making every agent's every search sixteen times slower by default. semlith setup fetches the model so that turning it on never pauses a query, and stats and doctor say which ranking answered.

What was tried, and what was kept

Every mean is a pair: three runs a side, one binary, git diff -- src/ clean between them. On the development seventy-seven, in the order they were tried:

  • Code chunks carry their definition — the enclosing signature and the first line of its doc comment, in front of the text at embed time and nowhere in the stored bytes, the way a Markdown chunk already carries its heading path. 65 → 66 at k=8, 62 → 62 at k=3, 54 → 51 at k=1. Kept.
  • A cross-encoder writing the order outright — 59/67/71 → 59/67/71. It moved sixteen questions and gained nothing: rank 7 to rank 1 for one, rank 1 to rank 6 for another. Not kept.
  • The same cross-encoder fused with the fused order — 59/67/71 → 61/68/71. Kept, behind the switch above.
  • A deeper candidate pool for questions, 32 → 50 — identical at every depth on the 51 questions both runs scored, and four questions slightly worse. Not kept.
  • Normalising spellings before comparing a hint against a path — five more call edges of 6 930 settled, no question moved at any depth. Not kept.

The rest

semlith stats, semlith_stats and one table on the portal's Index page state what the graph covers per language: files, files whose parser gave up, definitions, call edges by support class, and call targets no definition satisfies. An absent edge and an unparsed file are different problems and a single store-wide percentage hid both. A test reads the CLI and the tool over one store and fails if they disagree.

semlith brief carries one span of text rather than three: 2 209 tokens per answered question against search-then-read's 724 becomes 1 112 against 725, at 1.00 calls against 2.54.

semlith doctor now names the key that actually holds a disabled server rather than the documented spelling of it — the defect that hid a silently absent server on the reference machine for a third time, because the first thing anybody does with that message is search their configuration for the key it names.

The six daemon index-run tests of issue [#118] pass: five asserted a streaming contract the daemon replaced in 0.20.0, and the sixth found a real fault — a forwarded semlith_index dropped the refusals the in-process server names, so an agent was held to a boundary it was never told about.

Faster, measured beside the release it replaces

Both binaries on the same laptop in the same run, median of twenty searches, one test thread:

chunks 0.23.0 0.25.0
700 20.5 ms 16.2 ms
7 000 46.9 ms 37.9 ms
70 000 362.4 ms 159.1 ms

The pair matters more than either number: the 6.5 / 13.7 / 129.9 ms the 0.23.0 record states were taken on a quieter machine, and this laptop is about three times slower today for both binaries. Measured against each other rather than against a figure from another day, the release is faster at every size. Peak memory while indexing stays under 240 MB at every size, an idle watcher costs 0.00 s of CPU over 60 s, and an edit on disk is searchable in about 2 s.

A reader holding three stores costs 1 MB per extra store beyond the first, against 123 MB before the cross-encoder was made one per process.

Upgrading

A store written by an earlier release is re-chunked and re-embedded by the first full index pass, because what the model is shown has changed and a store half embedded each way ranks its own files unevenly. The run says why it is doing it. Nothing you indexed is touched, and the store format moves to 4; an older binary refuses a format-4 store by name rather than misreading it.

Install

macOS and Linux

:::sh
curl -fsSL https://raw.githubusercontent.com/semlith/semlith/main/install.sh | sh

Windows

:::powershell
irm https://raw.githubusercontent.com/semlith/semlith/main/install.ps1 | iex

Or download the archive for your platform below, unpack it, and put semlith on your PATH. Intel macOS has no prebuilt binary: ONNX Runtime no longer publishes x86_64 macOS builds.

Verify a download against SHA256SUMS before running it.

Source: README.md, updated 2026-09-20