@critiq/rules 0.0.2 → 0.1.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 (203) hide show
  1. package/README.md +52 -4
  2. package/catalog.yaml +985 -19
  3. package/package.json +6 -1
  4. package/rules/go/go.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  5. package/rules/go/go.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  6. package/rules/go/go.performance.no-unbounded-concurrency.rule.yaml +33 -0
  7. package/rules/go/go.security.echo-sensitive-binding-without-validation.rule.yaml +46 -0
  8. package/rules/go/go.security.echo-unsafe-multipart-upload.rule.yaml +45 -0
  9. package/rules/go/go.security.fiber-sensitive-binding-without-validation.rule.yaml +45 -0
  10. package/rules/go/go.security.fiber-unsafe-multipart-upload.rule.yaml +45 -0
  11. package/rules/go/go.security.gin-sensitive-binding-without-validation.rule.yaml +45 -0
  12. package/rules/go/go.security.gin-trust-all-proxies.rule.yaml +45 -0
  13. package/rules/go/go.security.gin-wildcard-cors-with-credentials.rule.yaml +47 -0
  14. package/rules/go/go.security.net-http-missing-timeouts.rule.yaml +45 -0
  15. package/rules/go/go.security.sensitive-data-egress.rule.yaml +46 -0
  16. package/rules/go/go.security.tar-path-traversal.rule.yaml +45 -0
  17. package/rules/go/go.security.template-unescaped-request-value.rule.yaml +45 -0
  18. package/rules/go/go.testing.real-network-in-unit-test.rule.yaml +33 -0
  19. package/rules/go/go.testing.t-skip-without-ticket-reference.rule.yaml +33 -0
  20. package/rules/go/go.testing.time-sleep-in-unit-test.rule.yaml +33 -0
  21. package/rules/java/java.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  22. package/rules/java/java.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  23. package/rules/java/java.performance.no-unbounded-concurrency.rule.yaml +33 -0
  24. package/rules/java/java.security.android-screenshot-exposure.rule.yaml +35 -0
  25. package/rules/java/java.security.android-world-readable-mode.rule.yaml +35 -0
  26. package/rules/java/java.security.jpa-concatenated-query.rule.yaml +47 -0
  27. package/rules/java/java.security.reflected-output-from-request.rule.yaml +35 -0
  28. package/rules/java/java.security.servlet-insecure-cookie.rule.yaml +35 -0
  29. package/rules/java/java.security.spring-actuator-health-details-always.rule.yaml +40 -0
  30. package/rules/java/java.security.spring-actuator-sensitive-exposure.rule.yaml +40 -0
  31. package/rules/java/java.security.spring-csrf-globally-disabled.rule.yaml +49 -0
  32. package/rules/java/java.security.spring-debug-exposure.rule.yaml +35 -0
  33. package/rules/java/java.security.spring-permit-all-default.rule.yaml +47 -0
  34. package/rules/java/java.security.spring-webmvc-unrestricted-data-binding.rule.yaml +47 -0
  35. package/rules/java/java.security.template-unescaped-user-output.rule.yaml +49 -0
  36. package/rules/java/java.testing.disabled-without-ticket-reference.rule.yaml +33 -0
  37. package/rules/java/java.testing.http-client-in-unit-test.rule.yaml +33 -0
  38. package/rules/java/java.testing.thread-sleep-in-unit-test.rule.yaml +33 -0
  39. package/rules/php/php.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  40. package/rules/php/php.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  41. package/rules/php/php.performance.no-unbounded-concurrency.rule.yaml +33 -0
  42. package/rules/php/php.security.insecure-cors-wildcard-with-credentials.rule.yaml +41 -0
  43. package/rules/php/php.security.insecure-mail-or-file-transport.rule.yaml +41 -0
  44. package/rules/php/php.security.insecure-session-or-cookie-config.rule.yaml +42 -0
  45. package/rules/php/php.security.laravel-sensitive-csrf-exclusion.rule.yaml +42 -0
  46. package/rules/php/php.security.laravel-unsafe-blade-output.rule.yaml +42 -0
  47. package/rules/php/php.security.laravel-unsafe-mass-assignment.rule.yaml +45 -0
  48. package/rules/php/php.security.sensitive-data-egress.rule.yaml +42 -0
  49. package/rules/php/php.security.symfony-csrf-disabled.rule.yaml +42 -0
  50. package/rules/php/php.security.symfony-debug-exposure.rule.yaml +44 -0
  51. package/rules/php/php.security.unsafe-file-upload-handling.rule.yaml +41 -0
  52. package/rules/php/php.security.wordpress-missing-nonce-or-capability.rule.yaml +42 -0
  53. package/rules/php/php.security.wordpress-unprepared-sql.rule.yaml +42 -0
  54. package/rules/php/php.testing.curl-in-unit-test.rule.yaml +33 -0
  55. package/rules/php/php.testing.mark-test-skipped-without-ticket-reference.rule.yaml +33 -0
  56. package/rules/php/php.testing.sleep-in-unit-test.rule.yaml +33 -0
  57. package/rules/python/py.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  58. package/rules/python/py.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  59. package/rules/python/py.performance.no-unbounded-concurrency.rule.yaml +33 -0
  60. package/rules/python/py.security.django-csrf-exempt-state-changing.rule.yaml +46 -0
  61. package/rules/python/py.security.django-missing-csrf-middleware.rule.yaml +47 -0
  62. package/rules/python/py.security.django-unsafe-production-settings.rule.yaml +47 -0
  63. package/rules/python/py.security.drf-allow-any-default.rule.yaml +46 -0
  64. package/rules/python/py.security.drf-allow-any-unsafe-method.rule.yaml +46 -0
  65. package/rules/python/py.security.fastapi-insecure-cors.rule.yaml +43 -0
  66. package/rules/python/py.security.flask-missing-upload-body-limit.rule.yaml +44 -0
  67. package/rules/python/py.security.flask-unsafe-html-output.rule.yaml +44 -0
  68. package/rules/python/py.security.flask-unsafe-upload-filename.rule.yaml +44 -0
  69. package/rules/python/py.testing.pytest-skip-without-ticket-reference.rule.yaml +33 -0
  70. package/rules/python/py.testing.real-network-in-unit-test.rule.yaml +33 -0
  71. package/rules/python/py.testing.time-sleep-in-unit-test.rule.yaml +33 -0
  72. package/rules/ruby/ruby.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  73. package/rules/ruby/ruby.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  74. package/rules/ruby/ruby.performance.no-unbounded-concurrency.rule.yaml +33 -0
  75. package/rules/ruby/ruby.security.rails-csrf-disabled.rule.yaml +45 -0
  76. package/rules/ruby/ruby.security.rails-detailed-exceptions-enabled.rule.yaml +44 -0
  77. package/rules/ruby/ruby.security.rails-open-redirect.rule.yaml +45 -0
  78. package/rules/ruby/ruby.security.rails-unsafe-html-output.rule.yaml +46 -0
  79. package/rules/ruby/ruby.security.rails-unsafe-render.rule.yaml +45 -0
  80. package/rules/ruby/ruby.security.rails-unsafe-session-or-cookie-store.rule.yaml +45 -0
  81. package/rules/ruby/ruby.security.rails-unsafe-strong-parameters.rule.yaml +46 -0
  82. package/rules/ruby/ruby.security.sensitive-data-egress.rule.yaml +45 -0
  83. package/rules/ruby/ruby.security.sidekiq-web-unauthenticated-mount.rule.yaml +45 -0
  84. package/rules/ruby/ruby.testing.focused-example.rule.yaml +33 -0
  85. package/rules/ruby/ruby.testing.pending-without-ticket-reference.rule.yaml +33 -0
  86. package/rules/ruby/ruby.testing.real-network-in-unit-test.rule.yaml +33 -0
  87. package/rules/ruby/ruby.testing.skip-without-ticket-reference.rule.yaml +33 -0
  88. package/rules/ruby/ruby.testing.sleep-in-unit-test.rule.yaml +33 -0
  89. package/rules/rust/rust.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  90. package/rules/rust/rust.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  91. package/rules/rust/rust.performance.no-unbounded-concurrency.rule.yaml +33 -0
  92. package/rules/rust/rust.security.actix-wildcard-cors-with-credentials.rule.yaml +47 -0
  93. package/rules/rust/rust.security.axum-body-limit-disabled.rule.yaml +45 -0
  94. package/rules/rust/rust.security.axum-insecure-cors-with-credentials.rule.yaml +47 -0
  95. package/rules/rust/rust.security.rocket-panic-prone-request-handler.rule.yaml +45 -0
  96. package/rules/rust/rust.security.rocket-unsafe-template-output.rule.yaml +47 -0
  97. package/rules/rust/rust.security.sqlx-diesel-raw-interpolated-query.rule.yaml +47 -0
  98. package/rules/rust/rust.security.template-unescaped-request-value.rule.yaml +47 -0
  99. package/rules/rust/rust.security.warp-blocking-or-panic-in-async-handler.rule.yaml +45 -0
  100. package/rules/rust/rust.testing.ignore-without-ticket-reference.rule.yaml +33 -0
  101. package/rules/rust/rust.testing.real-network-in-unit-test.rule.yaml +33 -0
  102. package/rules/rust/rust.testing.thread-sleep-in-unit-test.rule.yaml +33 -0
  103. package/rules/shared/security.archive-path-traversal.rule.yaml +41 -0
  104. package/rules/shared/security.external-file-upload.rule.yaml +40 -0
  105. package/rules/shared/security.permissive-file-permissions.rule.yaml +40 -0
  106. package/rules/shared/security.sensitive-data-egress.rule.yaml +36 -0
  107. package/rules/typescript/ts.correctness.assignment-in-condition.rule.yaml +36 -0
  108. package/rules/typescript/ts.correctness.assignment-to-import-binding.rule.yaml +36 -0
  109. package/rules/typescript/ts.correctness.async-promise-executor.rule.yaml +36 -0
  110. package/rules/typescript/ts.correctness.duplicate-function-parameter.rule.yaml +36 -0
  111. package/rules/typescript/ts.correctness.duplicate-import-source.rule.yaml +36 -0
  112. package/rules/typescript/ts.correctness.duplicate-object-key.rule.yaml +36 -0
  113. package/rules/typescript/ts.correctness.duplicate-switch-case.rule.yaml +36 -0
  114. package/rules/typescript/ts.correctness.empty-block-statement.rule.yaml +35 -0
  115. package/rules/typescript/ts.correctness.identical-comparison-operands.rule.yaml +36 -0
  116. package/rules/typescript/ts.correctness.reassign-catch-binding.rule.yaml +35 -0
  117. package/rules/typescript/ts.correctness.regexp-pattern-unusual-control-character.rule.yaml +35 -0
  118. package/rules/typescript/ts.correctness.self-assignment.rule.yaml +36 -0
  119. package/rules/typescript/ts.next.server-action-missing-local-auth.rule.yaml +35 -0
  120. package/rules/typescript/ts.performance.no-array-spread-in-hot-loop.rule.yaml +32 -0
  121. package/rules/typescript/ts.performance.no-cache-miss-from-unstable-key.rule.yaml +32 -0
  122. package/rules/typescript/ts.performance.no-expensive-sort-in-render-path.rule.yaml +32 -0
  123. package/rules/typescript/ts.performance.no-json-parse-stringify-clone.rule.yaml +32 -0
  124. package/rules/typescript/ts.performance.no-large-object-spread-in-loop.rule.yaml +32 -0
  125. package/rules/typescript/ts.performance.no-n-plus-one-await-in-map.rule.yaml +32 -0
  126. package/rules/typescript/ts.performance.no-redundant-network-fetch.rule.yaml +32 -0
  127. package/rules/typescript/ts.performance.no-regex-construction-in-loop.rule.yaml +32 -0
  128. package/rules/typescript/ts.performance.no-sync-fs-in-request-path.rule.yaml +32 -0
  129. package/rules/typescript/ts.performance.no-unbounded-concurrency.rule.yaml +32 -0
  130. package/rules/typescript/ts.quality.no-ambiguous-abbreviations.rule.yaml +27 -0
  131. package/rules/typescript/ts.quality.no-barrel-file-cycle.rule.yaml +27 -0
  132. package/rules/typescript/ts.quality.no-boolean-parameter-trap.rule.yaml +27 -0
  133. package/rules/typescript/ts.quality.no-dead-export.rule.yaml +27 -0
  134. package/rules/typescript/ts.quality.no-hidden-side-effect-import.rule.yaml +27 -0
  135. package/rules/typescript/ts.quality.no-inconsistent-error-shape.rule.yaml +27 -0
  136. package/rules/typescript/ts.quality.no-mixed-abstraction-level.rule.yaml +27 -0
  137. package/rules/typescript/ts.quality.no-primitive-obsession-in-domain-model.rule.yaml +27 -0
  138. package/rules/typescript/ts.quality.no-temporal-coupling.rule.yaml +27 -0
  139. package/rules/typescript/ts.quality.no-wide-public-surface.rule.yaml +27 -0
  140. package/rules/typescript/ts.react.no-accessibility-label-missing.rule.yaml +36 -0
  141. package/rules/typescript/ts.react.no-activedescendant-on-non-focusable-host.rule.yaml +36 -0
  142. package/rules/typescript/ts.react.no-click-without-keyboard-handler.rule.yaml +36 -0
  143. package/rules/typescript/ts.react.no-deprecated-create-factory.rule.yaml +34 -0
  144. package/rules/typescript/ts.react.no-deprecated-react-dom-root-api.rule.yaml +34 -0
  145. package/rules/typescript/ts.react.no-derived-state-from-props.rule.yaml +34 -0
  146. package/rules/typescript/ts.react.no-effect-fetch-without-cancellation.rule.yaml +35 -0
  147. package/rules/typescript/ts.react.no-find-dom-node.rule.yaml +34 -0
  148. package/rules/typescript/ts.react.no-img-missing-alt-text.rule.yaml +36 -0
  149. package/rules/typescript/ts.react.no-index-as-key-in-dynamic-list.rule.yaml +34 -0
  150. package/rules/typescript/ts.react.no-interactive-role-on-static-semantics.rule.yaml +36 -0
  151. package/rules/typescript/ts.react.no-invalid-anchor-href.rule.yaml +36 -0
  152. package/rules/typescript/ts.react.no-keyboard-interaction-without-widget-role.rule.yaml +36 -0
  153. package/rules/typescript/ts.react.no-legacy-lifecycle.rule.yaml +34 -0
  154. package/rules/typescript/ts.react.no-missing-error-boundary.rule.yaml +36 -0
  155. package/rules/typescript/ts.react.no-positive-tabindex.rule.yaml +36 -0
  156. package/rules/typescript/ts.react.no-static-element-with-synthetic-handlers.rule.yaml +36 -0
  157. package/rules/typescript/ts.react.no-string-ref.rule.yaml +34 -0
  158. package/rules/typescript/ts.react.no-uncontrolled-to-controlled-input.rule.yaml +34 -0
  159. package/rules/typescript/ts.react.no-widget-role-without-tabindex.rule.yaml +36 -0
  160. package/rules/typescript/ts.security.ajv-insecure-configuration.rule.yaml +34 -0
  161. package/rules/typescript/ts.security.angular-dom-sanitizer-bypass-untrusted-input.rule.yaml +35 -0
  162. package/rules/typescript/ts.security.apollo-server-csrf-disabled.rule.yaml +36 -0
  163. package/rules/typescript/ts.security.apollo-server-graphql-dev-tooling-exposure.rule.yaml +36 -0
  164. package/rules/typescript/ts.security.apollo-server-introspection-exposure.rule.yaml +35 -0
  165. package/rules/typescript/ts.security.apollo-server-missing-query-limits.rule.yaml +35 -0
  166. package/rules/typescript/ts.security.astro-vite-public-secret-define.rule.yaml +39 -0
  167. package/rules/typescript/ts.security.debug-statement-in-source.rule.yaml +36 -0
  168. package/rules/typescript/ts.security.electron-dangerous-webpreferences.rule.yaml +35 -0
  169. package/rules/typescript/ts.security.electron-insecure-local-state.rule.yaml +35 -0
  170. package/rules/typescript/ts.security.electron-missing-ipc-origin-check.rule.yaml +35 -0
  171. package/rules/typescript/ts.security.electron-shell-open-external-unvalidated.rule.yaml +35 -0
  172. package/rules/typescript/ts.security.express-error-handler-information-disclosure.rule.yaml +35 -0
  173. package/rules/typescript/ts.security.express-static-dotfiles-allow.rule.yaml +35 -0
  174. package/rules/typescript/ts.security.express-unbounded-body-parser.rule.yaml +34 -0
  175. package/rules/typescript/ts.security.express-user-controlled-static-mount.rule.yaml +35 -0
  176. package/rules/typescript/ts.security.fastify-excessive-body-limit.rule.yaml +34 -0
  177. package/rules/typescript/ts.security.fastify-public-bind-without-trust-proxy.rule.yaml +38 -0
  178. package/rules/typescript/ts.security.graphql-upload-without-csrf-guard.rule.yaml +36 -0
  179. package/rules/typescript/ts.security.iframe-missing-sandbox-attribute.rule.yaml +35 -0
  180. package/rules/typescript/ts.security.insecure-content-security-policy-literal.rule.yaml +35 -0
  181. package/rules/typescript/ts.security.insecure-helmet-hardening-options.rule.yaml +36 -0
  182. package/rules/typescript/ts.security.jwt-insecure-signing-algorithm.rule.yaml +35 -0
  183. package/rules/typescript/ts.security.legacy-buffer-constructor.rule.yaml +35 -0
  184. package/rules/typescript/ts.security.log-injection.rule.yaml +36 -0
  185. package/rules/typescript/ts.security.nestjs-helmet-after-route-mount.rule.yaml +34 -0
  186. package/rules/typescript/ts.security.nestjs-missing-global-validation-pipe.rule.yaml +35 -0
  187. package/rules/typescript/ts.security.nestjs-skip-throttle-sensitive-route.rule.yaml +35 -0
  188. package/rules/typescript/ts.security.nestjs-validation-pipe-without-whitelist.rule.yaml +36 -0
  189. package/rules/typescript/ts.security.nuxt-public-runtime-secret.rule.yaml +38 -0
  190. package/rules/typescript/ts.security.open-redirect.rule.yaml +2 -0
  191. package/rules/typescript/ts.security.request-driven-array-index-access.rule.yaml +33 -0
  192. package/rules/typescript/ts.security.sensitive-data-egress.rule.yaml +1 -0
  193. package/rules/typescript/ts.security.ssrf.rule.yaml +1 -0
  194. package/rules/typescript/ts.security.unsafe-dompurify-version.rule.yaml +36 -0
  195. package/rules/typescript/ts.security.unsafe-marked-version.rule.yaml +36 -0
  196. package/rules/typescript/ts.security.xml-parse-string-with-untrusted-input.rule.yaml +35 -0
  197. package/rules/typescript/ts.testing.no-flaky-timer-test.rule.yaml +38 -0
  198. package/rules/typescript/ts.testing.no-focused-test.rule.yaml +34 -0
  199. package/rules/typescript/ts.testing.no-missing-edge-case-tests.rule.yaml +35 -0
  200. package/rules/typescript/ts.testing.no-network-call-in-unit-test.rule.yaml +38 -0
  201. package/rules/typescript/ts.testing.no-skipped-test-without-ticket.rule.yaml +34 -0
  202. package/rules/typescript/ts.testing.no-snapshot-without-intent.rule.yaml +34 -0
  203. package/rules/typescript/ts.testing.no-test-only-code-in-production.rule.yaml +38 -0
@@ -0,0 +1,32 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.performance.no-expensive-sort-in-render-path
5
+ title: Avoid expensive sort or transforms in render path
6
+ summary: Sorting or heavy transforms in React render paths should be memoized or precomputed.
7
+ rationale: Sorting or heavy transforms in React render paths should be memoized or precomputed.
8
+ tags:
9
+ - performance
10
+ - rules-catalog
11
+ stability: stable
12
+ appliesTo: block
13
+ scope:
14
+ languages:
15
+ - typescript
16
+ - javascript
17
+ match:
18
+ fact:
19
+ kind: performance.no-expensive-sort-in-render-path
20
+ bind: issue
21
+ emit:
22
+ finding:
23
+ category: performance.render
24
+ severity: medium
25
+ confidence: 0.8
26
+ tags:
27
+ - performance
28
+ message:
29
+ title: Avoid expensive sort or transforms in render path
30
+ summary: "`${captures.issue.text}` matches ts.performance.no-expensive-sort-in-render-path."
31
+ remediation:
32
+ summary: Refactor this path to avoid repeated work in hot execution paths.
@@ -0,0 +1,32 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.performance.no-json-parse-stringify-clone
5
+ title: Avoid JSON parse/stringify deep-clone
6
+ summary: JSON stringify/parse cloning is expensive and loses type fidelity for rich objects.
7
+ rationale: JSON stringify/parse cloning is expensive and loses type fidelity for rich objects.
8
+ tags:
9
+ - performance
10
+ - rules-catalog
11
+ stability: stable
12
+ appliesTo: block
13
+ scope:
14
+ languages:
15
+ - typescript
16
+ - javascript
17
+ match:
18
+ fact:
19
+ kind: performance.no-json-parse-stringify-clone
20
+ bind: issue
21
+ emit:
22
+ finding:
23
+ category: performance.cpu
24
+ severity: medium
25
+ confidence: 0.8
26
+ tags:
27
+ - performance
28
+ message:
29
+ title: Avoid JSON parse/stringify deep-clone
30
+ summary: "`${captures.issue.text}` matches ts.performance.no-json-parse-stringify-clone."
31
+ remediation:
32
+ summary: Refactor this path to avoid repeated work in hot execution paths.
@@ -0,0 +1,32 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.performance.no-large-object-spread-in-loop
5
+ title: Avoid large object spread inside loops
6
+ summary: Object spread inside loops creates repeated allocations and can degrade throughput.
7
+ rationale: Object spread inside loops creates repeated allocations and can degrade throughput.
8
+ tags:
9
+ - performance
10
+ - rules-catalog
11
+ stability: stable
12
+ appliesTo: block
13
+ scope:
14
+ languages:
15
+ - typescript
16
+ - javascript
17
+ match:
18
+ fact:
19
+ kind: performance.no-large-object-spread-in-loop
20
+ bind: issue
21
+ emit:
22
+ finding:
23
+ category: performance.allocation
24
+ severity: medium
25
+ confidence: 0.8
26
+ tags:
27
+ - performance
28
+ message:
29
+ title: Avoid large object spread inside loops
30
+ summary: "`${captures.issue.text}` matches ts.performance.no-large-object-spread-in-loop."
31
+ remediation:
32
+ summary: Refactor this path to avoid repeated work in hot execution paths.
@@ -0,0 +1,32 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.performance.no-n-plus-one-await-in-map
5
+ title: Avoid N+1 await patterns in map flows
6
+ summary: Per-item awaits inside map-like flows often create avoidable latency and fan-out bottlenecks.
7
+ rationale: Per-item awaits inside map-like flows often create avoidable latency and fan-out bottlenecks.
8
+ tags:
9
+ - performance
10
+ - rules-catalog
11
+ stability: stable
12
+ appliesTo: block
13
+ scope:
14
+ languages:
15
+ - typescript
16
+ - javascript
17
+ match:
18
+ fact:
19
+ kind: performance.no-n-plus-one-await-in-map
20
+ bind: issue
21
+ emit:
22
+ finding:
23
+ category: performance.async
24
+ severity: high
25
+ confidence: 0.8
26
+ tags:
27
+ - performance
28
+ message:
29
+ title: Avoid N+1 await patterns in map flows
30
+ summary: "`${captures.issue.text}` matches ts.performance.no-n-plus-one-await-in-map."
31
+ remediation:
32
+ summary: Refactor this path to avoid repeated work in hot execution paths.
@@ -0,0 +1,32 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.performance.no-redundant-network-fetch
5
+ title: Avoid redundant network fetches in one path
6
+ summary: Repeated fetches for the same stable request identity waste network and CPU budget.
7
+ rationale: Repeated fetches for the same stable request identity waste network and CPU budget.
8
+ tags:
9
+ - performance
10
+ - rules-catalog
11
+ stability: stable
12
+ appliesTo: block
13
+ scope:
14
+ languages:
15
+ - typescript
16
+ - javascript
17
+ match:
18
+ fact:
19
+ kind: performance.no-redundant-network-fetch
20
+ bind: issue
21
+ emit:
22
+ finding:
23
+ category: performance.network
24
+ severity: medium
25
+ confidence: 0.8
26
+ tags:
27
+ - performance
28
+ message:
29
+ title: Avoid redundant network fetches in one path
30
+ summary: "`${captures.issue.text}` matches ts.performance.no-redundant-network-fetch."
31
+ remediation:
32
+ summary: Refactor this path to avoid repeated work in hot execution paths.
@@ -0,0 +1,32 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.performance.no-regex-construction-in-loop
5
+ title: Avoid regex construction inside loops
6
+ summary: Constructing regular expressions inside loops repeatedly allocates and reparses patterns.
7
+ rationale: Constructing regular expressions inside loops repeatedly allocates and reparses patterns.
8
+ tags:
9
+ - performance
10
+ - rules-catalog
11
+ stability: stable
12
+ appliesTo: block
13
+ scope:
14
+ languages:
15
+ - typescript
16
+ - javascript
17
+ match:
18
+ fact:
19
+ kind: performance.no-regex-construction-in-loop
20
+ bind: issue
21
+ emit:
22
+ finding:
23
+ category: performance.allocation
24
+ severity: medium
25
+ confidence: 0.8
26
+ tags:
27
+ - performance
28
+ message:
29
+ title: Avoid regex construction inside loops
30
+ summary: "`${captures.issue.text}` matches ts.performance.no-regex-construction-in-loop."
31
+ remediation:
32
+ summary: Refactor this path to avoid repeated work in hot execution paths.
@@ -0,0 +1,32 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.performance.no-sync-fs-in-request-path
5
+ title: Avoid sync filesystem calls in request paths
6
+ summary: Synchronous filesystem calls on request paths block the event loop and degrade latency.
7
+ rationale: Synchronous filesystem calls on request paths block the event loop and degrade latency.
8
+ tags:
9
+ - performance
10
+ - rules-catalog
11
+ stability: stable
12
+ appliesTo: block
13
+ scope:
14
+ languages:
15
+ - typescript
16
+ - javascript
17
+ match:
18
+ fact:
19
+ kind: performance.no-sync-fs-in-request-path
20
+ bind: issue
21
+ emit:
22
+ finding:
23
+ category: performance.io
24
+ severity: high
25
+ confidence: 0.8
26
+ tags:
27
+ - performance
28
+ message:
29
+ title: Avoid sync filesystem calls in request paths
30
+ summary: "`${captures.issue.text}` matches ts.performance.no-sync-fs-in-request-path."
31
+ remediation:
32
+ summary: Refactor this path to avoid repeated work in hot execution paths.
@@ -0,0 +1,32 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.performance.no-unbounded-concurrency
5
+ title: Avoid unbounded concurrency fan-out
6
+ summary: Unbounded Promise fan-out over unknown input can exhaust downstream capacity.
7
+ rationale: Unbounded Promise fan-out over unknown input can exhaust downstream capacity.
8
+ tags:
9
+ - performance
10
+ - rules-catalog
11
+ stability: stable
12
+ appliesTo: block
13
+ scope:
14
+ languages:
15
+ - typescript
16
+ - javascript
17
+ match:
18
+ fact:
19
+ kind: performance.no-unbounded-concurrency
20
+ bind: issue
21
+ emit:
22
+ finding:
23
+ category: performance.async
24
+ severity: high
25
+ confidence: 0.8
26
+ tags:
27
+ - performance
28
+ message:
29
+ title: Avoid unbounded concurrency fan-out
30
+ summary: "`${captures.issue.text}` matches ts.performance.no-unbounded-concurrency."
31
+ remediation:
32
+ summary: Refactor this path to avoid repeated work in hot execution paths.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-ambiguous-abbreviations
5
+ title: Avoid ambiguous abbreviations in public APIs
6
+ summary: Ambiguous abbreviated names in exported APIs reduce readability and onboarding speed.
7
+ rationale: Public API names are long-lived and should optimize for clarity over brevity.
8
+ tags: [quality, maintainability, rules-catalog]
9
+ stability: stable
10
+ appliesTo: file
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.ambiguous-abbreviation-public-api
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.maintainability
20
+ severity: low
21
+ confidence: 0.76
22
+ tags: [quality, naming]
23
+ message:
24
+ title: Use explicit naming for exported API symbols
25
+ summary: "`${captures.issue.text}` looks like an ambiguous abbreviation in a public API."
26
+ remediation:
27
+ summary: Rename exported symbols to descriptive terms that communicate domain intent.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-barrel-file-cycle
5
+ title: Avoid barrel file cycles
6
+ summary: Cycles involving barrel files obscure ownership and complicate module boundaries.
7
+ rationale: Re-export cycles make import behavior less predictable and harder to review.
8
+ tags: [quality, architecture, rules-catalog]
9
+ stability: stable
10
+ appliesTo: file
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.barrel-file-cycle
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.architecture
20
+ severity: medium
21
+ confidence: 0.83
22
+ tags: [quality, architecture]
23
+ message:
24
+ title: Break the barrel cycle between modules
25
+ summary: "`${captures.issue.text}` participates in a re-export cycle."
26
+ remediation:
27
+ summary: Remove cycle edges, move shared symbols to a third module, and keep barrel ownership explicit.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-boolean-parameter-trap
5
+ title: Avoid boolean parameter trap in public APIs
6
+ summary: Public APIs with multiple boolean flags reduce readability and increase change risk.
7
+ rationale: Boolean-heavy signatures hide intent and make call-sites brittle.
8
+ tags: [quality, maintainability, rules-catalog]
9
+ stability: stable
10
+ appliesTo: file
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.boolean-parameter-trap
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.maintainability
20
+ severity: medium
21
+ confidence: 0.86
22
+ tags: [quality, maintainability]
23
+ message:
24
+ title: Replace multiple boolean flags with an options object
25
+ summary: "`${captures.issue.text}` appears to accept multiple boolean flags."
26
+ remediation:
27
+ summary: Prefer explicit option objects or dedicated methods to encode behavior clearly.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-dead-export
5
+ title: Remove dead exports
6
+ summary: Exported symbols with no known consumers increase maintenance overhead.
7
+ rationale: Dead exports are accidental API surface that should be removed or documented.
8
+ tags: [quality, maintainability, rules-catalog]
9
+ stability: stable
10
+ appliesTo: file
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.dead-export
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.maintainability
20
+ severity: low
21
+ confidence: 0.78
22
+ tags: [quality, maintainability]
23
+ message:
24
+ title: Remove or justify unused exported symbol
25
+ summary: "`${captures.issue.text}` appears to be exported but unused by the project."
26
+ remediation:
27
+ summary: Remove dead exports, make them internal, or document supported public entrypoints.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-hidden-side-effect-import
5
+ title: Avoid hidden side-effect imports
6
+ summary: Bare side-effect imports outside setup files make module behavior implicit.
7
+ rationale: Hidden side effects are difficult to reason about and can create order-dependent bugs.
8
+ tags: [quality, maintainability, rules-catalog]
9
+ stability: stable
10
+ appliesTo: file
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.hidden-side-effect-import
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.maintainability
20
+ severity: medium
21
+ confidence: 0.85
22
+ tags: [quality, maintainability]
23
+ message:
24
+ title: Move side effects into explicit setup boundaries
25
+ summary: "`${captures.issue.text}` is a side-effect-only import outside allowlisted setup files."
26
+ remediation:
27
+ summary: Use explicit setup modules or import named symbols instead of hidden side effects.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-inconsistent-error-shape
5
+ title: Keep error payload shape consistent
6
+ summary: Inconsistent thrown or rejected error shapes make error handling brittle.
7
+ rationale: Standardized error construction simplifies observability, retries, and user-safe handling.
8
+ tags: [quality, error-handling, rules-catalog]
9
+ stability: stable
10
+ appliesTo: block
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.inconsistent-error-shape
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.error-handling
20
+ severity: medium
21
+ confidence: 0.82
22
+ tags: [quality, error-handling]
23
+ message:
24
+ title: Use a consistent error construction pattern
25
+ summary: "`${captures.issue.text}` indicates mixed error shapes in this module."
26
+ remediation:
27
+ summary: Standardize on one error type or envelope and normalize throw/reject paths.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-mixed-abstraction-level
5
+ title: Keep function abstraction levels consistent
6
+ summary: Functions that mix transport, persistence, validation, and domain logic are hard to change safely.
7
+ rationale: Mixed abstraction creates hidden coupling and complicates testing and review.
8
+ tags: [quality, architecture, rules-catalog]
9
+ stability: stable
10
+ appliesTo: file
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.mixed-abstraction-level
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.architecture
20
+ severity: medium
21
+ confidence: 0.8
22
+ tags: [quality, architecture]
23
+ message:
24
+ title: Split this flow into cohesive layers
25
+ summary: "`${captures.issue.text}` combines multiple abstraction levels in a single flow."
26
+ remediation:
27
+ summary: Separate transport, validation, persistence, and domain logic into dedicated functions or services.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-primitive-obsession-in-domain-model
5
+ title: Avoid primitive obsession in domain model APIs
6
+ summary: Domain-facing APIs with many primitive parameters should use richer value objects.
7
+ rationale: Grouping related primitives into value types improves readability and reduces argument-order bugs.
8
+ tags: [quality, maintainability, rules-catalog]
9
+ stability: stable
10
+ appliesTo: file
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.primitive-obsession-domain-model
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.design
20
+ severity: low
21
+ confidence: 0.8
22
+ tags: [quality, design]
23
+ message:
24
+ title: Replace primitive parameter groups with domain objects
25
+ summary: "`${captures.issue.text}` appears to rely on repeated primitive parameters."
26
+ remediation:
27
+ summary: Introduce a value object or typed input model for related arguments.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-temporal-coupling
5
+ title: Avoid APIs with hidden call-order requirements
6
+ summary: APIs that require callers to invoke methods in strict hidden order are fragile.
7
+ rationale: Temporal coupling is a common source of runtime bugs and unclear contracts.
8
+ tags: [quality, architecture, rules-catalog]
9
+ stability: experimental
10
+ appliesTo: file
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.temporal-coupling-api-order
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.architecture
20
+ severity: low
21
+ confidence: 0.65
22
+ tags: [quality, architecture]
23
+ message:
24
+ title: Encode call ordering in the API contract
25
+ summary: "`${captures.issue.text}` suggests implicit call ordering requirements."
26
+ remediation:
27
+ summary: Model lifecycle stages explicitly in types or stateful objects to prevent invalid sequences.
@@ -0,0 +1,27 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.no-wide-public-surface
5
+ title: Keep module public surface narrow
6
+ summary: Modules exporting too many symbols become hard to evolve safely.
7
+ rationale: Broad module APIs increase accidental coupling and long-term maintenance cost.
8
+ tags: [quality, architecture, rules-catalog]
9
+ stability: stable
10
+ appliesTo: file
11
+ scope:
12
+ languages: [typescript, javascript]
13
+ match:
14
+ fact:
15
+ kind: quality.wide-public-surface
16
+ bind: issue
17
+ emit:
18
+ finding:
19
+ category: quality.architecture
20
+ severity: medium
21
+ confidence: 0.84
22
+ tags: [quality, architecture]
23
+ message:
24
+ title: Reduce public exports in this module
25
+ summary: "`${captures.issue.text}` exports more public symbols than the maintainability threshold."
26
+ remediation:
27
+ summary: Split APIs, hide internals, or create focused entrypoints with fewer exports.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.react.no-accessibility-label-missing
5
+ title: Give interactive elements an accessible name
6
+ summary: Buttons, links, and inputs need labels, aria attributes, or visible text so assistive technologies can describe them.
7
+ rationale: Unlabeled controls are ambiguous to keyboard and screen reader users and fail basic accessibility expectations.
8
+ tags:
9
+ - react
10
+ - accessibility
11
+ - ui
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: function
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: ui.react.missing-accessible-name
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: correctness.ui
26
+ severity: high
27
+ confidence: 0.74
28
+ tags:
29
+ - react
30
+ - accessibility
31
+ - ui
32
+ message:
33
+ title: Add an accessible name to interactive elements
34
+ summary: "`${captures.issue.text}` renders without aria labeling or visible text."
35
+ remediation:
36
+ summary: Add aria-label or aria-labelledby, associate a label element, or include descriptive visible content.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.react.no-activedescendant-on-non-focusable-host
5
+ title: Make aria-activedescendant hosts keyboard focusable
6
+ summary: "Elements that manage active descendants must participate in the tab order or be native controls that already receive focus."
7
+ rationale: Screen readers and keyboard users cannot follow listbox and combobox patterns when the controlling node never becomes focused.
8
+ tags:
9
+ - react
10
+ - accessibility
11
+ - ui
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: function
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: ui.react.activedescendant-host-not-focusable
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: correctness.ui
26
+ severity: high
27
+ confidence: 0.8
28
+ tags:
29
+ - react
30
+ - accessibility
31
+ - ui
32
+ message:
33
+ title: Add focusability to the active-descendant owner
34
+ summary: "`${captures.issue.text}` sets `aria-activedescendant` on a host that is not keyboard focusable."
35
+ remediation:
36
+ summary: Use a native input or button where possible, or add `tabIndex={0}` on the owning element while preserving roving tabindex semantics for options.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.react.no-click-without-keyboard-handler
5
+ title: Support keyboard interaction for click handlers
6
+ summary: "Non-interactive JSX elements that respond to clicks also need an equivalent keyboard path."
7
+ rationale: Mouse-only interaction blocks keyboard users and creates inaccessible custom controls that do not behave like native UI elements.
8
+ tags:
9
+ - react
10
+ - accessibility
11
+ - ui
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: function
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: ui.react.click-without-keyboard-handler
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: correctness.ui
26
+ severity: high
27
+ confidence: 0.84
28
+ tags:
29
+ - react
30
+ - accessibility
31
+ - ui
32
+ message:
33
+ title: Add keyboard support to click-driven UI
34
+ summary: "`${captures.issue.text}` handles clicks without an equivalent keyboard event."
35
+ remediation:
36
+ summary: Prefer native buttons or links, or add the necessary role, focus behavior, and keyboard handlers for the same action.