pgbus 0.0.1

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 (89) hide show
  1. checksums.yaml +7 -0
  2. data/.bun-version +1 -0
  3. data/.claude/commands/architect.md +100 -0
  4. data/.claude/commands/github-review-comments.md +237 -0
  5. data/.claude/commands/lfg.md +271 -0
  6. data/.claude/commands/review-pr.md +69 -0
  7. data/.claude/commands/security.md +122 -0
  8. data/.claude/commands/tdd.md +148 -0
  9. data/.claude/rules/agents.md +49 -0
  10. data/.claude/rules/coding-style.md +91 -0
  11. data/.claude/rules/git-workflow.md +56 -0
  12. data/.claude/rules/performance.md +73 -0
  13. data/.claude/rules/testing.md +67 -0
  14. data/CHANGELOG.md +5 -0
  15. data/CLAUDE.md +80 -0
  16. data/CODE_OF_CONDUCT.md +10 -0
  17. data/LICENSE.txt +21 -0
  18. data/README.md +417 -0
  19. data/Rakefile +14 -0
  20. data/app/controllers/pgbus/api/stats_controller.rb +11 -0
  21. data/app/controllers/pgbus/application_controller.rb +35 -0
  22. data/app/controllers/pgbus/dashboard_controller.rb +27 -0
  23. data/app/controllers/pgbus/dead_letter_controller.rb +50 -0
  24. data/app/controllers/pgbus/events_controller.rb +23 -0
  25. data/app/controllers/pgbus/jobs_controller.rb +48 -0
  26. data/app/controllers/pgbus/processes_controller.rb +10 -0
  27. data/app/controllers/pgbus/queues_controller.rb +21 -0
  28. data/app/helpers/pgbus/application_helper.rb +69 -0
  29. data/app/views/layouts/pgbus/application.html.erb +76 -0
  30. data/app/views/pgbus/dashboard/_processes_table.html.erb +30 -0
  31. data/app/views/pgbus/dashboard/_queues_table.html.erb +39 -0
  32. data/app/views/pgbus/dashboard/_recent_failures.html.erb +33 -0
  33. data/app/views/pgbus/dashboard/_stats_cards.html.erb +28 -0
  34. data/app/views/pgbus/dashboard/show.html.erb +10 -0
  35. data/app/views/pgbus/dead_letter/_messages_table.html.erb +40 -0
  36. data/app/views/pgbus/dead_letter/index.html.erb +15 -0
  37. data/app/views/pgbus/dead_letter/show.html.erb +52 -0
  38. data/app/views/pgbus/events/index.html.erb +57 -0
  39. data/app/views/pgbus/events/show.html.erb +28 -0
  40. data/app/views/pgbus/jobs/_enqueued_table.html.erb +34 -0
  41. data/app/views/pgbus/jobs/_failed_table.html.erb +45 -0
  42. data/app/views/pgbus/jobs/index.html.erb +16 -0
  43. data/app/views/pgbus/jobs/show.html.erb +57 -0
  44. data/app/views/pgbus/processes/_processes_table.html.erb +37 -0
  45. data/app/views/pgbus/processes/index.html.erb +3 -0
  46. data/app/views/pgbus/queues/_queues_list.html.erb +41 -0
  47. data/app/views/pgbus/queues/index.html.erb +3 -0
  48. data/app/views/pgbus/queues/show.html.erb +49 -0
  49. data/bun.lock +18 -0
  50. data/config/routes.rb +45 -0
  51. data/docs/README.md +28 -0
  52. data/docs/switch_from_good_job.md +279 -0
  53. data/docs/switch_from_sidekiq.md +226 -0
  54. data/docs/switch_from_solid_queue.md +247 -0
  55. data/exe/pgbus +7 -0
  56. data/lib/generators/pgbus/install_generator.rb +56 -0
  57. data/lib/generators/pgbus/templates/migration.rb.erb +114 -0
  58. data/lib/generators/pgbus/templates/pgbus.yml.erb +74 -0
  59. data/lib/generators/pgbus/templates/pgbus_binstub.erb +7 -0
  60. data/lib/pgbus/active_job/adapter.rb +109 -0
  61. data/lib/pgbus/active_job/executor.rb +107 -0
  62. data/lib/pgbus/batch.rb +153 -0
  63. data/lib/pgbus/cli.rb +84 -0
  64. data/lib/pgbus/client.rb +162 -0
  65. data/lib/pgbus/concurrency/blocked_execution.rb +74 -0
  66. data/lib/pgbus/concurrency/semaphore.rb +66 -0
  67. data/lib/pgbus/concurrency.rb +65 -0
  68. data/lib/pgbus/config_loader.rb +27 -0
  69. data/lib/pgbus/configuration.rb +99 -0
  70. data/lib/pgbus/engine.rb +31 -0
  71. data/lib/pgbus/event.rb +31 -0
  72. data/lib/pgbus/event_bus/handler.rb +76 -0
  73. data/lib/pgbus/event_bus/publisher.rb +42 -0
  74. data/lib/pgbus/event_bus/registry.rb +54 -0
  75. data/lib/pgbus/event_bus/subscriber.rb +30 -0
  76. data/lib/pgbus/process/consumer.rb +113 -0
  77. data/lib/pgbus/process/dispatcher.rb +154 -0
  78. data/lib/pgbus/process/heartbeat.rb +71 -0
  79. data/lib/pgbus/process/signal_handler.rb +49 -0
  80. data/lib/pgbus/process/supervisor.rb +198 -0
  81. data/lib/pgbus/process/worker.rb +153 -0
  82. data/lib/pgbus/serializer.rb +43 -0
  83. data/lib/pgbus/version.rb +5 -0
  84. data/lib/pgbus/web/authentication.rb +24 -0
  85. data/lib/pgbus/web/data_source.rb +406 -0
  86. data/lib/pgbus.rb +49 -0
  87. data/package.json +9 -0
  88. data/sig/pgbus.rbs +4 -0
  89. metadata +198 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a6fe52568c3e3c18afc09f3ea5f0caaad2bf90010f59740191196075a93318d8
4
+ data.tar.gz: e0c87f85be32e39aa62d20e48f01ca8c8b5537084ba36e3f1e5aedfde0e6ada4
5
+ SHA512:
6
+ metadata.gz: 779ada35a2d41a76236c6fca3357aa35ee1e0133274b5aa0b4370996f56aa702ef94c271e15138c7f847bcbfeb66ff3d85d9a5220050fbc5fa0ae1ca00168624
7
+ data.tar.gz: 55fe48235d885182b12f58ec10db8dc89ae4039e5c929cffff6f0244f4864108ef1f4887ffccf95198358565f0d9a1aab8b834282ff5439192df17e239f2a863
data/.bun-version ADDED
@@ -0,0 +1 @@
1
+ 1.3.11
@@ -0,0 +1,100 @@
1
+ ---
2
+ description: "Coordinates development across pgbus layers. Use when planning multi-layer features, orchestrating implementation order, or designing new subsystems."
3
+ model: claude-opus-4-6
4
+ argument-hint: "feature or task to coordinate"
5
+ ---
6
+
7
+ # Pgbus Architect Mode
8
+
9
+ You are now in **Architect Mode** - coordinating development across all pgbus layers.
10
+
11
+ ## Why This Skill Exists
12
+
13
+ Pgbus spans multiple layers (PGMQ transport, ActiveJob adapter, event bus, process model, dashboard). Without coordination, developers tackle layers in the wrong order, miss integration points, or create inconsistent implementations.
14
+
15
+ ## Pgbus Architecture Layers
16
+
17
+ ```
18
+ Layer 6: Dashboard (Web UI) app/controllers/pgbus/, app/views/pgbus/
19
+ Layer 5: CLI lib/pgbus/cli.rb
20
+ Layer 4: Process Model lib/pgbus/process/ (supervisor, worker, dispatcher, consumer)
21
+ Layer 3: Event Bus lib/pgbus/event_bus/ (publisher, subscriber, registry, handler)
22
+ Layer 2: ActiveJob Adapter lib/pgbus/active_job/ (adapter, executor)
23
+ Layer 1: Client lib/pgbus/client.rb (PGMQ wrapper)
24
+ Layer 0: Configuration lib/pgbus/configuration.rb, config_loader.rb
25
+ ```
26
+
27
+ ## Typical Implementation Flow
28
+
29
+ 1. **Configuration** - Add new config options if needed
30
+ 2. **Client** - Add PGMQ operations to the client wrapper
31
+ 3. **Adapter / Event Bus** - Build the feature's core logic
32
+ 4. **Process Model** - Add worker/consumer support
33
+ 5. **Dashboard** - Expose in the web UI via DataSource
34
+ 6. **Tests** - Coverage across all touched layers
35
+
36
+ ## When to Delegate vs. Do Directly
37
+
38
+ **Delegate when**:
39
+ - Multiple files across a layer need changes
40
+ - Deep domain expertise is needed (e.g., PGMQ internals)
41
+ - Work is clearly scoped to one layer
42
+
43
+ **Handle directly when**:
44
+ - Simple, single-file changes
45
+ - Cross-cutting concerns affecting multiple layers
46
+ - Quick fixes or minor adjustments
47
+
48
+ ## Decision Guidelines
49
+
50
+ | Decision | Use When |
51
+ |----------|----------|
52
+ | New config option | Feature needs user-configurable behavior |
53
+ | New Client method | New PGMQ operation needed |
54
+ | New event handler | Business event needs processing |
55
+ | New worker type | Different processing pattern needed |
56
+ | Dashboard page | Users need visibility into new feature |
57
+ | Migration change | New metadata table or PGMQ queue |
58
+
59
+ ## Integration Points
60
+
61
+ | When working on... | Also consider... |
62
+ |-------------------|------------------|
63
+ | Client changes | Worker/consumer that calls it |
64
+ | New queue type | Dead letter queue, dashboard visibility |
65
+ | Event bus feature | Idempotency table, subscriber registry |
66
+ | Process model | Heartbeat, supervisor restart logic |
67
+ | Dashboard | DataSource queries, authentication |
68
+ | Configuration | Config loader YAML, generator template |
69
+
70
+ ## Common Mistakes to Avoid
71
+
72
+ | Wrong | Right |
73
+ |-------|-------|
74
+ | Start with dashboard | Start with client/adapter layer |
75
+ | Skip configuration | Make it configurable from the start |
76
+ | Direct PGMQ calls | Go through Client wrapper |
77
+ | Forget DLQ | Every queue needs a dead letter strategy |
78
+ | Skip tests | TDD -- tests first at every layer |
79
+ | Monolith methods | Small files, focused classes |
80
+
81
+ ## Verification Checklist
82
+
83
+ - [ ] Implementation order planned (bottom-up)
84
+ - [ ] Dependencies between layers identified
85
+ - [ ] PGMQ operations go through Client
86
+ - [ ] Configuration is extensible
87
+ - [ ] Dashboard exposes new data via DataSource
88
+ - [ ] Tests cover all touched layers
89
+ - [ ] `bundle exec rubocop` passes
90
+ - [ ] `bundle exec rspec` passes
91
+
92
+ ## Handoff
93
+
94
+ When complete, summarize:
95
+ - Implementation plan with layer order
96
+ - Files to create/modify per layer
97
+ - Integration points identified
98
+ - Architectural decisions made
99
+
100
+ Now, coordinate pgbus development with this architectural perspective.
@@ -0,0 +1,237 @@
1
+ ---
2
+ description: "Use when a PR has unresolved review comments that need responses -- evaluates each comment, implements valid fixes, pushes back on incorrect suggestions, and resolves all threads."
3
+ model: claude-opus-4-6
4
+ argument-hint: "PR number (e.g., 123 or #123)"
5
+ allowed-tools: Bash(gh pr view:*), Bash(gh pr diff:*), Bash(gh pr comment:*), Bash(gh api:*), Bash(git log:*), Bash(git blame:*), Bash(git push:*), Bash(git commit:*), Bash(git add:*), Bash(bundle exec:*), Read, Write, Edit, Glob, Grep, Agent
6
+ ---
7
+
8
+ # Review GitHub PR Comments: $ARGUMENTS
9
+
10
+ You are reviewing and responding to all unresolved review comments on a GitHub pull request. Apply technical rigour -- evaluate each comment against the actual codebase before accepting or rejecting it.
11
+
12
+ ## Phase 0: Determine the PR Number
13
+
14
+ The user may provide a PR number as `$ARGUMENTS`. Parse it flexibly:
15
+
16
+ - `PR123`, `PR 123`, `pr123` -> PR 123
17
+ - `123` -> PR 123
18
+ - `#123` -> PR 123
19
+ - Empty/blank -> auto-detect from current branch
20
+
21
+ **If no PR number is provided**, detect it automatically:
22
+
23
+ ```bash
24
+ gh pr list --author=@me --head="$(git branch --show-current)" --state=open --json number,title
25
+ ```
26
+
27
+ If exactly one open PR exists for the current branch, use it. If none or multiple, ask the user.
28
+
29
+ Once you have the PR number, confirm it:
30
+
31
+ ```bash
32
+ gh pr view <PR_NUMBER> --json title,state,url
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Phase 1: Fetch All Unresolved Review Comments
38
+
39
+ Retrieve all review comments and identify unresolved ones:
40
+
41
+ ```bash
42
+ # Get all review comments (not resolved)
43
+ gh api "repos/mhenrixon/pgbus/pulls/<PR_NUMBER>/comments" --paginate
44
+
45
+ # Get all review threads to check resolution status
46
+ gh api graphql -f query='
47
+ query($owner: String!, $repo: String!, $pr: Int!) {
48
+ repository(owner: $owner, name: $repo) {
49
+ pullRequest(number: $pr) {
50
+ reviewThreads(first: 100) {
51
+ nodes {
52
+ id
53
+ isResolved
54
+ path
55
+ line
56
+ comments(first: 20) {
57
+ nodes {
58
+ id
59
+ databaseId
60
+ body
61
+ author { login }
62
+ createdAt
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+ ' -f owner=mhenrixon -f repo=pgbus -F pr=<PR_NUMBER>
71
+ ```
72
+
73
+ For each unresolved thread, extract:
74
+ - Thread ID (for resolving)
75
+ - Comment body (the review feedback)
76
+ - File path and line number (if inline)
77
+ - Author (to understand context)
78
+
79
+ Filter to only **unresolved** threads. Skip bot comments (CodeRabbit, dependabot), resolved threads, and PR description comments.
80
+
81
+ If there are no unresolved review comments, report that and stop.
82
+
83
+ ---
84
+
85
+ ## Phase 2: Read and Categorise Each Comment
86
+
87
+ For each unresolved comment, read the full body and categorise it:
88
+
89
+ | Category | Action |
90
+ |----------|--------|
91
+ | Valid fix needed | Implement the fix |
92
+ | Valid test gap | Add the missing test |
93
+ | Valid style/consistency issue | Fix it |
94
+ | Incorrect suggestion | Push back with technical reasoning |
95
+ | Suggestion conflicts with architecture | Push back, reference existing patterns |
96
+ | Over-engineering / YAGNI | Push back, explain why it's unnecessary |
97
+ | Unclear | Ask for clarification (do NOT implement) |
98
+
99
+ **Before categorising**, always:
100
+ 1. Read the actual file and line being commented on
101
+ 2. Check if the suggestion is technically correct for THIS codebase
102
+ 3. Check if it would break existing functionality
103
+ 4. Check if existing patterns/conventions contradict the suggestion
104
+ 5. Check CLAUDE.md rules -- project conventions override reviewer preferences
105
+
106
+ ---
107
+
108
+ ## Phase 3: Implement Accepted Fixes
109
+
110
+ For all comments you've decided to accept:
111
+
112
+ 1. **Make the code changes** -- edit the relevant files
113
+ 2. **Run affected tests** to verify nothing breaks:
114
+ ```bash
115
+ bundle exec rspec <relevant_spec_files>
116
+ ```
117
+ 3. **Run validators**:
118
+ ```bash
119
+ bundle exec rubocop <changed_files>
120
+ ```
121
+ 4. **Commit** all fixes together with a clear message:
122
+ ```bash
123
+ git commit -m "$(cat <<'EOF'
124
+ fix: address PR review feedback
125
+
126
+ - Description of fix 1
127
+ - Description of fix 2
128
+ EOF
129
+ )"
130
+ ```
131
+ 5. **Push** to the remote branch:
132
+ ```bash
133
+ git push
134
+ ```
135
+
136
+ ---
137
+
138
+ ## Phase 4: Reply to Every Comment
139
+
140
+ For **each** unresolved thread, reply:
141
+
142
+ ### For accepted fixes:
143
+
144
+ Reply with what was fixed and the commit SHA:
145
+
146
+ ```bash
147
+ gh api "repos/mhenrixon/pgbus/pulls/<PR>/comments/<COMMENT_ID>/replies" \
148
+ --method POST \
149
+ -f 'body=Fixed in <SHA>. <Brief description of what changed>.'
150
+ ```
151
+
152
+ ### For rejected suggestions:
153
+
154
+ Reply with technical reasoning:
155
+
156
+ ```bash
157
+ gh api "repos/mhenrixon/pgbus/pulls/<PR>/comments/<COMMENT_ID>/replies" \
158
+ --method POST \
159
+ -f 'body=<Technical explanation of why the suggestion was not implemented>'
160
+ ```
161
+
162
+ ### Resolving threads (via GraphQL):
163
+
164
+ After replying, resolve the thread:
165
+
166
+ ```bash
167
+ gh api graphql -f query='
168
+ mutation($threadId: ID!) {
169
+ resolveReviewThread(input: {threadId: $threadId}) {
170
+ thread { isResolved }
171
+ }
172
+ }
173
+ ' -f threadId=<THREAD_NODE_ID>
174
+ ```
175
+
176
+ ### For general PR comments (not inline review threads):
177
+
178
+ Reply directly:
179
+
180
+ ```bash
181
+ gh pr comment <PR_NUMBER> --body "<Response addressing each point>"
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Phase 5: Verify Completion
187
+
188
+ After processing all comments, verify no unresolved threads remain:
189
+
190
+ ```bash
191
+ gh api graphql -f query='
192
+ query($owner: String!, $repo: String!, $pr: Int!) {
193
+ repository(owner: $owner, name: $repo) {
194
+ pullRequest(number: $pr) {
195
+ reviewThreads(first: 100) {
196
+ totalCount
197
+ nodes { isResolved }
198
+ }
199
+ }
200
+ }
201
+ }
202
+ ' -f owner=mhenrixon -f repo=pgbus -F pr=<PR_NUMBER>
203
+ ```
204
+
205
+ Report the final tally: how many comments were accepted/fixed, how many were pushed back on, and confirm all threads are resolved.
206
+
207
+ ---
208
+
209
+ ## Response Style
210
+
211
+ When replying to comments:
212
+
213
+ - **No performative agreement** -- never say "Great point!" or "You're absolutely right!"
214
+ - **No gratitude** -- never say "Thanks for catching that"
215
+ - **Be direct** -- state the fix or the reasoning, nothing more
216
+ - **Reference commits** -- always include the short SHA when a fix was made
217
+ - **Be specific** -- when pushing back, reference actual code, not abstract principles
218
+
219
+ When pushing back:
220
+
221
+ - Use technical reasoning grounded in the actual codebase
222
+ - Reference existing patterns if the suggestion contradicts them
223
+ - Reference CLAUDE.md rules when applicable
224
+ - Explain what would break or what edge case the reviewer missed
225
+ - If the suggestion is valid in principle but wrong for this context, say so
226
+
227
+ ---
228
+
229
+ ## Important Notes
230
+
231
+ - Always read the actual code before evaluating a comment -- reviewers sometimes misread diffs
232
+ - If a comment reveals a genuine bug you missed, fix it without defensiveness
233
+ - If multiple comments suggest the same change, implement it once and reference the fix in all replies
234
+ - Bot reviewers (CodeRabbit, etc.) sometimes suggest changes that conflict with project conventions -- verify against CLAUDE.md
235
+ - If a new round of review comments appears after your push (from re-review), report that to the user rather than entering an infinite loop
236
+
237
+ Now begin by determining the PR number from `$ARGUMENTS` or the current branch.
@@ -0,0 +1,271 @@
1
+ ---
2
+ description: "Executes full autonomous engineering workflow with verification. Use when implementing complete features, tackling GitHub issues, or running end-to-end development cycles."
3
+ model: claude-opus-4-6
4
+ argument-hint: "GitHub issue number/URL or feature description"
5
+ allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh pr create:*), Bash(gh pr view:*), Bash(bundle exec:*), Bash(git:*), Read, Write, Edit, Glob, Grep, Agent
6
+ ---
7
+
8
+ # LFG - Full Autonomous Workflow
9
+
10
+ Execute a complete engineering workflow with verification at each phase.
11
+
12
+ ## Phase 0: Branch Setup
13
+
14
+ **BEFORE any other work, prepare the git branch:**
15
+
16
+ 1. Check the current branch: `git branch --show-current`
17
+ 2. If NOT on `main`, switch: `git checkout main`
18
+ 3. Pull latest: `git pull origin main`
19
+ 4. Create feature branch: `git checkout -b issue-{number}-{brief-description}` (or `feature/{description}` if no issue number)
20
+
21
+ ---
22
+
23
+ ## Phase 1: Understand
24
+
25
+ ### Step 1: Gather Requirements
26
+
27
+ If `$ARGUMENTS` is a GitHub issue number or URL:
28
+
29
+ ```bash
30
+ gh issue view <number> --json title,body,labels,assignees,comments
31
+ ```
32
+
33
+ If `$ARGUMENTS` is a description, use it directly.
34
+
35
+ ### Step 2: Define Acceptance Criteria
36
+
37
+ **MANDATORY:** Write explicit acceptance criteria:
38
+
39
+ - **GIVEN** [context/setup]
40
+ - **WHEN** [action taken]
41
+ - **THEN** [expected outcome]
42
+
43
+ You MUST NOT proceed until you can articulate these clearly.
44
+
45
+ ### Step 3: Comprehension Gate
46
+
47
+ Before proceeding, you must:
48
+
49
+ 1. State the problem/feature in one sentence
50
+ 2. Explain WHY this is needed (business context)
51
+ 3. List what will change from the user's perspective
52
+ 4. Identify edge cases not explicitly mentioned
53
+ 5. Explain the data flow or code path involved
54
+
55
+ If you cannot complete ALL five items, investigate further.
56
+
57
+ ### Step 4: Create Task List
58
+
59
+ Create a TaskCreate todo list with specific implementation steps.
60
+
61
+ ---
62
+
63
+ ## Phase 2: Explore
64
+
65
+ 1. Find related files (Glob/Grep or Explore agent)
66
+ 2. Read existing patterns in similar features
67
+ 3. Understand dependencies and integration points
68
+ 4. Check existing test coverage
69
+ 5. Review PGMQ client interactions in `lib/pgbus/client.rb`
70
+ 6. Check ActiveJob adapter in `lib/pgbus/active_job/`
71
+ 7. Review event bus patterns in `lib/pgbus/event_bus/`
72
+ 8. Check process model in `lib/pgbus/process/`
73
+
74
+ ---
75
+
76
+ ## Phase 3: Plan
77
+
78
+ 1. List files to modify with specific changes
79
+ 2. List new files to create with purpose
80
+ 3. Identify migration changes needed (PGMQ queues, metadata tables)
81
+ 4. Plan test coverage (TDD: tests FIRST)
82
+ 5. Update task list with implementation steps
83
+ 6. Consider backwards compatibility with existing queue configurations
84
+
85
+ ---
86
+
87
+ ## Phase 4: Implement (TDD)
88
+
89
+ For each logical unit:
90
+
91
+ ### 4.1: Write Failing Test First
92
+
93
+ Create a test that demonstrates the expected behavior. Run it to confirm it FAILS:
94
+
95
+ ```bash
96
+ bundle exec rspec <spec_file>
97
+ ```
98
+
99
+ ### 4.2: Implement Minimum Code
100
+
101
+ Write the MINIMUM code to make the test pass. Follow project patterns:
102
+
103
+ | Never Do | Always Do |
104
+ |----------|-----------|
105
+ | Direct PGMQ SQL calls | Use `Pgbus::Client` wrapper |
106
+ | Skip queue prefixing | Always use `config.queue_name()` |
107
+ | Hardcode queue names | Use configuration |
108
+ | Skip visibility timeout | Use PGMQ's native VT mechanism |
109
+ | Ignore dead letter routing | Check `read_ct` against `max_retries` |
110
+ | Raw SQL in controllers | Use `Web::DataSource` for dashboard |
111
+
112
+ ### 4.3: Refactor
113
+
114
+ Once green, refactor while keeping tests passing.
115
+
116
+ ### 4.4: Validate
117
+
118
+ ```bash
119
+ bundle exec rubocop <changed_files>
120
+ ```
121
+
122
+ ### 4.5: Repeat
123
+
124
+ Move to next logical unit. Mark task items complete.
125
+
126
+ ---
127
+
128
+ ## Phase 5: Deep Root Cause Analysis (Bug Fixes Only)
129
+
130
+ **If this is a bug fix, apply deep investigation before implementing:**
131
+
132
+ ### Trace the Data Lifecycle
133
+
134
+ For the message/job/event causing the issue:
135
+ - Where and when was the message enqueued? By what adapter call?
136
+ - What visibility timeout was set? Has it expired?
137
+ - What ASSUMPTIONS does the code make at the failure point?
138
+ - Which assumption was violated, and WHY?
139
+
140
+ ### Use Git History
141
+
142
+ ```bash
143
+ git log --oneline -20 <file>
144
+ git blame <file>
145
+ ```
146
+
147
+ - When was the code written? What was the original intent?
148
+ - Has something ELSE changed that invalidated the original assumptions?
149
+
150
+ ### Map All Callers
151
+
152
+ Don't just look at the method that failed:
153
+ - Use Grep to find all call sites
154
+ - Different contexts (ActiveJob adapter vs event bus vs dashboard)?
155
+ - Does the error only happen in ONE context? Why?
156
+
157
+ ### Five Whys
158
+
159
+ Keep asking WHY until you reach a meaningful fix point:
160
+
161
+ 1. Error: X happened -> Why?
162
+ 2. Because Y -> Why was Y in that state?
163
+ 3. Because Z -> Why wasn't Z prevented?
164
+ 4. Because no check existed -> Why not?
165
+ 5. **THIS** is where the fix belongs
166
+
167
+ ### Fix Location Principle
168
+
169
+ The best fix is usually NOT where the error is raised:
170
+ - Nil message in executor -> fix in worker that should provide non-nil
171
+ - Queue not found -> fix in code that should ensure_queue first
172
+ - Race condition -> PGMQ-level visibility timeout
173
+ - Dead letter overflow -> fix the retry/DLQ routing logic
174
+
175
+ **Ask: "Where is the EARLIEST point I could prevent this error?" Fix there.**
176
+
177
+ ### Unacceptable Superficial Fixes -- DO NOT DO THESE
178
+
179
+ - `rescue nil` without understanding why the exception occurs
180
+ - `&.` to silence nil errors without investigating why nil occurs
181
+ - `if object.present?` guards without understanding why missing
182
+ - `return if message.nil?` to silently skip processing
183
+ - Wrapping everything in `begin/rescue` to swallow errors
184
+
185
+ **These HIDE bugs. The root cause continues causing issues elsewhere.**
186
+
187
+ ---
188
+
189
+ ## Phase 6: Verify
190
+
191
+ **ALL of these must pass before committing:**
192
+
193
+ ```bash
194
+ bundle exec rubocop # Style
195
+ bundle exec rspec <relevant_specs> # Tests
196
+ ```
197
+
198
+ ### Solution Verification
199
+
200
+ Re-read the original requirements and verify:
201
+ - "If I were the requester, would I consider this fully resolved?"
202
+ - "Have I addressed the ROOT CAUSE, not just the symptom?"
203
+ - "Do my tests prove the issue is ACTUALLY fixed, not just suppressed?"
204
+ - "Does this maintain backwards compatibility?"
205
+
206
+ ---
207
+
208
+ ## Phase 7: Commit & PR
209
+
210
+ ### Commit
211
+
212
+ ```bash
213
+ git add <specific_files>
214
+ git commit -m "$(cat <<'EOF'
215
+ feat(scope): brief description
216
+
217
+ ## Summary
218
+ [What changed and why]
219
+
220
+ ## Test Coverage
221
+ - spec 1: validates requirement X
222
+ - spec 2: validates edge case Y
223
+
224
+ ## Verification
225
+ - [x] bundle exec rubocop passes
226
+ - [x] bundle exec rspec passes
227
+ EOF
228
+ )"
229
+ ```
230
+
231
+ ### Push & PR
232
+
233
+ ```bash
234
+ git push -u origin $(git branch --show-current)
235
+
236
+ gh pr create --title "feat(scope): brief description" --body "$(cat <<'EOF'
237
+ ## Summary
238
+ - Key change 1
239
+ - Key change 2
240
+
241
+ Closes #<issue_number>
242
+
243
+ ## Test plan
244
+ - [ ] Scenario 1
245
+ - [ ] Scenario 2
246
+ EOF
247
+ )"
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Verification Checklist
253
+
254
+ - [ ] All acceptance criteria met
255
+ - [ ] Tests written BEFORE implementation
256
+ - [ ] `bundle exec rubocop` passes
257
+ - [ ] `bundle exec rspec` passes
258
+ - [ ] Backwards compatibility maintained
259
+ - [ ] PGMQ operations go through Client wrapper
260
+ - [ ] PR created with description
261
+
262
+ ---
263
+
264
+ ## Handoff
265
+
266
+ When complete:
267
+ - All phases executed
268
+ - Verification passed
269
+ - PR created and linked
270
+
271
+ Now, execute this workflow for the provided issue or feature.
@@ -0,0 +1,69 @@
1
+ ---
2
+ description: Review a GitHub pull request for code quality, patterns, and best practices
3
+ model: claude-opus-4-6
4
+ argument-hint: "PR URL or number (e.g., 5 or https://github.com/mhenrixon/pgbus/pull/5)"
5
+ ---
6
+
7
+ # PR Review
8
+
9
+ Review PR for pattern compliance and issues. Be concise.
10
+
11
+ ## Workflow
12
+
13
+ 1. Fetch PR details and diff via `mcp__github__pull_request_read`
14
+ 2. Categorize files by type
15
+ 3. Check for pattern violations
16
+ 4. Output structured review
17
+
18
+ ## Pattern Violations to Check
19
+
20
+ ```ruby
21
+ # WRONG -> RIGHT
22
+ Direct PGMQ calls outside Client -> Use Pgbus::Client wrapper
23
+ Raw SQL in controllers/views -> Use Web::DataSource
24
+ Hardcoded queue names -> Use config.queue_name()
25
+ Missing visibility timeout -> Always pass vt: parameter
26
+ Skip dead letter routing -> Check read_ct > max_retries
27
+ No error handling in workers -> Rescue and log via Pgbus.logger
28
+ Polling without LISTEN/NOTIFY -> Use enable_notify_insert
29
+ Missing queue prefix -> All queues go through config.queue_name
30
+ Thread.new for concurrency -> Use Concurrent::* primitives
31
+ rescue StandardError => nil -> Specific error handling
32
+ ```
33
+
34
+ ## Output Format
35
+
36
+ ```
37
+ ## Files Requiring Manual Review
38
+
39
+ | File | Reason |
40
+ |------|--------|
41
+ | lib/pgbus/process/worker.rb | Worker recycling logic, verify thresholds |
42
+ | lib/pgbus/client.rb | PGMQ interaction, check thread safety |
43
+
44
+ ## Critical Issues
45
+
46
+ - `lib/pgbus/client.rb:45` - Missing mutex synchronization
47
+ - `lib/pgbus/process/worker.rb:12` - Memory check not platform-aware
48
+
49
+ ## Suggestions (non-blocking)
50
+
51
+ - Consider extracting X to shared module
52
+
53
+ ## Verdict
54
+
55
+ **Request Changes** - Fix thread safety before merge
56
+ ```
57
+
58
+ ## Tools
59
+
60
+ ```
61
+ mcp__github__pull_request_read
62
+ method: "get" -> PR details
63
+ method: "get_diff" -> Changes
64
+ method: "get_files" -> File list
65
+ method: "get_status" -> CI status
66
+
67
+ bundle exec rubocop -> Style checks
68
+ bundle exec rspec -> Tests
69
+ ```