prr-kit 1.1.3 → 1.2.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 (173) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +260 -235
  3. package/docs/assets/banner.svg +30 -248
  4. package/docs/assets/how-it-works.svg +87 -0
  5. package/package.json +60 -60
  6. package/src/core/agents/prr-master.agent.yaml +18 -7
  7. package/src/core/tasks/clear.md +140 -0
  8. package/src/core/tasks/help.md +15 -13
  9. package/src/core/workflows/clear/workflow.md +6 -0
  10. package/src/core/workflows/help/workflow.md +6 -0
  11. package/src/core/workflows/party-mode/steps/step-01-load-reviewers.md +35 -24
  12. package/src/core/workflows/party-mode/steps/step-02-discussion.md +45 -25
  13. package/src/core/workflows/party-mode/workflow.md +2 -2
  14. package/src/prr/agents/architecture-reviewer.agent.yaml +65 -45
  15. package/src/prr/agents/business-reviewer.agent.yaml +66 -0
  16. package/src/prr/agents/general-reviewer.agent.yaml +64 -48
  17. package/src/prr/agents/performance-reviewer.agent.yaml +65 -45
  18. package/src/prr/agents/security-reviewer.agent.yaml +67 -43
  19. package/src/prr/config-template.yaml +97 -0
  20. package/src/prr/data/stacks/actix.md +55 -0
  21. package/src/prr/data/stacks/alpine.md +47 -0
  22. package/src/prr/data/stacks/android.md +53 -0
  23. package/src/prr/data/stacks/angular.md +96 -0
  24. package/src/prr/data/stacks/ansible.md +55 -0
  25. package/src/prr/data/stacks/apollo.md +54 -0
  26. package/src/prr/data/stacks/astro.md +48 -0
  27. package/src/prr/data/stacks/aws-cdk.md +55 -0
  28. package/src/prr/data/stacks/axum.md +56 -0
  29. package/src/prr/data/stacks/babylonjs.md +55 -0
  30. package/src/prr/data/stacks/bash.md +53 -0
  31. package/src/prr/data/stacks/bevy.md +53 -0
  32. package/src/prr/data/stacks/bootstrap.md +52 -0
  33. package/src/prr/data/stacks/bun.md +55 -0
  34. package/src/prr/data/stacks/cpp.md +57 -0
  35. package/src/prr/data/stacks/csharp.md +95 -0
  36. package/src/prr/data/stacks/css.md +55 -0
  37. package/src/prr/data/stacks/cypress.md +53 -0
  38. package/src/prr/data/stacks/d3.md +53 -0
  39. package/src/prr/data/stacks/deno.md +49 -0
  40. package/src/prr/data/stacks/django.md +92 -0
  41. package/src/prr/data/stacks/docker.md +79 -0
  42. package/src/prr/data/stacks/drizzle.md +54 -0
  43. package/src/prr/data/stacks/dynamodb.md +55 -0
  44. package/src/prr/data/stacks/electron.md +44 -0
  45. package/src/prr/data/stacks/elixir.md +53 -0
  46. package/src/prr/data/stacks/expo.md +53 -0
  47. package/src/prr/data/stacks/expressjs.md +82 -0
  48. package/src/prr/data/stacks/fastapi.md +88 -0
  49. package/src/prr/data/stacks/fastify.md +60 -0
  50. package/src/prr/data/stacks/fiber.md +55 -0
  51. package/src/prr/data/stacks/firebase.md +43 -0
  52. package/src/prr/data/stacks/flask.md +46 -0
  53. package/src/prr/data/stacks/flutter.md +75 -0
  54. package/src/prr/data/stacks/gin.md +57 -0
  55. package/src/prr/data/stacks/github-actions.md +71 -0
  56. package/src/prr/data/stacks/go.md +88 -0
  57. package/src/prr/data/stacks/godot.md +56 -0
  58. package/src/prr/data/stacks/graphql.md +76 -0
  59. package/src/prr/data/stacks/grpc.md +56 -0
  60. package/src/prr/data/stacks/haskell.md +48 -0
  61. package/src/prr/data/stacks/helm.md +54 -0
  62. package/src/prr/data/stacks/hono.md +54 -0
  63. package/src/prr/data/stacks/htmx.md +38 -0
  64. package/src/prr/data/stacks/java.md +87 -0
  65. package/src/prr/data/stacks/jest-vitest.md +87 -0
  66. package/src/prr/data/stacks/jquery.md +50 -0
  67. package/src/prr/data/stacks/junit.md +53 -0
  68. package/src/prr/data/stacks/kotlin.md +89 -0
  69. package/src/prr/data/stacks/kubernetes.md +148 -0
  70. package/src/prr/data/stacks/langchain.md +56 -0
  71. package/src/prr/data/stacks/laravel.md +56 -0
  72. package/src/prr/data/stacks/libgdx.md +46 -0
  73. package/src/prr/data/stacks/lit.md +49 -0
  74. package/src/prr/data/stacks/love2d.md +51 -0
  75. package/src/prr/data/stacks/lua.md +51 -0
  76. package/src/prr/data/stacks/mobx.md +54 -0
  77. package/src/prr/data/stacks/mongodb.md +85 -0
  78. package/src/prr/data/stacks/monogame.md +51 -0
  79. package/src/prr/data/stacks/mysql.md +57 -0
  80. package/src/prr/data/stacks/nestjs.md +95 -0
  81. package/src/prr/data/stacks/nextjs.md +88 -0
  82. package/src/prr/data/stacks/nginx.md +55 -0
  83. package/src/prr/data/stacks/node.md +56 -0
  84. package/src/prr/data/stacks/nuxtjs.md +91 -0
  85. package/src/prr/data/stacks/openai-api.md +54 -0
  86. package/src/prr/data/stacks/opengl.md +54 -0
  87. package/src/prr/data/stacks/phaser.md +54 -0
  88. package/src/prr/data/stacks/phoenix.md +55 -0
  89. package/src/prr/data/stacks/php.md +56 -0
  90. package/src/prr/data/stacks/playwright.md +86 -0
  91. package/src/prr/data/stacks/postgresql.md +60 -0
  92. package/src/prr/data/stacks/prisma.md +81 -0
  93. package/src/prr/data/stacks/pygame.md +52 -0
  94. package/src/prr/data/stacks/pytest.md +53 -0
  95. package/src/prr/data/stacks/python.md +94 -0
  96. package/src/prr/data/stacks/pytorch.md +54 -0
  97. package/src/prr/data/stacks/qwik.md +50 -0
  98. package/src/prr/data/stacks/rails.md +48 -0
  99. package/src/prr/data/stacks/react-native.md +77 -0
  100. package/src/prr/data/stacks/react.md +104 -0
  101. package/src/prr/data/stacks/redis.md +76 -0
  102. package/src/prr/data/stacks/redux.md +107 -0
  103. package/src/prr/data/stacks/remix.md +51 -0
  104. package/src/prr/data/stacks/rust.md +88 -0
  105. package/src/prr/data/stacks/sass.md +51 -0
  106. package/src/prr/data/stacks/scala.md +50 -0
  107. package/src/prr/data/stacks/scikit-learn.md +53 -0
  108. package/src/prr/data/stacks/sequelize.md +54 -0
  109. package/src/prr/data/stacks/socket-io.md +54 -0
  110. package/src/prr/data/stacks/solidity.md +53 -0
  111. package/src/prr/data/stacks/solidjs.md +45 -0
  112. package/src/prr/data/stacks/spring-boot.md +92 -0
  113. package/src/prr/data/stacks/sql.md +85 -0
  114. package/src/prr/data/stacks/sqlite.md +55 -0
  115. package/src/prr/data/stacks/styled-components.md +51 -0
  116. package/src/prr/data/stacks/supabase.md +57 -0
  117. package/src/prr/data/stacks/svelte.md +77 -0
  118. package/src/prr/data/stacks/sveltekit.md +54 -0
  119. package/src/prr/data/stacks/swift.md +61 -0
  120. package/src/prr/data/stacks/tailwindcss.md +10 -0
  121. package/src/prr/data/stacks/tanstack-query.md +48 -0
  122. package/src/prr/data/stacks/tauri.md +52 -0
  123. package/src/prr/data/stacks/terraform.md +53 -0
  124. package/src/prr/data/stacks/three.md +53 -0
  125. package/src/prr/data/stacks/trpc.md +49 -0
  126. package/src/prr/data/stacks/typeorm.md +40 -0
  127. package/src/prr/data/stacks/typescript.md +83 -0
  128. package/src/prr/data/stacks/unity.md +61 -0
  129. package/src/prr/data/stacks/unreal.md +58 -0
  130. package/src/prr/data/stacks/vite.md +48 -0
  131. package/src/prr/data/stacks/vue3.md +95 -0
  132. package/src/prr/data/stacks/vulkan.md +53 -0
  133. package/src/prr/data/stacks/wasm.md +49 -0
  134. package/src/prr/data/stacks/webpack.md +48 -0
  135. package/src/prr/data/stacks/zig.md +51 -0
  136. package/src/prr/data/stacks/zustand.md +56 -0
  137. package/src/prr/workflows/1-discover/select-pr/steps/step-05-confirm.md +1 -0
  138. package/src/prr/workflows/1-discover/select-pr/workflow.md +1 -1
  139. package/src/prr/workflows/2-analyze/collect-pr-context/steps/step-01-analyze-files.md +334 -0
  140. package/src/prr/workflows/2-analyze/collect-pr-context/steps/step-02-collect-sources.md +451 -0
  141. package/src/prr/workflows/2-analyze/collect-pr-context/steps/step-03-build-knowledge-base.md +337 -0
  142. package/src/prr/workflows/2-analyze/collect-pr-context/workflow.md +123 -0
  143. package/src/prr/workflows/2-analyze/describe-pr/steps/step-02-classify.md +12 -6
  144. package/src/prr/workflows/2-analyze/describe-pr/steps/step-03-walkthrough.md +59 -1
  145. package/src/prr/workflows/3-review/architecture-review/checklist.md +4 -0
  146. package/src/prr/workflows/3-review/architecture-review/instructions.xml +32 -4
  147. package/src/prr/workflows/3-review/architecture-review/workflow.yaml +17 -18
  148. package/src/prr/workflows/3-review/business-review/checklist.md +27 -0
  149. package/src/prr/workflows/3-review/business-review/instructions.xml +153 -0
  150. package/src/prr/workflows/3-review/business-review/workflow.yaml +17 -0
  151. package/src/prr/workflows/3-review/general-review/checklist.md +5 -1
  152. package/src/prr/workflows/3-review/general-review/instructions.xml +39 -8
  153. package/src/prr/workflows/3-review/general-review/workflow.yaml +17 -18
  154. package/src/prr/workflows/3-review/performance-review/checklist.md +3 -1
  155. package/src/prr/workflows/3-review/performance-review/instructions.xml +10 -3
  156. package/src/prr/workflows/3-review/performance-review/workflow.yaml +17 -18
  157. package/src/prr/workflows/3-review/security-review/checklist.md +2 -1
  158. package/src/prr/workflows/3-review/security-review/instructions.xml +8 -3
  159. package/src/prr/workflows/3-review/security-review/workflow.yaml +18 -19
  160. package/src/prr/workflows/4-improve/improve-code/workflow.yaml +17 -18
  161. package/src/prr/workflows/6-report/generate-report/steps/step-01-collect.md +9 -2
  162. package/src/prr/workflows/6-report/generate-report/steps/step-02-organize.md +28 -7
  163. package/src/prr/workflows/6-report/generate-report/steps/step-03-write.md +6 -4
  164. package/src/prr/workflows/6-report/generate-report/templates/review-report.template.md +124 -78
  165. package/src/prr/workflows/6-report/post-comments/steps/step-01-format.md +104 -13
  166. package/src/prr/workflows/6-report/post-comments/steps/step-02-post.md +92 -21
  167. package/src/prr/workflows/6-report/post-comments/workflow.md +6 -0
  168. package/src/prr/workflows/quick/workflow.md +138 -32
  169. package/src/prr/workflows/0-setup/collect-project-context/steps/step-01-scan-configs.md +0 -106
  170. package/src/prr/workflows/0-setup/collect-project-context/steps/step-02-extract-rules.md +0 -131
  171. package/src/prr/workflows/0-setup/collect-project-context/steps/step-03-ask-context.md +0 -194
  172. package/src/prr/workflows/0-setup/collect-project-context/steps/step-04-save-context.md +0 -161
  173. package/src/prr/workflows/0-setup/collect-project-context/workflow.md +0 -58
@@ -0,0 +1,96 @@
1
+ # Angular — Stack-Specific Review Rules
2
+
3
+ > Applies to: GR · SR · PR · AR · BR
4
+ > Detection signals: `*.component.ts`, `@Component(`, `@Injectable(`, `@NgModule(`, `angular.json`, `@angular/` in deps, `standalone: true`, `signal(`, `inject(`
5
+
6
+ ---
7
+
8
+ ## Security
9
+
10
+ - **[CRITICAL]** `bypassSecurityTrustHtml()` / `DomSanitizer.bypassSecurityTrust*()` with user-controlled content → XSS. Angular sanitizes by default; bypass only for fully trusted content.
11
+ - **[CRITICAL]** `[innerHTML]` binding with user content without sanitization → XSS.
12
+ - **[HIGH]** Route guard missing on protected routes (`canActivate`, `canActivateChild`, `canMatch`) → unauthenticated access.
13
+ - **[HIGH]** HTTP interceptor not adding auth header on all requests → API calls without credentials.
14
+ - **[HIGH]** `HttpClient` calls made without CSRF token on state-changing requests.
15
+ - **[HIGH]** Template injection via Angular's `templateUrl` loading from user-controlled path (server-rendered).
16
+ - **[HIGH]** Sensitive data stored in `localStorage` via Angular service → accessible to injected scripts.
17
+ - **[HIGH]** `window.location.href` set from route params without validation → open redirect.
18
+ - **[MEDIUM]** CORS configured permissively in Angular proxy config (`angular.json`) left in production.
19
+ - **[MEDIUM]** Error messages from HTTP errors shown directly to user → info disclosure.
20
+ - **[MEDIUM]** JWT stored in memory (signal/service) not cleared on logout → token persists in JS heap.
21
+ - **[LOW]** Angular DevTools enabled in production → component tree exposed.
22
+
23
+ ---
24
+
25
+ ## Performance
26
+
27
+ - **[HIGH]** Component not using `OnPush` change detection for data-heavy components → Angular checks entire tree on every event.
28
+ - **[HIGH]** Subscription not unsubscribed in `ngOnDestroy` (or not using `async` pipe / `takeUntilDestroyed`) → memory leak.
29
+ - **[HIGH]** `trackBy` missing on `*ngFor` / `@for` with large/dynamic lists → full DOM re-render on any change.
30
+ - **[HIGH]** Signal computed function doing expensive work → not memoized correctly if dependencies unstable.
31
+ - **[HIGH]** Multiple HTTP calls made sequentially that could be parallel → use `forkJoin` or `combineLatest`.
32
+ - **[HIGH]** Not using lazy-loaded feature modules / routes for large sections → oversized initial bundle.
33
+ - **[HIGH]** `BehaviorSubject.value` accessed synchronously in template → not reactive, stale value.
34
+ - **[HIGH]** `toSignal()` without `initialValue` causing nullable type complications and unnecessary null checks.
35
+ - **[MEDIUM]** Heavy computation in template expressions → recalculated every CD cycle; use `pipe` (pure) or `computed()`.
36
+ - **[MEDIUM]** `APP_INITIALIZER` doing slow async work → delays app startup; defer non-critical init.
37
+ - **[MEDIUM]** Zone.js detecting changes from unrelated third-party events (analytics, maps) → use `runOutsideAngular`.
38
+ - **[MEDIUM]** Images not using `NgOptimizedImage` → no lazy loading or size optimization.
39
+ - **[MEDIUM]** `ChangeDetectorRef.detectChanges()` called in a loop → manual CD triggering defeats OnPush benefits.
40
+ - **[LOW]** `async` pipe used multiple times on same observable in template → multiple subscriptions; use `as` syntax.
41
+ - **[LOW]** Not using `@defer` blocks (Angular 17+) for below-fold components.
42
+
43
+ ---
44
+
45
+ ## Architecture
46
+
47
+ - **[HIGH]** Business logic in component class → controllers should only handle view concerns; move to injectable service.
48
+ - **[HIGH]** Component directly calling `HttpClient` instead of going through service layer → untestable, tightly coupled.
49
+ - **[HIGH]** Circular dependency between services → Angular DI throws at runtime.
50
+ - **[HIGH]** `inject()` called outside injection context (not in constructor, field initializer, or factory) → runtime error.
51
+ - **[HIGH]** Smart/dumb component boundary violated — presentational component directly injecting services.
52
+ - **[HIGH]** State management done via service with plain properties instead of `BehaviorSubject`/`signal` → no reactivity.
53
+ - **[HIGH]** `NgModule` architecture mixed with standalone components without migration plan → confusion.
54
+ - **[MEDIUM]** Missing `providedIn: 'root'` vs module-scoped provider — wrong scope causes multiple instances.
55
+ - **[MEDIUM]** Using `any` type in component `@Input()`/`@Output()` → loses type safety at component boundary.
56
+ - **[MEDIUM]** `Subject` used where `BehaviorSubject` needed — late subscribers miss current value.
57
+ - **[MEDIUM]** Effects not used for signal-based side effects (Angular 17+) → mixing reactive and imperative.
58
+ - **[MEDIUM]** Route resolver overloading — doing too much data fetching causing slow navigation.
59
+ - **[LOW]** Module not feature-scoped — all declarations in `AppModule` → slow compilation, poor separation.
60
+ - **[LOW]** Not using `InjectionToken` for config values → relying on `string` tokens causing collision.
61
+
62
+ ---
63
+
64
+ ## Code Quality
65
+
66
+ - **[HIGH]** `ngOnInit` subscribing to Observable without `async` pipe or `takeUntilDestroyed` → memory leak.
67
+ - **[HIGH]** `@Input()` not using `required: true` (Angular 16+) for required inputs → runtime undefined with no warning.
68
+ - **[HIGH]** Signal mutations done with `set()` instead of `update()` when new value depends on old → stale value race.
69
+ - **[HIGH]** `EventEmitter` type not specified (`EventEmitter` vs `EventEmitter<string>`) → runtime type mismatch.
70
+ - **[MEDIUM]** Template reference variables (`#ref`) used for logic across complex templates → tight coupling.
71
+ - **[MEDIUM]** `@ViewChild` accessed before `ngAfterViewInit` → undefined access.
72
+ - **[MEDIUM]** `*ngIf` with multiple conditions not extracted to component method → unreadable template.
73
+ - **[MEDIUM]** RxJS operators not used (`switchMap`, `takeUntil`, `shareReplay`) → anti-patterns.
74
+ - **[MEDIUM]** `switchMap` used when `mergeMap` needed (or vice versa) → requests cancelled or duplicated.
75
+ - **[MEDIUM]** Not using Angular's new control flow (`@if`, `@for`, `@switch`) in Angular 17+ projects.
76
+ - **[LOW]** Missing `standalone: true` when upgrading from NgModule-based components (Angular 14+).
77
+ - **[LOW]** `console.log` left in component lifecycle hooks → production noise.
78
+ - **[LOW]** Pipes not used for data transformation in template → inline ternary/method calls everywhere.
79
+
80
+ ---
81
+
82
+ ## Common Bugs & Pitfalls
83
+
84
+ - **[HIGH]** `ExpressionChangedAfterItHasBeenCheckedError` — modifying bound value in `ngAfterViewInit` without `ChangeDetectorRef.detectChanges()`.
85
+ - **[HIGH]** `async` pipe used with cold observable that never completes → subscription held forever.
86
+ - **[HIGH]** `switchMap` in effects cancelling in-flight HTTP requests on rapid emissions → use `exhaustMap` for form submits.
87
+ - **[HIGH]** Signal `effect()` creating infinite loop — reading and writing same signal in effect body.
88
+ - **[HIGH]** `DestroyRef` injection not used with `takeUntilDestroyed()` outside constructor → requires injection context.
89
+ - **[HIGH]** `HttpClient` returning cold observable — not subscribing means request never fires.
90
+ - **[MEDIUM]** `Subject` vs `BehaviorSubject` confusion — using Subject where late subscribers need current value.
91
+ - **[MEDIUM]** Calling `markForCheck()` excessively in OnPush → defeats the purpose.
92
+ - **[MEDIUM]** Route params accessed via `snapshot` inside component that needs to react to param changes → use `paramMap` observable.
93
+ - **[MEDIUM]** Interceptor modifying request without cloning → mutating immutable `HttpRequest`.
94
+ - **[MEDIUM]** `providedIn: 'root'` on service with state meant to be scoped per module → shared state bug.
95
+ - **[LOW]** Forgetting `@Output()` decorator on EventEmitter → event never emits to parent.
96
+ - **[LOW]** `HostListener` not cleaned up — unlike subscriptions, it IS cleaned up by Angular but double-attaching is possible via manual `addEventListener`.
@@ -0,0 +1,55 @@
1
+ # Ansible — Stack-Specific Review Rules
2
+
3
+ > Applies to: GR · SR · PR · AR · BR
4
+ > Detection signals: `*.yml` with `hosts:`, `tasks:`, `playbook`, `ansible`, `roles/`, `inventory`, `- name:`, `ansible.cfg`
5
+
6
+ ---
7
+
8
+ ## Security
9
+ - **[CRITICAL]** Plaintext secrets/passwords in playbooks or vars files → credentials committed to version control. Use Ansible Vault to encrypt sensitive values.
10
+ - **[CRITICAL]** `command:` or `shell:` module used with user-controlled variables → command injection. Sanitize inputs or use purpose-built modules instead.
11
+ - **[HIGH]** `become: yes` applied at play level instead of per task → unnecessarily broad privilege escalation. Scope `become` to only the tasks that require it.
12
+ - **[HIGH]** SSH private keys stored unencrypted inside roles or repo → key material exposed. Store keys in Vault or an external secrets manager.
13
+ - **[HIGH]** `no_log: false` on tasks that handle credentials → secrets appear in Ansible logs. Set `no_log: true` on any task processing passwords or tokens.
14
+ - **[HIGH]** Galaxy roles installed without version pinning in `requirements.yml` → supply chain risk from updated or compromised role versions. Pin to a specific `version:` tag or commit.
15
+ - **[MEDIUM]** `validate_certs: no` in `uri:`, `get_url:`, or package tasks → MITM attacks possible. Remove the override and ensure proper CA trust is configured.
16
+
17
+ ---
18
+
19
+ ## Performance
20
+ - **[HIGH]** `gather_facts: true` (default) on plays that do not use facts → adds latency per host. Set `gather_facts: false` when facts are not needed.
21
+ - **[HIGH]** Long-running tasks executed sequentially instead of using `async` + `poll` → unnecessary wall-clock time. Use async tasks with a polling interval or `poll: 0` for fire-and-forget.
22
+ - **[MEDIUM]** No tags on tasks → entire playbook must run in CI when only a subset is needed. Tag tasks and roles to allow selective execution with `--tags`.
23
+ - **[MEDIUM]** Large files transferred with the `copy` module instead of `synchronize` (rsync) → slow transfers over the Ansible SSH connection. Use `synchronize` for directories and large files.
24
+ - **[MEDIUM]** Tasks that can run on the control node forced to execute on remote hosts → unnecessary round trips. Use `delegate_to: localhost` for control-node-eligible work.
25
+ - **[LOW]** `serial` not set for rolling updates on large inventories → all hosts updated simultaneously. Set `serial` to a count or percentage to limit blast radius.
26
+
27
+ ---
28
+
29
+ ## Architecture
30
+ - **[HIGH]** Single monolithic playbook containing all tasks → not reusable or maintainable. Refactor into roles with clear responsibilities.
31
+ - **[HIGH]** Hardcoded IP addresses in playbooks instead of dynamic inventory → breaks across environments. Use dynamic inventory plugins or inventory files with group variables.
32
+ - **[MEDIUM]** Role variable defaults not defined in `defaults/main.yml` → callers must know internal variable names. Expose all overridable values in defaults with documented choices.
33
+ - **[MEDIUM]** Variables defined at multiple precedence levels without documentation → unpredictable resolution order. Establish a clear precedence strategy and document it.
34
+ - **[MEDIUM]** No `handlers/main.yml` usage → services restarted inline causing unnecessary restarts on repeated runs. Use handlers triggered by `notify` for service restarts.
35
+ - **[LOW]** `meta/main.yml` not used to declare role dependencies → dependent roles must be listed manually. Declare dependencies so `ansible-galaxy install` resolves them automatically.
36
+
37
+ ---
38
+
39
+ ## Code Quality
40
+ - **[HIGH]** Missing `when:` conditionals on OS- or role-specific tasks → tasks run on incompatible host types. Add `when: ansible_os_family == '...'` or equivalent guards.
41
+ - **[HIGH]** `command:` or `shell:` tasks that change system state on every run → playbook is not idempotent. Add `creates:`, `removes:`, or `changed_when:` to reflect actual change status.
42
+ - **[MEDIUM]** Tasks without descriptive `name:` fields → unreadable output and hard to debug. Provide a human-readable `name` for every task.
43
+ - **[MEDIUM]** `template` module used without `validate:` for config files that support validation → invalid configs deployed silently. Use `validate:` with the appropriate check command.
44
+ - **[MEDIUM]** Not using FQCN (Fully Qualified Collection Name) for modules → name conflicts across collections. Prefix all modules with their collection namespace.
45
+ - **[LOW]** Tasks not compatible with `--check` mode → dry runs are inaccurate. Use `check_mode: yes` compatible modules and add `check_mode:` annotations where needed.
46
+
47
+ ---
48
+
49
+ ## Common Bugs & Pitfalls
50
+ - **[HIGH]** Jinja2 expression `{{ variable }}` evaluated at template-parse time rather than task execution time → wrong value used. Use `"{{ var }}"` quoting correctly and be aware of lazy vs eager evaluation in loops.
51
+ - **[HIGH]** `copy` module used where `template` is needed → Jinja2 variables not substituted in the file. Use `template` for any file containing `{{ }}` expressions.
52
+ - **[MEDIUM]** Loop variable `item` shadowed when nesting loops → inner loop overwrites outer `item`. Use `loop_var:` to rename the loop variable in nested loops.
53
+ - **[MEDIUM]** `changed_when: false` not set on read-only or check commands → task always reports changed. Add `changed_when: false` to commands that never modify state.
54
+ - **[MEDIUM]** `register` variable used without checking `.rc` or `.stdout` → silent failure consumed. Always check return codes or use `failed_when:` to define failure conditions.
55
+ - **[LOW]** YAML boolean trap: `yes`, `no`, `on`, `off`, `true`, `false` interpreted as booleans → unexpected type passed to module parameter. Quote string values that resemble booleans.
@@ -0,0 +1,54 @@
1
+ # Apollo GraphQL — Stack-Specific Review Rules
2
+
3
+ > Applies to: GR · SR · PR · AR · BR
4
+ > Detection signals: `from '@apollo/client'`, `from 'apollo-server'`, `ApolloClient`, `` gql` ``, `useQuery`, `useMutation`, `ApolloServer`
5
+
6
+ ---
7
+
8
+ ## Security
9
+ - **[CRITICAL]** GraphQL introspection enabled in production → full schema structure (types, fields, mutations) exposed to attackers for reconnaissance. Disable with `introspection: process.env.NODE_ENV !== 'production'` in `ApolloServer` options.
10
+ - **[CRITICAL]** Field-level authorization missing in resolvers → any authenticated user can query any field regardless of ownership or role. Implement field-level authorization in each resolver using a library like `graphql-shield` or explicit permission checks.
11
+ - **[HIGH]** Query depth not limited → deeply nested queries (exponential explosion) cause CPU and memory DoS. Add `graphql-depth-limit` and `graphql-query-complexity` plugins to `ApolloServer`.
12
+ - **[HIGH]** Query complexity not calculated → a single query joining many relations can overload the database. Define complexity scores per field and reject queries exceeding a threshold.
13
+ - **[HIGH]** User input passed directly to database query inside a resolver without parameterization → SQL or NoSQL injection. Always use parameterized queries or ORM methods; never interpolate input into query strings.
14
+ - **[HIGH]** Resolver errors leaking stack traces to the client in production → internal implementation details and file paths exposed. Use `formatError` in `ApolloServer` to strip stack traces and internal details from production error responses.
15
+ - **[MEDIUM]** Subscriptions not authenticated → WebSocket connections for GraphQL subscriptions bypass HTTP middleware auth checks. Validate auth token in the `onConnect` hook of the subscriptions server.
16
+
17
+ ---
18
+
19
+ ## Performance
20
+ - **[HIGH]** N+1 problem in list resolvers: parent resolver fetches a list, child resolver fetches per-item → 1 + N database queries per request. Batch child resolvers with `DataLoader`, keying by parent ID.
21
+ - **[HIGH]** `@cacheControl` directives absent on cacheable query fields → CDN and Apollo's response cache cannot cache responses, every request hits the origin. Add `@cacheControl(maxAge: N)` directives to stable fields.
22
+ - **[HIGH]** `useQuery` called without `fetchPolicy` in a context where fresh data is not required → defaults to network request on mount in some configurations, bypassing cache. Set `fetchPolicy: 'cache-first'` for stable data and `'network-only'` only where freshness is critical.
23
+ - **[MEDIUM]** Large fragments applied to every query even when only a few fields are needed → over-fetching increases payload size and resolver execution cost. Use specific field selections; reserve fragments for genuinely shared selection sets.
24
+ - **[MEDIUM]** GraphQL subscriptions not unsubscribed on component unmount → WebSocket subscriptions continue consuming server resources. Return the unsubscribe function from `useEffect` or rely on Apollo Client's `useSubscription` cleanup.
25
+ - **[LOW]** Automatic Persisted Queries (APQ) not enabled in production → full query strings sent on every request, increasing payload size. Enable APQ on both client and server to send only a hash after the first request.
26
+
27
+ ---
28
+
29
+ ## Architecture
30
+ - **[HIGH]** Business logic (validation, side effects, external API calls) implemented directly in resolvers → resolvers untestable in isolation and logic duplicated across REST and GraphQL endpoints. Extract to a service/domain layer called from resolvers.
31
+ - **[HIGH]** Schema defined entirely in code-first style without a reviewed SDL → schema design reviewed only after implementation, making structural problems expensive to fix. Adopt schema-first design with a reviewed `.graphql` SDL file as the source of truth.
32
+ - **[MEDIUM]** `context` not used to share common dependencies (database connection, authenticated user, DataLoader instances) → dependencies instantiated inside each resolver causing inconsistency and waste. Build a typed context object in the `context` factory function and inject shared resources.
33
+ - **[MEDIUM]** Mutations not following the `input` type convention `mutation CreateUser(input: CreateUserInput!)` → argument lists grow unwieldy and breaking changes are harder to manage. Wrap all mutation arguments in a single named `input` type.
34
+ - **[MEDIUM]** Schema not using federation for a microservices architecture → all types defined in a monolithic schema, creating a single point of failure. Use Apollo Federation with `@key` directives to distribute schema ownership across services.
35
+ - **[LOW]** No query cost analysis in CI → expensive queries introduced by developers go undetected until production load. Add complexity analysis to the test suite with cost thresholds enforced as failing tests.
36
+
37
+ ---
38
+
39
+ ## Code Quality
40
+ - **[HIGH]** Resolver `context` parameter typed as `any` → no autocomplete, no type safety on auth user, DB, or DataLoader access. Define and export a typed `Context` interface and apply it to all resolvers.
41
+ - **[HIGH]** Query fragments not used for shared field selections across multiple operations → same field list copy-pasted across queries, diverging silently. Define named fragments for shared selections and import via `...FragmentName`.
42
+ - **[MEDIUM]** `__resolveType` not implemented on union or interface types → Apollo cannot determine the concrete type for polymorphic responses, causing runtime errors. Implement `__resolveType` in the resolver map for every union and interface.
43
+ - **[MEDIUM]** Resolver return types do not match the schema definition (e.g., returning `null` for non-nullable fields) → Apollo throws a null propagation error that can mask the root cause. Align resolver return types strictly with the schema and handle nullability explicitly.
44
+ - **[LOW]** Generated TypeScript types from GraphQL schema (`graphql-codegen`) not used → type safety benefit of GraphQL wasted. Run `graphql-codegen` in CI and use generated types for all resolver and hook signatures.
45
+
46
+ ---
47
+
48
+ ## Common Bugs & Pitfalls
49
+ - **[HIGH]** `useQuery` result destructuring does not handle `loading` or `error` states → component renders with `undefined` data causing runtime crashes. Always handle all three states: `if (loading) return <Spinner />; if (error) return <Error />;`.
50
+ - **[HIGH]** Apollo cache not normalized correctly after mutation → stale cached data persists because the mutated object is not updated by ID. Ensure Apollo's `InMemoryCache` has a correct `keyFields` configuration and that mutations return updated objects with their `id`.
51
+ - **[MEDIUM]** `refetchQueries` not listing all queries affected by a mutation → related queries display stale data after mutation succeeds. Enumerate all affected operation names in `refetchQueries` or use `update` to manually update the cache.
52
+ - **[MEDIUM]** Optimistic response shape does not exactly match the server response shape → cache corruption when the real response arrives and cannot be merged with the optimistic entry. Match the optimistic response field names, types, and `__typename` exactly to the expected server response.
53
+ - **[MEDIUM]** `useMutation` error not caught → mutation rejection is an unhandled promise if `onError` is not provided and the result is not checked. Always provide an `onError` callback or check the returned `error` value.
54
+ - **[LOW]** Apollo Client DevTools browser extension not installed during development → cache contents, query results, and mutation history not inspectable. Install the Apollo DevTools extension and enable it via `connectToDevTools: true` in dev builds.
@@ -0,0 +1,48 @@
1
+ # Astro — Stack-Specific Review Rules
2
+
3
+ > Applies to: GR · SR · PR · AR · BR
4
+ > Detection signals: `*.astro` files · `astro.config.*` · `from 'astro'` · `@astrojs/` imports · `Astro.props`
5
+
6
+ ---
7
+
8
+ ## Security
9
+
10
+ - **[HIGH]** `set:html={userInput}` directive with user-controlled data → XSS. Use `{userInput}` (text interpolation) or sanitize with DOMPurify.
11
+ - **[MEDIUM]** `PUBLIC_*` env vars contain secrets → `PUBLIC_` prefix exposes values to the client bundle. Non-public secrets must use server-only access.
12
+ - **[MEDIUM]** `Astro.cookies.set()` without `httpOnly: true` and `secure: true` on session cookies → JavaScript-accessible cookies.
13
+
14
+ ---
15
+
16
+ ## Performance
17
+
18
+ - **[HIGH]** Heavy framework component imported without `client:` directive → component renders as static HTML, JS still shipped to client if component file imports heavy deps. Verify with bundle analyzer.
19
+ - **[HIGH]** `client:load` on non-critical interactive components → increases Time-to-Interactive. Prefer `client:idle` (after page load) or `client:visible` (when in viewport).
20
+ - **[MEDIUM]** `<img>` used instead of Astro's `<Image>` component for local images → no automatic format conversion (WebP/AVIF), no lazy loading, no dimension optimization.
21
+ - **[MEDIUM]** `getStaticPaths` with `paginate()` and no `pageSize` → defaults to 10, may generate excessive static pages or under-paginate.
22
+ - **[LOW]** `define:vars={{ largeObject }}` passing large data to client script → serializes entire object inline. Use `data-*` attributes for small values or a separate API endpoint.
23
+
24
+ ---
25
+
26
+ ## Architecture
27
+
28
+ - **[HIGH]** Mutable state (arrays, objects) declared at Astro component top-level (outside a function) → runs once at build time for SSG, or once per request for SSR, but is shared across renders in the same process. Use server-side state carefully.
29
+ - **[MEDIUM]** Framework component (React/Vue/Svelte) used where an Astro component suffices → unnecessary hydration overhead.
30
+ - **[MEDIUM]** `Astro.request` / `Astro.cookies` accessed in a `.astro` file without `output: 'server'` or `export const prerender = false` → build error in static mode.
31
+ - **[LOW]** Deep island nesting (interactive component inside another `client:*` component) → double hydration, unclear ownership.
32
+
33
+ ---
34
+
35
+ ## Code Quality
36
+
37
+ - **[MEDIUM]** Framework component imported but no `client:*` directive → renders as static HTML with no interactivity. If interactivity is needed, add `client:load` or appropriate directive.
38
+ - **[MEDIUM]** `Astro.props` accessed in a `<script>` tag → props are server-only. Pass values via `data-*` attributes or `define:vars`.
39
+ - **[LOW]** `---` frontmatter containing complex business logic → extract to utility functions in `src/lib/` for testability.
40
+
41
+ ---
42
+
43
+ ## Common Bugs & Pitfalls
44
+
45
+ - **[HIGH]** `Astro.props` destructured incorrectly in `.astro` file: `const { title = 'Default' }` with no TypeScript interface → missing props silently get `undefined`. Define `interface Props` for type safety.
46
+ - **[MEDIUM]** `getStaticPaths` returning `params` with non-string values → Astro requires all params to be strings. Use `.toString()` on numeric IDs.
47
+ - **[MEDIUM]** Content Collections `getCollection()` called at runtime in SSR without `prerender = false` → hydration mismatch or empty results.
48
+ - **[LOW]** Named slots in Astro component used with framework child components → slot forwarding behaves differently than HTML slots.
@@ -0,0 +1,55 @@
1
+ # AWS CDK — Stack-Specific Review Rules
2
+
3
+ > Applies to: GR · SR · PR · AR · BR
4
+ > Detection signals: `aws-cdk-lib`, `from 'aws-cdk-lib'`, `new Stack(`, `cdk.App()`, `cdk synth`, `cdk deploy`, `*.ts` with CDK constructs
5
+
6
+ ---
7
+
8
+ ## Security
9
+ - **[CRITICAL]** IAM inline policies or managed policies with `actions: ['*']` → any principal with this role can perform every AWS action. Enumerate the exact actions required and nothing more.
10
+ - **[CRITICAL]** S3 bucket with `blockPublicAccess` not explicitly enforced → accidental ACL or policy change exposes data publicly. Always set `blockPublicAccess: BlockPublicAccess.BLOCK_ALL`.
11
+ - **[HIGH]** Lambda function granted `AdministratorAccess` or an overly broad managed policy → full blast radius on function compromise. Apply least-privilege inline policies scoped to the specific resources the function accesses.
12
+ - **[HIGH]** Security group with `peer: Peer.anyIpv4()` on sensitive ports (22, 3306, 5432, etc.) → service exposed to the internet. Restrict ingress to known CIDR ranges or security group references.
13
+ - **[HIGH]** Secrets, API keys, or database passwords hardcoded as CDK string literals → credentials committed to version control. Use `secretsmanager.Secret` or `ssm.StringParameter.fromSecureStringParameterAttributes`.
14
+ - **[HIGH]** RDS instance with `publiclyAccessible: true` and no VPC isolation → database reachable from the internet. Set `publiclyAccessible: false` and place instances in private subnets.
15
+ - **[MEDIUM]** CloudWatch log groups without `retention` set → logs stored indefinitely, increasing cost and privacy exposure. Set `retention: RetentionDays.ONE_MONTH` or an appropriate value per log group.
16
+
17
+ ---
18
+
19
+ ## Performance
20
+ - **[HIGH]** Lambda `memorySize` set to 128MB for CPU-bound functions → Lambda CPU allocation scales linearly with memory; low memory means slow execution. Profile with AWS Lambda Power Tuning and increase memory.
21
+ - **[HIGH]** NAT Gateway deployed in one AZ serving traffic from others → cross-AZ data transfer costs accumulate. Deploy a NAT Gateway per AZ or use NAT Instances/VPC endpoints to reduce cost.
22
+ - **[MEDIUM]** RDS instance class not sized for actual workload → either over-provisioned (cost) or under-provisioned (latency). Use Performance Insights to right-size the instance class.
23
+ - **[MEDIUM]** CloudFront distribution not used for static assets or API → all requests traverse to the origin. Add a CloudFront distribution in front of S3 and API Gateway for latency reduction.
24
+ - **[MEDIUM]** VPC endpoints not configured for S3, DynamoDB, or other frequently called AWS services → traffic routes through the NAT Gateway incurring cost and latency. Add `InterfaceVpcEndpoint` or `GatewayVpcEndpoint` for high-traffic services.
25
+ - **[LOW]** Lambda cold starts not mitigated for latency-sensitive functions → provisioned concurrency not set. Consider `lambda.Function` with `addAlias` and `provisionedConcurrentExecutions`.
26
+
27
+ ---
28
+
29
+ ## Architecture
30
+ - **[HIGH]** All resources defined in a single CDK stack → one deployment unit for the entire application with no separation of lifecycle, permissions, or failure domains. Split into stacks by layer (network, data, compute, application).
31
+ - **[HIGH]** Lambda source code bundled without `bundling` options → entire `node_modules` included in deployment package, inflating size and cold start time. Use `NodejsFunction` with esbuild bundling or `lambda.Code.fromAsset` with bundling hooks.
32
+ - **[MEDIUM]** Account IDs and region strings hardcoded in CDK constructs → stack not portable across environments. Use `cdk.Aws.ACCOUNT_ID`, `cdk.Aws.REGION`, or environment-specific context values.
33
+ - **[MEDIUM]** CDK Aspects not used for organization-wide policy enforcement → security and tagging policies not consistently applied. Use `cdk.Aspects.of(app).add()` for cross-cutting concerns like encryption checks.
34
+ - **[MEDIUM]** Infrastructure not deployed via CDK Pipelines → manual `cdk deploy` runs are untracked and error-prone. Implement a `CodePipeline` construct for automated, gated deployments.
35
+ - **[LOW]** Constructs not organized into reusable `Construct` subclasses → copy-paste CDK code across stacks. Extract repeated patterns into custom constructs with configuration parameters.
36
+
37
+ ---
38
+
39
+ ## Code Quality
40
+ - **[HIGH]** `cdk.RemovalPolicy.DESTROY` set on stateful resources (RDS, DynamoDB, S3) in a production stack → data deleted permanently on stack destruction. Use `RETAIN` for production and `SNAPSHOT` for databases.
41
+ - **[HIGH]** Cross-stack references implemented with string literals instead of `CfnOutput` + `Fn.importValue` → brittle coupling that breaks on stack rename. Use CDK's native cross-stack reference mechanism via exported outputs.
42
+ - **[MEDIUM]** Logical IDs changed by refactoring construct paths → CloudFormation treats the change as delete-and-recreate, potentially causing data loss. Use `overrideLogicalId` to preserve logical IDs when refactoring.
43
+ - **[MEDIUM]** Cost allocation tags not applied to stacks or resources → spending not attributable to teams or services. Use `Tags.of(stack).add('Team', 'platform')` at the app or stack level.
44
+ - **[MEDIUM]** Lambda functions and stacks missing `description` property → CloudFormation console and Lambda list are unreadable. Add descriptions to all named resources.
45
+ - **[LOW]** `cdk.context.json` not committed to version control → `cdk synth` produces different output across machines. Commit `cdk.context.json` to ensure deterministic synthesis.
46
+
47
+ ---
48
+
49
+ ## Common Bugs & Pitfalls
50
+ - **[HIGH]** Construct path refactored, changing the CloudFormation logical ID of a resource → CloudFormation deletes the old resource and creates a new one, causing data loss for stateful resources. Check `cdk diff` for unexpected resource replacements before deploying.
51
+ - **[HIGH]** CDK `Token` (e.g., `bucket.bucketName`) used in a context that stringifies it (e.g., `JSON.stringify`) → produces `[object Object]` or an unresolved token string. Use CDK-aware methods and avoid premature string conversion of lazy tokens.
52
+ - **[MEDIUM]** Cross-stack `Fn.importValue` reference creating an implicit deployment ordering dependency → deployments of the consumer stack fail if the producer stack has not been deployed first. Document and enforce the deployment order, or use SSM Parameter Store for decoupled sharing.
53
+ - **[MEDIUM]** CDK CLI version mismatched with `aws-cdk-lib` library version → construct APIs or synthesis behaviour differs. Pin both the CLI and library to the same version in `package.json` and CI tooling.
54
+ - **[MEDIUM]** `aws_lambda_nodejs.NodejsFunction` used without specifying `entry` explicitly → CDK infers entry from the calling file path, which breaks in monorepos or after refactoring. Always specify `entry` and `handler` explicitly.
55
+ - **[LOW]** `cdk diff` not run before `cdk deploy` in automation → surprising destructive changes applied without review. Always run `cdk diff` as a prior step and gate on human approval for replacements.
@@ -0,0 +1,56 @@
1
+ # Axum — Stack-Specific Review Rules
2
+
3
+ > Applies to: GR · SR · PR · AR · BR
4
+ > Detection signals: axum, Router::new(), axum::extract, tower, tokio, async fn handler, State<
5
+
6
+ ---
7
+
8
+ ## Security
9
+ - **[CRITICAL]** Missing authentication layer or middleware on protected routes → unauthenticated requests reach sensitive handlers. Wrap protected routes in an authentication middleware using Tower layers.
10
+ - **[HIGH]** `Path` and `Query` extractors trusted without validation → raw user input flows into business logic unchecked. Validate extractor values with a validation crate (e.g., `validator`) in the handler.
11
+ - **[HIGH]** SSRF via user-controlled URLs in server-side HTTP requests → attacker triggers requests to internal services or cloud metadata endpoints. Validate and whitelist allowed URL schemes and hosts before fetching.
12
+ - **[HIGH]** Missing CORS configuration via `tower-http::cors` → default behavior rejects all cross-origin requests or is too permissive depending on config. Explicitly configure allowed origins, methods, and headers.
13
+ - **[CRITICAL]** SQL injection via string formatting in sqlx queries → user input alters query structure. Always use parameterized queries with `query!` or `query_as!` macros in sqlx.
14
+ - **[MEDIUM]** Secret management via environment variables not validated at startup → missing secrets cause runtime panics deep in request handling. Validate all required environment variables at startup and panic early with a clear message.
15
+ - **[HIGH]** JWT or session tokens not validated for expiry and signature → expired or forged tokens accepted. Use a well-tested JWT library and validate claims (exp, iss, aud) on every request.
16
+ - **[MEDIUM]** User-supplied filenames used in file system operations without sanitization → path traversal allows reading or overwriting arbitrary files. Canonicalize paths and reject any that escape the intended directory.
17
+
18
+ ---
19
+
20
+ ## Performance
21
+ - **[CRITICAL]** Blocking operations (`std::fs`, `std::thread::sleep`, synchronous network calls) inside async handlers → Tokio runtime thread stalls, starving all other tasks. Use `tokio::fs`, `tokio::time::sleep`, and async I/O throughout.
22
+ - **[HIGH]** Missing `tower::limit::ConcurrencyLimit` or similar for expensive handlers → unbounded concurrent requests overwhelm downstream services or exhaust resources. Apply concurrency limits on resource-intensive endpoints.
23
+ - **[HIGH]** Large payloads not streamed, loaded fully into memory → high memory pressure under concurrent load. Use `axum::body::Body` streaming or chunked transfer for large uploads and downloads.
24
+ - **[MEDIUM]** No HTTP response caching layer for idempotent endpoints → repeated identical requests hit the database or compute layer unnecessarily. Add `tower-http::set-header` or a caching proxy layer.
25
+ - **[MEDIUM]** Database connection pool not configured (min/max connections, timeouts) → pool exhaustion under load causes request queuing and timeouts. Configure `sqlx::PgPoolOptions` with realistic bounds.
26
+ - **[HIGH]** CPU-bound computation (hashing, encoding, compression) run on the async runtime → blocks the Tokio thread pool. Offload to `tokio::task::spawn_blocking` for CPU-heavy work.
27
+
28
+ ---
29
+
30
+ ## Architecture
31
+ - **[HIGH]** Shared state not wrapped in `Arc<T>` when used across handlers → clone overhead or borrow errors at compile time, or incorrect shared mutable state. Use `Arc<T>` for shared read-only state and `Arc<RwLock<T>>` for mutable state.
32
+ - **[MEDIUM]** Handler functions growing too large with mixed concerns → handlers become hard to read, test, and reuse. Extract business logic into service types and call them from thin handler functions.
33
+ - **[HIGH]** Error types not implementing `IntoResponse` → all handler errors returned as opaque 500 responses with no detail. Define a custom error type implementing `IntoResponse` with appropriate status codes and messages.
34
+ - **[MEDIUM]** Not using Tower middleware layers for cross-cutting concerns (logging, tracing, auth) → each handler re-implements the same boilerplate. Apply concerns as Tower layers via `Router::layer()`.
35
+ - **[MEDIUM]** Route organization not modular → all routes defined in one file, making navigation difficult in large codebases. Split routes into domain modules and merge them in the main router.
36
+ - **[LOW]** Not using `axum::extract::State` in favor of `Extension` → `Extension` panics at runtime if not added; State catches missing state at compile time. Prefer typed `State<T>` extractors.
37
+
38
+ ---
39
+
40
+ ## Code Quality
41
+ - **[LOW]** Missing `#[derive(Debug)]` on custom error and state types → debugging and logging produce unhelpful output. Derive Debug on all domain types.
42
+ - **[CRITICAL]** `unwrap()` or `expect()` in handler code → panics in async context crash the handler task and return a 500 with no diagnostic. Replace with proper error propagation using `?` and `IntoResponse`.
43
+ - **[MEDIUM]** `anyhow::Error` returned directly from handlers instead of typed errors → response leaks internal error detail and response codes are always 500. Map errors to typed responses at the handler boundary.
44
+ - **[MEDIUM]** Extractor ordering in handler signatures not matching Axum requirements → compilation fails or extractors consume the body before others can read it. Consult Axum extractor ordering docs; `Json` must be last.
45
+ - **[MEDIUM]** Not using `#[axum::debug_handler]` during development → type errors in handler signatures produce cryptic compiler messages. Add the attribute during development for better diagnostics.
46
+ - **[LOW]** Not enabling Tower tracing middleware (`tower-http::trace`) → request/response logging absent in production. Add `TraceLayer::new_for_http()` to the router.
47
+
48
+ ---
49
+
50
+ ## Common Bugs & Pitfalls
51
+ - **[HIGH]** `Extension` extractor used without adding extension to the router → every request to that route returns a 500 with a confusing error message. Switch to typed `State<T>` extractors which are checked at router construction.
52
+ - **[MEDIUM]** `Json` extractor returning 422 with no body for content-type mismatch → clients receive an opaque error. Add a custom rejection handler via `.layer(HandleErrorLayer...)` to return structured error bodies.
53
+ - **[MEDIUM]** `State` not derived from `Clone` → compiler error or accidental deep clone overhead on every request. Implement `Clone` on state types or wrap in `Arc`.
54
+ - **[HIGH]** Timeout middleware not configured → slow upstream calls hold connections open indefinitely, exhausting worker capacity. Add `tower::timeout::TimeoutLayer` with a reasonable timeout per route group.
55
+ - **[HIGH]** Not propagating request cancellation via context → abandoned requests continue consuming resources after the client disconnects. Use `tokio::select!` or check cancellation tokens in long-running operations.
56
+ - **[MEDIUM]** Missing graceful shutdown handling → in-flight requests dropped on SIGTERM. Implement a shutdown signal handler and use `axum::Server::with_graceful_shutdown` to drain active connections.
@@ -0,0 +1,55 @@
1
+ # Babylon.js — Stack-Specific Review Rules
2
+
3
+ > Applies to: GR · SR · PR · AR · BR
4
+ > Detection signals: `babylonjs`, `from '@babylonjs/core'`, `BABYLON.`, `Engine`, `Scene`, `Mesh`, `ArcRotateCamera`, `babylon`
5
+
6
+ ---
7
+
8
+ ## Security
9
+ - **[HIGH]** Meshes or scenes loaded via `SceneLoader.ImportMesh()` from user-provided URLs → loading arbitrary 3D assets including GLTF files with embedded scripts; validate URLs against an allowlist and disable `allowPendingTexturesInBackground` for untrusted sources.
10
+ - **[HIGH]** GLTF files loaded without sanitization → GLTF 2.0 can embed custom extensions with executable logic; strip unrecognized extensions or load from trusted sources only.
11
+ - **[MEDIUM]** Babylon.js Inspector (`scene.debugLayer.show()`) exposed in production builds → full scene graph manipulation and state inspection available in the browser; guard with environment checks and strip from production bundles.
12
+ - **[MEDIUM]** Texture CDN not configured with appropriate CORS headers → cross-origin texture loading blocked or insecure wildcard `Access-Control-Allow-Origin: *`; configure CDN CORS specifically for your domain.
13
+ - **[LOW]** WebXR session not exiting properly when user navigates away → lingering XR session can lock browser XR APIs; handle `session.end()` in `beforeunload` and `visibilitychange` events.
14
+
15
+ ---
16
+
17
+ ## Performance
18
+ - **[CRITICAL]** Meshes, materials, or textures not disposed when removed from the scene → GPU memory leak accumulates over time; always call `mesh.dispose()`, `material.dispose()`, and `texture.dispose()` when objects are no longer needed.
19
+ - **[HIGH]** Shadow generators attached to point lights or multiple lights → shadow map rendering is extremely expensive; limit shadow generation to a single directional or spot light and use shadow-only meshes.
20
+ - **[HIGH]** Repeated identical geometry not using `InstancedMesh` → one draw call per mesh copy; use `mesh.createInstance()` for any geometry rendered more than a handful of times.
21
+ - **[HIGH]** Physics impostors attached to every small decorative mesh → unnecessary physics simulation overhead; apply physics only to meshes that require collision response.
22
+ - **[MEDIUM]** Large GLTF/GLB assets not compressed with Draco geometry compression and KTX2 texture compression → slow downloads and high memory usage; compress with `gltf-transform` before serving.
23
+ - **[MEDIUM]** LOD levels not configured for complex meshes via `mesh.addLODLevel(distance, lodMesh)` → full-detail meshes rendered at all distances; add at least two LOD levels for meshes visible across a large distance range.
24
+ - **[MEDIUM]** Render loop (`engine.runRenderLoop`) not stopped and engine not disposed when the component or page unmounts → continued GPU usage after navigation; call `engine.stopRenderLoop()` and `engine.dispose()` on cleanup.
25
+ - **[LOW]** `scene.getMeshByName()` or `scene.getMaterialByName()` called inside the render loop → O(n) linear scan every frame; cache references at scene creation time.
26
+
27
+ ---
28
+
29
+ ## Architecture
30
+ - **[HIGH]** All scene setup, game logic, animation, and input handling in a single file or function → monolithic; decompose into class-based systems (SceneManager, InputController, AssetLoader) with clear responsibilities.
31
+ - **[MEDIUM]** Inter-system communication done via direct object references instead of Babylon.js's `Observable` system → tight coupling; use `scene.onBeforeRenderObservable`, custom `Observable` instances, or an event bus for decoupled communication.
32
+ - **[MEDIUM]** Assets loaded ad-hoc with individual `SceneLoader` calls instead of a centralized `AssetsManager` → no load progress tracking and harder error handling; use `AssetsManager` with task queuing for all asset loading.
33
+ - **[MEDIUM]** Materials created per mesh even when identical → redundant GPU state changes; create one material and assign it to all meshes sharing the same appearance.
34
+ - **[LOW]** Scene hierarchy not organized with parent `TransformNode` containers for logical groups of meshes → difficult to apply group transforms; use `TransformNode` as a lightweight parent for organizing mesh groups.
35
+
36
+ ---
37
+
38
+ ## Code Quality
39
+ - **[HIGH]** Babylon.js used without TypeScript → full type definitions available via `@babylonjs/core`; use TypeScript to catch API misuse at compile time.
40
+ - **[HIGH]** `scene.dispose()` not called when switching between multiple scenes → previous scene's resources remain in GPU memory; always dispose the old scene before creating a new one.
41
+ - **[MEDIUM]** `engine.resize()` not called in a `window.resize` event listener → canvas rendering at wrong resolution after browser window resize; hook `window.addEventListener('resize', () => engine.resize())`.
42
+ - **[MEDIUM]** `Vector3` objects created inside the render loop for intermediate calculations → GC pressure from frequent heap allocation; use `Vector3.TransformCoordinatesToRef()` and in-place methods (`addInPlace`, `scaleInPlace`) for hot paths.
43
+ - **[MEDIUM]** Animation groups not stopped before mesh disposal → Babylon continues animating a disposed mesh → errors; always call `animationGroup.stop()` before `mesh.dispose()`.
44
+ - **[LOW]** Babylon.js version not pinned in `package.json` → breaking API changes across minor versions; pin to an exact version or use `~` patch-range pinning.
45
+
46
+ ---
47
+
48
+ ## Common Bugs & Pitfalls
49
+ - **[HIGH]** GPU memory leak from not disposing meshes, textures, and materials over the application lifetime → progressive slowdown and eventual browser crash; audit every dynamic object creation to ensure a corresponding `dispose()` call.
50
+ - **[HIGH]** Animation not stopped before its target mesh is disposed → Babylon.js throws errors on the next render frame; stop all animations targeting a mesh before disposing it.
51
+ - **[MEDIUM]** `Vector3` arithmetic methods (`add`, `scale`, `normalize`) returning new instances not assigned back → original vector unchanged; use `addInPlace`, `scaleInPlace`, `normalizeToRef` for mutation or capture the returned value.
52
+ - **[MEDIUM]** WebXR session not properly ended on user exit or navigation → browser WebXR API remains locked; listen to `xrSession.addEventListener('end', ...)` and handle cleanup explicitly.
53
+ - **[MEDIUM]** Babylon.js uses a left-handed coordinate system by default (unlike Three.js which is right-handed) → imported assets may appear mirrored; account for the handedness difference when migrating assets from other 3D frameworks.
54
+ - **[LOW]** `PickingInfo.hit` not checked before accessing `PickingInfo.pickedMesh` → `pickedMesh` is null when no mesh was hit; always guard with `if (pickResult.hit && pickResult.pickedMesh)`.
55
+ - **[LOW]** `scene.onPointerObservable` callbacks not removed when the associated UI or game object is destroyed → stale pointer handlers firing on removed objects; unregister with `observable.remove(observer)`.
@@ -0,0 +1,53 @@
1
+ # Bash / Shell — Stack-Specific Review Rules
2
+
3
+ > Applies to: GR · SR · PR · AR · BR
4
+ > Detection signals: `*.sh`, `#!/bin/bash`, `#!/bin/sh`, `#!/usr/bin/env bash`, `.bashrc`, `.zshrc`, `Makefile` with shell recipes
5
+
6
+ ---
7
+
8
+ ## Security
9
+ - **[CRITICAL]** Unquoted variables in commands (`rm -rf $DIR`) → word splitting and glob expansion on values with spaces or wildcards causes unintended file deletion or command injection. Always double-quote variable expansions: `rm -rf "$DIR"`.
10
+ - **[CRITICAL]** `eval "$user_input"` or equivalent dynamic execution → arbitrary command execution by any attacker who controls the input. Never pass user-controlled data to `eval`; use parameter expansion and whitelisted commands instead.
11
+ - **[HIGH]** `curl | bash` pattern for installation scripts → remote code executed without inspection or integrity check. Download to a temp file, verify SHA-256/GPG signature, then execute.
12
+ - **[HIGH]** Temporary files created in `/tmp` with predictable names → symlink attacks redirect writes to arbitrary paths. Always create temp files with `mktemp` and remove them with a `trap ... EXIT`.
13
+ - **[HIGH]** Secrets (tokens, passwords) stored as plain text in scripts committed to the repository → extracted from git history. Use environment variables loaded from a secrets manager; add secret file patterns to `.gitignore`.
14
+ - **[HIGH]** Downloaded scripts executed without checksum verification → supply-chain compromise undetectable. Verify SHA-256 or GPG signature before executing any downloaded artifact.
15
+ - **[MEDIUM]** `chmod 777` applied to directories or files containing sensitive data → world-writable, any local user can modify. Use least-privilege permissions (e.g., `750` for dirs, `640` for files).
16
+ - **[MEDIUM]** `set -e` not set → script continues after a failing command, leaving system in a partially modified state. Add `set -euo pipefail` at the top of every script.
17
+
18
+ ---
19
+
20
+ ## Performance
21
+ - **[HIGH]** `cat file | grep pattern` (useless cat) → spawns an extra process for no benefit. Use `grep pattern file` directly.
22
+ - **[HIGH]** Command substitution `$(command)` inside a loop → spawns a subshell on every iteration; multiplied cost on large inputs. Capture the output once before the loop or use process substitution `< <(command)`.
23
+ - **[MEDIUM]** `find . | xargs cmd` without `-print0` / `-0` → breaks on filenames containing spaces or newlines, causing wrong files to be processed. Use `find . -print0 | xargs -0 cmd`.
24
+ - **[MEDIUM]** `while read line` without `IFS=` and `-r` flag → leading/trailing whitespace stripped and backslashes interpreted. Use `while IFS= read -r line`.
25
+ - **[MEDIUM]** Calling external tools (`sed`, `awk`, `cut`) for simple string operations achievable with bash parameter expansion → unnecessary subprocess overhead. Use `${var#prefix}`, `${var%suffix}`, `${var//pat/rep}` built-ins.
26
+ - **[LOW]** Not using `local` in functions → function variables pollute the global shell namespace and can cause subtle bugs in larger scripts. Declare all function variables with `local`.
27
+
28
+ ---
29
+
30
+ ## Architecture
31
+ - **[HIGH]** Monolithic script with no functions → not testable, reusable, or auditable. Break logic into named functions; consider `bats` or `shunit2` for unit testing.
32
+ - **[HIGH]** No error handling (`set -euo pipefail` absent) → silent partial failures leave the system in an unknown state. Add `set -euo pipefail` and trap on `ERR` to log and exit cleanly.
33
+ - **[MEDIUM]** Script not idempotent → running it twice causes errors or duplicate side effects. Guard each action with existence checks (`[ -f ... ]`, `[ -d ... ]`) before creating or modifying.
34
+ - **[MEDIUM]** Hardcoded absolute paths (`/opt/myapp`) → breaks in different environments. Use configurable variables at the top or derive paths from `$SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)`.
35
+ - **[LOW]** Scripts intended for others lack `--help`, argument validation, and usage messages → opaque interface for consumers. Add argument parsing with `getopts` and a `usage()` function.
36
+
37
+ ---
38
+
39
+ ## Code Quality
40
+ - **[HIGH]** Missing `set -euo pipefail` at the start of the script → errors in pipelines and unset variables go undetected. Add as the first non-comment line of every script.
41
+ - **[HIGH]** `[ $var == "value" ]` with unquoted variable → if `$var` is empty, the expression degrades to `[ == "value" ]` causing a syntax error. Quote all variable expansions inside `[ ]`.
42
+ - **[MEDIUM]** Using `[ ]` (POSIX `test`) instead of `[[ ]]` in bash scripts → `[ ]` requires quoting to prevent word splitting; `[[ ]]` is safer and supports pattern matching. Prefer `[[ ]]` in all bash (not sh) scripts.
43
+ - **[MEDIUM]** Missing or incorrect shebang → script executed by the wrong interpreter. Use `#!/usr/bin/env bash` for portability or `#!/bin/bash` for explicit path; never omit it.
44
+ - **[LOW]** Not running ShellCheck in CI → entire categories of bugs (quoting, globbing, SC codes) go undetected. Add `shellcheck *.sh` as a CI lint step.
45
+
46
+ ---
47
+
48
+ ## Common Bugs & Pitfalls
49
+ - **[HIGH]** `if [ $? -eq 0 ]` checked after intervening commands have reset `$?` → wrong exit code evaluated. Test the command directly: `if some_command; then ... fi`, or capture `ret=$?` immediately after.
50
+ - **[HIGH]** `for f in $(ls)` → fails on filenames with spaces; `ls` output is not reliably parseable. Use `for f in *` or `find` with `-print0` for recursive traversal.
51
+ - **[MEDIUM]** `[ $var = "" ]` fails with "unary operator expected" when `var` is unset → script aborts or branches incorrectly. Use `[ -z "${var}" ]` or `[ "${var:-}" = "" ]`.
52
+ - **[MEDIUM]** `exit` vs `return` not distinguished for sourced scripts → `exit` in a sourced script terminates the parent shell. Use `return` inside functions and sourced files; reserve `exit` for top-level script termination.
53
+ - **[LOW]** Trailing whitespace or mixed indentation in heredocs → unexpected literal whitespace in generated files or commands. Use `<<-HEREDOC` with tab indentation stripping, or prefer explicit `printf` / `cat` concatenation.
@@ -0,0 +1,53 @@
1
+ # Bevy — Stack-Specific Review Rules
2
+
3
+ > Applies to: GR · SR · PR · AR · BR
4
+ > Detection signals: `bevy`, `use bevy::`, `App::new()`, `add_systems(`, `Query<`, `Commands`, `Res<`, `ResMut<`, `Component`, `#[derive(Component)]`
5
+
6
+ ---
7
+
8
+ ## Security
9
+ - **[HIGH]** Scene files or asset files loaded from user-controlled paths via `AssetServer::load()` without path sanitization → directory traversal enabling access to sensitive files outside the asset directory; validate and canonicalize all user-supplied asset paths.
10
+ - **[MEDIUM]** Bevy's reflect system (`ReflectDeserialize`) used to deserialize untrusted data into registered types → arbitrary type instantiation via reflection; disable `ReflectDeserialize` on sensitive types or validate input schemas before deserialization.
11
+ - **[MEDIUM]** WebAssembly (WASM) builds exposing full game logic and asset paths in the browser bundle → no server-side authority; treat all WASM game state as untrusted for any competitive or monetized feature.
12
+ - **[LOW]** Debug systems (`bevy_inspector_egui`, world inspector) compiled into release builds → runtime scene manipulation exposed; gate debug plugins behind `#[cfg(debug_assertions)]`.
13
+
14
+ ---
15
+
16
+ ## Performance
17
+ - **[HIGH]** Systems with overly broad queries (`Query<&mut Transform>`) locking entire archetypes → prevents parallel system execution; narrow queries with `With<PlayerMarker>`, `Without<Static>`, and other filters to reduce contention.
18
+ - **[HIGH]** Missing `With<T>` or `Without<T>` filter markers in queries that iterate a subset of entities → Bevy schedules these as potentially conflicting with broader systems; add explicit filter components to enable parallelism.
19
+ - **[HIGH]** Compute-heavy work (pathfinding, physics solving, procedural generation) running in `Update` schedule without frame budget awareness → frame time spikes; offload to `AsyncComputeTaskPool` and poll results with `Task<T>`.
20
+ - **[HIGH]** Entities spawned and despawned every frame (projectiles, particles) without recycling → archetype fragmentation causing layout churn; use an object pool pattern with `Visibility` toggling and component reuse.
21
+ - **[MEDIUM]** Unnecessary `.chain()` on systems that have no actual data dependency → forces sequential execution where parallelism is possible; only chain systems that genuinely require ordering.
22
+ - **[MEDIUM]** Per-system local state stored in a `Resource` instead of `Local<T>` → shared resource access contends with other systems; use `Local<T>` for system-private state that no other system needs.
23
+ - **[LOW]** `bevy/trace` and `bevy/trace_chrome` features not used during profiling → bottlenecks identified only by guessing; enable tracing features to get a flame graph of system execution.
24
+
25
+ ---
26
+
27
+ ## Architecture
28
+ - **[HIGH]** Single large system handling input, physics updates, animation, and rendering logic → violates ECS principles and prevents parallelism; decompose into small, single-purpose systems with explicit scheduling relationships.
29
+ - **[HIGH]** Cross-system communication done via shared `ResMut<T>` instead of Bevy's `EventWriter<E>` / `EventReader<E>` → tight data coupling and ordering sensitivity; use Bevy events for decoupled, ordered inter-system communication.
30
+ - **[MEDIUM]** Game phase transitions (Menu → Loading → Playing → Paused → GameOver) not modeled with Bevy `States` → ad-hoc flags scattered across resources; define a `#[derive(States)]` enum and use `OnEnter`/`OnExit`/`in_state` to scope systems.
31
+ - **[MEDIUM]** Related systems, components, and resources not grouped into `Plugin` implementations → flat `App` setup becomes unmanageable; use the Plugin pattern to encapsulate cohesive game systems.
32
+ - **[MEDIUM]** Configuration and tuning data hardcoded in system logic → must recompile to tune; load from Bevy asset files (`ron`, `json`) via the asset system for hot-reloadable configuration.
33
+ - **[LOW]** No `Name` component added to spawned entities → Bevy Inspector and logging show only entity IDs with no context; add `.insert(Name::new("PlayerShip"))` to all meaningful entities.
34
+
35
+ ---
36
+
37
+ ## Code Quality
38
+ - **[HIGH]** `Query::get(entity).unwrap()` or `Query::single().unwrap()` used without error handling → panics when the entity is missing, despawned, or the query matches multiple entities; use `if let Ok(...)` or return early on `Err`.
39
+ - **[HIGH]** Multiple systems in the same schedule accessing the same `ResMut<T>` without explicit ordering → Bevy may warn or schedule them non-deterministically; add `.before()`/`.after()` constraints or split the resource.
40
+ - **[MEDIUM]** `#[derive(Resource)]` or `#[derive(Component)]` derive macros not used on custom types → manual impl required and easily missed; always derive these traits rather than implementing them manually.
41
+ - **[MEDIUM]** System ordering constraints not declared when a system reads data written by another in the same schedule → non-deterministic order between runs; use `app.add_systems(Update, writer.before(reader))`.
42
+ - **[MEDIUM]** `Commands` used to despawn entities and the same entity queried in a later system within the same schedule → despawn is deferred to end of schedule, query still sees it; be aware of command application timing.
43
+ - **[LOW]** Missing `Name` component on spawned entities → Bevy inspector and log output show raw `Entity(id, gen)` with no human-readable label; add `Name::new("description")` to entities during spawn.
44
+
45
+ ---
46
+
47
+ ## Common Bugs & Pitfalls
48
+ - **[HIGH]** Entity spawned with `Commands::spawn()` and then queried in the same system or a system in the same schedule set → `Commands` are applied at the end of the schedule; use `Added<T>` filter in a subsequent system to react to newly spawned entities.
49
+ - **[HIGH]** `Resource` not inserted into the `App` before a system that uses `Res<T>` or `ResMut<T>` runs → Bevy panics at startup with a "resource not found" error; ensure all resources are inserted via `app.insert_resource()` or `app.init_resource()` before any system accesses them.
50
+ - **[MEDIUM]** `Changed<T>` filter not triggering as expected → change detection is deferred; components mutably accessed via `Query<&mut T>` are marked changed even if the value was not actually modified; use `DetectChangesMut::set_if_neq()` to avoid spurious change detection.
51
+ - **[MEDIUM]** Exclusive systems (taking `&mut World` directly) blocking all parallel system execution → used unnecessarily for simple tasks that a normal system with appropriate queries could handle; reserve exclusive systems for operations that genuinely require full world access.
52
+ - **[MEDIUM]** Event not read by any system before it is cleared at the end of the next frame → Bevy clears events after two frames; if an event needs to persist longer, store it in a resource or use a `FixedUpdate` reader.
53
+ - **[LOW]** `App::run()` called on the main thread in a context that also needs async runtime access → `App::run()` blocks indefinitely; for non-game executables using Bevy for ECS only, use `app.update()` in a manual loop or run Bevy in a dedicated thread.