Stages, measured
LiLM is a month old and has passed through nine measurable stages. Each row is one stage, the number it produced, and what that number changed. The numbers come from the stage’s own report; where a stage found its predecessor wrong, that is the finding.
| # | Stage | What was measured | What it changed |
|---|---|---|---|
| 1 | Synthetic scale test (v0.0.1 engine) | 1,000,000 procedurally generated documents → 3,000,000 nodes. 152 s of total processing, of which the write itself ran at 12,407 documents per second (about 81 s); the rest was generating the documents. 64 s to consolidate the index. | Found two quadratic scans (an idempotency check and a keyword-membership check that took four minutes for 50,000 papers) and a 10 GB stop-word bloat. All three fixed before real data. |
| 2 | Index spike (synthetic) | A full-text index library beat the hand-rolled index at about 10 ms per query; a companion compressed edge store at about 29 bytes per edge. | Adopted the library and the edge store. The report’s own caveat: the corpus was synthetic, one edge type, at most two edges per node, so every density figure needed re-confirming on real text. |
| 3 | Real-corpus gate (“mode 5”) | 120,934 documents → 244,242 nodes across five tiers, ingested through the production path in 31.9 s; 37 ms cold query; 8,691 queries per second; a 55 MB index, 6% of the store; 10 of 10 matched-set queries correct; 959,067 of 959,068 terms preserved. | The architecture passed. The same gate showed the summariser truncating, relations at 0.29% of nodes against the synthetic near-saturation, and a weighted-AND shortcut running slower than the plain path (0.83×), so it was dropped everywhere. |
| 4 | Factory end to end (real slice) | Version A: 8,510 documents → 37,552 nodes, 349 edges, shipped. Version B built additively on top: 9,114 → 39,848, 356 edges. Rolled back; A re-served. A rebuild of A was byte-identical. | Deterministic build ids, atomic ship, working rollback. A real non-determinism (random index ids plus hash-map order in two languages) was found and fixed to get the byte-identical result. |
| 5 | QA gate and promotion | A scorecard with hard-fail buckets for correctness and query type, thresholds for latency that always record numbers, and a regression bucket. Every check was proven failable by a planted defect. Promotion validates the live served store and rolls back on failure; proven by sabotaging a frozen artefact. | The ledger is never updated for a build that failed validation. Shipping and building are different acts with different gates. |
| 6 | First full-corpus run (325 shards, 153 GB, 31.7M documents → about 57.8M nodes) | Five failed runs first (Losses). The first measured full run: ingest 15 min (2%), merge 662 min (83%), index build 110 min (14%), gates 19 min (2%). The merge pushed about 1.7 billion postings through B-trees six or seven times, serialised behind one table holding 68% of all postings. | The bottleneck was named with a number. Everything in stages 7 and 8 exists because 83% of eleven hours was one serial merge. |
| 7 | Flat sorted postings + a Rust merge | Design approved with amendments after a five-iteration loop of implement, adversarial review, and live 40-shard validation; the old-path baseline pinned before any change. | Replaces the per-cell database tables with node-grouped sorted runs and a k-way merge. In progress; the number goes here when the full rebuild runs. |
| 8 | GPU index proof of concept | Kill gate: 23.6 s against a 60 s bound at 210 million postings, oracle 10 of 10; GPU core 1.84 s, 12.7× the CPU baseline. Full corpus: 1.68 billion postings, about 18 s of GPU time, 76.8 GB peak, zero ordering violations. Today’s index build is 110 min. | Conditional go. Host memory binds first at twice the corpus, and it coexists with the current index rather than replacing it until a query-feature audit is done. |
| 9 | User stack: admission control | Before: a health probe got no answer within 1 s behind one stalled client; fast queries collapsed behind it; a concurrency cap of 10 was exceeded (13 on disk) through a check-then-act race. After: probe answered in 0.01 s; fast-tenant worst case 10 to 40 ms during a 10 s slow request; cap held at exactly 10. Eight of eight exit criteria green in 25 s. | Multi-tenant serving that cannot be taken down by one slow tenant. The user-interface phases that followed pass a criterion only when a sabotage makes it fail: twenty-five sabotages in the third phase.1 |
Reading the table
Three things repeat. A synthetic stage sets a number, a real stage corrects it (stages 2 and 3, and the relation density in Losses). A gate is not trusted until something has made it fail (stages 5 and 9). And the biggest single measurement on the page, the eleven-hour merge, was not a failure but a diagnosis: it named the serial wall with a percentage, and the next two stages are the response.
Stage 7’s number is missing on purpose. It will be filled in when the full rebuild on the new merge path completes, and not before.
Sources
Numbers on this page are quoted from the lab's own records. The records are private; each note gives the record's date.
- lab record, 2026-08-31 ↩