1@README.md 2 3## Notes for agents 4 5Every folder has its own CLAUDE.md with the invariants of the code in it: the 6questions and verdicts in `crates/jevhooks-daemon/src/`, the read-only filter in 7`crates/jevhooks-mod/src/`, the mod's memory, `$` calls and hook layering in 8`plugin/hooks/`, running the plugin tests in `plugin/tests/`. What follows holds 9everywhere. 10 11**Never make Jev's absence block anything.** No key, a throttle, a timeout, an 12unreachable daemon: all are `Pass`. The mod has its own 2.5 s limit on the daemon for 13the same reason. 14 15**Run `just mod` after any change to `crates/jevhooks-mod` or `jevhooks-events`,** and 16`just daemon` after any change to the daemon. The plugin loads 17`plugin/hooks/jevhooks.js` (wasm2js output, never edited by hand) and starts 18`plugin/bin/jevhooks` (a copy, not a link into `target/`). A session started after a 19rebuild replaces the running daemon by itself; to do it by hand, 20`plugin/bin/jevhooks stop` and start a session, or `op-env-run -- plugin/bin/jevhooks serve`. 21 22**Never remove the `[patch.crates-io] rmcp` entry because "3.5.0 is the latest".** rmcp 233.5.0 refuses every request after Claude Code's `server/discover` then `initialize` 24opening, so the MCP server connects and lists no tools. The fix is on the private 25`deizel/rust-sdk` fork (commit `1c69053`, on top of the `rmcp-v3.5.0` tag). Before 26dropping it, confirm in a session that the `status` tool is listed. 27 28**Assume nothing about the machine.** This is a plugin for anyone's machine, not for 29the one it was written on: no host-specific helpers, no WSL, no systemd, no particular 30host in the daemon or the mod. Where a figure is only knowable on some systems 31(available memory is `MemAvailable` on Linux and nothing built in elsewhere), the 32default is the generic one, a config key lets the user supply a command, and the 33absence of both is a `Pass`, never a guess. A configured command is the only source 34once set: do not fall back to the built-in figure when it fails, because the user set 35it to say the built-in figure is wrong there. 36 37**The key is never written anywhere.** Not in `.mcp.json`'s `env`, an `.envrc` or a 38file, and never printed; `status` says whether it arrived. 39 40**Build in the devshell, and check memory first.** Crates' build scripts link with a 41host `cc` even when the target is wasm32; `mkShell` supplies it. A release build of 42the daemon uses several gigabytes: `free -m` before starting one. 43 44**The docs are a guide, chapter by chapter.** Every folder with tracked files has a 45README that is a chapter (`# Chapter N: <name>, <subtitle>`, an opening that teaches, 46`> **Aside.**` detours, a `> **Try it.**`, then "For the people who maintain it" with 47a file map) and a CLAUDE.md beside it starting `@README.md`. The last line of each 48README is `← Previous: … · Up: … · Next: … →`, and the chain is a depth-first 49preorder of the folders in the order the root's table lists them; the lmjtfy site's 50README viewer follows those lines. A new folder gets its chapter, and the chapters 51after it are renumbered. Playful, never at the expense of a true fact: read the code 52before describing it, and keep every relative link pointing at a tracked path. 53 54**The README must not claim a build works for outsiders.** The rmcp patch is fetched 55over SSH from a private repository, and Cargo resolves the whole workspace before 56building any member, so without access every `cargo` command fails (measured 572026-10-02 with a fresh `CARGO_HOME` and SSH disabled). `claude plugin test plugin` 58needs no Cargo and is the thing an outside reader can run.