ariadna 1.3.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ariadna.gemspec +0 -1
- data/data/agents/ariadna-codebase-mapper.md +34 -722
- data/data/agents/ariadna-debugger.md +44 -1139
- data/data/agents/ariadna-executor.md +75 -396
- data/data/agents/ariadna-planner.md +78 -1215
- data/data/agents/ariadna-roadmapper.md +55 -582
- data/data/agents/ariadna-verifier.md +60 -702
- data/data/ariadna/templates/config.json +8 -33
- data/data/ariadna/workflows/debug.md +28 -0
- data/data/ariadna/workflows/execute-phase.md +31 -513
- data/data/ariadna/workflows/map-codebase.md +20 -319
- data/data/ariadna/workflows/new-milestone.md +20 -365
- data/data/ariadna/workflows/new-project.md +19 -880
- data/data/ariadna/workflows/plan-phase.md +24 -443
- data/data/ariadna/workflows/progress.md +20 -376
- data/data/ariadna/workflows/quick.md +19 -221
- data/data/ariadna/workflows/roadmap-ops.md +28 -0
- data/data/ariadna/workflows/verify-work.md +23 -560
- data/data/commands/ariadna/add-phase.md +11 -22
- data/data/commands/ariadna/debug.md +11 -143
- data/data/commands/ariadna/execute-phase.md +12 -30
- data/data/commands/ariadna/insert-phase.md +7 -14
- data/data/commands/ariadna/map-codebase.md +16 -49
- data/data/commands/ariadna/new-milestone.md +12 -25
- data/data/commands/ariadna/new-project.md +22 -26
- data/data/commands/ariadna/plan-phase.md +13 -22
- data/data/commands/ariadna/progress.md +16 -6
- data/data/commands/ariadna/quick.md +9 -11
- data/data/commands/ariadna/remove-phase.md +9 -12
- data/data/commands/ariadna/verify-work.md +14 -19
- data/data/skills/rails-backend/API.md +138 -0
- data/data/skills/rails-backend/CONTROLLERS.md +154 -0
- data/data/skills/rails-backend/JOBS.md +132 -0
- data/data/skills/rails-backend/MODELS.md +213 -0
- data/data/skills/rails-backend/SKILL.md +169 -0
- data/data/skills/rails-frontend/ASSETS.md +154 -0
- data/data/skills/rails-frontend/COMPONENTS.md +253 -0
- data/data/skills/rails-frontend/SKILL.md +187 -0
- data/data/skills/rails-frontend/VIEWS.md +168 -0
- data/data/skills/rails-performance/PROFILING.md +106 -0
- data/data/skills/rails-performance/SKILL.md +217 -0
- data/data/skills/rails-security/AUDIT.md +118 -0
- data/data/skills/rails-security/SKILL.md +422 -0
- data/data/skills/rails-testing/FIXTURES.md +78 -0
- data/data/skills/rails-testing/SKILL.md +160 -0
- data/data/skills/rails-testing/SYSTEM-TESTS.md +73 -0
- data/lib/ariadna/installer.rb +11 -15
- data/lib/ariadna/tools/cli.rb +0 -12
- data/lib/ariadna/tools/config_manager.rb +10 -72
- data/lib/ariadna/tools/frontmatter.rb +23 -1
- data/lib/ariadna/tools/init.rb +201 -401
- data/lib/ariadna/tools/model_profiles.rb +6 -14
- data/lib/ariadna/tools/phase_manager.rb +1 -10
- data/lib/ariadna/tools/state_manager.rb +170 -451
- data/lib/ariadna/tools/template_filler.rb +4 -12
- data/lib/ariadna/tools/verification.rb +21 -399
- data/lib/ariadna/uninstaller.rb +9 -0
- data/lib/ariadna/version.rb +1 -1
- data/lib/ariadna.rb +1 -0
- metadata +20 -91
- data/data/agents/ariadna-backend-executor.md +0 -261
- data/data/agents/ariadna-frontend-executor.md +0 -259
- data/data/agents/ariadna-integration-checker.md +0 -418
- data/data/agents/ariadna-phase-researcher.md +0 -469
- data/data/agents/ariadna-plan-checker.md +0 -622
- data/data/agents/ariadna-project-researcher.md +0 -618
- data/data/agents/ariadna-research-synthesizer.md +0 -236
- data/data/agents/ariadna-test-executor.md +0 -266
- data/data/ariadna/references/checkpoints.md +0 -772
- data/data/ariadna/references/continuation-format.md +0 -249
- data/data/ariadna/references/decimal-phase-calculation.md +0 -65
- data/data/ariadna/references/git-integration.md +0 -248
- data/data/ariadna/references/git-planning-commit.md +0 -38
- data/data/ariadna/references/model-profile-resolution.md +0 -32
- data/data/ariadna/references/model-profiles.md +0 -73
- data/data/ariadna/references/phase-argument-parsing.md +0 -61
- data/data/ariadna/references/planning-config.md +0 -194
- data/data/ariadna/references/questioning.md +0 -153
- data/data/ariadna/references/rails-conventions.md +0 -416
- data/data/ariadna/references/tdd.md +0 -267
- data/data/ariadna/references/ui-brand.md +0 -160
- data/data/ariadna/references/verification-patterns.md +0 -853
- data/data/ariadna/templates/codebase/architecture.md +0 -481
- data/data/ariadna/templates/codebase/concerns.md +0 -380
- data/data/ariadna/templates/codebase/conventions.md +0 -434
- data/data/ariadna/templates/codebase/integrations.md +0 -328
- data/data/ariadna/templates/codebase/stack.md +0 -189
- data/data/ariadna/templates/codebase/structure.md +0 -418
- data/data/ariadna/templates/codebase/testing.md +0 -606
- data/data/ariadna/templates/context.md +0 -283
- data/data/ariadna/templates/continue-here.md +0 -78
- data/data/ariadna/templates/debug-subagent-prompt.md +0 -91
- data/data/ariadna/templates/phase-prompt.md +0 -609
- data/data/ariadna/templates/planner-subagent-prompt.md +0 -117
- data/data/ariadna/templates/research-project/ARCHITECTURE.md +0 -439
- data/data/ariadna/templates/research-project/FEATURES.md +0 -168
- data/data/ariadna/templates/research-project/PITFALLS.md +0 -406
- data/data/ariadna/templates/research-project/STACK.md +0 -251
- data/data/ariadna/templates/research-project/SUMMARY.md +0 -247
- data/data/ariadna/templates/state.md +0 -176
- data/data/ariadna/templates/summary-complex.md +0 -59
- data/data/ariadna/templates/summary-minimal.md +0 -41
- data/data/ariadna/templates/summary-standard.md +0 -48
- data/data/ariadna/templates/user-setup.md +0 -310
- data/data/ariadna/workflows/add-phase.md +0 -111
- data/data/ariadna/workflows/add-todo.md +0 -157
- data/data/ariadna/workflows/audit-milestone.md +0 -241
- data/data/ariadna/workflows/check-todos.md +0 -176
- data/data/ariadna/workflows/complete-milestone.md +0 -644
- data/data/ariadna/workflows/diagnose-issues.md +0 -219
- data/data/ariadna/workflows/discovery-phase.md +0 -289
- data/data/ariadna/workflows/discuss-phase.md +0 -408
- data/data/ariadna/workflows/execute-plan.md +0 -448
- data/data/ariadna/workflows/help.md +0 -470
- data/data/ariadna/workflows/insert-phase.md +0 -129
- data/data/ariadna/workflows/list-phase-assumptions.md +0 -178
- data/data/ariadna/workflows/pause-work.md +0 -122
- data/data/ariadna/workflows/plan-milestone-gaps.md +0 -256
- data/data/ariadna/workflows/remove-phase.md +0 -154
- data/data/ariadna/workflows/research-phase.md +0 -74
- data/data/ariadna/workflows/resume-project.md +0 -306
- data/data/ariadna/workflows/set-profile.md +0 -80
- data/data/ariadna/workflows/settings.md +0 -145
- data/data/ariadna/workflows/transition.md +0 -493
- data/data/ariadna/workflows/update.md +0 -212
- data/data/ariadna/workflows/verify-phase.md +0 -226
- data/data/commands/ariadna/add-todo.md +0 -42
- data/data/commands/ariadna/audit-milestone.md +0 -42
- data/data/commands/ariadna/check-todos.md +0 -41
- data/data/commands/ariadna/complete-milestone.md +0 -136
- data/data/commands/ariadna/discuss-phase.md +0 -86
- data/data/commands/ariadna/help.md +0 -22
- data/data/commands/ariadna/list-phase-assumptions.md +0 -50
- data/data/commands/ariadna/pause-work.md +0 -35
- data/data/commands/ariadna/plan-milestone-gaps.md +0 -40
- data/data/commands/ariadna/reapply-patches.md +0 -110
- data/data/commands/ariadna/research-phase.md +0 -187
- data/data/commands/ariadna/resume-work.md +0 -40
- data/data/commands/ariadna/set-profile.md +0 -34
- data/data/commands/ariadna/settings.md +0 -36
- data/data/commands/ariadna/update.md +0 -37
- data/data/guides/backend.md +0 -3069
- data/data/guides/frontend.md +0 -1479
- data/data/guides/performance.md +0 -1193
- data/data/guides/security.md +0 -1522
- data/data/guides/style-guide.md +0 -1091
- data/data/guides/testing.md +0 -504
- data/data/templates.md +0 -94
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
<rails_conventions>
|
|
2
|
-
|
|
3
|
-
Pre-baked Rails knowledge for Ariadna planning and execution agents. This document replaces generic research for standard Rails projects, encoding well-known conventions, patterns, and pitfalls so agents don't need to web-search for common Rails patterns.
|
|
4
|
-
|
|
5
|
-
<standard_stack>
|
|
6
|
-
|
|
7
|
-
## Standard Rails Stack (2025)
|
|
8
|
-
|
|
9
|
-
| Layer | Technology | Notes |
|
|
10
|
-
|-------|-----------|-------|
|
|
11
|
-
| Framework | Rails 8+ | Defaults to SQLite in dev, includes Solid Queue/Cache/Cable |
|
|
12
|
-
| Database | PostgreSQL (production) | SQLite for dev/test is fine for most projects |
|
|
13
|
-
| Background Jobs | Solid Queue | Rails 8 default, replaces Sidekiq for most cases |
|
|
14
|
-
| Caching | Solid Cache | Rails 8 default, database-backed cache |
|
|
15
|
-
| WebSockets | Action Cable + Solid Cable | Rails 8 default |
|
|
16
|
-
| Real-time UI | Turbo (Hotwire) | Turbo Drive, Frames, Streams |
|
|
17
|
-
| JS Sprinkles | Stimulus (Hotwire) | Controllers for interactive behavior |
|
|
18
|
-
| CSS | Tailwind CSS or Propshaft | Rails 8 defaults to Propshaft asset pipeline |
|
|
19
|
-
| Auth | Rails 8 built-in authentication (`has_secure_password` + auth generator) | No external gems needed |
|
|
20
|
-
| Email | Action Mailer | Built-in |
|
|
21
|
-
| File Upload | Active Storage | Built-in |
|
|
22
|
-
| API | Rails API mode or Jbuilder | Built-in |
|
|
23
|
-
| Testing | Minitest | Rails default, use fixtures not factories |
|
|
24
|
-
| Linting | RuboCop + rubocop-rails | Standard community linting |
|
|
25
|
-
|
|
26
|
-
**What NOT to use (and why):**
|
|
27
|
-
- Devise unless explicitly requested by the user — Rails 8 auth generator + `has_secure_password` covers signup, login, password reset, session management out of the box
|
|
28
|
-
- Pundit/CanCanCan unless explicitly requested — `before_action` checks + `Current` context handle authorization for most apps without adding a gem
|
|
29
|
-
- acts_as_tenant — use `Current.account` scoping with explicit scopes (see backend guide); no gem needed for path-based multi-tenancy
|
|
30
|
-
- Factories (FactoryBot) when fixtures suffice — fixtures are faster, declarative, and Rails-native
|
|
31
|
-
- RSpec unless the project already uses it — Minitest is simpler and Rails-native
|
|
32
|
-
- Webpacker/Shakapacker — replaced by importmap-rails or jsbundling-rails
|
|
33
|
-
- Sprockets — replaced by Propshaft in Rails 8
|
|
34
|
-
- Redis for jobs/cache — Solid Queue/Cache use the database, simpler ops
|
|
35
|
-
|
|
36
|
-
</standard_stack>
|
|
37
|
-
|
|
38
|
-
<rails_defaults_first>
|
|
39
|
-
|
|
40
|
-
## Rails Defaults First (Opinionated)
|
|
41
|
-
|
|
42
|
-
For new projects, ALWAYS start with Rails built-in solutions. Only introduce external gems when the user explicitly requests them or requirements demonstrably exceed what Rails provides.
|
|
43
|
-
|
|
44
|
-
| Need | Rails Default | External Gem (only if explicitly requested) |
|
|
45
|
-
|------|--------------|---------------------------------------------|
|
|
46
|
-
| Authentication | `has_secure_password` + Rails 8 auth generator | Devise |
|
|
47
|
-
| Authorization | `before_action` + `Current` context | Pundit, CanCanCan |
|
|
48
|
-
| Multi-tenancy | `Current.account` + explicit scoping | acts_as_tenant |
|
|
49
|
-
| Background Jobs | Solid Queue | Sidekiq |
|
|
50
|
-
| Caching | Solid Cache | Redis |
|
|
51
|
-
| WebSockets | Solid Cable | Redis + AnyCable |
|
|
52
|
-
| Testing | Minitest + fixtures | RSpec + FactoryBot |
|
|
53
|
-
|
|
54
|
-
**Why:** External gems add dependencies, upgrade burden, and conceptual overhead. Rails 8 ships with excellent defaults that cover 90% of use cases. Starting with built-ins keeps the app simple and maintainable.
|
|
55
|
-
|
|
56
|
-
**The rule:** Never recommend Devise, Pundit, acts_as_tenant, or similar gems as the default choice for new projects. If the user hasn't asked for them, use Rails built-ins. If the user asks for "authentication", build it with `has_secure_password`. If they ask for "authorization", use `before_action` checks. If they ask for "multi-tenancy", use `Current.account` scoping.
|
|
57
|
-
|
|
58
|
-
</rails_defaults_first>
|
|
59
|
-
|
|
60
|
-
<architecture_patterns>
|
|
61
|
-
|
|
62
|
-
## Rails Architecture Patterns
|
|
63
|
-
|
|
64
|
-
### MVC Foundation
|
|
65
|
-
- **Models:** Business logic lives here. Validations, scopes, callbacks, associations.
|
|
66
|
-
- **Controllers:** Thin. Receive request, call model, render response. 7 RESTful actions max.
|
|
67
|
-
- **Views:** ERB templates. Logic delegated to presenters or helpers.
|
|
68
|
-
|
|
69
|
-
### Concern-Driven Architecture
|
|
70
|
-
```
|
|
71
|
-
app/models/concerns/
|
|
72
|
-
shared/ # Cross-model concerns (Trackable, Searchable)
|
|
73
|
-
model_name/ # Model-specific concerns (User::Authenticatable)
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
**When to extract a concern:**
|
|
77
|
-
- Behavior reused across 2+ models → shared concern
|
|
78
|
-
- Model file exceeds ~100 lines → model-specific concern
|
|
79
|
-
- Logical grouping of related methods → named concern
|
|
80
|
-
|
|
81
|
-
### Service Objects (When Needed)
|
|
82
|
-
Use plain Ruby objects in `app/services/` for:
|
|
83
|
-
- Multi-model operations (CreateOrderWithPayment)
|
|
84
|
-
- External API integrations (StripeChargeService)
|
|
85
|
-
- Complex business processes spanning multiple steps
|
|
86
|
-
|
|
87
|
-
**Don't use for:** Simple CRUD, single-model operations, or anything a model method handles.
|
|
88
|
-
|
|
89
|
-
### Presenter Pattern
|
|
90
|
-
Plain Ruby classes for complex view logic:
|
|
91
|
-
```ruby
|
|
92
|
-
# app/models/dashboard_presenter.rb (NOT app/presenters/)
|
|
93
|
-
class DashboardPresenter
|
|
94
|
-
include ActionView::Helpers::TagHelper
|
|
95
|
-
|
|
96
|
-
def initialize(user)
|
|
97
|
-
@user = user
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def greeting
|
|
101
|
-
"Welcome, #{@user.name}"
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### RESTful Resource Design
|
|
107
|
-
- Prefer creating new controllers over adding custom actions
|
|
108
|
-
- `POST /messages/:id/archive` → `ArchivesController#create`
|
|
109
|
-
- Nest resources max 1 level: `/posts/:post_id/comments`
|
|
110
|
-
- Use `concerns` in routes for shared resource patterns
|
|
111
|
-
|
|
112
|
-
### Current Attributes
|
|
113
|
-
```ruby
|
|
114
|
-
# app/models/current.rb
|
|
115
|
-
class Current < ActiveSupport::CurrentAttributes
|
|
116
|
-
attribute :user, :session, :account
|
|
117
|
-
end
|
|
118
|
-
```
|
|
119
|
-
Set in `ApplicationController`, access everywhere. No parameter passing for auth context.
|
|
120
|
-
|
|
121
|
-
</architecture_patterns>
|
|
122
|
-
|
|
123
|
-
<common_pitfalls>
|
|
124
|
-
|
|
125
|
-
## Common Rails Pitfalls (with Prevention)
|
|
126
|
-
|
|
127
|
-
### 1. N+1 Queries
|
|
128
|
-
**Problem:** Loading associated records in a loop.
|
|
129
|
-
**Prevention:** Use `includes`, `preload`, or `eager_load` in controllers. Add `strict_loading` to models in development.
|
|
130
|
-
```ruby
|
|
131
|
-
# Bad
|
|
132
|
-
@posts = Post.all # then post.comments in view
|
|
133
|
-
|
|
134
|
-
# Good
|
|
135
|
-
@posts = Post.includes(:comments, :author).all
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
### 2. Missing Database Indexes
|
|
139
|
-
**Prevention:** Always add indexes for:
|
|
140
|
-
- Foreign keys (`add_index :posts, :user_id`)
|
|
141
|
-
- Columns used in `where` clauses
|
|
142
|
-
- Columns used in `order` clauses
|
|
143
|
-
- Unique constraints (`add_index :users, :email, unique: true`)
|
|
144
|
-
|
|
145
|
-
### 3. Mass Assignment Vulnerabilities
|
|
146
|
-
**Prevention:** Always use `strong_parameters` in controllers.
|
|
147
|
-
```ruby
|
|
148
|
-
def post_params
|
|
149
|
-
params.require(:post).permit(:title, :body, :published)
|
|
150
|
-
end
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### 4. Callback Hell
|
|
154
|
-
**Prevention:** Limit callbacks to:
|
|
155
|
-
- `before_validation` for normalization (strip whitespace, downcase email)
|
|
156
|
-
- `after_create_commit` for async side effects (send email, broadcast)
|
|
157
|
-
- Avoid `after_save` chains that trigger cascading updates
|
|
158
|
-
|
|
159
|
-
### 5. Fat Controllers
|
|
160
|
-
**Prevention:** Controllers should only:
|
|
161
|
-
1. Authenticate/authorize
|
|
162
|
-
2. Load/build the resource
|
|
163
|
-
3. Call save/update/destroy
|
|
164
|
-
4. Respond with redirect or render
|
|
165
|
-
|
|
166
|
-
### 6. Missing Validations
|
|
167
|
-
**Prevention:** Validate at model level, not just in forms:
|
|
168
|
-
- Presence on required fields
|
|
169
|
-
- Uniqueness with database-level constraint
|
|
170
|
-
- Format for emails, URLs, phone numbers
|
|
171
|
-
- Numericality for quantities, prices
|
|
172
|
-
|
|
173
|
-
### 7. Unscoped Queries (Multi-tenancy)
|
|
174
|
-
**Prevention:** Always scope queries to current user/account:
|
|
175
|
-
```ruby
|
|
176
|
-
# Bad
|
|
177
|
-
Post.find(params[:id])
|
|
178
|
-
|
|
179
|
-
# Good
|
|
180
|
-
Current.user.posts.find(params[:id])
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### 8. Missing Error Handling
|
|
184
|
-
**Prevention:** Add `rescue_from` in `ApplicationController`:
|
|
185
|
-
```ruby
|
|
186
|
-
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
|
187
|
-
rescue_from ActionController::ParameterMissing, with: :bad_request
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### 9. Synchronous External Calls
|
|
191
|
-
**Prevention:** Always use background jobs for:
|
|
192
|
-
- Sending emails
|
|
193
|
-
- Calling external APIs
|
|
194
|
-
- Processing uploads
|
|
195
|
-
- Generating reports
|
|
196
|
-
|
|
197
|
-
### 10. Missing CSRF Protection
|
|
198
|
-
**Prevention:** Rails enables CSRF by default. Don't disable `protect_from_forgery`. For API endpoints, use token auth instead.
|
|
199
|
-
|
|
200
|
-
</common_pitfalls>
|
|
201
|
-
|
|
202
|
-
<testing_patterns>
|
|
203
|
-
|
|
204
|
-
## Rails Testing Patterns (Minitest)
|
|
205
|
-
|
|
206
|
-
### Test Organization
|
|
207
|
-
```
|
|
208
|
-
test/
|
|
209
|
-
models/ # Unit tests for models
|
|
210
|
-
controllers/ # Integration tests for request/response
|
|
211
|
-
system/ # Browser-based end-to-end tests
|
|
212
|
-
helpers/ # Helper method tests
|
|
213
|
-
jobs/ # Background job tests
|
|
214
|
-
mailers/ # Mailer tests
|
|
215
|
-
fixtures/ # YAML test data
|
|
216
|
-
test_helper.rb # Shared setup
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### Fixtures Over Factories
|
|
220
|
-
```yaml
|
|
221
|
-
# test/fixtures/users.yml
|
|
222
|
-
alice:
|
|
223
|
-
name: Alice
|
|
224
|
-
email: alice@example.com
|
|
225
|
-
password_digest: <%= BCrypt::Password.create('password') %>
|
|
226
|
-
|
|
227
|
-
bob:
|
|
228
|
-
name: Bob
|
|
229
|
-
email: bob@example.com
|
|
230
|
-
password_digest: <%= BCrypt::Password.create('password') %>
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
**Why fixtures:** Faster (loaded once per test suite), declarative, Rails-native, no external gem needed.
|
|
234
|
-
|
|
235
|
-
### Model Test Pattern
|
|
236
|
-
```ruby
|
|
237
|
-
class UserTest < ActiveSupport::TestCase
|
|
238
|
-
setup do
|
|
239
|
-
Current.session = sessions(:alice_session) # Always set Current context
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
test "validates email presence" do
|
|
243
|
-
user = User.new(name: "Test")
|
|
244
|
-
|
|
245
|
-
assert_not user.valid?
|
|
246
|
-
assert_includes user.errors[:email], "can't be blank"
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
test "creates user with valid attributes" do
|
|
250
|
-
assert_difference "User.count", 1 do
|
|
251
|
-
User.create!(name: "New", email: "new@example.com", password: "password")
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
end
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Controller Test Pattern (Integration)
|
|
258
|
-
```ruby
|
|
259
|
-
class PostsControllerTest < ActionDispatch::IntegrationTest
|
|
260
|
-
setup do
|
|
261
|
-
@user = users(:alice)
|
|
262
|
-
sign_in @user # Helper method
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
test "index returns posts" do
|
|
266
|
-
get posts_url
|
|
267
|
-
|
|
268
|
-
assert_response :success
|
|
269
|
-
assert_select "h2", posts(:first).title
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
test "create redirects on success" do
|
|
273
|
-
assert_difference "Post.count", 1 do
|
|
274
|
-
post posts_url, params: { post: { title: "New", body: "Content" } }
|
|
275
|
-
end
|
|
276
|
-
assert_redirected_to post_url(Post.last)
|
|
277
|
-
end
|
|
278
|
-
end
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### System Test Pattern
|
|
282
|
-
```ruby
|
|
283
|
-
class UserFlowsTest < ApplicationSystemTestCase
|
|
284
|
-
test "user can sign up and create a post" do
|
|
285
|
-
visit new_registration_url
|
|
286
|
-
fill_in "Name", with: "Test User"
|
|
287
|
-
fill_in "Email", with: "test@example.com"
|
|
288
|
-
fill_in "Password", with: "password123"
|
|
289
|
-
click_on "Sign up"
|
|
290
|
-
|
|
291
|
-
assert_text "Welcome, Test User"
|
|
292
|
-
|
|
293
|
-
click_on "New Post"
|
|
294
|
-
fill_in "Title", with: "My First Post"
|
|
295
|
-
fill_in "Body", with: "Hello world"
|
|
296
|
-
click_on "Create Post"
|
|
297
|
-
|
|
298
|
-
assert_text "My First Post"
|
|
299
|
-
end
|
|
300
|
-
end
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### Key Testing Conventions
|
|
304
|
-
- Use `assert_difference` for state changes, not just boolean checks
|
|
305
|
-
- Set `Current.session` in setup blocks for multi-tenancy
|
|
306
|
-
- Test happy path and one key failure path per method
|
|
307
|
-
- Use `assert_select` for HTML assertions in controller tests
|
|
308
|
-
- Run `bin/rails test` (not `rspec`) for the full suite
|
|
309
|
-
|
|
310
|
-
</testing_patterns>
|
|
311
|
-
|
|
312
|
-
<domain_templates>
|
|
313
|
-
|
|
314
|
-
## Rails Task Templates for Planning
|
|
315
|
-
|
|
316
|
-
These templates help the planner agent decompose common Rails work into well-structured tasks.
|
|
317
|
-
|
|
318
|
-
### Add Model
|
|
319
|
-
```
|
|
320
|
-
Tasks:
|
|
321
|
-
1. Create migration + model with validations, associations, and concerns
|
|
322
|
-
Files: db/migrate/xxx_create_[model].rb, app/models/[model].rb
|
|
323
|
-
2. Add model tests + fixtures
|
|
324
|
-
Files: test/models/[model]_test.rb, test/fixtures/[model].yml
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
### Add Controller (with views)
|
|
328
|
-
```
|
|
329
|
-
Tasks:
|
|
330
|
-
1. Add routes + controller with RESTful actions
|
|
331
|
-
Files: config/routes.rb, app/controllers/[model]_controller.rb
|
|
332
|
-
2. Add views (index, show, new, edit, _form partial)
|
|
333
|
-
Files: app/views/[model]/*.html.erb
|
|
334
|
-
3. Add controller tests
|
|
335
|
-
Files: test/controllers/[model]_controller_test.rb
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### Add Authentication
|
|
339
|
-
```
|
|
340
|
-
Tasks:
|
|
341
|
-
1. Generate auth scaffold (Rails 8: bin/rails generate authentication)
|
|
342
|
-
or: Add User model with has_secure_password, Session model, SessionsController
|
|
343
|
-
Files: app/models/user.rb, app/models/session.rb, app/controllers/sessions_controller.rb
|
|
344
|
-
2. Add auth views (login, registration)
|
|
345
|
-
Files: app/views/sessions/*.html.erb, app/views/registrations/*.html.erb
|
|
346
|
-
3. Add auth tests
|
|
347
|
-
Files: test/controllers/sessions_controller_test.rb, test/models/user_test.rb
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
### Add Background Job
|
|
351
|
-
```
|
|
352
|
-
Tasks:
|
|
353
|
-
1. Create job class + model method it delegates to
|
|
354
|
-
Files: app/jobs/[name]_job.rb, app/models/[model].rb
|
|
355
|
-
2. Add job tests
|
|
356
|
-
Files: test/jobs/[name]_job_test.rb
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
### Add Mailer
|
|
360
|
-
```
|
|
361
|
-
Tasks:
|
|
362
|
-
1. Create mailer + views
|
|
363
|
-
Files: app/mailers/[name]_mailer.rb, app/views/[name]_mailer/*.html.erb
|
|
364
|
-
2. Add mailer tests
|
|
365
|
-
Files: test/mailers/[name]_mailer_test.rb
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
### Add Turbo/Hotwire Feature
|
|
369
|
-
```
|
|
370
|
-
Tasks:
|
|
371
|
-
1. Add Turbo Frame wrapping to target views + controller turbo_stream responses
|
|
372
|
-
Files: app/views/[model]/*.html.erb, app/controllers/[model]_controller.rb
|
|
373
|
-
Conventions: 422 for validation errors, 303 for redirects, dom_id for frame IDs
|
|
374
|
-
2. Add Stimulus controller (if interactive behavior needed)
|
|
375
|
-
Files: app/javascript/controllers/[name]_controller.js
|
|
376
|
-
Conventions: static values/targets/outlets first, connect/disconnect symmetry
|
|
377
|
-
3. Add Turbo Stream broadcasts (if real-time updates needed)
|
|
378
|
-
Files: app/models/[model].rb (after_create_commit callbacks)
|
|
379
|
-
Conventions: prefer default stream actions, broadcast_append_to/replace_to
|
|
380
|
-
4. Add system test for Turbo/Stimulus behavior
|
|
381
|
-
Files: test/system/[feature]_test.rb
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
</domain_templates>
|
|
385
|
-
|
|
386
|
-
<known_domains>
|
|
387
|
-
|
|
388
|
-
## Known Rails Domains (Skip Research)
|
|
389
|
-
|
|
390
|
-
These domains are well-understood in Rails and don't need web research:
|
|
391
|
-
|
|
392
|
-
| Domain | Key Patterns | Research Needed? |
|
|
393
|
-
|--------|-------------|-----------------|
|
|
394
|
-
| Models & Migrations | ActiveRecord, validations, associations, concerns | No |
|
|
395
|
-
| Controllers & Routes | RESTful resources, before_action, strong params | No |
|
|
396
|
-
| Views & Templates | ERB, partials, layouts, content_for | No |
|
|
397
|
-
| Authentication | Rails 8 auth generator, has_secure_password | No |
|
|
398
|
-
| Authorization | before_action + Current context, hand-rolled | No |
|
|
399
|
-
| Background Jobs | Solid Queue, ActiveJob | No |
|
|
400
|
-
| Email | Action Mailer, letter_opener | No |
|
|
401
|
-
| File Uploads | Active Storage | No |
|
|
402
|
-
| Real-time | Action Cable, Turbo Streams | No |
|
|
403
|
-
| Testing | Minitest, fixtures, system tests | No |
|
|
404
|
-
| API Mode | Jbuilder, API-only controllers, token auth | No |
|
|
405
|
-
| Caching | Fragment caching, Russian doll, Solid Cache | No |
|
|
406
|
-
| Search | pg_search, Ransack | Maybe (depends on complexity) |
|
|
407
|
-
| Payments | Stripe, Pay gem | Yes (API details change) |
|
|
408
|
-
| External APIs | Third-party integrations | Yes (API-specific) |
|
|
409
|
-
| Novel Gems | Unfamiliar libraries | Yes |
|
|
410
|
-
| Infrastructure | Docker, Kamal, deployment | Maybe |
|
|
411
|
-
|
|
412
|
-
**Heuristic:** If all phase requirements map to "No" domains, skip research automatically. If any requirement maps to "Yes", consider `--research` flag.
|
|
413
|
-
|
|
414
|
-
</known_domains>
|
|
415
|
-
|
|
416
|
-
</rails_conventions>
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
<overview>
|
|
2
|
-
TDD is about design quality, not coverage metrics. The red-green-refactor cycle forces you to think about behavior before implementation, producing cleaner interfaces and more testable code.
|
|
3
|
-
|
|
4
|
-
**Principle:** If you can describe the behavior as `assert_equal expected, fn(input)` before writing `fn`, TDD improves the result.
|
|
5
|
-
|
|
6
|
-
**Key insight:** TDD work is fundamentally heavier than standard tasks—it requires 2-3 execution cycles (RED → GREEN → REFACTOR), each with file reads, test runs, and potential debugging. TDD features get dedicated plans to ensure full context is available throughout the cycle.
|
|
7
|
-
</overview>
|
|
8
|
-
|
|
9
|
-
<when_to_use_tdd>
|
|
10
|
-
## When TDD Improves Quality
|
|
11
|
-
|
|
12
|
-
**TDD candidates (create a TDD plan):**
|
|
13
|
-
- Business logic with defined inputs/outputs
|
|
14
|
-
- API endpoints with request/response contracts
|
|
15
|
-
- Data transformations, parsing, formatting
|
|
16
|
-
- Validation rules and constraints
|
|
17
|
-
- Algorithms with testable behavior
|
|
18
|
-
- State machines and workflows
|
|
19
|
-
- Utility functions with clear specifications
|
|
20
|
-
|
|
21
|
-
**Skip TDD (use standard plan with `type="auto"` tasks):**
|
|
22
|
-
- UI layout, styling, visual components
|
|
23
|
-
- Configuration changes
|
|
24
|
-
- Glue code connecting existing components
|
|
25
|
-
- One-off scripts and migrations
|
|
26
|
-
- Simple CRUD with no business logic
|
|
27
|
-
- Exploratory prototyping
|
|
28
|
-
|
|
29
|
-
**Heuristic:** Can you write `assert_equal expected, fn(input)` before writing `fn`?
|
|
30
|
-
→ Yes: Create a TDD plan
|
|
31
|
-
→ No: Use standard plan, add tests after if needed
|
|
32
|
-
</when_to_use_tdd>
|
|
33
|
-
|
|
34
|
-
<tdd_plan_structure>
|
|
35
|
-
## TDD Plan Structure
|
|
36
|
-
|
|
37
|
-
Each TDD plan implements **one feature** through the full RED-GREEN-REFACTOR cycle.
|
|
38
|
-
|
|
39
|
-
```markdown
|
|
40
|
-
---
|
|
41
|
-
phase: XX-name
|
|
42
|
-
plan: NN
|
|
43
|
-
type: tdd
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
<objective>
|
|
47
|
-
[What feature and why]
|
|
48
|
-
Purpose: [Design benefit of TDD for this feature]
|
|
49
|
-
Output: [Working, tested feature]
|
|
50
|
-
</objective>
|
|
51
|
-
|
|
52
|
-
<context>
|
|
53
|
-
@.ariadna_planning/PROJECT.md
|
|
54
|
-
@.ariadna_planning/ROADMAP.md
|
|
55
|
-
@relevant/source/files.rb
|
|
56
|
-
</context>
|
|
57
|
-
|
|
58
|
-
<feature>
|
|
59
|
-
<name>[Feature name]</name>
|
|
60
|
-
<files>[source file, test file]</files>
|
|
61
|
-
<behavior>
|
|
62
|
-
[Expected behavior in testable terms]
|
|
63
|
-
Cases: input → expected output
|
|
64
|
-
</behavior>
|
|
65
|
-
<implementation>[How to implement once tests pass]</implementation>
|
|
66
|
-
</feature>
|
|
67
|
-
|
|
68
|
-
<verification>
|
|
69
|
-
[Test command that proves feature works]
|
|
70
|
-
</verification>
|
|
71
|
-
|
|
72
|
-
<success_criteria>
|
|
73
|
-
- Failing test written and committed
|
|
74
|
-
- Implementation passes test
|
|
75
|
-
- Refactor complete (if needed)
|
|
76
|
-
- All 2-3 commits present
|
|
77
|
-
</success_criteria>
|
|
78
|
-
|
|
79
|
-
<output>
|
|
80
|
-
After completion, create SUMMARY.md with:
|
|
81
|
-
- RED: What test was written, why it failed
|
|
82
|
-
- GREEN: What implementation made it pass
|
|
83
|
-
- REFACTOR: What cleanup was done (if any)
|
|
84
|
-
- Commits: List of commits produced
|
|
85
|
-
</output>
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
**One feature per TDD plan.** If features are trivial enough to batch, they're trivial enough to skip TDD—use a standard plan and add tests after.
|
|
89
|
-
</tdd_plan_structure>
|
|
90
|
-
|
|
91
|
-
<execution_flow>
|
|
92
|
-
## Red-Green-Refactor Cycle
|
|
93
|
-
|
|
94
|
-
**RED - Write failing test:**
|
|
95
|
-
1. Create test file following project conventions
|
|
96
|
-
2. Write test describing expected behavior (from `<behavior>` element)
|
|
97
|
-
3. Run test - it MUST fail
|
|
98
|
-
4. If test passes: feature exists or test is wrong. Investigate.
|
|
99
|
-
5. Commit: `test({phase}-{plan}): add failing test for [feature]`
|
|
100
|
-
|
|
101
|
-
**GREEN - Implement to pass:**
|
|
102
|
-
1. Write minimal code to make test pass
|
|
103
|
-
2. No cleverness, no optimization - just make it work
|
|
104
|
-
3. Run test - it MUST pass
|
|
105
|
-
4. Commit: `feat({phase}-{plan}): implement [feature]`
|
|
106
|
-
|
|
107
|
-
**REFACTOR (if needed):**
|
|
108
|
-
1. Clean up implementation if obvious improvements exist
|
|
109
|
-
2. Run tests - MUST still pass
|
|
110
|
-
3. Only commit if changes made: `refactor({phase}-{plan}): clean up [feature]`
|
|
111
|
-
|
|
112
|
-
**Result:** Each TDD plan produces 2-3 atomic commits.
|
|
113
|
-
</execution_flow>
|
|
114
|
-
|
|
115
|
-
<test_quality>
|
|
116
|
-
## Good Tests vs Bad Tests
|
|
117
|
-
|
|
118
|
-
**Test behavior, not implementation:**
|
|
119
|
-
- Good: "returns formatted date string"
|
|
120
|
-
- Bad: "calls formatDate helper with correct params"
|
|
121
|
-
- Tests should survive refactors
|
|
122
|
-
|
|
123
|
-
**One concept per test:**
|
|
124
|
-
- Good: Separate tests for valid input, empty input, malformed input
|
|
125
|
-
- Bad: Single test checking all edge cases with multiple assertions
|
|
126
|
-
|
|
127
|
-
**Descriptive names:**
|
|
128
|
-
- Good: "should reject empty email", "returns null for invalid ID"
|
|
129
|
-
- Bad: "test1", "handles error", "works correctly"
|
|
130
|
-
|
|
131
|
-
**No implementation details:**
|
|
132
|
-
- Good: Test public API, observable behavior
|
|
133
|
-
- Bad: Mock internals, test private methods, assert on internal state
|
|
134
|
-
</test_quality>
|
|
135
|
-
|
|
136
|
-
<framework_setup>
|
|
137
|
-
## Test Framework Setup (If None Exists)
|
|
138
|
-
|
|
139
|
-
When executing a TDD plan but no test framework is configured, set it up as part of the RED phase:
|
|
140
|
-
|
|
141
|
-
**1. Detect project type:**
|
|
142
|
-
```bash
|
|
143
|
-
# Ruby
|
|
144
|
-
if [ -f Gemfile ] || [ -f *.gemspec ]; then echo "ruby"; fi
|
|
145
|
-
|
|
146
|
-
# Python
|
|
147
|
-
if [ -f requirements.txt ] || [ -f pyproject.toml ]; then echo "python"; fi
|
|
148
|
-
|
|
149
|
-
# Go
|
|
150
|
-
if [ -f go.mod ]; then echo "go"; fi
|
|
151
|
-
|
|
152
|
-
# Rust
|
|
153
|
-
if [ -f Cargo.toml ]; then echo "rust"; fi
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
**2. Install minimal framework:**
|
|
157
|
-
| Project | Framework | Install |
|
|
158
|
-
|---------|-----------|---------|
|
|
159
|
-
| Ruby | Minitest (recommended) | Built-in (stdlib) |
|
|
160
|
-
| Ruby on Rails | Minitest (recommended) | Built-in (Rails default) |
|
|
161
|
-
| Ruby | RSpec (alternative) | `bundle add rspec --group test` |
|
|
162
|
-
| Python | pytest | `pip install pytest` |
|
|
163
|
-
| Go | testing | Built-in |
|
|
164
|
-
| Rust | cargo test | Built-in |
|
|
165
|
-
|
|
166
|
-
**3. Create config if needed:**
|
|
167
|
-
- Minitest: `test/test_helper.rb` with requires
|
|
168
|
-
- RSpec (if using RSpec): `.rspec` and `spec/spec_helper.rb` via `rspec --init`
|
|
169
|
-
- Rails: `test/test_helper.rb` (generated by default)
|
|
170
|
-
- pytest: `pytest.ini` or `pyproject.toml` section
|
|
171
|
-
|
|
172
|
-
**4. Verify setup:**
|
|
173
|
-
```bash
|
|
174
|
-
# Run empty test suite - should pass with 0 tests
|
|
175
|
-
bundle exec rake test # Ruby (Minitest)
|
|
176
|
-
bundle exec rspec # Ruby (if using RSpec)
|
|
177
|
-
bin/rails test # Rails
|
|
178
|
-
pytest # Python
|
|
179
|
-
go test ./... # Go
|
|
180
|
-
cargo test # Rust
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
**5. Create first test file:**
|
|
184
|
-
Follow project conventions for test location:
|
|
185
|
-
- `test/` directory at root (Minitest — recommended Ruby convention)
|
|
186
|
-
- `spec/` directory at root (RSpec)
|
|
187
|
-
- `test/models/`, `test/controllers/` etc. (Rails convention)
|
|
188
|
-
|
|
189
|
-
Framework setup is a one-time cost included in the first TDD plan's RED phase.
|
|
190
|
-
</framework_setup>
|
|
191
|
-
|
|
192
|
-
<error_handling>
|
|
193
|
-
## Error Handling
|
|
194
|
-
|
|
195
|
-
**Test doesn't fail in RED phase:**
|
|
196
|
-
- Feature may already exist - investigate
|
|
197
|
-
- Test may be wrong (not testing what you think)
|
|
198
|
-
- Fix before proceeding
|
|
199
|
-
|
|
200
|
-
**Test doesn't pass in GREEN phase:**
|
|
201
|
-
- Debug implementation
|
|
202
|
-
- Don't skip to refactor
|
|
203
|
-
- Keep iterating until green
|
|
204
|
-
|
|
205
|
-
**Tests fail in REFACTOR phase:**
|
|
206
|
-
- Undo refactor
|
|
207
|
-
- Commit was premature
|
|
208
|
-
- Refactor in smaller steps
|
|
209
|
-
|
|
210
|
-
**Unrelated tests break:**
|
|
211
|
-
- Stop and investigate
|
|
212
|
-
- May indicate coupling issue
|
|
213
|
-
- Fix before proceeding
|
|
214
|
-
</error_handling>
|
|
215
|
-
|
|
216
|
-
<commit_pattern>
|
|
217
|
-
## Commit Pattern for TDD Plans
|
|
218
|
-
|
|
219
|
-
TDD plans produce 2-3 atomic commits (one per phase):
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
test(08-02): add failing test for email validation
|
|
223
|
-
|
|
224
|
-
- Tests valid email formats accepted
|
|
225
|
-
- Tests invalid formats rejected
|
|
226
|
-
- Tests empty input handling
|
|
227
|
-
|
|
228
|
-
feat(08-02): implement email validation
|
|
229
|
-
|
|
230
|
-
- Regex pattern matches RFC 5322
|
|
231
|
-
- Returns boolean for validity
|
|
232
|
-
- Handles edge cases (empty, null)
|
|
233
|
-
|
|
234
|
-
refactor(08-02): extract regex to constant (optional)
|
|
235
|
-
|
|
236
|
-
- Moved pattern to EMAIL_REGEX constant
|
|
237
|
-
- No behavior changes
|
|
238
|
-
- Tests still pass
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
**Comparison with standard plans:**
|
|
242
|
-
- Standard plans: 1 commit per task, 2-4 commits per plan
|
|
243
|
-
- TDD plans: 2-3 commits for single feature
|
|
244
|
-
|
|
245
|
-
Both follow same format: `{type}({phase}-{plan}): {description}`
|
|
246
|
-
|
|
247
|
-
**Benefits:**
|
|
248
|
-
- Each commit independently revertable
|
|
249
|
-
- Git bisect works at commit level
|
|
250
|
-
- Clear history showing TDD discipline
|
|
251
|
-
- Consistent with overall commit strategy
|
|
252
|
-
</commit_pattern>
|
|
253
|
-
|
|
254
|
-
<context_budget>
|
|
255
|
-
## Context Budget
|
|
256
|
-
|
|
257
|
-
TDD plans target **~40% context usage** (lower than standard plans' ~50%).
|
|
258
|
-
|
|
259
|
-
Why lower:
|
|
260
|
-
- RED phase: write test, run test, potentially debug why it didn't fail
|
|
261
|
-
- GREEN phase: implement, run test, potentially iterate on failures
|
|
262
|
-
- REFACTOR phase: modify code, run tests, verify no regressions
|
|
263
|
-
|
|
264
|
-
Each phase involves reading files, running commands, analyzing output. The back-and-forth is inherently heavier than linear task execution.
|
|
265
|
-
|
|
266
|
-
Single feature focus ensures full quality throughout the cycle.
|
|
267
|
-
</context_budget>
|