1@README.md 2 3- **Only the Worker talks to Jev**, through `jev-client` on `jev-worker`'s 4 ports. Do not add a second Jev client or a retry loop here. Anything 5 missing belongs in `~/jevcrates`, and this repo moves its submodule pin 6 (the user, 2026-10-02: move shared functionality to jevcrates and depend on it). 7- **The rules decide what happens to a query** (`packages/rules`, `RULES`), 8 and `decide` in `apps/lmjtfy/src/lib.rs` only carries out what 9 `Network::next` says. A new step is a new fact and a rule, not an `if` in 10 the Worker. The diagram is drawn from the same network, so it cannot show 11 rules other than the ones that run. 12- **Jev facts are asked for together.** `Network::next` returns every Jev 13 fact a live rule is waiting on, and they go out as one request (the user, 14 2026-10-02: "firing a single request with N questions to backfill"). Do 15 not ask for one in a request of its own. 16- **The LLM is given only the tools the rules asked for** (`llm::request` 17 with `wants`), and a question of any other kind it writes is not sent 18 (`llm::takes`). Jev has already answered the other readings itself; a 19 second answer to one of them from the LLM's wording disagrees with the 20 first, as it did on 2026-10-02. 21- **Jev answers; the LLM only writes the question.** Never show the LLM's own 22 text as an answer, and never have it answer when it makes no tool call. 23- **The tool call panels show the bodies that crossed the wire**, indented and 24 coloured for reading (the user, 2026-10-02). Printing may add whitespace and 25 nothing else: no reordered keys, no dropped or summarised fields. `view`'s 26 test parses the printed JSON back and compares it to the raw body, and 27 `ask`'s tests hold the body shown equal to the body sent. 28- **`/ask` sends the whole transcript in every event.** Keep it that way: the 29 browser has no state to get out of step with. 30- **The same request is never sent to the same model twice** (the user, 31 2026-10-02: "never send the same exact shape to the same 32 model, ever"), **unless a visitor presses ↻ on it** (the owner, later the 33 same day: "a button to bypass cache for a request"). Every Jev and LLM call 34 goes through `archive::call` (`apps/lmjtfy/src/archive.rs`), which returns 35 the kept response or makes the call once. `Pick::Fresh` is the only way to 36 send a kept request again, and only `$pins` from the page sets it: never 37 add another path that does. Every response is kept, as a numbered version, 38 and does not expire; stepping through versions (`Pick::Version`) sends 39 nothing, and neither does any call after the one stepped (`KeptOnly`). A new call site that reaches 40 Jev or Workers AI any other way breaks the rule, and is also unmetered 41 public spend: the archive is where the budget is held. 42- **The site shows questions and answers and nothing about who asked.** No 43 page, feed, toast or preview may show a visitor's address, browser id, 44 network or exact place (the online list's city and country is the one 45 thing shown, the owner's ruling of 2026-10-02). 46- **The archive keeps everything, for the owner alone** (the owner, 47 2026-10-03: "anywhere in the app where we are dropping data we should 48 plug", and of visitors, "Everything, linked"). Every request worth keeping 49 is a row of `events` (`packages/archive/src/event.rs`): the question, how 50 it ended, the address, the browser's id, the user agent, and Cloudflare's 51 network and place. This reverses the rulings of 2026-10-02 (no address, 52 nothing linking one browser's questions). Do not write that the site keeps 53 nothing about visitors; chapter 2, "What is kept about visitors", is the 54 true account, and a new thing that is known and thrown away is a bug. 55- **`events` is read only through the admin door** (`archive::ADMIN`, the 56 archive object's `/admin` path), which only the owner's separate admin 57 Worker reaches, by binding the object. This Worker must never send a 58 request there or pass a visitor's request to the object, a socket upgrade 59 on `/live` aside: the object would read it as a message. 60- **A question counts each browser once** (`askers`, the owner, 61 2026-10-02): the archive gets `asker(id, question)`, a hash per browser 62 per question, which is what counts it once. The hash is the key and says 63 nothing to a reader; the browser's id is kept beside it (`browser`), as 64 it is in `events`, for the owner's backend. 65- **What is listed is the rules' call** (`Note::List`, which needs Jev's `fit` 66 fact), **unless the owner overrules it** (`asked.moderated`, set through 67 the admin door; the owner, 2026-10-03: "approve or unapprove, basic 68 moderation"). Jev's verdict stays in `listed` beside it. Do not list a 69 question by any other path, and read the feed with 70 `COALESCE(moderated, listed)`. 71- **A link preview reads the archive and asks nothing.** Bots fetch every 72 pasted link; a preview that made a call would spend the shared budget on 73 them. 74- **The `wasm-bindgen` crate is pinned to the nix CLI's exact version** in the 75 root `Cargo.toml`. After `nix flake update`, move the pin and `cargo update 76 -p wasm-bindgen` together. 77- **The dev server is pitchfork's, and starting it is the agent's job.** 78 `nix develop .#owner -c pitchfork start --local`, then read `pitchfork logs worker`. 79 Do not start `wrangler dev` by hand beside it, and do not hand the user a 80 command to run (the user, 2026-10-02). 81- **Stop or restart it with pitchfork** (`pitchfork stop --local`, `pitchfork 82 restart worker`), never with `pkill -f wrangler`: `-f` matches the shell 83 running the command and kills it (twice, 2026-10-02). 84- **Two shells: `nix develop` for anyone, `nix develop .#owner` for the 85 owner's tools** (lmjtfy-wrangler, lmjtfy-secret, lmjtfy-eval, pitchfork). 86 Only the owner shell may use `nix-pkgs` or `nix-facts`: Nix fetches a 87 locked input only when an output uses it, so one reference from the 88 default shell breaks `nix develop` for everyone who clones (they cannot 89 read those repositories). 90- **Do not export an `op://` value from the devshell.** `op-env-run` resolves 91 every such value in the environment it is started from, with an account 92 that cannot read the Cloudflare item, and refuses to start. That is why the 93 eval's reference lives inside `lmjtfy-eval`. 94- **Never pipe a value into `lmjtfy-wrangler`.** It runs op.exe before 95 wrangler, and op.exe eats the stdin (an empty secret went live that way, 96 2026-10-02). Use `lmjtfy-secret jev | account | analytics`. 97- **The neuron count is the account's, read from Cloudflare.** Do not go back 98 to counting only this Worker's calls: on 2026-10-02 the eval and local dev 99 had spent 950 neurons the site's counter knew nothing about. 100- **Do not load-test the live site.** Every answered ask is counted on the 101 public feed and in "So far" (2026-10-02: the agent's own rate-limit test put 102 "asked 67 times" on the home page). Load-test the dev server. On the live 103 site, ask once; to test the visitor limit there, post an empty `q`, which 104 counts towards the limit and touches nothing else. 105- **After a deploy, check Jev with `/gate` on text never sent before** 106 (`{"q":"deploy check <time>"}`): a missing or empty key still deploys 107 cleanly and serves the page, and only a request that is really sent shows 108 it. Never check with `/ask`: a question already kept sends nothing, so it 109 tests nothing, and it adds an ask to the public count (2026-10-02: four 110 such checks took one question from ×3 to ×7; MIGRATIONS step 4 undid it). 111 To check the clone proxy, `git ls-remote <site>/lmjtfy.git`, which is not 112 counted; a clone is. 113- **The clone proxy serves `Repo::ALL` and only `git-upload-pack`.** Its 114 token must stay read-only (Contents: read on those repositories), so a push 115 is impossible at GitHub and not only at the routes. A new repository is a 116 new `Repo` variant; never take the upstream from the request path. 117 `.gitmodules` URLs stay relative, or a clone from the site points its 118 submodule at private GitHub and fails. 119- **The folders are a guide, chapter by chapter** (the owner, 2026-10-02: 120 "read like the documentation subsite and like a tutorial flow", in the 121 spirit of why's (poignant) guide). Every folder's README is a chapter: 122 `# Chapter N: <name>, <subtitle>`, an opening that teaches the idea, `> 123 **Aside.**` detours, a `Try it` against the live site or `cargo test`, the 124 maintainers' reference, and a last line `← Previous · Up · Next →` in 125 reading order (the prologue's table). A new folder gets its chapter and a 126 CLAUDE.md, and the chapters after it are renumbered; `view::code::guide` 127 fails the build on a folder without both, or a link that goes nowhere. 128 The code pages' ◀ ▶ tabs follow those last lines, so the Next chain must 129 be a depth-first walk (each folder before its subfolders, a subtree 130 finished before its next sibling, every folder once, the last chapter with 131 no Next); `the_chapters_lead_on_depth_first_through_every_folder` holds it. 132 Playful, never at the expense of a true fact. 133- **A deploy that people on the site should hear about carries a 134 `Release-Note:` trailer** in its HEAD commit: one line, plain text, shown 135 as a toast to every page from an earlier build when it reconnects 136 (`build.rs`, `LMJTFY_NOTE`). Most deploys have none. 137- **The site is `https://lmjtfy.fun`, bare.** `lmjtfy.deizel.workers.dev` 138 (where it began) and `www.lmjtfy.fun` answer only to redirect there for 139 good (`moved`, `ELSEWHERE`). Write the bare address in docs, clone lines 140 and Cargo lines. Do not redirect a request that is not a navigation: a 141 page still open on the old address would lose its socket and its posts. 142- **Deploy without asking** (the user, 2026-10-02: "please deploy without 143 asking"). It is public and spends real money for every visitor, so deploy 144 only verified, committed work, and check the live site after. 145 Open work lives in the brain page `technology/artificial-intelligence/jev/lmjtfy.md`.