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.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/ariadna.gemspec +0 -1
  3. data/data/agents/ariadna-codebase-mapper.md +34 -722
  4. data/data/agents/ariadna-debugger.md +44 -1139
  5. data/data/agents/ariadna-executor.md +75 -396
  6. data/data/agents/ariadna-planner.md +78 -1215
  7. data/data/agents/ariadna-roadmapper.md +55 -582
  8. data/data/agents/ariadna-verifier.md +60 -702
  9. data/data/ariadna/templates/config.json +8 -33
  10. data/data/ariadna/workflows/debug.md +28 -0
  11. data/data/ariadna/workflows/execute-phase.md +31 -513
  12. data/data/ariadna/workflows/map-codebase.md +20 -319
  13. data/data/ariadna/workflows/new-milestone.md +20 -365
  14. data/data/ariadna/workflows/new-project.md +19 -880
  15. data/data/ariadna/workflows/plan-phase.md +24 -443
  16. data/data/ariadna/workflows/progress.md +20 -376
  17. data/data/ariadna/workflows/quick.md +19 -221
  18. data/data/ariadna/workflows/roadmap-ops.md +28 -0
  19. data/data/ariadna/workflows/verify-work.md +23 -560
  20. data/data/commands/ariadna/add-phase.md +11 -22
  21. data/data/commands/ariadna/debug.md +11 -143
  22. data/data/commands/ariadna/execute-phase.md +12 -30
  23. data/data/commands/ariadna/insert-phase.md +7 -14
  24. data/data/commands/ariadna/map-codebase.md +16 -49
  25. data/data/commands/ariadna/new-milestone.md +12 -25
  26. data/data/commands/ariadna/new-project.md +22 -26
  27. data/data/commands/ariadna/plan-phase.md +13 -22
  28. data/data/commands/ariadna/progress.md +16 -6
  29. data/data/commands/ariadna/quick.md +9 -11
  30. data/data/commands/ariadna/remove-phase.md +9 -12
  31. data/data/commands/ariadna/verify-work.md +14 -19
  32. data/data/skills/rails-backend/API.md +138 -0
  33. data/data/skills/rails-backend/CONTROLLERS.md +154 -0
  34. data/data/skills/rails-backend/JOBS.md +132 -0
  35. data/data/skills/rails-backend/MODELS.md +213 -0
  36. data/data/skills/rails-backend/SKILL.md +169 -0
  37. data/data/skills/rails-frontend/ASSETS.md +154 -0
  38. data/data/skills/rails-frontend/COMPONENTS.md +253 -0
  39. data/data/skills/rails-frontend/SKILL.md +187 -0
  40. data/data/skills/rails-frontend/VIEWS.md +168 -0
  41. data/data/skills/rails-performance/PROFILING.md +106 -0
  42. data/data/skills/rails-performance/SKILL.md +217 -0
  43. data/data/skills/rails-security/AUDIT.md +118 -0
  44. data/data/skills/rails-security/SKILL.md +422 -0
  45. data/data/skills/rails-testing/FIXTURES.md +78 -0
  46. data/data/skills/rails-testing/SKILL.md +160 -0
  47. data/data/skills/rails-testing/SYSTEM-TESTS.md +73 -0
  48. data/lib/ariadna/installer.rb +11 -15
  49. data/lib/ariadna/tools/cli.rb +0 -12
  50. data/lib/ariadna/tools/config_manager.rb +10 -72
  51. data/lib/ariadna/tools/frontmatter.rb +23 -1
  52. data/lib/ariadna/tools/init.rb +201 -401
  53. data/lib/ariadna/tools/model_profiles.rb +6 -14
  54. data/lib/ariadna/tools/phase_manager.rb +1 -10
  55. data/lib/ariadna/tools/state_manager.rb +170 -451
  56. data/lib/ariadna/tools/template_filler.rb +4 -12
  57. data/lib/ariadna/tools/verification.rb +21 -399
  58. data/lib/ariadna/uninstaller.rb +9 -0
  59. data/lib/ariadna/version.rb +1 -1
  60. data/lib/ariadna.rb +1 -0
  61. metadata +20 -91
  62. data/data/agents/ariadna-backend-executor.md +0 -261
  63. data/data/agents/ariadna-frontend-executor.md +0 -259
  64. data/data/agents/ariadna-integration-checker.md +0 -418
  65. data/data/agents/ariadna-phase-researcher.md +0 -469
  66. data/data/agents/ariadna-plan-checker.md +0 -622
  67. data/data/agents/ariadna-project-researcher.md +0 -618
  68. data/data/agents/ariadna-research-synthesizer.md +0 -236
  69. data/data/agents/ariadna-test-executor.md +0 -266
  70. data/data/ariadna/references/checkpoints.md +0 -772
  71. data/data/ariadna/references/continuation-format.md +0 -249
  72. data/data/ariadna/references/decimal-phase-calculation.md +0 -65
  73. data/data/ariadna/references/git-integration.md +0 -248
  74. data/data/ariadna/references/git-planning-commit.md +0 -38
  75. data/data/ariadna/references/model-profile-resolution.md +0 -32
  76. data/data/ariadna/references/model-profiles.md +0 -73
  77. data/data/ariadna/references/phase-argument-parsing.md +0 -61
  78. data/data/ariadna/references/planning-config.md +0 -194
  79. data/data/ariadna/references/questioning.md +0 -153
  80. data/data/ariadna/references/rails-conventions.md +0 -416
  81. data/data/ariadna/references/tdd.md +0 -267
  82. data/data/ariadna/references/ui-brand.md +0 -160
  83. data/data/ariadna/references/verification-patterns.md +0 -853
  84. data/data/ariadna/templates/codebase/architecture.md +0 -481
  85. data/data/ariadna/templates/codebase/concerns.md +0 -380
  86. data/data/ariadna/templates/codebase/conventions.md +0 -434
  87. data/data/ariadna/templates/codebase/integrations.md +0 -328
  88. data/data/ariadna/templates/codebase/stack.md +0 -189
  89. data/data/ariadna/templates/codebase/structure.md +0 -418
  90. data/data/ariadna/templates/codebase/testing.md +0 -606
  91. data/data/ariadna/templates/context.md +0 -283
  92. data/data/ariadna/templates/continue-here.md +0 -78
  93. data/data/ariadna/templates/debug-subagent-prompt.md +0 -91
  94. data/data/ariadna/templates/phase-prompt.md +0 -609
  95. data/data/ariadna/templates/planner-subagent-prompt.md +0 -117
  96. data/data/ariadna/templates/research-project/ARCHITECTURE.md +0 -439
  97. data/data/ariadna/templates/research-project/FEATURES.md +0 -168
  98. data/data/ariadna/templates/research-project/PITFALLS.md +0 -406
  99. data/data/ariadna/templates/research-project/STACK.md +0 -251
  100. data/data/ariadna/templates/research-project/SUMMARY.md +0 -247
  101. data/data/ariadna/templates/state.md +0 -176
  102. data/data/ariadna/templates/summary-complex.md +0 -59
  103. data/data/ariadna/templates/summary-minimal.md +0 -41
  104. data/data/ariadna/templates/summary-standard.md +0 -48
  105. data/data/ariadna/templates/user-setup.md +0 -310
  106. data/data/ariadna/workflows/add-phase.md +0 -111
  107. data/data/ariadna/workflows/add-todo.md +0 -157
  108. data/data/ariadna/workflows/audit-milestone.md +0 -241
  109. data/data/ariadna/workflows/check-todos.md +0 -176
  110. data/data/ariadna/workflows/complete-milestone.md +0 -644
  111. data/data/ariadna/workflows/diagnose-issues.md +0 -219
  112. data/data/ariadna/workflows/discovery-phase.md +0 -289
  113. data/data/ariadna/workflows/discuss-phase.md +0 -408
  114. data/data/ariadna/workflows/execute-plan.md +0 -448
  115. data/data/ariadna/workflows/help.md +0 -470
  116. data/data/ariadna/workflows/insert-phase.md +0 -129
  117. data/data/ariadna/workflows/list-phase-assumptions.md +0 -178
  118. data/data/ariadna/workflows/pause-work.md +0 -122
  119. data/data/ariadna/workflows/plan-milestone-gaps.md +0 -256
  120. data/data/ariadna/workflows/remove-phase.md +0 -154
  121. data/data/ariadna/workflows/research-phase.md +0 -74
  122. data/data/ariadna/workflows/resume-project.md +0 -306
  123. data/data/ariadna/workflows/set-profile.md +0 -80
  124. data/data/ariadna/workflows/settings.md +0 -145
  125. data/data/ariadna/workflows/transition.md +0 -493
  126. data/data/ariadna/workflows/update.md +0 -212
  127. data/data/ariadna/workflows/verify-phase.md +0 -226
  128. data/data/commands/ariadna/add-todo.md +0 -42
  129. data/data/commands/ariadna/audit-milestone.md +0 -42
  130. data/data/commands/ariadna/check-todos.md +0 -41
  131. data/data/commands/ariadna/complete-milestone.md +0 -136
  132. data/data/commands/ariadna/discuss-phase.md +0 -86
  133. data/data/commands/ariadna/help.md +0 -22
  134. data/data/commands/ariadna/list-phase-assumptions.md +0 -50
  135. data/data/commands/ariadna/pause-work.md +0 -35
  136. data/data/commands/ariadna/plan-milestone-gaps.md +0 -40
  137. data/data/commands/ariadna/reapply-patches.md +0 -110
  138. data/data/commands/ariadna/research-phase.md +0 -187
  139. data/data/commands/ariadna/resume-work.md +0 -40
  140. data/data/commands/ariadna/set-profile.md +0 -34
  141. data/data/commands/ariadna/settings.md +0 -36
  142. data/data/commands/ariadna/update.md +0 -37
  143. data/data/guides/backend.md +0 -3069
  144. data/data/guides/frontend.md +0 -1479
  145. data/data/guides/performance.md +0 -1193
  146. data/data/guides/security.md +0 -1522
  147. data/data/guides/style-guide.md +0 -1091
  148. data/data/guides/testing.md +0 -504
  149. data/data/templates.md +0 -94
@@ -1,434 +0,0 @@
1
- # Coding Conventions Template
2
-
3
- Template for `.ariadna_planning/codebase/CONVENTIONS.md` - captures coding style and patterns.
4
-
5
- **Purpose:** Document how code is written in this codebase. Prescriptive guide for Claude to match existing style.
6
-
7
- ---
8
-
9
- ## File Template
10
-
11
- ```markdown
12
- # Coding Conventions
13
-
14
- **Analysis Date:** [YYYY-MM-DD]
15
-
16
- ## Naming Patterns
17
-
18
- **Files:**
19
- - [Pattern: e.g., "snake_case for all Ruby files"]
20
- - [Test files: e.g., "`*_test.rb` in `test/` mirroring `app/` structure"]
21
- - [Controllers: e.g., "`users_controller.rb`, plural resource name"]
22
- - [Models: e.g., "`user.rb`, singular"]
23
- - [Concerns: e.g., "`closeable.rb` for shared, `card/closeable.rb` for model-specific"]
24
-
25
- **Methods:**
26
- - [Pattern: e.g., "snake_case for all methods"]
27
- - [Booleans: e.g., "`?` suffix — `active?`, `closed?`, `can_edit?`"]
28
- - [Bang: e.g., "`!` only when a non-bang counterpart exists — `save!`/`save`"]
29
- - [Actions: e.g., "imperative verbs — `close`, `gild`, `postpone`"]
30
-
31
- **Variables:**
32
- - [Pattern: e.g., "snake_case for locals and parameters"]
33
- - [Instance: e.g., "`@board`, `@card` — set in `before_action`"]
34
- - [Constants: e.g., "`SCREAMING_SNAKE_CASE` — `MAX_RETRIES`, `DEFAULT_LIMIT`"]
35
- - [Class variables: e.g., "`@@class_var` — rarely used, prefer class-level accessors"]
36
-
37
- **Classes & Modules:**
38
- - [Classes: e.g., "PascalCase — `User`, `CardPolicy`, `ApplicationController`"]
39
- - [Modules: e.g., "PascalCase — `Eventable`, `Card::Closeable`"]
40
- - [Namespacing: e.g., "`Card::Closeable` maps to `app/models/card/closeable.rb`"]
41
-
42
- ## Code Style
43
-
44
- **Formatting:**
45
- - [Tool: e.g., "RuboCop with `.rubocop.yml`"]
46
- - [Pragma: e.g., "`# frozen_string_literal: true` at top of every file"]
47
- - [Line length: e.g., "120 characters max"]
48
- - [Quotes: e.g., "double quotes for strings"]
49
- - [Indentation: e.g., "2-space indentation, no tabs"]
50
-
51
- **Linting:**
52
- - [Tool: e.g., "RuboCop"]
53
- - [Config: e.g., "`.rubocop.yml` with project-specific overrides"]
54
- - [Run: e.g., "`bundle exec rubocop` / `bundle exec rubocop -a`"]
55
-
56
- ## Require & Include Organization
57
-
58
- **Require Order:**
59
- 1. [e.g., "Standard library (`require 'json'`, `require 'net/http'`)"]
60
- 2. [e.g., "Gem requires (`require 'nokogiri'`)"]
61
- 3. [e.g., "Application requires (`require_relative '../lib/parser'`)"]
62
-
63
- **Include/Extend Order in Models:**
64
- - [e.g., "`include` for concerns — listed alphabetically on one line"]
65
- - [e.g., "`extend` for class-level modules"]
66
- - [e.g., "Concern declaration: `extend ActiveSupport::Concern` as first line"]
67
-
68
- **Concern Declaration:**
69
- - [e.g., "`extend ActiveSupport::Concern` + `included do` block"]
70
- - [e.g., "Associations, scopes, callbacks inside `included do`"]
71
- - [e.g., "Instance methods below the `included` block"]
72
-
73
- ## Error Handling
74
-
75
- **Patterns:**
76
- - [Strategy: e.g., "`rescue_from` in controllers, `begin/rescue` in methods"]
77
- - [Custom errors: e.g., "inherit `StandardError`, named `*Error`"]
78
- - [Model validation: e.g., "re-render form with `@model.errors`"]
79
-
80
- **Error Types:**
81
- - [When to raise: e.g., "invalid input, authorization failures, missing records"]
82
- - [When to return: e.g., "expected failures return `false` or `nil`"]
83
- - [Jobs: e.g., "`retry_on` for transient, `discard_on` for permanent failures"]
84
-
85
- ## Logging
86
-
87
- **Framework:**
88
- - [Tool: e.g., "`Rails.logger`"]
89
- - [Levels: e.g., "debug, info, warn, error, fatal"]
90
-
91
- **Patterns:**
92
- - [Format: e.g., "tagged logging with request ID and user context"]
93
- - [Request logs: e.g., "Lograge for structured single-line request logs"]
94
- - [When: e.g., "log external API calls, state transitions, errors"]
95
-
96
- ## Comments
97
-
98
- **When to Comment:**
99
- - [e.g., "explain why, not what"]
100
- - [e.g., "document business rules and edge cases"]
101
- - [e.g., "avoid obvious comments"]
102
-
103
- **Documentation:**
104
- - [Pragma: e.g., "`# frozen_string_literal: true` — required first line"]
105
- - [YARD: e.g., "`@param`, `@return` if YARD is used, optional otherwise"]
106
- - [TODO: e.g., "`# TODO:` format, link to issue if available"]
107
-
108
- ## Method Design
109
-
110
- **Size:**
111
- - [e.g., "max ~30 lines per method (RuboCop enforced)"]
112
- - [e.g., "extract private helpers for complex logic"]
113
-
114
- **Parameters:**
115
- - [e.g., "keyword arguments for clarity: `def create(name:, email:)`"]
116
- - [e.g., "default to `Current` context: `def close(user: Current.user)`"]
117
-
118
- **Return Values:**
119
- - [e.g., "guard clauses for early returns at method start"]
120
- - [e.g., "expanded conditionals preferred over guard clauses mid-method"]
121
- - [e.g., "implicit return of last expression"]
122
-
123
- **Visibility:**
124
- - [e.g., "public methods first, then `private` keyword, then private methods"]
125
- - [e.g., "private methods indented under `private`, no blank line after keyword"]
126
- - [e.g., "private methods ordered by invocation order"]
127
-
128
- ## Module & Concern Design
129
-
130
- **Concerns:**
131
- - [Shared: e.g., "adjective names — `Eventable`, `Searchable`, `Notifiable`"]
132
- - [Model-specific: e.g., "namespaced — `Card::Closeable`, `Board::Accessible`"]
133
- - [Pattern: e.g., "`ActiveSupport::Concern` with `included do` block"]
134
-
135
- **Plain Ruby Objects:**
136
- - [e.g., "semantic names — `Signup`, `Notifier`, not `SignupService`"]
137
- - [e.g., "concerns delegate complex logic to dedicated objects"]
138
-
139
- ---
140
-
141
- *Convention analysis: [date]*
142
- *Update when patterns change*
143
- ```
144
-
145
- <good_examples>
146
- ```markdown
147
- # Coding Conventions
148
-
149
- **Analysis Date:** 2025-01-20
150
-
151
- ## Naming Patterns
152
-
153
- **Files:**
154
- - snake_case for all Ruby files (`user.rb`, `users_controller.rb`, `card_policy.rb`)
155
- - `*_test.rb` in `test/` mirroring `app/` structure (`test/models/card_test.rb`)
156
- - Controllers: plural resource name + `_controller.rb` (`boards_controller.rb`)
157
- - Models: singular (`card.rb`, `event.rb`)
158
- - Concerns: adjective for shared (`eventable.rb`), namespaced for model-specific (`card/closeable.rb`)
159
- - Jobs: descriptive + `_job.rb` (`notify_recipients_job.rb`)
160
- - Mailers: descriptive + `_mailer.rb` (`invitation_mailer.rb`)
161
-
162
- **Methods:**
163
- - snake_case for all methods
164
- - `?` suffix for boolean queries — `closed?`, `open?`, `golden?`, `can_edit?`
165
- - `!` suffix only when a non-bang counterpart exists — `save!`/`save`, `update!`/`update`
166
- - Imperative verbs for actions — `close`, `reopen`, `gild`, `ungild`, `postpone`, `archive`
167
- - No generic names — `close` not `process`, `gild` not `handle`
168
- - Boolean pairs — always provide both: `closed?`/`open?`, `golden?`/`not_golden?`
169
-
170
- **Variables:**
171
- - snake_case for locals and parameters (`board_name`, `card_count`)
172
- - `@instance_vars` set in `before_action` callbacks (`@board`, `@card`)
173
- - `SCREAMING_SNAKE_CASE` for constants (`MAX_RETRIES`, `DEFAULT_PAGE_SIZE`)
174
- - No Hungarian notation, no type prefixes
175
-
176
- **Classes & Modules:**
177
- - PascalCase for classes (`User`, `CardPolicy`, `ApplicationController`)
178
- - PascalCase for modules (`Eventable`, `Card::Closeable`, `Board::Accessible`)
179
- - Namespace maps to directory: `Card::Closeable` lives at `app/models/card/closeable.rb`
180
-
181
- ## Code Style
182
-
183
- **Formatting:**
184
- - RuboCop with `.rubocop.yml`
185
- - `# frozen_string_literal: true` as first line of every `.rb` file
186
- - Double quotes for strings
187
- - 120 character line length
188
- - 2-space indentation, no tabs
189
- - No trailing whitespace
190
- - Newline at end of file
191
-
192
- **Linting:**
193
- - RuboCop with project `.rubocop.yml`
194
- - Method length max ~30 lines (RuboCop `Metrics/MethodLength`)
195
- - ABC size max ~30 (RuboCop `Metrics/AbcSize`)
196
- - Run: `bundle exec rubocop`
197
- - Auto-fix: `bundle exec rubocop -a`
198
-
199
- ## Require & Include Organization
200
-
201
- **Require Order (in non-Rails files like gems and scripts):**
202
- 1. Standard library (`require "json"`, `require "net/http"`)
203
- 2. Gem requires (`require "nokogiri"`)
204
- 3. Application requires (`require_relative "../lib/parser"`)
205
-
206
- **Include Order in Models:**
207
- - Concerns listed alphabetically on one line, wrapped if long:
208
- ```ruby
209
- include Assignable, Attachments, Closeable, Eventable, Golden,
210
- Mentions, Postponable, Searchable, Taggable, Watchable
211
- ```
212
- - `extend` for class-level modules (rare)
213
-
214
- **Concern Declaration:**
215
- - `extend ActiveSupport::Concern` as first line
216
- - `included do` block for associations, scopes, callbacks
217
- - Instance methods below the `included` block
218
- - Private methods at the bottom under `private`
219
-
220
- ```ruby
221
- module Card::Closeable
222
- extend ActiveSupport::Concern
223
-
224
- included do
225
- has_one :closure, dependent: :destroy
226
- scope :closed, -> { joins(:closure) }
227
- scope :open, -> { where.missing(:closure) }
228
- end
229
-
230
- def closed?
231
- closure.present?
232
- end
233
-
234
- def close(user: Current.user)
235
- # ...
236
- end
237
-
238
- private
239
- def track_closure_event(user)
240
- # ...
241
- end
242
- end
243
- ```
244
-
245
- ## Error Handling
246
-
247
- **Patterns:**
248
- - `rescue_from` in `ApplicationController` for cross-cutting error handling
249
- - `begin/rescue/ensure` blocks in methods for specific recovery
250
- - Custom error classes inherit `StandardError`
251
- - Model validation errors re-render form with `@model.errors`
252
-
253
- **Error Types:**
254
- - Raise on authorization failures: `rescue_from NotAuthorizedError`
255
- - Raise on missing records: `rescue_from ActiveRecord::RecordNotFound`
256
- - Return `false`/`nil` for expected domain failures
257
- - Jobs: `retry_on` for transient failures (network, timeouts), `discard_on ActiveRecord::RecordNotFound`
258
-
259
- **Custom Errors:**
260
- ```ruby
261
- class InsufficientStorageError < StandardError; end
262
- class AccountSuspendedError < StandardError; end
263
- ```
264
-
265
- ## Logging
266
-
267
- **Framework:**
268
- - `Rails.logger` — standard Rails logger
269
- - Levels: debug, info, warn, error, fatal
270
-
271
- **Patterns:**
272
- - Tagged logging with request context: `Rails.logger.tagged("ImportJob") { logger.info "..." }`
273
- - Lograge for structured single-line request logs
274
- - Log external API calls, state transitions, unexpected conditions
275
- - No `puts` or `p` in committed code
276
-
277
- ## Comments
278
-
279
- **When to Comment:**
280
- - Explain why, not what: `# Retry because API has transient 503 errors`
281
- - Document business rules: `# Users must verify email within 24 hours`
282
- - Explain non-obvious workarounds or edge cases
283
- - Avoid obvious comments: `# Close the card` above `card.close`
284
-
285
- **Pragmas & Documentation:**
286
- - `# frozen_string_literal: true` — required first line, every file
287
- - YARD docs (`@param`, `@return`) if the project uses YARD, optional otherwise
288
- - `# TODO:` format with description, link to issue if exists
289
-
290
- ## Method Design
291
-
292
- **Size:**
293
- - Max ~30 lines per method (RuboCop enforced)
294
- - Extract private helpers for complex logic
295
- - One level of abstraction per method
296
-
297
- **Parameters:**
298
- - Keyword arguments for clarity: `def close(user: Current.user)`
299
- - Default to `Current` context where appropriate
300
- - Max 3-4 parameters; use keyword arguments for more
301
-
302
- **Return Values:**
303
- - Guard clauses only at method start for non-trivial bodies
304
- - Expanded conditionals preferred over mid-method guard clauses:
305
- ```ruby
306
- # Preferred
307
- def todos_for_group
308
- if ids = params.require(:todolist)[:todo_ids]
309
- @bucket.recordings.todos.find(ids.split(","))
310
- else
311
- []
312
- end
313
- end
314
- ```
315
- - Implicit return of last expression (no explicit `return` at end)
316
-
317
- **Method Ordering:**
318
- 1. Class methods (`class << self`)
319
- 2. Public instance methods (`initialize` first if present)
320
- 3. `private` keyword (no blank line after)
321
- 4. Private methods (indented, ordered by invocation order)
322
-
323
- ```ruby
324
- class Board
325
- class << self
326
- def default_for(account)
327
- # ...
328
- end
329
- end
330
-
331
- def archive
332
- # ...
333
- end
334
-
335
- private
336
- def notify_members
337
- # ...
338
- end
339
-
340
- def track_archive_event
341
- # ...
342
- end
343
- end
344
- ```
345
-
346
- **Visibility Modifier Style:**
347
- - No blank line after `private` keyword
348
- - Private methods indented one level under `private`
349
- - Private methods ordered by invocation order (read top-to-bottom)
350
-
351
- ## Module & Concern Design
352
-
353
- **Shared Concerns:**
354
- - Adjective names for cross-cutting behavior: `Eventable`, `Searchable`, `Notifiable`, `Attachments`
355
- - Located in `app/models/concerns/`
356
- - Reusable across 3+ unrelated models
357
-
358
- **Model-Specific Concerns:**
359
- - Namespaced names for domain behavior: `Card::Closeable`, `Card::Golden`, `Board::Accessible`
360
- - Located in model subdirectories: `app/models/card/`, `app/models/board/`
361
- - Extract when 50+ lines of cohesive behavior
362
-
363
- **Concern Anatomy:**
364
- - `extend ActiveSupport::Concern` first line
365
- - `included do` block: associations, scopes, callbacks
366
- - Public API methods: intention-revealing names
367
- - Template method pattern for override points (`should_track_event?`, `eventable_prefix`)
368
-
369
- **Plain Ruby Objects:**
370
- - Semantic names: `Signup`, `Notifier`, `Detector` — not `SignupService`, `NotificationHandler`
371
- - Concerns delegate complex logic to dedicated objects:
372
- ```
373
- Concern (framework integration) --> Plain Ruby Object (business logic)
374
- ```
375
-
376
- **Intention-Revealing APIs:**
377
- - Action methods use imperative verbs: `close`, `gild`, `postpone`, `archive`
378
- - Not implementation-revealing: `close` not `create_closure_record`
379
- - Boolean pairs always provided: `closed?`/`open?`, `golden?`
380
- - Business-named scopes: `closed` not `with_closures`, `open` not `without_closures`
381
-
382
- ---
383
-
384
- *Convention analysis: 2025-01-20*
385
- *Update when patterns change*
386
- ```
387
- </good_examples>
388
-
389
- <guidelines>
390
- **What belongs in CONVENTIONS.md:**
391
- - Naming patterns for files, methods, variables, classes, and modules
392
- - Code formatting rules (RuboCop config, line length, quotes, indentation)
393
- - Require/include organization patterns
394
- - Error handling strategy
395
- - Logging approach
396
- - Comment conventions
397
- - Method design patterns (size, parameters, returns, ordering, visibility)
398
- - Module and concern design patterns
399
-
400
- **What does NOT belong here:**
401
- - Architecture decisions (that's ARCHITECTURE.md)
402
- - Technology choices and gem versions (that's STACK.md)
403
- - Test patterns (that's TESTING.md)
404
- - File organization (that's STRUCTURE.md)
405
-
406
- **When filling this template:**
407
- - Check `.rubocop.yml` for formatting rules, line length, method size limits
408
- - Check `Gemfile` for linting gems (rubocop, standard, etc.)
409
- - Examine 5-10 representative files in `app/models/`, `app/controllers/`, `app/models/concerns/`
410
- - Look for consistency: if 80%+ follows a pattern, document it
411
- - Be prescriptive: "Use X" not "Sometimes Y is used"
412
- - Note deviations: "Legacy code uses Y, new code should use X"
413
- - Keep under ~150 lines total
414
-
415
- **Useful for phase planning when:**
416
- - Writing new code (match existing style)
417
- - Adding features (follow naming patterns — imperative verbs, boolean pairs, concern naming)
418
- - Creating concerns (follow `ActiveSupport::Concern` anatomy, naming conventions)
419
- - Refactoring (apply consistent conventions — method ordering, visibility style)
420
- - Code review (check against documented patterns)
421
- - Onboarding (understand style expectations)
422
-
423
- **Analysis approach:**
424
- - Read `.rubocop.yml` for enforced style rules (line length, method size, ABC size, quote style)
425
- - Check `Gemfile` for `rubocop`, `standard`, or other linting gems
426
- - Scan `app/models/` and `app/controllers/` for file naming patterns
427
- - Read 2-3 model files to identify method naming, concern composition, and visibility style
428
- - Read 2-3 concern files to identify concern anatomy (`included do` block, public API, private methods)
429
- - Check `app/models/concerns/` for shared concern naming conventions (adjective names)
430
- - Check for model-specific concern directories (`app/models/card/`, `app/models/board/`)
431
- - Read a controller to identify error handling, parameter style, before_action patterns
432
- - Note patterns in method ordering, visibility modifiers, conditional style
433
- - Look for `# frozen_string_literal: true` pragma usage
434
- </guidelines>