ariadna 1.3.1 → 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 (148) 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. metadata +20 -91
  61. data/data/agents/ariadna-backend-executor.md +0 -261
  62. data/data/agents/ariadna-frontend-executor.md +0 -259
  63. data/data/agents/ariadna-integration-checker.md +0 -418
  64. data/data/agents/ariadna-phase-researcher.md +0 -469
  65. data/data/agents/ariadna-plan-checker.md +0 -622
  66. data/data/agents/ariadna-project-researcher.md +0 -618
  67. data/data/agents/ariadna-research-synthesizer.md +0 -236
  68. data/data/agents/ariadna-test-executor.md +0 -266
  69. data/data/ariadna/references/checkpoints.md +0 -772
  70. data/data/ariadna/references/continuation-format.md +0 -249
  71. data/data/ariadna/references/decimal-phase-calculation.md +0 -65
  72. data/data/ariadna/references/git-integration.md +0 -248
  73. data/data/ariadna/references/git-planning-commit.md +0 -38
  74. data/data/ariadna/references/model-profile-resolution.md +0 -32
  75. data/data/ariadna/references/model-profiles.md +0 -73
  76. data/data/ariadna/references/phase-argument-parsing.md +0 -61
  77. data/data/ariadna/references/planning-config.md +0 -194
  78. data/data/ariadna/references/questioning.md +0 -153
  79. data/data/ariadna/references/rails-conventions.md +0 -416
  80. data/data/ariadna/references/tdd.md +0 -267
  81. data/data/ariadna/references/ui-brand.md +0 -160
  82. data/data/ariadna/references/verification-patterns.md +0 -853
  83. data/data/ariadna/templates/codebase/architecture.md +0 -481
  84. data/data/ariadna/templates/codebase/concerns.md +0 -380
  85. data/data/ariadna/templates/codebase/conventions.md +0 -434
  86. data/data/ariadna/templates/codebase/integrations.md +0 -328
  87. data/data/ariadna/templates/codebase/stack.md +0 -189
  88. data/data/ariadna/templates/codebase/structure.md +0 -418
  89. data/data/ariadna/templates/codebase/testing.md +0 -606
  90. data/data/ariadna/templates/context.md +0 -283
  91. data/data/ariadna/templates/continue-here.md +0 -78
  92. data/data/ariadna/templates/debug-subagent-prompt.md +0 -91
  93. data/data/ariadna/templates/phase-prompt.md +0 -609
  94. data/data/ariadna/templates/planner-subagent-prompt.md +0 -117
  95. data/data/ariadna/templates/research-project/ARCHITECTURE.md +0 -439
  96. data/data/ariadna/templates/research-project/FEATURES.md +0 -168
  97. data/data/ariadna/templates/research-project/PITFALLS.md +0 -406
  98. data/data/ariadna/templates/research-project/STACK.md +0 -251
  99. data/data/ariadna/templates/research-project/SUMMARY.md +0 -247
  100. data/data/ariadna/templates/state.md +0 -176
  101. data/data/ariadna/templates/summary-complex.md +0 -59
  102. data/data/ariadna/templates/summary-minimal.md +0 -41
  103. data/data/ariadna/templates/summary-standard.md +0 -48
  104. data/data/ariadna/templates/user-setup.md +0 -310
  105. data/data/ariadna/workflows/add-phase.md +0 -111
  106. data/data/ariadna/workflows/add-todo.md +0 -157
  107. data/data/ariadna/workflows/audit-milestone.md +0 -241
  108. data/data/ariadna/workflows/check-todos.md +0 -176
  109. data/data/ariadna/workflows/complete-milestone.md +0 -644
  110. data/data/ariadna/workflows/diagnose-issues.md +0 -219
  111. data/data/ariadna/workflows/discovery-phase.md +0 -289
  112. data/data/ariadna/workflows/discuss-phase.md +0 -408
  113. data/data/ariadna/workflows/execute-plan.md +0 -448
  114. data/data/ariadna/workflows/help.md +0 -470
  115. data/data/ariadna/workflows/insert-phase.md +0 -129
  116. data/data/ariadna/workflows/list-phase-assumptions.md +0 -178
  117. data/data/ariadna/workflows/pause-work.md +0 -122
  118. data/data/ariadna/workflows/plan-milestone-gaps.md +0 -256
  119. data/data/ariadna/workflows/remove-phase.md +0 -154
  120. data/data/ariadna/workflows/research-phase.md +0 -74
  121. data/data/ariadna/workflows/resume-project.md +0 -306
  122. data/data/ariadna/workflows/set-profile.md +0 -80
  123. data/data/ariadna/workflows/settings.md +0 -145
  124. data/data/ariadna/workflows/transition.md +0 -493
  125. data/data/ariadna/workflows/update.md +0 -212
  126. data/data/ariadna/workflows/verify-phase.md +0 -226
  127. data/data/commands/ariadna/add-todo.md +0 -42
  128. data/data/commands/ariadna/audit-milestone.md +0 -42
  129. data/data/commands/ariadna/check-todos.md +0 -41
  130. data/data/commands/ariadna/complete-milestone.md +0 -136
  131. data/data/commands/ariadna/discuss-phase.md +0 -86
  132. data/data/commands/ariadna/help.md +0 -22
  133. data/data/commands/ariadna/list-phase-assumptions.md +0 -50
  134. data/data/commands/ariadna/pause-work.md +0 -35
  135. data/data/commands/ariadna/plan-milestone-gaps.md +0 -40
  136. data/data/commands/ariadna/reapply-patches.md +0 -110
  137. data/data/commands/ariadna/research-phase.md +0 -187
  138. data/data/commands/ariadna/resume-work.md +0 -40
  139. data/data/commands/ariadna/set-profile.md +0 -34
  140. data/data/commands/ariadna/settings.md +0 -36
  141. data/data/commands/ariadna/update.md +0 -37
  142. data/data/guides/backend.md +0 -3069
  143. data/data/guides/frontend.md +0 -1479
  144. data/data/guides/performance.md +0 -1193
  145. data/data/guides/security.md +0 -1522
  146. data/data/guides/style-guide.md +0 -1091
  147. data/data/guides/testing.md +0 -504
  148. 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>