I rebuild real systems, then publish where the design broke.

Kubernetes' API server, reimplemented far enough that the real kubectl can't tell. A browser tab scheduler that destroys 6 tabs where discarding destroys 8. A search engine with its own crawler, index and ranker.

I'm Seth Wheeler, a software engineer and graduate student. Day to day I work on platform and integration engineering (Node microservices, Kubernetes, CI/CD) and, increasingly, MCP servers and retrieval-augmented tooling. What keeps pulling me in is systems that have to hold a resource contract under concurrency: schedulers, protocol implementations, anything whose correct behaviour is only observable from outside the process that's supposed to guarantee it.

Start here

Evaluating my work
The write-ups are the best evidence of how I work: a modelling error I found in my own design and quantified, and a bug that was only observable from outside my process. Background on the about page.
Here to read code
nodejs-k8s is the most substantial public codebase, and the compatibility claim is testable in about a minute with a kubectl you already have. The projects page has the measured detail on each one.
Just browsing
All writing, or the feed.

Projects

  • nodejs-k8s124 stars · JavaScript

    Kubernetes' core APIs, reimplemented in Node. Point your real kubectl at it.

    Pods, deployments, replica sets, services and jobs served over the same REST surface the real API server exposes, so the unmodified kubectl CLI and standard YAML work against it unchanged.

  • KestrelSwift · WebKit

    A macOS browser with a memory budget for tabs: 788 MB against discard-LRU's 802 MB, destroying 6 tabs to its 8.

    ~5,500 lines of Swift on WKWebView. Background tabs are demoted down a ladder of measured states to stay under budget. Re-measured against real process footprint rather than per-tab attribution, the reduction on heavy pages is 1.24× rather than the 1.43× first reported, and on a budget 2.9× below its own feasibility floor the ladder is 1.35× worse than managing nothing at all.

  • lambda-languageJavaScript · four backends

    A small language whose four independent backends (C, WebAssembly, ARM64, a bytecode VM) have to agree byte for byte.

    Twenty test programs and ten examples run through all four code generators and diffed against each other, which caught an inverted || in the bytecode compiler and a u64 literal wasm encoded with a bit too many. The compiler is then rewritten in the language itself, stage by stage against the JavaScript it replaces, and bootstraps to a fixpoint: the last two stages are byte-identical across 6,883 lines.

  • social-deduction-benchJavaScript · Ollama

    Social deduction as an LLM benchmark: scored per turn and corrected for chance, not ranked by win rate.

    522 games across 19 models, measuring deception and deception-detection separately, with a rule-based control that nothing has beaten yet.

  • reckoner (research)Research · write-up

    Fifty-plus experiments on whether language-model capability really needs billions of parameters.

    A mixture-of-experts streaming cost model validated byte-for-byte against a runtime I didn't write, and to 1.1% against an unrelated model; then a 276B model run from SSD whose bytes-per-token prediction held while its speed prediction missed by 23×, for a limitation declared in advance. Not a public repo; the write-up is the artifact.

  • video-timelinePython · ffmpeg · Tesseract

    Hands a video to a language model as a measured timeline, not a pile of screenshots.

    Turns an MP4 or MOV into timestamped intervals (shot boundaries, camera-motion vectors, on-screen text, audio activity) so the model reasons about what happened between frames instead of inventing it. Python over ffmpeg and Tesseract; no sample video ships, because the test fixtures are generated with known contents.

  • assay-checkson npm · Python · JavaScript · zero-dependency

    Finds duplicate functions by executing them, not by reading their names.

    Two questions ordinary CI does not ask about code that already passes: could those tests have failed, and does the tree already answer this? Candidate pairs are functions whose outcome vectors match across one deterministic ladder of inputs, so the decider is execution rather than text: it paired is_wordy with _word, which no name-based detector puts together. The other half audits mutation harnesses against six named ways a run can report success without a test having run. Python and JavaScript, zero dependencies in both, and pointed at itself with 78 mutations.

  • sql-nodejson npm · JavaScript · zero-dependency

    An in-memory SQL engine on npm with a hand-written parser and genuinely zero dependencies.

    Parses SQL strings and answers SELECT with real column projection over its own table and row storage. Deliberately small (one equality per WHERE, no joins or aggregates) and the limits are listed in the README rather than discovered.

  • webCrawlerJavaScript · MongoDB

    A search engine (crawler, inverted index, BM25 ranker) with no Elasticsearch.

    A hand-written robots.txt parser and a politeness limiter that survives 100 concurrent worker processes, asserted against what the crawled server actually received rather than what the limiter reported.

  • Postmastr-Backend3 stars · JavaScript

    A mailroom tracker that reads shipping labels off a photo and emails the recipient.

    Tesseract.js OCR over label images, wired into a Node/Express and MongoDB backend.

All projects, in detail →

Writing

  • Asking Trained Among Us Bots Why They Moved

    My Among Us crew bots explain each move by splitting the decision score into one part per input, exact to about 1e-14 over 155,209 decisions. The captions built from it were still wrong: 45 of 61 moves captioned "fixing the reactor" went farther from the reactor.

  • Training Among Us Bots: The Crew That Stopped Fixing the Reactor

    Ten thousand games into a self-play run, my Among Us impostors found that sabotaging the reactor beat the crew. The crew now weighted its next task 4.1 times as much as the fix, and fixed 0 of 7 sabotages. Paying for each fix flipped that to 7 times toward the fix, and 30 of 34.

  • Giving Evolved Monopoly Players a Memory of Past Trades

    Evolved Monopoly players with a memory of past trades won 56.1% of two-against-two games against the same setup without one. A third population that barely used its one history-based input won 55.8% against the same opponents, so that margin does not show that memory helped.

  • Why NEAT Stopped Forming Species When the Starting Genome Grew

    The same NEAT code that split an XOR population into 13 species in ten generations kept a Monopoly population in exactly one, because a 180-gene starting genome shrank every compatibility distance to a median of 0.368 against a threshold of 3. Counting only the genes added since the start moved that median to 6.379.

  • Hill Climbing, Backpropagation and NEAT on the Same XOR Problem

    I expected backpropagation to learn XOR with the least work. At learning rate 0.5 it needed 9,268 to 11,124 network runs where a random-nudge hill climber needed 1,512 to 1,648. Only on a two-output full adder did it win, needing about a third of the hill climber's work.

All writing →