Cursor rules for a Rails codebase
September 24, 2026
Keep reading
- Rails vs Rust in 2026, after HEY moved its backend
- Is Rails token efficient code? Counting what an agent has to read
- Testing what an agent wrote
- Reviewing Rails an agent wrote
- Pencils down: what DHH actually said at Rails World 2026
- Convention over configuration is a context argument now
- Claude Code in a Rails codebase
- AGENTS.md for a Rails app
DHH opened Rails World 2026 in Austin with a position he summarised himself as "It's pencils down, people. Writing code by hand is no longer an economically viable skill for most programmers at most companies." If that is where the work is going, then what an editor's rules file is for changes too. A rules file stops being a style preference and becomes the part of the repository that tells an agent what it cannot infer from the code in front of it.
Which is a much smaller file than most people write.
Which file Cursor reads in September 2026
Two formats are in circulation and they are not equivalent. The older one is a single
.cursorrulesfile at the project root. The current one is a directory,.cursor/rules/, holding one or more.mdcfiles, each with YAML frontmatter..cursorrulesstill works. A member of the Cursor team answering a thread on the community forum on 15 July 2025 said that "Cursor always sends your rules to the model", and nobody from Cursor has said the file stopped being read. What has happened is quieter: the rules documentation atcursor.com/docs/context/rulesdoes not contain the string.cursorrulesat all, not as a supported format and not as a deprecation note. Every feature shipped since, which is glob scoping, per rule activation modes and agent requested rules, exists only in the.mdcformat. A format that works and is undocumented is a format with a date on it.Four sources of rules merge into one context, and the precedence is documented: Team Rules, then Project Rules, then User Rules, with the note that "All applicable rules are merged; earlier sources take precedence when guidance conflicts."
AGENTS.mdsits alongside them as a plain Markdown file with no frontmatter, supported in the project root and in subdirectories, where "Instructions from nestedAGENTS.mdfiles are combined with parent directories, with more specific instructions taking precedence." Writing an AGENTS.md for a Rails app covers that file on its own terms, and it is the one to reach for first if your team is not all on Cursor.What the three frontmatter fields actually do
A
.mdcrule carries three frontmatter keys, and the combination decides when the rule is loaded. Cursor publishes the resolution as a table, and the first row is the one that surprises people:alwaysApplydescriptionglobstruefalsefalsefalse@-mention the rule in chatSetting
alwaysApply: truedoes not mean "apply this, and also scope it". Globs and description are discarded. A Rails rule about controllers that is marked always applied is a rule about controllers that loads while you are editing a migration.The glob syntax is comma separated, so
app/models/**/*.rb,app/forms/**/*.rbis one field and not two. And the file extension is load bearing: "A plain.mdfile in.cursor/rulesis ignored by the rules system because it has no frontmatter to specifydescription,globs, andalwaysApply." Renaming an existingrules.mdinto the directory produces a file that is present, committed, reviewed, and never sent.The Rails rules worth writing
A rule earns its place when it names a decision the model cannot see from the file it is editing. In a Rails 8 application that list is short and specific, and almost all of it is where the app departs from the default the model will otherwise predict.
The queue is the clearest case. Rails 8 ships Solid Queue, configured in
config/queue.yml, and an agent with no instruction reaches forperform_asyncoften enough to be worth one line, because Sidekiq dominates two decades of published Rails background job code and Solid Queue only became a default in Rails 8.The same shape covers the other four that matter. Tests are RSpec under
spec/withfactory_botfactories, not Minitest undertest/. Assets are Propshaft and importmap, soyarn addis the wrong answer to a JavaScript question. Authentication is the Rails 8 generator, socurrent_usercomes from a session record andauthenticate_user!is Devise and will not resolve. User facing strings live inconfig/locales/en.ymlrather than in views.Each of those is one sentence, checkable, and false in a neighbouring repository. That is the test. What a Rails agent actually needs as context is the longer argument for why the deviations are the whole payload.
The Rails rules that are convention with a hat on
"Use RESTful routes." "Keep controllers thin." "Follow MVC." "Use strong parameters." "Write clean, maintainable code." Searching for cursor rules rails returns pack after pack of exactly that list, and none of it does anything, because convention over configuration means the convention is exactly what the model already predicts. Rails has been documented in public for twenty years and its conventions barely move, so the default a model reaches for when told nothing is usually the default the guide recommends anyway.
Cursor says this about its own product, in a list of mistakes, and the wording is blunt: "Copying entire style guides: Use a linter instead. Agent already knows common style conventions." Followed by "Duplicating what's already in your codebase: Point to canonical examples instead of copying code." A rules file that transcribes
.rubocop.ymlhas bought a second copy of a file that was already enforced by a program that cannot be persuaded to ignore it, and the copy goes stale first.The @rails account's own line for the keynote week was that Rails is "Token-efficient code that's easy for agents to write and beautiful for humans to review." Read as a claim about rules files, it cuts both ways: the same conventionality that makes Rails cheap to generate makes most Rails rules redundant to state. Token efficient Rails takes the rest of that argument.
How long a rules file should be
Cursor's guidance is "Keep rules under 500 lines" and "Split large rules into multiple, composable rules". Take the first number as a ceiling on one glob scoped rule, and not as anything resembling a target for the rule marked
alwaysApply: true. My position: the always applied rule should fit on one screen, call it 40 lines, and everything else should be scoped or deleted.Two reasons, and only one of them is about cost. The documented mechanic is that "When applied, rule contents are included at the start of the model context", which means an always applied rule is paid for on every request in the session, including the ones where it is irrelevant. That is the cheap argument. The expensive one is attention: 300 lines of instruction, of which eleven lines are the deviations that matter and the rest is restated Rails, is not a longer version of those eleven lines. It is those eleven lines diluted, and the model's own hit rate on them goes down.
Cursor's advice agrees from the other end: "Start simple. Add rules only when you notice Agent making the same mistake repeatedly."
What would change my mind. If Cursor exposed per rule telemetry showing that a rule was loaded and followed, the guess in the paragraph above would become a measurement, and I would follow the measurement. A prompt cache that made rule length free would kill the cost half of the argument and leave the attention half standing.
Where Cursor rules fail to fire
Glob scoping has a failure mode that the documentation states plainly and that nobody reads as a warning: a rule with
globsis "Auto-attached when a matching file is in context." A file you are about to create is not in context. Ask for a new service object in an app whose service conventions live in a rule scoped toapp/services/**/*.rb, and the rule that describes how to write one is not loaded at the moment it is needed. The fix is unglamorous: creation rules belong in the always applied file or in a rule you@-mention on purpose, and the glob scoped ones are for editing what exists.The second failure has no fix. Rules are sent, not enforced. The Cursor forum answer quoted earlier continues that although significant work has gone into making models respect rules, "the models still may choose to ignore them or only partially follow them". A rule is a strong prior and never a constraint, which puts the enforcement somewhere else entirely: in the test suite, in RuboCop, and in the diff. Reviewing Rails an agent wrote is where that goes, and the honest summary is that a rules file reduces how often you catch something rather than removing the need to look.
What this page does not cover
Nothing here is a Cursor Rails rules pack to copy. A rules file taken from somebody else's repository is the failure mode described above with extra steps, since its value was supposed to be the part that is true of your app and nobody else's.
Nor does it cover what to do once the agent has written the Rails. Rules shape the first draft, and the draft still arrives as a diff somebody owns. Testing what an agent wrote picks up there.
One last note on provenance. Everything quoted above about Cursor's behaviour comes from Cursor's rules documentation or from a dated reply on its community forum, both read on 24 September 2026, and not from the keynote. What DHH actually said separates the quotations from the readings of them, which is a distinction this week needs.