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.
- 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
- 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,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>
|