lmjtfy: a guide in fifteen chapters

Let Me Jev That For You. You know the joke: someone asks a question they could have searched for, so you send them a link that slowly types it into a search box for them. This is that joke, aimed at Jev, and then it gets carried away and actually answers.

Jev is TypeSafe AI's "System One" model. It does not write. You cannot ask it to explain anything. You hand it a question whose answers are already written down (yes or no; one of these five; somewhere on this scale), and it tells you how likely each one is, with numbers you can trust. That is the whole trick, and this site is built around the one thing Jev cannot do, which is write the question.

It is live at https://lmjtfy.fun. Jev's own documentation is at https://docs.typesafe.ai.

Try it. Open https://lmjtfy.fun/?q=Is+a+slot+machine+a+good+retirement+plan%3F and watch. The question types itself, Jev answers, and under the answer is every call that was made to get it, with the bytes that crossed the wire. (That question has been asked before, so nothing is spent: you get the kept answer. Chapter 9 explains why that matters so much.)

How to read this

Every folder in this repository is a chapter, and each one ends with a link to the next. Read them in order and you will know how all of it works; jump in anywhere and the chapter tells you what it is and what is beside it. Each chapter starts with the idea, in plain words, and ends with the parts a maintainer needs (files, invariants, commands). The CLAUDE.md tab on each folder is what an AI agent working here is told on top of the chapter.

ChapterFolderWhat you learn
1apps/Why there is one app, and what an "app" is here.
2apps/lmjtfy/The Worker: everything it serves, keeps and pushes.
3apps/lmjtfy/src/The Worker's files, in the order to read them.
4apps/lmjtfy/src/view/Pages as pure functions: data in, HTML out.
5packages/The libraries that do no I/O, which is most of the thinking.
6packages/rules/A rules engine, a Rete network, and why it batches.
7packages/ask/The eight questions Jev is asked about every question.
8packages/llm/The LLM, kept on a short leash.
9packages/archive/Never send the same request twice.
10packages/budget/Two daily budgets, and being fair to strangers.
11packages/card/Drawing a PNG one pixel at a time, in under ten milliseconds.
12packages/tree/How these very pages are made.
13tools/The helpers that are not the site.
14tools/eval/Choosing an LLM with a test, not a hunch.
15ds-bundle/ and third-party/What came from elsewhere.

If you know Nuxt

It is a website, and its parts have counterparts in any JavaScript framework. Here they are next to Nuxt's.

HereWhat it isIn Nuxt terms
A Cloudflare WorkerThe whole server, run at Cloudflare's edge on each request.The Nitro server, deployed to Cloudflare.
Rust, compiled to WebAssemblyThe language of all of it; wasm-bindgen lets it run inside the Worker's JavaScript runtime.TypeScript, compiled ahead of time.
axumRoutes a request to a handler (apps/lmjtfy/src/lib.rs).server/api/*.ts and h3.
maudHTML written in Rust, checked by the compiler, escaped by default..vue templates.
DatastarThe page sends what was typed; the server streams back HTML that replaces parts of the page. No client state, no JSON API.Vue's reactivity, but the server owns the state.
Durable ObjectsOne small server per name, with its own SQLite, that every request can reach: the archive and the budgets.A database and a singleton service in one.
packages/*Pure Rust libraries with no I/O, tested with cargo test.Composables and utils/, with unit tests.
NixEvery tool at an exact version, from nix develop.package.json and a Node version manager.

The whole story in one picture

Here is what happens between Enter and the answer. Every arrow is a chapter somewhere in this guide.

sequenceDiagram
  participant B as Browser
  participant W as Worker (axum)
  participant A as Archive (Durable Object)
  participant J as Jev
  participant L as LLM (Workers AI)
  B->>W: POST /ask {q}
  W->>A: facts about q?
  A->>J: one request, eight questions
  J-->>A: probabilities
  A-->>W: kept, and shared with anyone else asking
  W-->>B: SSE: the transcript so far
  alt the rules need options or a scale written
    W->>A: the LLM's tool call
    A->>L: the request
    L-->>A: tool calls
    W->>A: Jev, judge them
    A->>J: one request
    J-->>A: answers
  end
  W-->>B: SSE: the answer, and every call that made it
  A-->>B: every open page: a toast, and the feeds

In words:

  1. Jev is asked about the question first: eight typed questions in one request. Can it be judged at all? What kind of question is it? Is it several? And what is Jev's own answer, read each way? (Chapter 7.)
  2. Rules decide what that means (chapter 6). Most questions end right here, with a refusal or with Jev's own answer, and no LLM is involved.
  3. Only when something has to be written, the options of a pick, the levels of a scale, the parts of several questions, does the LLM write it, as tool calls (chapter 8).
  4. Jev judges what the LLM wrote, in one more request.

Aside. Why go to Jev first, before the clever model that can write? Price. A Jev request costs about a hundredth of an LLM call, so every question Jev can settle by itself is a call the LLM never gets. The whole design leans that way: ask the cheap honest thing first, and only call in the expensive eloquent thing when someone has to write.

Running it yourself

Anyone who clones it can build and test it. No GitHub account needed:

git clone --recurse-submodules https://lmjtfy.fun/lmjtfy.git
cd lmjtfy
nix develop                   # or direnv; the toolchain, from public inputs
cargo test --workspace        # everything but the Worker's I/O, natively
cd apps/lmjtfy && worker-build --release

The other projects, and the client they share

Three more of the owner's projects ask Jev, and all four share one client, jevcrates. Each is served here the same way, with its own pages:

CloneWhat
https://lmjtfy.fun/jevcrates.gitThe Rust client for Jev. To use it in your own project, add it to Cargo.toml straight from this site: its front page has the lines.
https://lmjtfy.fun/postjevsql.gitJev in Postgres: a pgrx extension, in SQL.
https://lmjtfy.fun/jevsnes.gitJev plays A Link to the Past on a SNES core.
https://lmjtfy.fun/jevhooks.gitJev judges Claude Code's hooks.

To run the Worker itself you need your own Cloudflare account (Workers AI has no local emulation) and a TypeSafe API key: wrangler login, put LMJTFY_TYPESAFE_API_KEY=... in apps/lmjtfy/.dev.vars, and run wrangler dev in apps/lmjtfy. The budgets and the clone proxy run without their secrets, counting only themselves and answering clones with 503.

For the owner

The owner's shell, nix develop .#owner, adds the tools that read this deployment's credentials from 1Password through the private nix-facts and nix-pkgs inputs:

nix develop .#owner
pitchfork start --local       # the dev server, on http://localhost:8787/
pitchfork logs worker         # what it is doing
pitchfork stop --local

pitchfork supervises the dev server from pitchfork.toml, as it does ~/aifleet's. Its one long-running daemon, worker, is the Worker under wrangler dev, inside op-env-run for the Jev key and through lmjtfy-wrangler for the Cloudflare token. wrangler rebuilds the Worker when a source changes. If it dies, pitchfork starts it again (tools/wrangler-dev).

To deploy:

nix develop .#owner
pitchfork stop --local                      # the deploy builds into the dev server's build/
lmjtfy-wrangler apps/lmjtfy deploy
op-env-run -- lmjtfy-secret jev             # only when the Jev key changes
pitchfork start --local

Both read the Cloudflare token from 1Password, which asks for approval on the Windows side: an "authorization timeout" means its prompt was not answered. The site is public and every visitor spends from the shared budgets. The secrets are listed in chapter 2, apps/lmjtfy/.

Files at the top

FileWhat
Cargo.tomlThe Cargo workspace: every crate, and the versions they share.
flake.nixThe two dev shells: nix develop for anyone, nix develop .#owner for the owner's tools.
pitchfork.tomlThe dev server's processes.
.gitmodulesThe jevcrates submodule, by a relative URL (chapter 15).
.envrcdirenv: the owner's shell where it can be built, the public one elsewhere.

Next: Chapter 1, apps/ →