1# lmjtfy: a guide in fifteen chapters 2 3**Let Me Jev That For You.** You know the joke: someone asks a question they 4could have searched for, so you send them a link that slowly types it into a 5search box for them. This is that joke, aimed at Jev, and then it gets 6carried away and actually answers. 7 8Jev is TypeSafe AI's "System One" model. It does not write. You cannot ask 9it to explain anything. You hand it a question whose answers are already 10written down (yes or no; one of these five; somewhere on this scale), and it 11tells you how likely each one is, with numbers you can trust. That is the 12whole trick, and this site is built around the one thing Jev cannot do, 13which is write the question. 14 15It is live at <https://lmjtfy.fun>. Jev's own documentation 16is at <https://docs.typesafe.ai>. 17 18> **Try it.** Open 19> <https://lmjtfy.fun/?q=Is+a+slot+machine+a+good+retirement+plan%3F> 20> and watch. The question types itself, Jev answers, and under the answer is 21> every call that was made to get it, with the bytes that crossed the wire. 22> (That question has been asked before, so nothing is spent: you get the 23> kept answer. Chapter 9 explains why that matters so much.) 24 25## How to read this 26 27Every folder in this repository is a chapter, and each one ends with a link 28to the next. Read them in order and you will know how all of it works; jump 29in anywhere and the chapter tells you what it is and what is beside it. 30Each chapter starts with the idea, in plain words, and ends with the parts a 31maintainer needs (files, invariants, commands). The `CLAUDE.md` tab on each 32folder is what an AI agent working here is told on top of the chapter. 33 34| Chapter | Folder | What you learn | 35| --- | --- | --- | 36| 1 | [apps/](apps/) | Why there is one app, and what an "app" is here. | 37| 2 | [apps/lmjtfy/](apps/lmjtfy/) | The Worker: everything it serves, keeps and pushes. | 38| 3 | [apps/lmjtfy/src/](apps/lmjtfy/src/) | The Worker's files, in the order to read them. | 39| 4 | [apps/lmjtfy/src/view/](apps/lmjtfy/src/view/) | Pages as pure functions: data in, HTML out. | 40| 5 | [packages/](packages/) | The libraries that do no I/O, which is most of the thinking. | 41| 6 | [packages/rules/](packages/rules/) | A rules engine, a Rete network, and why it batches. | 42| 7 | [packages/ask/](packages/ask/) | The eight questions Jev is asked about every question. | 43| 8 | [packages/llm/](packages/llm/) | The LLM, kept on a short leash. | 44| 9 | [packages/archive/](packages/archive/) | Never send the same request twice. | 45| 10 | [packages/budget/](packages/budget/) | Two daily budgets, and being fair to strangers. | 46| 11 | [packages/card/](packages/card/) | Drawing a PNG one pixel at a time, in under ten milliseconds. | 47| 12 | [packages/tree/](packages/tree/) | How these very pages are made. | 48| 13 | [tools/](tools/) | The helpers that are not the site. | 49| 14 | [tools/eval/](tools/eval/) | Choosing an LLM with a test, not a hunch. | 50| 15 | [ds-bundle/](ds-bundle/) and [third-party/](third-party/) | What came from elsewhere. | 51 52## If you know Nuxt 53 54It is a website, and its parts have counterparts in any JavaScript 55framework. Here they are next to Nuxt's. 56 57| Here | What it is | In Nuxt terms | 58| --- | --- | --- | 59| A Cloudflare Worker | The whole server, run at Cloudflare's edge on each request. | The Nitro server, deployed to Cloudflare. | 60| Rust, compiled to WebAssembly | The language of all of it; `wasm-bindgen` lets it run inside the Worker's JavaScript runtime. | TypeScript, compiled ahead of time. | 61| axum | Routes a request to a handler (`apps/lmjtfy/src/lib.rs`). | `server/api/*.ts` and h3. | 62| maud | HTML written in Rust, checked by the compiler, escaped by default. | `.vue` templates. | 63| Datastar | The 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. | 64| Durable Objects | One 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. | 65| `packages/*` | Pure Rust libraries with no I/O, tested with `cargo test`. | Composables and `utils/`, with unit tests. | 66| Nix | Every tool at an exact version, from `nix develop`. | `package.json` and a Node version manager. | 67 68## The whole story in one picture 69 70Here is what happens between Enter and the answer. Every arrow is a chapter 71somewhere in this guide. 72 73```mermaid 74sequenceDiagram 75 participant B as Browser 76 participant W as Worker (axum) 77 participant A as Archive (Durable Object) 78 participant J as Jev 79 participant L as LLM (Workers AI) 80 B->>W: POST /ask {q} 81 W->>A: facts about q? 82 A->>J: one request, eight questions 83 J-->>A: probabilities 84 A-->>W: kept, and shared with anyone else asking 85 W-->>B: SSE: the transcript so far 86 alt the rules need options or a scale written 87 W->>A: the LLM's tool call 88 A->>L: the request 89 L-->>A: tool calls 90 W->>A: Jev, judge them 91 A->>J: one request 92 J-->>A: answers 93 end 94 W-->>B: SSE: the answer, and every call that made it 95 A-->>B: every open page: a toast, and the feeds 96``` 97 98In words: 99 1001. **Jev is asked about the question first**: eight typed questions in one 101 request. Can it be judged at all? What kind of question is it? Is it 102 several? And what is Jev's own answer, read each way? (Chapter 7.) 1032. **Rules decide what that means** (chapter 6). Most questions end right 104 here, with a refusal or with Jev's own answer, and no LLM is involved. 1053. **Only when something has to be written**, the options of a pick, the 106 levels of a scale, the parts of several questions, does the LLM write it, 107 as tool calls (chapter 8). 1084. **Jev judges what the LLM wrote**, in one more request. 109 110> **Aside.** Why go to Jev first, before the clever model that can write? 111> Price. A Jev request costs about a hundredth of an LLM call, so every 112> question Jev can settle by itself is a call the LLM never gets. The whole 113> design leans that way: ask the cheap honest thing first, and only call in 114> the expensive eloquent thing when someone has to write. 115 116## Running it yourself 117 118Anyone who clones it can build and test it. No GitHub account needed: 119 120 git clone --recurse-submodules https://lmjtfy.fun/lmjtfy.git 121 cd lmjtfy 122 nix develop # or direnv; the toolchain, from public inputs 123 cargo test --workspace # everything but the Worker's I/O, natively 124 cd apps/lmjtfy && worker-build --release 125 126## The other projects, and the client they share 127 128Three more of the owner's projects ask Jev, and all four share one client, 129jevcrates. Each is served here the same way, with its own pages: 130 131| Clone | What | 132| --- | --- | 133| <https://lmjtfy.fun/jevcrates.git> | The 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. | 134| <https://lmjtfy.fun/postjevsql.git> | Jev in Postgres: a pgrx extension, in SQL. | 135| <https://lmjtfy.fun/jevsnes.git> | Jev plays A Link to the Past on a SNES core. | 136| <https://lmjtfy.fun/jevhooks.git> | Jev judges Claude Code's hooks. | 137 138To run the Worker itself you need your own Cloudflare account (Workers AI 139has no local emulation) and a TypeSafe API key: `wrangler login`, put 140`LMJTFY_TYPESAFE_API_KEY=...` in `apps/lmjtfy/.dev.vars`, and run 141`wrangler dev` in `apps/lmjtfy`. The budgets and the clone proxy run without 142their secrets, counting only themselves and answering clones with 503. 143 144## For the owner 145 146The owner's shell, `nix develop .#owner`, adds the tools that read this 147deployment's credentials from 1Password through the private `nix-facts` and 148`nix-pkgs` inputs: 149 150 nix develop .#owner 151 pitchfork start --local # the dev server, on http://localhost:8787/ 152 pitchfork logs worker # what it is doing 153 pitchfork stop --local 154 155[pitchfork](https://pitchfork.jdx.dev) supervises the dev server from 156`pitchfork.toml`, as it does `~/aifleet`'s. Its one long-running daemon, 157`worker`, is the Worker under `wrangler dev`, inside `op-env-run` for the Jev 158key and through `lmjtfy-wrangler` for the Cloudflare token. wrangler rebuilds 159the Worker when a source changes. If it dies, pitchfork starts it again 160(`tools/wrangler-dev`). 161 162To deploy: 163 164 nix develop .#owner 165 pitchfork stop --local # the deploy builds into the dev server's build/ 166 lmjtfy-wrangler apps/lmjtfy deploy 167 op-env-run -- lmjtfy-secret jev # only when the Jev key changes 168 pitchfork start --local 169 170Both read the Cloudflare token from 1Password, which asks for approval on 171the Windows side: an "authorization timeout" means its prompt was not 172answered. The site is public and every visitor spends from the shared 173budgets. The secrets are listed in chapter 2, 174[apps/lmjtfy/](apps/lmjtfy/#credentials). 175 176## Files at the top 177 178| File | What | 179| --- | --- | 180| [Cargo.toml](Cargo.toml) | The Cargo workspace: every crate, and the versions they share. | 181| [flake.nix](flake.nix) | The two dev shells: `nix develop` for anyone, `nix develop .#owner` for the owner's tools. | 182| [pitchfork.toml](pitchfork.toml) | The dev server's processes. | 183| [.gitmodules](.gitmodules) | The jevcrates submodule, by a relative URL (chapter 15). | 184| [.envrc](.envrc) | direnv: the owner's shell where it can be built, the public one elsewhere. | 185 186Next: [Chapter 1, apps/](apps/) →