For an agent
Claude Code does not know rofl-nb exists. Paste this into the project's CLAUDE.md:
This project keeps checked invariants as ROFL notebooks (*.rofl.md). Run `rofl-nb --help` once.
After editing a notebook or the code it names, run `rofl-nb <file.rofl.md>` (`--json` to parse).
Exit 1: a `never` fails, fix the code or the rule. Exit 2: something was not read, see the errors.
Exit 3: it holds only as far as the model sees; read the rows listed as out of sight.
Commands
rofl-nb <file.rofl.md> [--json] [--cell N] what every cell says
rofl-nb <file.rofl.md> --all every answer, not the first 12 (JSON: 50)
rofl-nb <file.rofl.md> --timing the time of each phase, on stderr
rofl-nb <file.rofl.md> --format F a `draw` in the form F: mermaid, dot, argdown, vega-lite, ... (DRAWING.md)
rofl-nb edit <file.rofl.md> --cell N the new text of cell N from stdin (`--lang L` for a new cell); the only
safe way for a program to change a notebook: it writes the file only
if it reads back as written
rofl-nb translate <file.rofl.md> a model writes a rofl cell under each natural cell (rofl-nb models)
rofl-nb vocab [<file.rofl.md>] [word] the sentences a cell can use; with a file, its own too
rofl-nb --help env the environment variables:
$ rofl-nb --help env
ROFL_NB_LIMIT=120 seconds a run evaluates before it stops and answers what it found (exit 3)
ROFL_NB_MEMORY=<GB> gigabytes of heap likewise; by default most of what Node allows
ROFL_NB_DAEMON=0 run in this process; by default runs go to a kept kernel, started on first use
(the model loads once, 10 to 20 s; later runs take seconds)
ROFL_NB_TIMEOUT=<s> how long to wait for the kept kernel; by default ROFL_NB_LIMIT + 180
ROFL_NB_IDLE=900 seconds the kept kernel waits for a run before it exits
ROFL_NB_MODEL_CMD=<sh> a command that reads the prompt on stdin and prints the answer (the harness named command)
ROFL_NB_<NAME>=<path> the binary of that harness, e.g. ROFL_NB_CLAUDE=/opt/claude
ROFL_NB_ALLOW_TOOLS=1 run a harness that cannot be run without tools (codex, copilot, hermes)
ROFL_NB_MODEL_TIMEOUT=180 seconds translate waits for the model
ROFL_NB_READ_ROUNDS=6 rounds the model may read the workspace's files before it writes; ROFL_NB_READ_BUDGET=200000 bytes in all
ROFL_NB_UNTRACKED_COMMAND=<sh> prints the files your version control tracks, for untracked_by(command) in .rofl/read.rofl
Exit codes
0 every never holds · 1 a never fails · 2 something was not read · 3 holds, some only as far as the model sees, or the run hit its time or memory limit.
--json
One object. status is ok, fails, unread or blind (exit 0, 1, 2, 3). errors lists what was not read; unresolved, when present, the imports the model could not follow. cells[] has index, kind (rofl, datalog, natural, prose), line, errors and lines[]. Each line has kind (answers, never, why, whynot, unsure, extends, excise), text, verdict (answers, holds, fails, blind, explained, unasked), total, and answers[] of { sentence, literal, at }, where at is where in the code.
Drawing
Asked for a picture, read rofl:visual/viewpoints.rofl.md: sixty viewpoints, each with the question it answers, what its boxes, lines and frames mean, and its layout. Pick one by the question (? V answers Q, ? V is recognised by the words W), then write the rules that map the notebook's own sentences onto rofl:visual/graph.rofl.md and end the cell with draw graph. The words, the layouts and the steps are in docs/schemas.md; every kind of picture is in DRAWING.md.
Beyond a notebook
A question about code from the command line, with no notebook, is rofl ask, rofl why and rofl whynot (ASKING.md). Every verb, the worlds it keeps, its exit codes and the rofl serve protocol are in docs/cli.md. A world is evaluated on one heap: before pointing it at thousands of files, read A corpus larger than one heap there.