rustoffrails / blueprints
AGENTS.md49 starsChanged 25 days agoApache-2.0View on GitHub
Each line is a mistake an agent shipped. The check that catches it is in parentheses.
- Reads credentials
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,774 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
The file
We split this AGENTS.md into the rules it gives an agent
3 rules. About 0 are common, 0 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 28
NEVER guess the running app's state: Ask it: curl -s $URL/dev/introspect.json (migrations, CSS staleness, protocol, streams) or cargo run …
- Very specific: line 35
NEVER
pkill/killall, or kill by name or pattern: Stop the PID file you started: kill "$(cat storage/pids/dev-$PORT.pid)" for bin/dev … - Very specific: line 41
Follow only the FRONTEND_MODE branch of each guide, and the UI_LIBRARY branch of the JS guides.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
<!-- Generated by Rust off Rails (generators/new.md). Agents keep the header current. Humans: edit product/, not code. -->APP: {{app_name}}
FRAMEWORK: Rust off Rails {{version}} (.offrails/, vendored {{date}})
FRONTEND_MODE: {{htmx | inertia | spa | api}}
UI_LIBRARY: {{react | svelte | none}} (none = no JS UI: htmx without islands, or api)
ISLANDS: {{yes | no}}
API: {{none | rest | graphql | both}} (a versioned API for other programs; api mode is never none)
DEV_DATABASE: sqlite (storage/development.sqlite3)
PROD_DATABASE: {{postgres | sqlite}}
DEPLOY_TARGET: {{later | fly | kamal | railway | render}}
ACCOUNTS: {{none | <methods>[ invite]: password | magic-link | password+magic-link, then " invite" when sign-up is closed}} ROLES: {{none | admin+member | …}} TENANCY: {{per-user | teams | shared | none}}
EMAIL: dev: local mailbox (/dev/mailbox); prod: {{smtp via <provider> | not yet (logged only)}}NEVER
Each line is a mistake an agent shipped. The check that catches it is in parentheses.
- NEVER look a record up without the actor.
<model>::find_for(db, &user, id), neverfind(db, id); rawfind/destroystaypub(in crate::models)(guard_test.rs,tenancy_test.rs,offrails check). - NEVER call work done while
sh .offrails/tools/offrails-checkprints aFAIL, or any Definition of Done command fails or was skipped without saying so. - NEVER add a retry, watchdog, reload cap,
sleepor raised limit without evidence (the failing request, its status and protocol) and adocs/decisions.mdline citing it (.offrails/workflow.md#when-something-fails). - NEVER serve a browser an untrusted certificate, or test login with certificate errors ignored. Chrome drops
Set-Cookieafter "Proceed (unsafe)", so login bounces. HTTPS in development only with mkcert (bin/dev-cert), else the http URLbin/devprints; smokes run with no certificate overrides (run.sh login). - NEVER ship a light surface, dark text or faint tone without its
dark:partner (abg-whitecard under a dark body: 1.09:1). The palette is in.offrails/guides/views.md#dark-mode(tests/app/theme_test.rs,run.sh a11yin light and dark). - NEVER guess the running app's state. Ask it:
curl -s $URL/dev/introspect.json(migrations, CSS staleness, protocol, streams) orcargo run -q -- introspect. - NEVER pick files by loose prefix, depend on
HashMaporder, or hash files per request (kernel/assets.rsuniqueness test). - NEVER change a header line (
FRONTEND_MODE,ISLANDS,UI_LIBRARY,TENANCY,FRAMEWORK) without the code to match, and never leaveFRAMEWORKbehind.offrails/VERSION(offrails check). - NEVER tick an acceptance criterion without a test that cites its id, or write a Security row without a test name (
offrails check). - NEVER edit
.offrails/or delete adocs/decisions.mdline. Supersede it with a new line (.offrails/workflow.md#decisions). - NEVER give an
idor*_ida 32-bit column, or let the suite run only on SQLite.big_pk_auto/big_integerandi64;INT4ids made every Postgres write a 500 behind a green SQLite suite (offrails check[ids],[postgres]). - NEVER bind development to
0.0.0.0or drop the Host check to "make it work"./devhas no login: the mailbox holds every sign-in link. A dev container or a phone setsAPP_BIND=0.0.0.0andAPP_ALLOWED_HOSTSon purpose (offrails check[bind],development_refuses_a_rebound_host_name). - NEVER
pkill/killall, or kill by name or pattern. Stop the PID file you started:kill "$(cat storage/pids/dev-$PORT.pid)"forbin/dev(it stops its whole tree),serve-$PORT.pidfor a plainserve(.offrails/cli.md#running-the-app-from-an-agent). Killing onlybin/dev's listener leaves its watchers running.
You are an agent working on a Rust off Rails app
- Read
.offrails/AGENTS.mdnow, then follow its load order. It overrides your general habits. - The human writes no code. Their intent lives in
product/. Update the spec before you build, and ask questions per.offrails/interview.md. - Follow only the
FRONTEND_MODEbranch of each guide, and theUI_LIBRARYbranch of the JS guides. - Done means
.offrails/workflow.md#definition-of-done, green, with each item's command run. Start withsh .offrails/tools/offrails-check. - Log decisions not covered by
.offrails/indocs/decisions.md; supersede, never edit. - Start app code from a snippet or a generator (both tested, both yours once copied); hand-write the rest.
cargo offrails snippets(snippet show <name>to read one),cargo offrails g --help; neither is mandatory. Commit after each run, then edit. Keep a feature in its own small files, and mark each line it adds to a shared file with its name (// posts).
Quick commands
bin/setup # first run
bin/dev # develop: open the URL it prints (https + HTTP/2 with mkcert, else http){{TS modes only: ", or :5173 via Vite"; htmx: nothing}}; tabs reload on save
sh .offrails/tools/offrails-check # mechanical gates: header, specs ↔ tests, tenancy, scoped lookups
cargo offrails verify # after each slice: fmt, CSS, clippy, one build, SQLite + Postgres suites at once
cargo offrails verify --full # before saying done: + offrails-check, coverage, deny, gitleaks, routes, browser smokes incl. every page after a boosted link, and prove (BASE=…)
BASE=… cargo offrails prove # screenshots + checks of every page → docs/proof/PROOF.md: link it in your final message
cargo offrails brand # after editing brand.toml (colors, fonts, radius, logo); components: /dev/components
cargo nextest run <name> # one test while it's red (SQLite)
docker compose up --build # the whole app, production-shaped, on Postgres (http://localhost:3000)
docker compose up -d db # a Postgres for verify (or set TEST_DATABASE_URL in .env)
cargo run -- db migrate # migrate (any DATABASE_URL)
cargo run -q -- introspect # the app's state as JSON (development; live parts: $URL/dev/introspect.json)
cargo run -- routes # list routes (with access levels); rewrites docs/routes.md
cargo offrails snippets # small tested code to copy: snippet show <name> (read), snippet add <name> (copy + wire)
cargo offrails g --help # generators: resource, model, controller (path params), page, api, job, mailer, channel, test
cargo offrails list-parts # parts (mailer, jobs, auth, realtime, dev dashboard): installed or available
cargo offrails add-part <name> # add one when the product needs it (dependencies first; re-running is a no-op)
cargo run -- jobs stats # with the jobs part: job counts per state (dashboard: /admin/jobs; dev tools: /dev)App-specific notes
<!-- Agents: add durable, app-specific guidance here (domain vocabulary, tricky invariants). Keep it short and link to product/ specs. -->This app started from the Rust off Rails template (.offrails/template/). Shared files carry one-line samples: <anchor> comments (// samples: config fields, {# samples: nav links #}) where cargo offrails add-part inserts a part's wiring. Keep them; they are inert comments.
Post-upgrade checks
<!-- Agents: list app-specific things /offrails:upgrade must verify after a framework upgrade, e.g. "the footer shows .offrails/VERSION (test: footer_shows_framework_version)". -->Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

