thoughtbot agents rules#783
Conversation
Add thoughtbot Rails AI development rules Create AI rules for AI-assisted Rails development.
3ee17cb to
c2619eb
Compare
Replace single rails-rules.md with a project memory template and separate rule files. This aligns with Claude Code's .claude/rules/ convention for domain-specific instructions. The project-memory.md serves as a CLAUDE.md template that developers copy into their projects, providing: - Project context (stack, commands) - Architecture principles with links to detailed rules Rule files are loaded on-demand, reducing context window usage while keeping detailed guidance available when needed. See more here: https://code.claude.com/docs/en/memory#determine-memory-type
c2619eb to
dcb5e3c
Compare
jaredlt
left a comment
There was a problem hiding this comment.
LOVE this! 🔥
Left a few comments but I think this looks great and something we can start testing and iterating on over time.
| - Use presenters to display logic. Instantiate in controller, use in view. | ||
| - Extract repeated markup into partials. Pass data via `locals:`, not instance variables. | ||
| - Helpers for simple formatting only (dates, currencies). If longer than 5 lines, use a presenter. | ||
| - Turbo: return `status: :unprocessable_entity` on failed forms. Keep Stimulus controllers small. |
There was a problem hiding this comment.
There's probably a Hotwire / Stimulus rule file to come in the future :)
| bin/rails server # Start dev server | ||
| bin/rails spec # Full test suite (Suspenders rake task) | ||
| bundle exec rspec spec/models # Model specs only | ||
| bundle exec rspec spec/requests # Request specs only |
There was a problem hiding this comment.
Have you found it knows how to run tests just for one file or how to run just one test? This can be useful for speed on a big project eg.
bundle exec rspec spec/path/to/file_spec.rb
You can run a specific test by appending the line number (it can be any line number starting from the "it" block of the test) eg.
bundle exec rspec spec/path/to/file_spec.rb:72
^ it's a bit wordy...
There was a problem hiding this comment.
oh! I haven't tried that. It tends to run the whole file for the affected areas.
We can definitely try and add it if we see that it works!
There was a problem hiding this comment.
I'm testing with
bundle exec rspec spec/path/to/file_spec.rb # Run all tests in file
bundle exec rspec spec/path/to/file_spec.rb:72 # Run just the test at line 72
There was a problem hiding this comment.
Claude running in cursor tends to run examples or groups with -e "example or context name" by default
https://rspec.info/features/3-12/rspec-core/command-line/example-matches-name-option/
Co-authored-by: Jared Turner <jared.turner@thoughtbot.com>
c121640 to
bd35016
Compare
Co-authored-by: Jared Turner <jared.turner@thoughtbot.com>
207a409 to
54e43e0
Compare
gokcelb
left a comment
There was a problem hiding this comment.
In general, I really like this setup of the rules files 💯 I found that my client has a similar approach as well.
One thing I'm not sure about is mentioning 'suspenders' or not, could that be confusing for the agent and something extra to think about. I feel like in a mature project, it doesn't make sense that the agent is searching for 'suspenders' and trying to understand what it is.
We don't have to answer this quesiton now but I was also wondering how should we flag the lines in specific rules files mentioning technologies that may or may not be used in client projects, e.g. Turbo or Sidekiq?
| @@ -0,0 +1,11 @@ | |||
| # Database & Migrations | |||
|
|
|||
| - Always use the rails generate migration command to create migration files. | |||
There was a problem hiding this comment.
Do we still follow strong_migrations guidelines? Should we warn against using safety_assured?
There was a problem hiding this comment.
We included now strong_migrations as default in Suspenders.
I haven't seen any output from Claude Code that needed correction related to safety_assured 🤔
| @@ -0,0 +1,15 @@ | |||
| # Testing | |||
|
|
|||
| - Must use TDD. Write tests first and follow red, green, refactor | |||
There was a problem hiding this comment.
What is your experience with this red, green, refactor process? How does your iterations look like if you have this process?
I mentioned my TDD workflow in the Hub message as well.
I think my recent use of TDD, even before coding agents, has been to focus on behavior by writing the test cases but I hadn't been doing the red-green process at all.
Maybe this is more a general TDD question about how folks are doing it, so it might be out of scope for this PR.
I do wonder how the agents work with this 3-step TDD process though.
There was a problem hiding this comment.
From my own experience of having this line in my CLAUDE.md, certainly the red > green process works well. I don't know if I've observed or thought too much about the refactor step
There was a problem hiding this comment.
So, does the agent stop its editing process twice to go from red -> green -> refactor? Then you review it? Or it just uses this as a coding process for itself, without you reviewing it?
There was a problem hiding this comment.
It does it automatically. You normally step in after the refactor.
There was a problem hiding this comment.
I've found that forcing red -> green causes agents to write higher quality tests. It's much harder to accidentally introduce a false positive.
Co-authored-by: Chad Pytel <chad@thoughtbot.com>
Co-authored-by: Laçin <lacin@thoughtbot.com>
Co-authored-by: Laçin <lacin@thoughtbot.com>
|
I'm going to merge this today unless I hear any objection from anyone 👍 |
JoelQ
left a comment
There was a problem hiding this comment.
Go ahead and merge! I think this is a strong base we can iterate from
| - No service objects. All domain classes live in `app/models/` with namespaces, never `app/services/`. | ||
| - Name classes after domain nouns, not actions. No `*Service`, `*Manager`, `*Handler` suffixes. | ||
| - Use `ActiveModel::Model` for POROs that need validation or form integration. | ||
| - Replace `.call` / `.perform` with domain verbs: `#save`, `#complete`, `#submit`, `#deliver`. |
There was a problem hiding this comment.
Is this just service objects by another name?
There was a problem hiding this comment.
I guess it can be, if you're not thoughtful about it. Perhaps these rules oversimplify that what really matters is whether the class represents a genuine concept in the domain. That said, they've been useful for me when I'm working with Claude. With these rules Claude stop suggesting yet another service object when there are already plenty in the codebase.
Relates to #1350 and #1351. We introduced [thoughtbot agents rules](thoughtbot/guides#783) to our guides a few months ago. This commit simply pulls those files into newly generated Suspenders applications. There's a case to be made that these should be kept separate, but I like having a single source of truth.
Relates to #1350 and #1351. We introduced [thoughtbot agents rules](thoughtbot/guides#783) to our guides a few months ago. This commit simply pulls those files into newly generated Suspenders applications. There's a case to be made that these should be kept separate, but I like having a single source of truth.
Relates to #1350 and #1351. We introduced [thoughtbot agents rules](thoughtbot/guides#783) to our guides a few months ago. This commit simply pulls those files into newly generated Suspenders applications. There's a case to be made that these should be kept separate, but I like having a single source of truth.
Relates to #1350 and #1351. We introduced [thoughtbot agents rules](thoughtbot/guides#783) to our guides a few months ago. This commit simply pulls those files into newly generated Suspenders applications. There's a case to be made that these should be kept separate, but I like having a single source of truth.
Relates to #1350 and #1351. We introduced [thoughtbot agents rules](thoughtbot/guides#783) to our guides a few months ago. This commit simply pulls those files into newly generated Suspenders applications. There's a case to be made that these should be kept separate, but I like having a single source of truth. Finally, we update the Ruby matrix to account for other supported versions, and by avoiding point releases.
Relates to #1350 and #1351. We introduced [thoughtbot agents rules](thoughtbot/guides#783) to our guides a few months ago. This commit simply pulls those files into newly generated Suspenders applications. There's a case to be made that these should be kept separate, but I like having a single source of truth. Finally, we update the Ruby matrix to account for other supported versions, and by avoiding point releases.
| - Use presenters to display logic. Instantiate in controller, use in view. | ||
| - Extract repeated markup into partials. Pass data via `locals:`, not instance variables. | ||
| - Helpers for simple formatting only (dates, currencies). If longer than 5 lines, use a presenter. | ||
| - Turbo: return `status: :unprocessable_entity` on failed forms. Keep Stimulus controllers small. |
There was a problem hiding this comment.
Rubocop's Rails/HttpStatusNameConsistency recommends usage of :unprocessable_content:
| - Turbo: return `status: :unprocessable_entity` on failed forms. Keep Stimulus controllers small. | |
| - Turbo: return `status: :unprocessable_content` on failed forms. Keep Stimulus controllers small. |
Follow-up to #783. First, move the usage section into a dedicated README. Next, update commands to reflect what's actually supported with Suspenders and a new Rails application.
Follow-up to #783. First, move the usage section into a dedicated README. Next, update commands to reflect what's actually supported with Suspenders and a new Rails application.
Relates to #1350 and #1351. We introduced [thoughtbot agents rules](thoughtbot/guides#783) to our guides a few months ago. This commit simply pulls those files into newly generated Suspenders applications. There's a case to be made that these should be kept separate, but I like having a single source of truth.
Relates to #1350 and #1351. We introduced [thoughtbot agents rules](thoughtbot/guides#783) to our guides a few months ago. This commit simply pulls those files into newly generated Suspenders applications. There's a case to be made that these should be kept separate, but I like having a single source of truth.





Summary
This proposed change for the rules is based on what I've been reading about the CLAUDE.md/agents.md file, rules, skills in their own documentation and my own testing in client and personal projects with good results.
I think these are good defaults that you can add at the start of any project, or even projects that have been running for a while. Obviously each of us has observed different behaviour from our interactions with the models because all our prompts are different. Some of you might feel these rules are a bit too detailed and that's totally fine, but they have worked well across different projects for me. I'd love to hear what has been working for you!
What does good results mean?
Files included
Why not skills?
Skills are supposed to be invoked on demand. CLAUDE.md and rules should be for every session. We should keep CLAUDE.md and rules under 500 lines.
Why this project-memory.md format?
The
project-memory.mdtemplate is designed as a project context file that describe the stack, list common commands and links to the detail rules.See also "give Codex a map, not a 1,000-page instruction manual."
From Claude documentation chatbot:
Test plan
As mentioned above I've been testing this in client and personal projects and I'm happy with the behaviour (with modifications to meet the application differences).
.claude/CLAUDE.mdand make the necessary modifications based on your projectrules/folder to.claude/rules/