Ten repositories appeared this week, among them a web engine that finished at Acid3 100/100, a JavaScript engine that finished at 88% of test262, and a text rasterizer with hinting. All three began the same way, and it is the way the last three months taught this project to begin.
| Repo | Commits | Lines | Focus | ||
|---|---|---|---|---|---|
| weft | 181 | +149,098 | −15,631 | born; URL parser to Acid3 100/100 | |
| shuttle | 80 | +39,785 | −2,450 | born; 12.4% to 88% of test262 | |
| modus | 66 | +4,379 | −772 | production eval changes hands | |
| scribe | 58 | +45,140 | −664 | born; outlines, shaping, hinting | |
| cl-tor | 10 | +2,214 | −179 | born; curl through Tor works | |
| cl-consensus | 9 | +449 | −74 | peer manager, archival backfill | |
| secp256k1-fast | 9 | +568 | −54 | constant-time secret operations | |
| brotli-pure | 5 | +1,658 | −74 | born; RFC 7932, both directions | |
| zstd-pure | 5 | +1,232 | −63 | born; Huffman + FSE | |
| gesso | 4 | +996 | −31 | born; 2D vector graphics on scribe | |
| loom | 3 | +996 | −4 | born; a window, and DOM input | |
| stencil | 3 | +952 | −16 | born; SVG on gesso | |
| cl-nostr | 2 | +1,346 | −3 | born; a Nostr client | |
| pagetree | 2 | +27 | −6 | an O(n²) read overflow, fixed | |
Here are the opening commits of two separate repositories, written a day apart, by a project that has spent three months learning what happens when you grade your own work.
weft: start a self-sovereign web engine — P0 WHATWG URL parser P0 encoding: kernel + UTF-8 decoder + differential oracle + worker stubs P0 encoding: 7 decoders built by a parallel agent swarm P0 encoding complete: 11/11 charsets scribe: scaffold + gamma-correct linear-light compositing scribe: adopt SWARM — sfnt kernel + ttx oracle + W1 table wave
In both cases the second or third commit is not a feature. It is the thing that will decide
whether the features are right: a differential oracle for character encodings in one, the
ttx font dumper in the other. Only then do the workers fan out, each taking one
decoder or one table, looping against the oracle until it stops improving.
That order is the accumulated lesson of this dispatch so far. № 5 adopted somebody else’s test suite so the implementation could not grade itself. № 6 discovered that a suite is worthless if the harness counting it can lose 17,587 tests without saying so. № 8 built a fuzzer as an instrument rather than chase a bug that moved when observed. № 14 pointed a real library at the implementation and used the form it died on as the measure. № 15 called into Bitcoin Core’s own compiled library and compared verdicts.
What is new here is that the oracle now comes before the code, and that it makes fanning work out possible at all. Nobody can supervise seven parallel character-set decoders by reading them. An oracle can.
The first commit is a WHATWG URL parser at 97.2% conformance. The second raises it to 97.7% by handling spaces in an opaque path before the query and fragment. Then character encoding — kernel, oracle, workers — reaching all 36 decoders the specification lists, including the Chinese, Japanese and Korean sets that need real tables. Then the HTML tokenizer, which lands at 100% of the html5lib suite in a single commit.
Tree construction is where the week’s texture shows. HTML’s parsing algorithm is a pile of special cases accumulated over thirty years, and there is no way to be clever about it — only to implement each rule and watch the number move:
DOM node kernel + core tree construction raw-text/RCDATA reentrancy (script/style/title/textarea) 173 → 187 stray </p> synthesizes empty <p>; dd/dt auto-close 187 → 190 TABLE insertion modes + foster parenting 190 → 212 scope bounds, foster setf bug, pre/textarea newline 224 → 246 frameset modes + form pointer + button scope 246 → 261 adoption agency algorithm + active formatting elements 261 → 281
That is the same ratchet the ANSI suite produced in № 5 and the same per-commit accounting as № 8, arriving in a brand-new repository on its second day, because by now it is simply how work is done here.
From there the week runs through the CSS cascade, layout and painting into scripting: the
DOM bound to a JavaScript engine, hit testing, box-tree rendering, viewport scrolling and event
dispatch, canvas gradients with alpha compositing, and SVG in an <img>. The
last Acid3 cluster closes on Friday — a NodeIterator mutation case and
scripts inside XHTML frames — taking it from 98 to 100. And one commit purely for taste:
the Big5 table rewritten as a data literal instead of fourteen thousand assignment statements.
shuttle starts on Tuesday as a skeleton — a value model, a bytecode virtual machine, and the seam through which a host binds its own objects. Control flow and a test262 runner follow the same day, which produces the first honest number: 12.4% of 47,058 tests. It closes the week at 41,404, or 87.99%.
The commits in between record where the count stood, and those history rows are kept in the repository rather than remembered — the same instinct as the status lines in № 14, and for the same reason: a number that only exists in somebody’s memory cannot be checked and cannot be regressed against.
Most of that climb is not the language but the library around it: property introspection and
the abstract operations the specification is written in, Symbol, regular
expressions, BigInt, and — because test262 does not grade on charm — the
internationalisation collators, segmenters and display names. The last commits of the week turn
back toward weft, exporting the host-binding predicates and a microtask drain, which is what a
DOM needs to run scripts on a real event loop.
scribe opens with gamma-correct linear-light compositing, which is the right thing to get
right first: blending in the wrong colour space is invisible until it is everywhere. By that
evening it has the metric, naming and character-map tables green against ttx,
outlines from the TrueType tables, an analytic rasterizer, and cubic charstrings with flex from
the Compact Font Format.
What is striking is how the later commits describe themselves. Shaping is “= HarfBuzz”. Variable fonts and advance-width variations are “= fontTools instancer”. The claim is not that a feature exists but that it agrees with the reference implementation, which is exactly the form of № 15’s zero divergence against Bitcoin Core. By Friday: WOFF and WOFF2 decompression that is outline-exact, hinting, stem darkening, a high-resolution demo comparing one-times and two-times rendering, and bounded glyph caches.
Friday also brings the three pieces that turn a rasterizer into a browser. gesso is 2D vector graphics standing on scribe’s coverage contract, and its second commit fixes stroke joins whose winding was cancelling them out under a non-zero fill. stencil parses SVG and renders it through gesso. loom is a window — an SDL shell over weft with DOM input, launched with a four-gigabyte heap and a large control stack because, as the commit says, the JavaScript engine recurses deep.
While all that was being built, Modus quietly changed how it runs Lisp. It has had two evaluators since № 6 built a tree-walking interpreter as one of its layers, alongside the path that compiles to bytecode and interprets that. Two evaluators means every semantic fix lands twice, and the one that misses it is the one somebody hits.
This week the bytecode path reached parity and became the default. Getting there is a list
of the places parity was missing: catch and throw through the
interpreter’s own jump mechanism, closures that capture and mutate, secondary values
across the runtime-call bridge, higher-order calls with a function object,
defstruct, handler-case catching a signalled condition, CLOS initarg
validation and compiler macros, and top-level defun persistence — the
keystone, because ASDF needs it and № 14 had made ASDF
the frontier.
Two pieces of method matter more than the fixes. An in-image differential gate runs the same form through both evaluators and compares, so parity is measured rather than asserted. And the flip itself is reversible behind a switch that is byte-identical when off, so the default can move and move back. Compile caching, worth about twenty times on repeated forms, is what makes running production evaluation through a compiler affordable at all.