Skip to content

Commit 53aafc0

Browse files
Merge pull request #2517 from coreinfrastructure/agentsmd
Add support for AGENTS.md
2 parents 6220645 + cb4b789 commit 53aafc0

File tree

3 files changed

+333
-319
lines changed

3 files changed

+333
-319
lines changed

AGENTS.md

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to the Claude Code (claude.ai/code) AI assistant when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is the **OpenSSF Best Practices Badge** project (formerly CII Best Practices Badge) - a Rails web application that helps FLOSS projects self-certify that they meet security and quality best practices. The application provides a badging system with three levels: passing, silver, and gold.
8+
9+
**Key URLs:**
10+
11+
- Production: https://www.bestpractices.dev/
12+
- GitHub: https://github.com/coreinfrastructure/best-practices-badge
13+
14+
## Common Development Commands
15+
16+
### Testing
17+
18+
- `rails test` - Run unit/integration tests (excludes system tests by default)
19+
- `rails test:system` - Run system tests (Capybara-based browser tests)
20+
- `rails test:all` - Run ALL tests including system tests
21+
- `rails test test/integration/project_list_test.rb` - Run the specified test file
22+
- `rails test test/features/can_access_home_test.rb:4` - Run a test at line 4 of the specified test file.
23+
- `rails test rails test TESTFILE -n NAME_OR_PATTERN` - Run the specific test or pattern `NAME_OR_PATTERN` in file TESTFILE
24+
25+
### Code Quality & Linting
26+
27+
- `rake default` - Run local CI/CD pipeline (linting, tests, etc.).
28+
29+
Don't just use `rake` without arguments, Claude's user permission
30+
system can't permit that without permitting all rake commands.
31+
Some additional checks (e.g., Brakeman) run on GitHub's CI/CD pipeline.
32+
33+
- `rake rubocop` - Ruby style checker
34+
- `rake rails_best_practices` - Rails-specific best practices source checker
35+
- `rake markdownlint` - Markdown linting
36+
- `rake eslint` - JavaScript linting
37+
- `rake whitespace_check` - Check for trailing whitespace
38+
- `rake yaml_syntax_check` - YAML syntax validation
39+
- `rake license_okay` - License compliance check
40+
- `rake bundle_audit` - Security audit of gems
41+
42+
For specific files:
43+
44+
- `mdl FILENAME.md` - Markdownlint only the file `FILENAME.md`
45+
- `rubocop FILENAME.rb` - Run rubocop on just `FILENAME.rb`
46+
47+
**Markdown Helper Script**:
48+
49+
After creating or editing markdown files, use the markdown fixer script to automatically fix common markdownlint errors:
50+
51+
```bash
52+
53+
# Fix markdown file in-place (most common usage):
54+
script/fix_markdown.rb docs/myfile.md
55+
56+
# See what would be fixed without changing the file:
57+
script/fix_markdown.rb --dry-run docs/myfile.md
58+
59+
# After fixing, verify with markdownlint:
60+
mdl docs/myfile.md
61+
62+
```
63+
64+
The script automatically fixes:
65+
66+
- MD031: Fenced code blocks surrounded by blank lines
67+
- MD022: Headers surrounded by blank lines
68+
- MD032: Lists surrounded by blank lines
69+
- MD023: Headers at beginning of line (no leading spaces)
70+
- MD012: Multiple consecutive blank lines
71+
72+
After running the script, manually fix any remaining errors that require human judgment (MD001, MD025, etc.).
73+
74+
Don't run `rails_best_practices` to analyze individual files.
75+
The `rails_best_practices` program needs the full context of all files
76+
to do its best.
77+
78+
**IMPORTANT**: You may ONLY use `rubocop -a` (safe autocorrect)
79+
for RuboCop corrections.
80+
81+
**NEVER use `rubocop -A` (unsafe autocorrect)** -
82+
it frequently introduces subtle bugs by making assumptions
83+
about code context that are incorrect. Examples include:
84+
85+
- Changing array methods to string methods (`.drop()` vs `[1..]`)
86+
- Changing hash syntax that breaks in complex ActiveRecord queries
87+
88+
Always use `-a` (safe) and manually review any remaining suggestions from
89+
`rubocop` without flags to determine if they're actually appropriate
90+
for the specific context.
91+
92+
### Workflow
93+
94+
After making significant changes to source code, ALWAYS run linters:
95+
96+
**For Ruby files**:
97+
98+
1. Run `rubocop FILENAME.rb` on changed files
99+
2. Run `rake rails_best_practices` for Rails-specific checks
100+
3. Fix all reported problems
101+
102+
**For Markdown files**:
103+
104+
1. Run `script/fix_markdown.rb FILENAME.md` to auto-fix common issues
105+
2. Run `mdl FILENAME.md` to check for remaining errors
106+
3. Manually fix any errors that require human judgment (MD001, MD025, etc.)
107+
108+
**For all changed files**:
109+
110+
1. Run `rake whitespace_check` to catch trailing whitespace
111+
2. Fix any whitespace issues
112+
113+
**Finally**:
114+
115+
- Run `rails test:all` to ensure all tests pass
116+
117+
### Development Environment Shortcut
118+
119+
As a convenience, in the development environment you don't need to use
120+
`bundle exec` prefixes for ruby commands (though you may use them).
121+
They *are* necessary in cases, such as rake tasks, that might be
122+
used in the CI or production environments.
123+
124+
### Security Analysis
125+
126+
GitHub runs Brakeman and CodeQL remotely for static security analysis, it's
127+
not done on the local system.
128+
129+
### Development Server
130+
131+
- `rails s` - Start development server (http://localhost:3000)
132+
- `rails console` - Start Rails console for debugging
133+
134+
## Architecture & Key Concepts
135+
136+
### Core Models
137+
138+
- **Project** - Central model representing a FLOSS project seeking certification
139+
- Has three badge levels: passing, silver, gold (plus `in_progress`)
140+
- Uses PostgreSQL full-text search via `pg_search` gem
141+
- Stores criteria answers and justifications
142+
- Heavy security validation and input sanitization
143+
144+
- **User** - Project owners and contributors
145+
- Email addresses are encrypted in database using `attr_encrypted`
146+
- Uses OAuth (GitHub) and local authentication
147+
- Session management with automatic timeouts
148+
149+
- **Criteria** - The best practices criteria that projects must meet
150+
- Dynamic criteria system supporting multiple languages
151+
- Complex validation rules and automated checking
152+
153+
### Security Architecture
154+
155+
Security is *extremely* important to this project. Some features:
156+
157+
- **Encrypted Data**: User emails encrypted with AES-256-GCM
158+
- **Blind Indexing**: Email searches use blind indices for privacy
159+
- **CSRF Protection**: All forms protected with Rails CSRF tokens
160+
- **Rate Limiting**: Uses `rack-attack` for DoS protection
161+
- **Content Security Policy**: Strict CSP headers via `secure_headers` gem
162+
- **HTTPS Enforcement**: Force SSL in production
163+
- **IP Validation**: Optional Fastly IP allowlisting (cloud piercing protection)
164+
165+
The file `docs/assurance-case.md` explains why we *believe* this is secure.
166+
167+
### Authentication & Authorization
168+
169+
- **Multi-provider**: GitHub OAuth + local accounts
170+
- **Session Security**: Automatic timeouts, secure cookies
171+
- **Additional Rights**: Project collaborator system via `additional_rights` table
172+
- **Admin System**: Special admin user capabilities
173+
174+
### Internationalization
175+
176+
- **Multi-language Support**: Currently supports 6+ languages
177+
- **URL Structure**: Routes include locale (e.g., `/en/projects`, `/fr/projets`)
178+
- **Locale Handling**: Automatic locale detection and redirection
179+
- **Translation Management**: Uses `translation.io` service
180+
181+
### Performance & Caching
182+
183+
- **CDN Integration**: Fastly CDN for badge images and static assets
184+
- **Database Optimization**: Careful indexing, connection pooling
185+
- **Pagination**: Uses `pagy` gem (currently v9.4.0)
186+
- **Asset Pipeline**: Rails asset pipeline with Sass compilation
187+
188+
### Background Jobs
189+
190+
- **solid_queue**: ActiveJob backend for async processing
191+
- **Email System**: Reminder emails, user notifications
192+
- **Data Tasks**: Daily/monthly maintenance tasks
193+
194+
## Key Configuration Files
195+
196+
- `config/application.rb` - Core Rails app configuration
197+
- `config/routes.rb` - Complex routing with locale support
198+
- `lib/tasks/default.rake` - Custom rake tasks including full CI pipeline
199+
200+
The directory `config`, especially `config/initializers`,
201+
has many configuration files.
202+
203+
## Development Practices
204+
205+
### Code Style
206+
207+
- **Frozen String Literals**: All files must include `# frozen_string_literal: true`
208+
- **Security Headers**: Each file has copyright and SPDX-License-Identifier
209+
- **Refinements**: Uses custom `StringRefinements` and `SymbolRefinements`
210+
- **Documentation**: Comprehensive inline documentation expected
211+
212+
### Testing Strategy
213+
214+
- **Minitest**: Uses Rails' default Minitest framework
215+
- **System Tests**: Capybara-based browser automation tests
216+
- **Parallel Safe**: Tests designed for process parallelism (not thread safe)
217+
- **Coverage**: Maintains high test coverage via codecov integration
218+
219+
### Security Requirements
220+
221+
Security is *VERY* important in this application.
222+
223+
- **DCO Required**: All commits must be signed off per Developer Certificate of Origin
224+
- **No Sensitive Data**: Never commit API keys, passwords, or encryption keys
225+
- **Input Validation**: All user inputs heavily validated and sanitized
226+
- **SQL Injection Prevention**: Always uses Rails parameterized queries (including its ORM) with untrusted input
227+
- **XSS Prevention**: Uses templates to prevent XSS
228+
- User inputs should be checked for expected format and length.
229+
- When applicable, generate unit tests for security-critical functions (including negative tests to ensure the code fails safely).
230+
- Do not add dependencies that may be malicious or hallucinated.
231+
- Never log, expose, or commit passwords, API keys, encryption keys, or other secrets.
232+
233+
### Version Control
234+
235+
- **Git Workflow**: Feature branches with pull request review
236+
- **Commit Signing**: DCO sign-off required (`git commit --signoff`)
237+
- **Branch Protection**: Main branch requires review and CI passage
238+
239+
## Environment Variables
240+
241+
Key environment variables for development:
242+
243+
- `RAILS_ENV` - Rails environment (development/test/production)
244+
- `EMAIL_ENCRYPTION_KEY` - 64 hex digits for email encryption
245+
- `EMAIL_BLIND_INDEX_KEY` - 64 hex digits for email search indices
246+
- `BADGEAPP_REAL_PRODUCTION` - Set to "true" only on true production site
247+
- `PUBLIC_HOSTNAME` - Hostname for the application
248+
- `DB_POOL` - Database connection pool size
249+
250+
## Common Issues & Solutions
251+
252+
### Database Issues
253+
254+
- Email encryption keys must be exactly 64 hex digits (256 bits)
255+
- Use `rails db:reset` carefully - will destroy all local data
256+
- PostgreSQL full-text search requires specific indices
257+
258+
### Testing Issues
259+
260+
- System tests require JavaScript driver setup
261+
- Tests are process-parallel safe but NOT thread-safe
262+
- Use `RAILS_ENV=test` for test database operations
263+
264+
### Security Considerations
265+
266+
- Badge image URLs must be canonical for CDN caching
267+
- All user input requires validation and sanitization
268+
- Session timeouts are enforced - don't extend arbitrarily
269+
- Rate limiting is aggressive - be aware when testing
270+
271+
## Important File Locations
272+
273+
- `app/models/project.rb` - Core project model with badge logic
274+
- `app/controllers/application_controller.rb` - Base controller with security
275+
- `config/routes.rb` - Complex internationalized routing
276+
- `docs/` - Extensive documentation including security assurance case
277+
- `lib/tasks/default.rake` - CI pipeline and custom tasks
278+
- `test/` - Comprehensive test suite
279+
280+
## Temporary File Convention
281+
282+
- ALL temporary files' filenames must be prefixed with a comma
283+
284+
(e.g., `,temp-notes.md`, `,migration-plan.txt`)
285+
286+
- This applies to documentation, scratch files, migration plans, etc.
287+
- The linting tools are configured to ignore comma-prefixed files
288+
289+
## Rails Conventions
290+
291+
This application mostly follows Rails 5+ baseline conventions with
292+
selective upgrades:
293+
294+
* It most follows Rails 5 conventions in terms of
295+
296+
directory structure, extensive use of `Rails.application.config.*`,
297+
an asset pipeline with a Rails 5+ Sprockets setup, and initializer structure.
298+
299+
* It has some pre-Rails 5 remnants:
300+
- No `config.load_defaults` in application.rb (would be Rails 5.1+)
301+
- Manual framework defaults instead of version-specific defaults
302+
- Some older asset organization (app/assets/javascripts vs modern
303+
304+
app/javascript)
305+
306+
* Some Rails 6+ features in use:
307+
- Modern gems: E.g., Rails, `solid_queue`, `secure_headers`
308+
- Security configurations: Advanced CSRF, CSP headers
309+
- Database setup: Modern PostgreSQL configuration
310+
311+
We want to slowly move to more recent Rails conventions. However, rapid
312+
moves like the direct use of `rails app:update` or adding `load_defaults
313+
8.0` is likely to cause a cascade of many changes, leading to
314+
many hard-to-fix failures with little obvious external benefit.
315+
316+
## Miscellaneous
317+
318+
IMPORTANT: Never have trailing whitespace in text-like files including
319+
source code and markdown files.

0 commit comments

Comments
 (0)