@thedecipherist/claude-packs 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (827) hide show
  1. package/CHANGELOG.md +680 -0
  2. package/LICENSE +21 -0
  3. package/README.md +316 -2
  4. package/bin/claude-packs.mjs +204 -0
  5. package/configurations/base/config.json +85 -0
  6. package/configurations/cpp/config.json +92 -0
  7. package/configurations/full-stack/config.json +152 -0
  8. package/configurations/go/config.json +96 -0
  9. package/configurations/node/config.json +100 -0
  10. package/configurations/python/config.json +97 -0
  11. package/configurations/synth-creator/config.json +148 -0
  12. package/global/hooks/gnu-shell.mjs +131 -0
  13. package/global/hooks/lib/program-read.mjs +196 -0
  14. package/global/hooks/lib/program-writes.mjs +177 -0
  15. package/global/hooks/lib/shell-writes.mjs +293 -0
  16. package/global/hooks/shell-traps.mjs +79 -0
  17. package/global/hooks/version-pin-guard.mjs +280 -0
  18. package/global/skills/latest-versions/SKILL.md +49 -0
  19. package/lib/backup.mjs +34 -0
  20. package/lib/claude-md.mjs +58 -0
  21. package/lib/config-cli.mjs +36 -0
  22. package/lib/configs.mjs +145 -0
  23. package/lib/coverage.mjs +86 -0
  24. package/lib/custom-packs.mjs +93 -0
  25. package/lib/doctor.mjs +115 -0
  26. package/lib/fix-plan.mjs +71 -0
  27. package/lib/git-tokens.mjs +64 -0
  28. package/lib/global.mjs +125 -0
  29. package/lib/hook-proof.mjs +28 -0
  30. package/lib/hook-timing.mjs +42 -0
  31. package/lib/hover-gate.mjs +29 -0
  32. package/lib/kit-lock.mjs +149 -0
  33. package/lib/layout.mjs +75 -0
  34. package/lib/logs.mjs +69 -0
  35. package/lib/manifest.mjs +24 -0
  36. package/lib/new.mjs +49 -0
  37. package/lib/once-only-report.mjs +54 -0
  38. package/lib/pack-manifest.mjs +20 -0
  39. package/lib/packs.mjs +107 -0
  40. package/lib/planner.mjs +59 -0
  41. package/lib/repeats.mjs +65 -0
  42. package/lib/repo-weight.mjs +28 -0
  43. package/lib/rules.mjs +40 -0
  44. package/lib/scan-detect.mjs +94 -0
  45. package/lib/scan.mjs +168 -0
  46. package/lib/selftest-cache.mjs +39 -0
  47. package/lib/settings.mjs +138 -0
  48. package/lib/shape-cli.mjs +76 -0
  49. package/lib/shape.mjs +4 -0
  50. package/lib/suggest.mjs +18 -0
  51. package/lib/switches.mjs +44 -0
  52. package/lib/symmetry-doctor.mjs +26 -0
  53. package/lib/sync.mjs +130 -0
  54. package/package.json +34 -4
  55. package/packs/ai/checks/boundary-computes-its-own-hash.json +30 -0
  56. package/packs/ai/checks/model-call-needs-boundary.json +29 -0
  57. package/packs/ai/checks/model-id-from-config.json +28 -0
  58. package/packs/ai/checks/model-output-validated.json +26 -0
  59. package/packs/ai/pack.json +38 -0
  60. package/packs/ai/rules/ai-input-sha-boundary.md +31 -0
  61. package/packs/ai/rules/llm-pipeline-security.md +26 -0
  62. package/packs/audio-core/checks/denormals-not-in-prepare.json +12 -0
  63. package/packs/audio-core/checks/dsp-without-apvts.json +12 -0
  64. package/packs/audio-core/checks/float-phase-or-rate.json +12 -0
  65. package/packs/audio-core/checks/juce-snap-to-zero-off.json +12 -0
  66. package/packs/audio-core/checks/keep-werror.json +12 -0
  67. package/packs/audio-core/checks/no-fast-math.json +14 -0
  68. package/packs/audio-core/checks/no-locale-change.json +12 -0
  69. package/packs/audio-core/checks/no-march-native.json +14 -0
  70. package/packs/audio-core/clang-tidy +28 -0
  71. package/packs/audio-core/hooks/lib/realtime-checks.mjs +56 -0
  72. package/packs/audio-core/hooks/param-id-lock.mjs +129 -0
  73. package/packs/audio-core/hooks/realtime-guard.mjs +67 -0
  74. package/packs/audio-core/pack.json +187 -0
  75. package/packs/audio-core/rules/audio-thread-realtime-safe.md +27 -0
  76. package/packs/audio-core/rules/audio-ui-thread-handoff.md +21 -0
  77. package/packs/audio-core/rules/boundary-tests-cross-the-boundary.md +16 -0
  78. package/packs/audio-core/rules/build-flags-safe.md +20 -0
  79. package/packs/audio-core/rules/cached-parameter-pointers.md +28 -0
  80. package/packs/audio-core/rules/clang-tidy-core-guidelines.md +21 -0
  81. package/packs/audio-core/rules/control-reaches-every-surface.md +23 -0
  82. package/packs/audio-core/rules/cpu-worst-case-per-block.md +26 -0
  83. package/packs/audio-core/rules/dc-block-after-asymmetry.md +22 -0
  84. package/packs/audio-core/rules/discrete-params-snap.md +19 -0
  85. package/packs/audio-core/rules/double-where-precision-matters.md +20 -0
  86. package/packs/audio-core/rules/filters-stable-under-modulation.md +29 -0
  87. package/packs/audio-core/rules/host-parameters-at-scale.md +24 -0
  88. package/packs/audio-core/rules/house-control-behaviours.md +34 -0
  89. package/packs/audio-core/rules/math-domain-guards.md +19 -0
  90. package/packs/audio-core/rules/modulated-delay-interpolation.md +22 -0
  91. package/packs/audio-core/rules/multiband-phase-coherent.md +22 -0
  92. package/packs/audio-core/rules/nonlinear-stages-antialiased.md +28 -0
  93. package/packs/audio-core/rules/note-ledger-and-pedals.md +22 -0
  94. package/packs/audio-core/rules/one-formula-per-value.md +20 -0
  95. package/packs/audio-core/rules/optimisations-are-null-tested.md +23 -0
  96. package/packs/audio-core/rules/oscillators-bandlimited.md +23 -0
  97. package/packs/audio-core/rules/output-limiter.md +23 -0
  98. package/packs/audio-core/rules/parameter-ids-never-change.md +20 -0
  99. package/packs/audio-core/rules/params-and-state-thread-safe.md +19 -0
  100. package/packs/audio-core/rules/params-snapshot-per-block.md +21 -0
  101. package/packs/audio-core/rules/patch-excludes-performance-controls.md +18 -0
  102. package/packs/audio-core/rules/per-sample-code-inlinable.md +22 -0
  103. package/packs/audio-core/rules/prepare-is-repeatable.md +23 -0
  104. package/packs/audio-core/rules/recursive-state-nan-guard.md +20 -0
  105. package/packs/audio-core/rules/reverb-loop-gain-bounded.md +24 -0
  106. package/packs/audio-core/rules/sample-accurate-midi.md +22 -0
  107. package/packs/audio-core/rules/sample-rate-and-block-size-from-host.md +23 -0
  108. package/packs/audio-core/rules/scoped-no-denormals.md +26 -0
  109. package/packs/audio-core/rules/smooth-continuous-parameters.md +22 -0
  110. package/packs/audio-core/rules/state-load-versioned-and-safe.md +22 -0
  111. package/packs/audio-core/rules/straight-on-and-aligned.md +21 -0
  112. package/packs/audio-core/rules/ui-matches-reference-look.md +21 -0
  113. package/packs/audio-core/rules/undo-one-gesture-one-step.md +21 -0
  114. package/packs/audio-core/rules/voice-steal-fades.md +21 -0
  115. package/packs/audio-core/rules/voice-sum-headroom.md +20 -0
  116. package/packs/audio-core/skills/analyse-reference-look/SKILL.md +21 -0
  117. package/packs/audio-core/skills/copy-and-prove/SKILL.md +98 -0
  118. package/packs/audio-core/skills/juce-realtime-audit/SKILL.md +22 -0
  119. package/packs/audio-core/skills/measure-tone/SKILL.md +20 -0
  120. package/packs/audio-core/skills/new-panel-control/SKILL.md +15 -0
  121. package/packs/audio-core/skills/prove-control/SKILL.md +23 -0
  122. package/packs/audio-core/skills/trace-parameter/SKILL.md +29 -0
  123. package/packs/audio-core/tools/lib/spectrum.mjs +112 -0
  124. package/packs/audio-core/tools/lib/wav.mjs +41 -0
  125. package/packs/audio-core/tools/tone-report.mjs +47 -0
  126. package/packs/base/checks/field-map-over-if-runs.json +25 -0
  127. package/packs/base/checks/lookup-over-if-chains.json +25 -0
  128. package/packs/base/checks/lookup-over-ternary-chains.json +20 -0
  129. package/packs/base/checks/no-code-after-midline-comment.json +12 -0
  130. package/packs/base/checks/one-walk-per-template.json +23 -0
  131. package/packs/base/checks/stub-reports-success.json +31 -0
  132. package/packs/base/checks/test-skip-on-failed-setup.json +17 -0
  133. package/packs/base/hooks/brief-guard.mjs +96 -0
  134. package/packs/base/hooks/code-shape.mjs +95 -0
  135. package/packs/base/hooks/dispatch-once.mjs +87 -0
  136. package/packs/base/hooks/file-size-guard.mjs +61 -0
  137. package/packs/base/hooks/folder-law.mjs +74 -0
  138. package/packs/base/hooks/git-guard.mjs +289 -0
  139. package/packs/base/hooks/lesson-checks.mjs +174 -0
  140. package/packs/base/hooks/lib/apply-edit.mjs +20 -0
  141. package/packs/base/hooks/lib/code-shapes.mjs +137 -0
  142. package/packs/base/hooks/lib/content.mjs +14 -0
  143. package/packs/base/hooks/lib/cpp-scan.mjs +94 -0
  144. package/packs/base/hooks/lib/dup-index.mjs +199 -0
  145. package/packs/base/hooks/lib/dup.mjs +127 -0
  146. package/packs/base/hooks/lib/elements.mjs +87 -0
  147. package/packs/base/hooks/lib/event-log.mjs +67 -0
  148. package/packs/base/hooks/lib/function-shapes.mjs +90 -0
  149. package/packs/base/hooks/lib/git-adds.mjs +20 -0
  150. package/packs/base/hooks/lib/git-guard-selftest.mjs +99 -0
  151. package/packs/base/hooks/lib/glob.mjs +33 -0
  152. package/packs/base/hooks/lib/hook-log.mjs +100 -0
  153. package/packs/base/hooks/lib/house.py +77 -0
  154. package/packs/base/hooks/lib/languages.mjs +66 -0
  155. package/packs/base/hooks/lib/layout.mjs +54 -0
  156. package/packs/base/hooks/lib/making-check-selftest.mjs +109 -0
  157. package/packs/base/hooks/lib/near-copies.mjs +76 -0
  158. package/packs/base/hooks/lib/program-read.mjs +196 -0
  159. package/packs/base/hooks/lib/program-writes.mjs +177 -0
  160. package/packs/base/hooks/lib/project.mjs +81 -0
  161. package/packs/base/hooks/lib/prose.mjs +11 -0
  162. package/packs/base/hooks/lib/pushed.mjs +201 -0
  163. package/packs/base/hooks/lib/repo-index.mjs +52 -0
  164. package/packs/base/hooks/lib/secret-patterns.mjs +18 -0
  165. package/packs/base/hooks/lib/selftest.mjs +45 -0
  166. package/packs/base/hooks/lib/shape-code.mjs +126 -0
  167. package/packs/base/hooks/lib/shape.mjs +294 -0
  168. package/packs/base/hooks/lib/shell-writes-selftest.mjs +65 -0
  169. package/packs/base/hooks/lib/shell-writes.mjs +293 -0
  170. package/packs/base/hooks/lib/turn.mjs +81 -0
  171. package/packs/base/hooks/lib/writes.mjs +71 -0
  172. package/packs/base/hooks/making-check.mjs +243 -0
  173. package/packs/base/hooks/making.mjs +106 -0
  174. package/packs/base/hooks/once-only.mjs +150 -0
  175. package/packs/base/hooks/placement-law.mjs +84 -0
  176. package/packs/base/hooks/repo-litter.mjs +75 -0
  177. package/packs/base/hooks/reuse-hint.mjs +75 -0
  178. package/packs/base/hooks/run-hooks.mjs +132 -0
  179. package/packs/base/hooks/secrets-guard.mjs +99 -0
  180. package/packs/base/hooks/shape-law.mjs +133 -0
  181. package/packs/base/hooks/suite-once.mjs +80 -0
  182. package/packs/base/hooks/template-law.mjs +148 -0
  183. package/packs/base/hooks/untrusted-boundary.mjs +53 -0
  184. package/packs/base/pack.json +214 -0
  185. package/packs/base/rules/a-control-is-seen-to-fire.md +27 -0
  186. package/packs/base/rules/behaviour-lives-with-its-kind.md +51 -0
  187. package/packs/base/rules/bug-fix-starts-red.md +25 -0
  188. package/packs/base/rules/field-map-over-if-runs.md +47 -0
  189. package/packs/base/rules/finished-work-lands.md +17 -0
  190. package/packs/base/rules/git-right-first-time.md +19 -0
  191. package/packs/base/rules/instances-by-index-identities-by-id.md +54 -0
  192. package/packs/base/rules/lookup-over-if-chains.md +49 -0
  193. package/packs/base/rules/making-line-first.md +14 -0
  194. package/packs/base/rules/open-items-tagged.md +17 -0
  195. package/packs/base/rules/plan-and-logs.md +22 -0
  196. package/packs/base/rules/references-use-anchors.md +19 -0
  197. package/packs/base/rules/refusals-are-judged.md +18 -0
  198. package/packs/base/rules/reuse-before-writing.md +15 -0
  199. package/packs/base/rules/secrets-never-committed.md +16 -0
  200. package/packs/base/rules/skill-writing.md +23 -0
  201. package/packs/base/rules/split-before-the-limit.md +14 -0
  202. package/packs/base/rules/subagent-dispatch.md +26 -0
  203. package/packs/base/rules/test-only-what-changed.md +17 -0
  204. package/packs/base/rules/test-the-template-once.md +22 -0
  205. package/packs/base/rules/untrusted-content-boundary.md +15 -0
  206. package/packs/base/skills/add-lesson-check/SKILL.md +26 -0
  207. package/packs/base/skills/fix-from-scan/SKILL.md +25 -0
  208. package/packs/base/skills/land-branch/SKILL.md +24 -0
  209. package/packs/base/skills/make-it-a-template/SKILL.md +23 -0
  210. package/packs/base/skills/pdf-to-md/SKILL.md +25 -0
  211. package/packs/base/skills/pick-tests/SKILL.md +20 -0
  212. package/packs/base/skills/pressure-test-skill/SKILL.md +23 -0
  213. package/packs/base/skills/prove-instances-identical/SKILL.md +37 -0
  214. package/packs/base/tools/shape-symmetry-selftest.mjs +66 -0
  215. package/packs/base/tools/shape-symmetry.mjs +178 -0
  216. package/packs/base/tools/test-verdict.mjs +75 -0
  217. package/packs/ci/checks/ci-permissions-stated.json +18 -0
  218. package/packs/ci/checks/ci-tools-pinned.json +14 -0
  219. package/packs/ci/pack.json +21 -0
  220. package/packs/ci/rules/ci-covers-what-ships.md +20 -0
  221. package/packs/ci/rules/generated-files-have-no-diff.md +15 -0
  222. package/packs/content-site/checks/captcha-is-not-constant.json +27 -0
  223. package/packs/content-site/checks/img-has-size.json +20 -0
  224. package/packs/content-site/checks/page-head-complete.json +26 -0
  225. package/packs/content-site/pack.json +22 -0
  226. package/packs/content-site/rules/content-has-one-source.md +23 -0
  227. package/packs/content-site/rules/media-is-sized.md +24 -0
  228. package/packs/content-site/rules/page-head-is-complete.md +26 -0
  229. package/packs/content-site/rules/public-forms-are-defended.md +27 -0
  230. package/packs/content-site/skills/publish-a-page/SKILL.md +21 -0
  231. package/packs/cpp/checks/cpp-clamp-before-cast.json +16 -0
  232. package/packs/cpp/checks/cpp-find-with-the-library.json +12 -0
  233. package/packs/cpp/checks/cpp-hardened-test-build.json +18 -0
  234. package/packs/cpp/checks/cpp-m-pi-not-standard.json +23 -0
  235. package/packs/cpp/checks/cpp-no-atoi.json +16 -0
  236. package/packs/cpp/checks/cpp-no-const-cast.json +16 -0
  237. package/packs/cpp/checks/cpp-no-float-loop-counter.json +16 -0
  238. package/packs/cpp/checks/cpp-no-getenv-in-product.json +22 -0
  239. package/packs/cpp/checks/cpp-no-mutable-global.json +20 -0
  240. package/packs/cpp/checks/cpp-no-mutable-local-static.json +23 -0
  241. package/packs/cpp/checks/cpp-no-unchecked-fwrite.json +17 -0
  242. package/packs/cpp/checks/cpp-no-using-namespace-in-header.json +19 -0
  243. package/packs/cpp/checks/cpp-no-zero-size-array.json +23 -0
  244. package/packs/cpp/checks/cpp-numbers-pi.json +16 -0
  245. package/packs/cpp/pack.json +22 -0
  246. package/packs/cpp/rules/cpp-absent-and-failed-are-types.md +24 -0
  247. package/packs/cpp/rules/cpp-builds-everywhere.md +26 -0
  248. package/packs/cpp/rules/cpp-faults-only-in-the-test-build.md +21 -0
  249. package/packs/cpp/rules/cpp-find-with-the-library.md +19 -0
  250. package/packs/cpp/rules/cpp-gates-share-one-reader.md +22 -0
  251. package/packs/cpp/rules/cpp-headers-declare.md +22 -0
  252. package/packs/cpp/rules/cpp-numbers-and-casts.md +22 -0
  253. package/packs/cpp/rules/cpp-repeats-become-templates.md +33 -0
  254. package/packs/cpp/rules/cpp-static-analysis-runs.md +22 -0
  255. package/packs/cpp/rules/cpp-thread-contracts-are-code.md +23 -0
  256. package/packs/cpp/skills/cpp-extract-template/SKILL.md +38 -0
  257. package/packs/docker/checks/alpine-with-native-build.json +13 -0
  258. package/packs/docker/checks/compose-db-needs-auth.json +14 -0
  259. package/packs/docker/checks/compose-image-pinned.json +14 -0
  260. package/packs/docker/checks/compose-no-hardcoded-ip.json +12 -0
  261. package/packs/docker/checks/compose-no-host-bind-for-data.json +18 -0
  262. package/packs/docker/checks/compose-no-plaintext-secret.json +13 -0
  263. package/packs/docker/checks/compose-no-swarm-ignored-keys.json +13 -0
  264. package/packs/docker/checks/compose-overlay-not-bridge.json +13 -0
  265. package/packs/docker/checks/compose-service-needs-healthcheck.json +11 -0
  266. package/packs/docker/checks/compose-service-needs-init.json +11 -0
  267. package/packs/docker/checks/copy-needs-chown-with-user.json +17 -0
  268. package/packs/docker/checks/copy-source-before-deps.json +13 -0
  269. package/packs/docker/checks/docker-exec-form.json +16 -0
  270. package/packs/docker/checks/dockerfile-needs-healthcheck.json +17 -0
  271. package/packs/docker/checks/dockerfile-needs-user.json +21 -0
  272. package/packs/docker/checks/dockerignore-has-the-basics.json +21 -0
  273. package/packs/docker/checks/gitattributes-forces-lf.json +17 -0
  274. package/packs/docker/checks/health-checks-nothing.json +25 -0
  275. package/packs/docker/checks/no-crlf-in-scripts.json +15 -0
  276. package/packs/docker/checks/no-latest-base.json +13 -0
  277. package/packs/docker/checks/no-secret-in-image.json +13 -0
  278. package/packs/docker/checks/no-sensitive-file-copy.json +13 -0
  279. package/packs/docker/checks/node-env-before-install.json +13 -0
  280. package/packs/docker/checks/npm-ci-not-install.json +13 -0
  281. package/packs/docker/pack.json +46 -0
  282. package/packs/docker/rules/compose-pinned-and-closed.md +21 -0
  283. package/packs/docker/rules/compose-swarm-safe.md +26 -0
  284. package/packs/docker/rules/docker-exec-form.md +19 -0
  285. package/packs/docker/rules/dockerfile-multistage.md +13 -0
  286. package/packs/docker/rules/dockerfile-production.md +25 -0
  287. package/packs/docker/skills/docker-diagnose/SKILL.md +23 -0
  288. package/packs/dynamic-data/checks/draft-on-the-server.json +27 -0
  289. package/packs/dynamic-data/checks/guard-does-its-job.json +28 -0
  290. package/packs/dynamic-data/checks/key-is-not-a-display-name.json +28 -0
  291. package/packs/dynamic-data/checks/no-code-from-data.json +29 -0
  292. package/packs/dynamic-data/checks/no-collection-from-request.json +27 -0
  293. package/packs/dynamic-data/checks/no-pipeline-from-stored-text.json +27 -0
  294. package/packs/dynamic-data/checks/no-regexp-from-stored-config.json +27 -0
  295. package/packs/dynamic-data/checks/no-template-from-stored-text.json +27 -0
  296. package/packs/dynamic-data/checks/save-takes-named-paths.json +27 -0
  297. package/packs/dynamic-data/pack.json +23 -0
  298. package/packs/dynamic-data/rules/a-list-is-a-saved-query.md +23 -0
  299. package/packs/dynamic-data/rules/definitions-are-validated-data.md +24 -0
  300. package/packs/dynamic-data/rules/every-dynamic-surface-has-a-boundary.md +29 -0
  301. package/packs/dynamic-data/rules/fields-have-owners.md +22 -0
  302. package/packs/dynamic-data/rules/imports-drop-nothing.md +26 -0
  303. package/packs/dynamic-data/rules/one-definition-many-surfaces.md +24 -0
  304. package/packs/dynamic-data/rules/one-fact-one-place.md +28 -0
  305. package/packs/dynamic-data/rules/rules-live-in-the-engine.md +29 -0
  306. package/packs/dynamic-data/rules/saves-are-patches.md +28 -0
  307. package/packs/dynamic-data/rules/tenant-costs-one-document.md +22 -0
  308. package/packs/dynamic-data/skills/design-a-definition/SKILL.md +24 -0
  309. package/packs/fastify/checks/api-routes-versioned.json +28 -0
  310. package/packs/fastify/checks/cookie-host-prefix.json +24 -0
  311. package/packs/fastify/checks/hijack-needs-try.json +28 -0
  312. package/packs/fastify/checks/no-cast-at-route-boundary.json +24 -0
  313. package/packs/fastify/checks/no-db-in-route-file.json +28 -0
  314. package/packs/fastify/checks/no-err-message-to-client.json +24 -0
  315. package/packs/fastify/checks/no-regexp-from-input.json +24 -0
  316. package/packs/fastify/checks/no-trust-proxy-true.json +25 -0
  317. package/packs/fastify/checks/one-error-body.json +26 -0
  318. package/packs/fastify/checks/origin-from-config-not-host.json +31 -0
  319. package/packs/fastify/checks/password-needs-slow-hash.json +30 -0
  320. package/packs/fastify/checks/sec-headers-present.json +28 -0
  321. package/packs/fastify/checks/secrets-compared-constant-time.json +24 -0
  322. package/packs/fastify/checks/sse-needs-error-listener.json +28 -0
  323. package/packs/fastify/checks/user-bytes-need-disposition.json +29 -0
  324. package/packs/fastify/pack.json +41 -0
  325. package/packs/fastify/rules/credentials-and-input.md +23 -0
  326. package/packs/fastify/rules/security-one-switch.md +28 -0
  327. package/packs/fastify/rules/streams-and-hijacks.md +22 -0
  328. package/packs/fastify/rules/tests-use-inject.md +13 -0
  329. package/packs/fastify/rules/three-layers.md +20 -0
  330. package/packs/fastify/rules/trust-config-not-headers.md +24 -0
  331. package/packs/full-stack/checks/no-express-no-vite.json +23 -0
  332. package/packs/full-stack/hooks/stack-guard.mjs +90 -0
  333. package/packs/full-stack/pack.json +76 -0
  334. package/packs/full-stack/rules/stack-is-fastify-and-nextjs.md +20 -0
  335. package/packs/go/checks/go-exec-result-ignored.json +15 -0
  336. package/packs/go/checks/go-unmarshal-error-ignored.json +15 -0
  337. package/packs/go/pack.json +21 -0
  338. package/packs/go/rules/go-errors-are-handled.md +22 -0
  339. package/packs/gpu-painter/checks/dawn-backends-and-validation.json +9 -0
  340. package/packs/gpu-painter/checks/dawn-no-spontaneous.json +10 -0
  341. package/packs/gpu-painter/checks/dawn-present-on-render-thread.json +17 -0
  342. package/packs/gpu-painter/checks/gpu-no-frame-stalls.json +12 -0
  343. package/packs/gpu-painter/checks/no-opengl-link.json +11 -0
  344. package/packs/gpu-painter/checks/no-opengl.json +13 -0
  345. package/packs/gpu-painter/hooks/browser-guard.py +196 -0
  346. package/packs/gpu-painter/pack.json +91 -0
  347. package/packs/gpu-painter/rules/dawn-build-and-shaders.md +27 -0
  348. package/packs/gpu-painter/rules/dawn-device-and-render-thread.md +26 -0
  349. package/packs/gpu-painter/rules/gpu-antialiasing.md +20 -0
  350. package/packs/gpu-painter/rules/gpu-blend-order.md +22 -0
  351. package/packs/gpu-painter/rules/gpu-bloom.md +20 -0
  352. package/packs/gpu-painter/rules/gpu-frame-budget.md +25 -0
  353. package/packs/gpu-painter/rules/gpu-frame-pacing-and-power.md +27 -0
  354. package/packs/gpu-painter/rules/gpu-frame-work.md +30 -0
  355. package/packs/gpu-painter/rules/gpu-golden-images.md +21 -0
  356. package/packs/gpu-painter/rules/gpu-hdr-and-tonemap.md +23 -0
  357. package/packs/gpu-painter/rules/gpu-picking-on-cpu.md +19 -0
  358. package/packs/gpu-painter/rules/gpu-render-lifecycle.md +25 -0
  359. package/packs/gpu-painter/rules/gpu-text-atlas.md +24 -0
  360. package/packs/gpu-painter/rules/gpu-travellers-from-snapshot.md +24 -0
  361. package/packs/gpu-painter/rules/hover-every-pressable.md +25 -0
  362. package/packs/gpu-painter/skills/gpu-capture/SKILL.md +15 -0
  363. package/packs/gpu-painter/skills/gpu-frame-bench/SKILL.md +14 -0
  364. package/packs/gpu-painter/skills/gpu-golden-check/SKILL.md +13 -0
  365. package/packs/gpu-painter/skills/gpu-golden-update/SKILL.md +16 -0
  366. package/packs/gpu-painter/skills/gpu-lifecycle-stress/SKILL.md +15 -0
  367. package/packs/gpu-painter/skills/hover-state/SKILL.md +33 -0
  368. package/packs/hook-proof/checks/hook-catch-must-not-allow.json +16 -0
  369. package/packs/hook-proof/checks/hook-command-no-pipe.json +16 -0
  370. package/packs/hook-proof/checks/hook-exit-1-does-not-block.json +17 -0
  371. package/packs/hook-proof/checks/hook-no-or-true.json +18 -0
  372. package/packs/hook-proof/checks/hook-refusal-on-stderr.json +17 -0
  373. package/packs/hook-proof/pack.json +38 -0
  374. package/packs/hook-proof/rules/a-refusal-is-exit-2.md +28 -0
  375. package/packs/hook-proof/skills/prove-a-hook/SKILL.md +21 -0
  376. package/packs/host-agent/checks/file-path-from-param.json +27 -0
  377. package/packs/host-agent/checks/integrity-check-optional.json +27 -0
  378. package/packs/host-agent/checks/quoted-value-into-config.json +24 -0
  379. package/packs/host-agent/checks/secret-on-argv.json +28 -0
  380. package/packs/host-agent/checks/ssh-verifies-host-key.json +27 -0
  381. package/packs/host-agent/checks/system-file-written-in-place.json +26 -0
  382. package/packs/host-agent/checks/tmp-path-predictable.json +27 -0
  383. package/packs/host-agent/pack.json +22 -0
  384. package/packs/host-agent/rules/root-on-other-machines.md +27 -0
  385. package/packs/html-ui/checks/email-html-escapes.json +25 -0
  386. package/packs/html-ui/checks/external-link-rel.json +21 -0
  387. package/packs/html-ui/checks/no-duplicate-escape.json +26 -0
  388. package/packs/html-ui/checks/no-inline-client-script.json +21 -0
  389. package/packs/html-ui/checks/no-inline-style.json +23 -0
  390. package/packs/html-ui/pack.json +33 -0
  391. package/packs/html-ui/rules/email-html-escapes.md +19 -0
  392. package/packs/html-ui/rules/server-html-escapes-everything.md +22 -0
  393. package/packs/http-api/checks/api-path-versioned.json +31 -0
  394. package/packs/http-api/checks/authz-from-request-body.json +26 -0
  395. package/packs/http-api/checks/client-calls-a-version.json +28 -0
  396. package/packs/http-api/checks/client-ip-not-leftmost-xff.json +28 -0
  397. package/packs/http-api/checks/cors-needs-origin.json +26 -0
  398. package/packs/http-api/checks/csp-not-switched-off.json +28 -0
  399. package/packs/http-api/checks/debug-route-not-shipped.json +26 -0
  400. package/packs/http-api/checks/encrypted-name-plaintext-value.json +26 -0
  401. package/packs/http-api/checks/err-text-stays-server-side.json +27 -0
  402. package/packs/http-api/checks/failure-is-not-empty.json +28 -0
  403. package/packs/http-api/checks/gate-is-not-a-todo.json +27 -0
  404. package/packs/http-api/checks/guard-fails-open.json +28 -0
  405. package/packs/http-api/checks/hmac-over-reserialised-body.json +26 -0
  406. package/packs/http-api/checks/jwt-verify-pins-algorithm.json +26 -0
  407. package/packs/http-api/checks/middleware-skips-without-user.json +26 -0
  408. package/packs/http-api/checks/next-api-route-versioned.json +47 -0
  409. package/packs/http-api/checks/no-security-off-switch.json +28 -0
  410. package/packs/http-api/checks/oauth-state-signed.json +26 -0
  411. package/packs/http-api/checks/one-time-code-compared-raw.json +26 -0
  412. package/packs/http-api/checks/query-cast-is-not-validation.json +28 -0
  413. package/packs/http-api/checks/queue-action-from-client.json +26 -0
  414. package/packs/http-api/checks/rate-limit-one-module.json +28 -0
  415. package/packs/http-api/checks/role-checked-in-one-guard.json +27 -0
  416. package/packs/http-api/checks/route-body-needs-schema.json +31 -0
  417. package/packs/http-api/checks/route-scopes-to-the-caller.json +31 -0
  418. package/packs/http-api/checks/secret-compared-constant-time-any.json +28 -0
  419. package/packs/http-api/checks/secret-in-job-record.json +27 -0
  420. package/packs/http-api/checks/server-fetches-tenant-url.json +30 -0
  421. package/packs/http-api/checks/short-code-needs-limit.json +26 -0
  422. package/packs/http-api/checks/user-url-through-safe-fetch.json +28 -0
  423. package/packs/http-api/checks/webhook-dedupes-event-id.json +30 -0
  424. package/packs/http-api/pack.json +45 -0
  425. package/packs/http-api/rules/adapters-one-db-gateway.md +18 -0
  426. package/packs/http-api/rules/apis-are-versioned.md +27 -0
  427. package/packs/http-api/rules/credentials-handled-safely.md +22 -0
  428. package/packs/http-api/rules/handlers-own-the-work.md +17 -0
  429. package/packs/http-api/rules/health-and-correlation.md +17 -0
  430. package/packs/http-api/rules/one-error-contract.md +17 -0
  431. package/packs/http-api/rules/routes-are-thin.md +17 -0
  432. package/packs/http-api/rules/routes-scope-to-the-caller.md +26 -0
  433. package/packs/http-api/rules/routes-validate-and-answer.md +25 -0
  434. package/packs/http-api/skills/change-an-api/SKILL.md +20 -0
  435. package/packs/http-api/skills/secure-a-route/SKILL.md +21 -0
  436. package/packs/instrument-shell/checks/no-raw-struct-blob.json +23 -0
  437. package/packs/instrument-shell/pack.json +22 -0
  438. package/packs/instrument-shell/rules/fold-keeps-every-route.md +24 -0
  439. package/packs/instrument-shell/rules/quiet-announces-itself.md +22 -0
  440. package/packs/instrument-shell/rules/render-the-extremes.md +25 -0
  441. package/packs/instrument-shell/rules/seams-are-declared.md +27 -0
  442. package/packs/instrument-shell/rules/session-blob-append-only.md +25 -0
  443. package/packs/instrument-shell/skills/gates-from-commit-one/SKILL.md +20 -0
  444. package/packs/instrument-shell/skills/hit-the-painted-control/SKILL.md +18 -0
  445. package/packs/js-ts/checks/async-callback-unguarded.json +26 -0
  446. package/packs/js-ts/checks/background-loop-needs-stop.json +28 -0
  447. package/packs/js-ts/checks/child-process-error-handler.json +28 -0
  448. package/packs/js-ts/checks/entry-registers-shutdown.json +31 -0
  449. package/packs/js-ts/checks/fetch-needs-timeout.json +30 -0
  450. package/packs/js-ts/checks/job-only-in-memory.json +28 -0
  451. package/packs/js-ts/checks/json-only-through-helper.json +29 -0
  452. package/packs/js-ts/checks/line-under-200-chars.json +34 -0
  453. package/packs/js-ts/checks/localhost-default-in-server.json +29 -0
  454. package/packs/js-ts/checks/no-any.json +27 -0
  455. package/packs/js-ts/checks/no-cast-escape-hatches.json +24 -0
  456. package/packs/js-ts/checks/no-console-in-app.json +31 -0
  457. package/packs/js-ts/checks/no-dynamic-import-node-builtin.json +25 -0
  458. package/packs/js-ts/checks/no-inline-binary.json +20 -0
  459. package/packs/js-ts/checks/no-inline-zod-outside-schemas.json +27 -0
  460. package/packs/js-ts/checks/no-local-sleep.json +25 -0
  461. package/packs/js-ts/checks/no-nested-ternary.json +20 -0
  462. package/packs/js-ts/checks/no-secret-in-log.json +24 -0
  463. package/packs/js-ts/checks/no-shell-string-interpolation.json +24 -0
  464. package/packs/js-ts/checks/no-swallowed-errors.json +25 -0
  465. package/packs/js-ts/checks/no-ts-enum.json +20 -0
  466. package/packs/js-ts/checks/process-env-only-in-config.json +31 -0
  467. package/packs/js-ts/checks/race-leaves-work-running.json +23 -0
  468. package/packs/js-ts/checks/reject-as-catch-all-exists.json +24 -0
  469. package/packs/js-ts/checks/secret-has-no-fallback.json +24 -0
  470. package/packs/js-ts/checks/secret-needs-crypto-random.json +24 -0
  471. package/packs/js-ts/checks/server-close-awaited.json +27 -0
  472. package/packs/js-ts/checks/session-user-typed-once.json +24 -0
  473. package/packs/js-ts/checks/switch-is-a-table.json +24 -0
  474. package/packs/js-ts/checks/test-imports-the-source.json +19 -0
  475. package/packs/js-ts/checks/test-name-says-behaviour.json +16 -0
  476. package/packs/js-ts/checks/tsconfig-flags.json +21 -0
  477. package/packs/js-ts/checks/void-needs-catch.json +24 -0
  478. package/packs/js-ts/checks/zod-string-needs-max.json +25 -0
  479. package/packs/js-ts/checks/zod-v4-formats.json +23 -0
  480. package/packs/js-ts/pack.json +84 -0
  481. package/packs/js-ts/rules/await-handled-at-a-boundary.md +66 -0
  482. package/packs/js-ts/rules/env-through-config.md +36 -0
  483. package/packs/js-ts/rules/errors-never-swallowed.md +33 -0
  484. package/packs/js-ts/rules/files-under-300-lines.md +18 -0
  485. package/packs/js-ts/rules/guard-clauses-over-nesting.md +34 -0
  486. package/packs/js-ts/rules/js-repeats-become-templates.md +26 -0
  487. package/packs/js-ts/rules/json-only-through-one-helper.md +62 -0
  488. package/packs/js-ts/rules/named-constants-not-magic-numbers.md +34 -0
  489. package/packs/js-ts/rules/no-any.md +34 -0
  490. package/packs/js-ts/rules/no-console.md +30 -0
  491. package/packs/js-ts/rules/no-floating-promises.md +31 -0
  492. package/packs/js-ts/rules/no-param-mutation.md +28 -0
  493. package/packs/js-ts/rules/no-unsafe-assertions.md +30 -0
  494. package/packs/js-ts/rules/one-logger.md +24 -0
  495. package/packs/js-ts/rules/outbound-calls-have-a-limit.md +20 -0
  496. package/packs/js-ts/rules/parallel-independent-awaits.md +29 -0
  497. package/packs/js-ts/rules/process-lifecycle.md +47 -0
  498. package/packs/js-ts/rules/schema-single-source-of-truth.md +36 -0
  499. package/packs/js-ts/rules/secrets-stay-secret.md +22 -0
  500. package/packs/js-ts/rules/small-functions.md +20 -0
  501. package/packs/js-ts/rules/test-names-describe-behavior.md +28 -0
  502. package/packs/js-ts/rules/tests-can-fail.md +19 -0
  503. package/packs/js-ts/rules/tsconfig-strict.md +32 -0
  504. package/packs/js-ts/rules/typed-exports.md +27 -0
  505. package/packs/js-ts/rules/types-once-at-the-edge.md +18 -0
  506. package/packs/js-ts/rules/unions-over-enums.md +29 -0
  507. package/packs/js-ts/rules/zod-at-route-boundaries.md +40 -0
  508. package/packs/midi/checks/active-sensing-no-pulse.json +24 -0
  509. package/packs/midi/checks/clock-not-at-sample-zero.json +23 -0
  510. package/packs/midi/checks/midi-realtime-first.json +27 -0
  511. package/packs/midi/checks/no-tempo-writeback.json +23 -0
  512. package/packs/midi/checks/position-not-integrated.json +25 -0
  513. package/packs/midi/checks/stub-playhead-advances.json +27 -0
  514. package/packs/midi/checks/sysex-length-literal.json +23 -0
  515. package/packs/midi/checks/sysex-not-on-audio.json +24 -0
  516. package/packs/midi/checks/sysex-survives-realtime.json +27 -0
  517. package/packs/midi/pack.json +22 -0
  518. package/packs/midi/rules/clock-is-a-pulse-stream.md +30 -0
  519. package/packs/midi/rules/imports-count-every-loss.md +25 -0
  520. package/packs/midi/rules/measure-the-clock-in-audio.md +30 -0
  521. package/packs/midi/rules/sync-is-a-mode.md +29 -0
  522. package/packs/midi/rules/sysex-is-a-record.md +29 -0
  523. package/packs/midi/skills/clock-probe/SKILL.md +23 -0
  524. package/packs/midi/skills/clock-probe/clock-law.md +417 -0
  525. package/packs/midi/skills/does-it-sync/SKILL.md +19 -0
  526. package/packs/mongo/checks/bulk-over-many.json +28 -0
  527. package/packs/mongo/checks/created-at-immutable.json +25 -0
  528. package/packs/mongo/checks/driver-outside-gateway.json +24 -0
  529. package/packs/mongo/checks/key-lookup-is-hashed.json +24 -0
  530. package/packs/mongo/checks/mongoclient-cached-and-named.json +34 -0
  531. package/packs/mongo/checks/mongoclient-outside-gateway.json +24 -0
  532. package/packs/mongo/checks/no-count-plus-one-ids.json +25 -0
  533. package/packs/mongo/checks/no-db-write-in-loop.json +25 -0
  534. package/packs/mongo/checks/no-drop-in-code.json +27 -0
  535. package/packs/mongo/checks/no-empty-deletemany.json +26 -0
  536. package/packs/mongo/checks/no-find-reads.json +26 -0
  537. package/packs/mongo/checks/no-input-spread-into-write.json +24 -0
  538. package/packs/mongo/checks/no-mongoose.json +23 -0
  539. package/packs/mongo/checks/no-negation-delete.json +26 -0
  540. package/packs/mongo/checks/no-non-null-after-findone.json +25 -0
  541. package/packs/mongo/checks/objectid-equals.json +26 -0
  542. package/packs/mongo/checks/update-then-reread.json +24 -0
  543. package/packs/mongo/checks/watch-not-poll.json +25 -0
  544. package/packs/mongo/pack.json +52 -0
  545. package/packs/mongo/rules/deletes-name-what-dies.md +21 -0
  546. package/packs/mongo/rules/driver-only-in-gateway.md +26 -0
  547. package/packs/mongo/rules/keys-hashed-input-picked.md +21 -0
  548. package/packs/mongo/rules/one-client-one-pool.md +32 -0
  549. package/packs/mongo/rules/reads-aggregate-writes-bulk.md +25 -0
  550. package/packs/mongo/rules/writes-are-atomic.md +27 -0
  551. package/packs/multi-tenant/checks/role-sees-all-tenants.json +26 -0
  552. package/packs/multi-tenant/checks/tenant-filter-from-url.json +25 -0
  553. package/packs/multi-tenant/pack.json +22 -0
  554. package/packs/multi-tenant/rules/no-role-crosses-a-tenant.md +21 -0
  555. package/packs/multi-tenant/skills/prove-tenant-isolation/SKILL.md +19 -0
  556. package/packs/nginx/checks/modsec-no-blanket-off.json +16 -0
  557. package/packs/nginx/checks/nginx-csp-no-unsafe.json +15 -0
  558. package/packs/nginx/checks/nginx-headers-always.json +15 -0
  559. package/packs/nginx/checks/nginx-keepalive-http11.json +20 -0
  560. package/packs/nginx/checks/nginx-logs-to-stdout.json +15 -0
  561. package/packs/nginx/checks/nginx-no-crlf.json +17 -0
  562. package/packs/nginx/checks/nginx-resolver-ttl.json +19 -0
  563. package/packs/nginx/pack.json +43 -0
  564. package/packs/nginx/rules/modsecurity-tuning.md +22 -0
  565. package/packs/nginx/rules/nginx-production.md +26 -0
  566. package/packs/nginx/skills/waf-rollout/SKILL.md +20 -0
  567. package/packs/python/checks/py-no-bare-except.json +18 -0
  568. package/packs/python/checks/py-no-eval.json +18 -0
  569. package/packs/python/checks/py-no-mutable-default.json +18 -0
  570. package/packs/python/checks/py-no-shell-true.json +18 -0
  571. package/packs/python/checks/py-no-star-import.json +18 -0
  572. package/packs/python/checks/py-no-swallowed-exception.json +18 -0
  573. package/packs/python/checks/py-none-by-is.json +18 -0
  574. package/packs/python/checks/py-open-with-with.json +18 -0
  575. package/packs/python/checks/py-requests-timeout.json +18 -0
  576. package/packs/python/checks/py-subprocess-output-checked.json +18 -0
  577. package/packs/python/checks/py-yaml-safe-load.json +18 -0
  578. package/packs/python/pack.json +26 -0
  579. package/packs/python/rules/python-errors-and-resources.md +26 -0
  580. package/packs/python/rules/python-repeats-become-templates.md +27 -0
  581. package/packs/python/skills/python-extract-template/SKILL.md +35 -0
  582. package/packs/react/checks/dialog-needs-role.json +28 -0
  583. package/packs/react/checks/effect-not-for-derived-state.json +24 -0
  584. package/packs/react/checks/icon-button-needs-name.json +24 -0
  585. package/packs/react/checks/label-needs-a-field.json +24 -0
  586. package/packs/react/checks/ui-failed-fetch-says-so.json +23 -0
  587. package/packs/react/checks/ui-ok-branch-has-an-else.json +23 -0
  588. package/packs/react/pack.json +20 -0
  589. package/packs/react/rules/react-accessible-controls.md +20 -0
  590. package/packs/react/rules/react-state-and-effects.md +23 -0
  591. package/packs/reverse-engineering/checks/ear-constant-tagged.json +23 -0
  592. package/packs/reverse-engineering/checks/no-default-on-distrust.json +24 -0
  593. package/packs/reverse-engineering/checks/no-rom-table-literal.json +29 -0
  594. package/packs/reverse-engineering/checks/prose-never-decides.json +22 -0
  595. package/packs/reverse-engineering/hooks/firmware-out-of-git.mjs +49 -0
  596. package/packs/reverse-engineering/pack.json +35 -0
  597. package/packs/reverse-engineering/rules/a-negative-names-what-was-scanned.md +19 -0
  598. package/packs/reverse-engineering/rules/account-every-term.md +20 -0
  599. package/packs/reverse-engineering/rules/addresses-name-their-space.md +21 -0
  600. package/packs/reverse-engineering/rules/every-law-has-a-source.md +18 -0
  601. package/packs/reverse-engineering/rules/findings-are-withdrawn-in-place.md +17 -0
  602. package/packs/reverse-engineering/rules/firmware-stays-out.md +18 -0
  603. package/packs/reverse-engineering/rules/names-before-code.md +19 -0
  604. package/packs/reverse-engineering/rules/reproduction-or-original.md +18 -0
  605. package/packs/reverse-engineering/rules/two-sources-before-naming.md +21 -0
  606. package/packs/reverse-engineering/skills/bank-census/SKILL.md +18 -0
  607. package/packs/reverse-engineering/skills/gather-sources/SKILL.md +21 -0
  608. package/packs/reverse-engineering/skills/menu-map/SKILL.md +28 -0
  609. package/packs/reverse-engineering/skills/names-first/SKILL.md +41 -0
  610. package/packs/reverse-engineering/skills/re-deliverables/SKILL.md +21 -0
  611. package/packs/reverse-engineering/skills/tripwire-the-law/SKILL.md +19 -0
  612. package/packs/reverse-engineering/tools/lib/unwrap.mjs +115 -0
  613. package/packs/reverse-engineering/tools/names-sweep.mjs +264 -0
  614. package/packs/shell/checks/sh-mktemp.json +18 -0
  615. package/packs/shell/checks/sh-no-backticks.json +18 -0
  616. package/packs/shell/checks/sh-no-eval.json +18 -0
  617. package/packs/shell/checks/sh-no-parse-ls.json +18 -0
  618. package/packs/shell/checks/sh-no-pipe-to-shell.json +18 -0
  619. package/packs/shell/checks/sh-no-program-in-heredoc.json +18 -0
  620. package/packs/shell/checks/sh-quote-arguments.json +18 -0
  621. package/packs/shell/checks/sh-rm-guarded.json +18 -0
  622. package/packs/shell/checks/sh-strict-mode.json +20 -0
  623. package/packs/shell/pack.json +28 -0
  624. package/packs/shell/rules/shell-repeats-become-templates.md +23 -0
  625. package/packs/shell/rules/shell-strict-and-quoted.md +27 -0
  626. package/packs/shell/skills/shell-extract-template/SKILL.md +32 -0
  627. package/packs/shell-hooks/checks/gnu-only-in-shell.json +18 -0
  628. package/packs/shell-hooks/checks/hook-command-anchored.json +12 -0
  629. package/packs/shell-hooks/checks/hook-json-by-tool.json +18 -0
  630. package/packs/shell-hooks/checks/no-bash-c-with-variable.json +20 -0
  631. package/packs/shell-hooks/pack.json +36 -0
  632. package/packs/shell-hooks/rules/hooks-portable-anchored-quoted.md +26 -0
  633. package/packs/sound-design/checks/audio-seed-fixed.json +23 -0
  634. package/packs/sound-design/checks/mix-is-a-crossfade.json +30 -0
  635. package/packs/sound-design/checks/no-hash-in-the-signal.json +30 -0
  636. package/packs/sound-design/checks/no-literal-key-anchor.json +30 -0
  637. package/packs/sound-design/checks/test-compares-a-function-with-itself.json +22 -0
  638. package/packs/sound-design/pack.json +22 -0
  639. package/packs/sound-design/rules/algorithms-are-data.md +26 -0
  640. package/packs/sound-design/rules/meter-before-engine.md +27 -0
  641. package/packs/sound-design/rules/neutral-is-exact.md +26 -0
  642. package/packs/sound-design/rules/test-off-the-easy-point.md +28 -0
  643. package/packs/sound-design/rules/unreachable-is-said.md +25 -0
  644. package/packs/sound-design/rules/waveforms-and-octaves.md +24 -0
  645. package/packs/sound-design/skills/choose-observable/SKILL.md +18 -0
  646. package/packs/sound-design/skills/measure-a-law/SKILL.md +18 -0
  647. package/packs/sound-design/skills/measure-reverb/SKILL.md +19 -0
  648. package/packs/sound-design/skills/spread-probe/SKILL.md +18 -0
  649. package/packs/stellix/checks/no-keyboard-focus.json +12 -0
  650. package/packs/stellix/checks/one-seeded-random.json +16 -0
  651. package/packs/stellix/checks/world-never-includes-painter.json +12 -0
  652. package/packs/stellix/checks/world-no-libm.json +15 -0
  653. package/packs/stellix/checks/world-no-unordered.json +10 -0
  654. package/packs/stellix/hooks/no-shipped-images.mjs +88 -0
  655. package/packs/stellix/pack.json +61 -0
  656. package/packs/stellix/rules/stellix-deterministic-world.md +29 -0
  657. package/packs/stellix/rules/stellix-reset-generated.md +24 -0
  658. package/packs/stellix/rules/stellix-world-snapshot.md +27 -0
  659. package/packs/stellix/rules/world-continuous-collision.md +26 -0
  660. package/packs/stellix/rules/world-fp-determinism.md +28 -0
  661. package/packs/stored-text/checks/no-raw-html-from-data.json +31 -0
  662. package/packs/stored-text/checks/stored-text-libs-only-in-renderer.json +31 -0
  663. package/packs/stored-text/checks/stored-text-renderer-complete.json +24 -0
  664. package/packs/stored-text/checks/stored-text-through-renderer.json +25 -0
  665. package/packs/stored-text/pack.json +41 -0
  666. package/packs/stored-text/rules/stored-text-renders-once.md +26 -0
  667. package/packs/stored-text/skills/render-stored-text/SKILL.md +24 -0
  668. package/packs/synth-creator/checks/timing-from-synthcore.json +24 -0
  669. package/packs/synth-creator/checks/ui-drawn-in-code.json +23 -0
  670. package/packs/synth-creator/hooks/build-guard.mjs +232 -0
  671. package/packs/synth-creator/hooks/build-sweep.mjs +166 -0
  672. package/packs/synth-creator/hooks/frozen-files.mjs +63 -0
  673. package/packs/synth-creator/hooks/idle-wake.mjs +90 -0
  674. package/packs/synth-creator/hooks/protect-vendor.mjs +174 -0
  675. package/packs/synth-creator/hooks/spec-lock.mjs +117 -0
  676. package/packs/synth-creator/hooks/stage-guard.mjs +50 -0
  677. package/packs/synth-creator/hooks/time-guard.mjs +292 -0
  678. package/packs/synth-creator/hooks/user-asks.mjs +165 -0
  679. package/packs/synth-creator/pack.json +136 -0
  680. package/packs/synth-creator/rules/copy-trees-read-only.md +25 -0
  681. package/packs/synth-creator/rules/debug-by-measurement.md +20 -0
  682. package/packs/synth-creator/rules/done-means-fresh-evidence.md +18 -0
  683. package/packs/synth-creator/rules/hooks-and-gates.md +21 -0
  684. package/packs/synth-creator/rules/long-work-in-the-background.md +16 -0
  685. package/packs/synth-creator/rules/timing-from-synthcore.md +16 -0
  686. package/packs/synth-creator/skills/build-step/SKILL.md +125 -0
  687. package/packs/synth-creator/skills/build-through-the-queue/SKILL.md +19 -0
  688. package/packs/synth-creator/tools/freeze.mjs +36 -0
  689. package/packs/tui/checks/tui-entry-restores-terminal.json +27 -0
  690. package/packs/tui/checks/tui-gates-on-tty.json +25 -0
  691. package/packs/tui/checks/tui-no-ris-reset.json +22 -0
  692. package/packs/tui/checks/tui-resize-listener-removed.json +26 -0
  693. package/packs/tui/checks/tui-width-is-state.json +33 -0
  694. package/packs/tui/pack.json +44 -0
  695. package/packs/tui/rules/tui-resize-and-screen.md +25 -0
  696. package/packs/tui/skills/build-tui/SKILL.md +21 -0
  697. package/packs/ui-craft/checks/ui-input-needs-autocomplete.json +23 -0
  698. package/packs/ui-craft/checks/ui-intl-for-dates.json +21 -0
  699. package/packs/ui-craft/checks/ui-no-ai-palette.json +22 -0
  700. package/packs/ui-craft/checks/ui-no-animate-layout.json +22 -0
  701. package/packs/ui-craft/checks/ui-no-assistant-palette.json +23 -0
  702. package/packs/ui-craft/checks/ui-no-bounce-easing.json +22 -0
  703. package/packs/ui-craft/checks/ui-no-custom-cursor.json +22 -0
  704. package/packs/ui-craft/checks/ui-no-emoji-as-ui.json +22 -0
  705. package/packs/ui-craft/checks/ui-no-empty-image.json +21 -0
  706. package/packs/ui-craft/checks/ui-no-eyebrow.json +21 -0
  707. package/packs/ui-craft/checks/ui-no-furniture-text.json +22 -0
  708. package/packs/ui-craft/checks/ui-no-gradient-text.json +22 -0
  709. package/packs/ui-craft/checks/ui-no-index-numbering.json +21 -0
  710. package/packs/ui-craft/checks/ui-no-lorem.json +22 -0
  711. package/packs/ui-craft/checks/ui-no-marketing-buzzword.json +22 -0
  712. package/packs/ui-craft/checks/ui-no-paste-block.json +21 -0
  713. package/packs/ui-craft/checks/ui-no-placeholder-names.json +21 -0
  714. package/packs/ui-craft/checks/ui-no-scroll-hijack.json +21 -0
  715. package/packs/ui-craft/checks/ui-no-side-tab.json +21 -0
  716. package/packs/ui-craft/checks/ui-no-stock-labels.json +22 -0
  717. package/packs/ui-craft/checks/ui-no-transition-all.json +22 -0
  718. package/packs/ui-craft/checks/ui-no-uppercase-table-header.json +21 -0
  719. package/packs/ui-craft/checks/ui-no-zebra-rows.json +22 -0
  720. package/packs/ui-craft/checks/ui-no-zoom-lock.json +21 -0
  721. package/packs/ui-craft/pack.json +43 -0
  722. package/packs/ui-craft/rules/apps-are-not-pages.md +26 -0
  723. package/packs/ui-craft/rules/data-tells-the-truth.md +26 -0
  724. package/packs/ui-craft/rules/dates-and-numbers.md +18 -0
  725. package/packs/ui-craft/rules/forms-never-fight.md +22 -0
  726. package/packs/ui-craft/rules/interface-copy.md +26 -0
  727. package/packs/ui-craft/rules/motion-is-rare.md +31 -0
  728. package/packs/ui-craft/rules/no-generated-look.md +37 -0
  729. package/packs/ui-craft/rules/page-holds-its-frame.md +28 -0
  730. package/packs/ui-craft/rules/page-proved-rendered.md +19 -0
  731. package/packs/ui-craft/rules/pictures-do-a-job.md +25 -0
  732. package/packs/ui-craft/rules/pointer-feedback.md +28 -0
  733. package/packs/ui-craft/rules/screen-answers-one-question.md +24 -0
  734. package/packs/ui-craft/rules/survives-real-data.md +23 -0
  735. package/packs/ui-craft/rules/touch-and-small-screens.md +19 -0
  736. package/packs/ui-craft/rules/type-space-colour.md +26 -0
  737. package/packs/ui-craft/rules/url-holds-the-state.md +19 -0
  738. package/packs/ui-craft/skills/app-screen/SKILL.md +33 -0
  739. package/packs/ui-craft/skills/build-from-reference/SKILL.md +28 -0
  740. package/packs/ui-craft/skills/chart-choice/SKILL.md +34 -0
  741. package/packs/ui-craft/skills/hover-state/SKILL.md +28 -0
  742. package/packs/ui-craft/skills/page-critique/SKILL.md +33 -0
  743. package/packs/ui-craft/skills/prove-page/SKILL.md +23 -0
  744. package/packs/ui-craft/skills/redesign-page/SKILL.md +19 -0
  745. package/packs/ui-craft/skills/ui-code-review/SKILL.md +22 -0
  746. package/packs/ui-craft/skills/write-the-page/SKILL.md +21 -0
  747. package/packs/ui-craft/tools/page-measure.mjs +41 -0
  748. package/packs/web/checks/a11y-img-needs-alt.json +26 -0
  749. package/packs/web/checks/a11y-no-bare-outline-none.json +21 -0
  750. package/packs/web/checks/a11y-no-clickable-div.json +26 -0
  751. package/packs/web/checks/a11y-no-positive-tabindex.json +26 -0
  752. package/packs/web/checks/client-no-api-key.json +29 -0
  753. package/packs/web/checks/client-no-browser-global-at-module-scope.json +28 -0
  754. package/packs/web/checks/client-no-server-import.json +31 -0
  755. package/packs/web/checks/client-no-window-location-nav.json +28 -0
  756. package/packs/web/checks/css-no-inline-style.json +30 -0
  757. package/packs/web/checks/ds-pages-compose-primitives.json +28 -0
  758. package/packs/web/checks/key-from-index.json +23 -0
  759. package/packs/web/checks/prodbuild-no-cdn-runtime-deps.json +21 -0
  760. package/packs/web/checks/prodbuild-no-dev-flags.json +21 -0
  761. package/packs/web/checks/prodbuild-no-remote-fonts.json +22 -0
  762. package/packs/web/checks/rcss-button-cursor.json +30 -0
  763. package/packs/web/checks/rcss-no-100vw.json +21 -0
  764. package/packs/web/checks/rcss-no-fixed-wide-width.json +21 -0
  765. package/packs/web/checks/rcss-viewport-meta.json +28 -0
  766. package/packs/web/checks/secret-not-in-web-storage.json +25 -0
  767. package/packs/web/checks/tw-no-raw-hex-in-markup.json +34 -0
  768. package/packs/web/checks/wp-hero-not-lazy.json +27 -0
  769. package/packs/web/checks/wp-img-needs-dimensions.json +26 -0
  770. package/packs/web/pack.json +73 -0
  771. package/packs/web/rules/accessibility.md +26 -0
  772. package/packs/web/rules/client-boundaries.md +23 -0
  773. package/packs/web/rules/production-build.md +22 -0
  774. package/packs/web/rules/secrets-not-in-the-browser.md +18 -0
  775. package/packs/web/rules/styles-live-in-stylesheets.md +23 -0
  776. package/packs/web/rules/tailwind-v4.md +23 -0
  777. package/packs/web/rules/ui-primitives-one-module.md +30 -0
  778. package/packs/web/rules/web-performance.md +21 -0
  779. package/packs/web/skills/design-direction/SKILL.md +30 -0
  780. package/packs/web/skills/design-review/SKILL.md +28 -0
  781. package/packs/web/skills/pick-rendering-mode/SKILL.md +21 -0
  782. package/packs/web/skills/preflight-build/SKILL.md +23 -0
  783. package/packs/web/skills/seo-audit/SKILL.md +22 -0
  784. package/packs/websocket/checks/no-token-in-query.json +26 -0
  785. package/packs/websocket/checks/stale-socket-deletes-new-entry.json +25 -0
  786. package/packs/websocket/checks/ws-identity-from-message.json +26 -0
  787. package/packs/websocket/pack.json +21 -0
  788. package/packs/websocket/rules/identity-comes-from-the-connection.md +24 -0
  789. package/packs/writing/checks/ascii-no-em-dash.json +17 -0
  790. package/packs/writing/checks/no-copula-dodging.json +18 -0
  791. package/packs/writing/checks/no-dramatic-colon.json +18 -0
  792. package/packs/writing/checks/no-not-x-but-y.json +18 -0
  793. package/packs/writing/checks/no-participial-opener.json +18 -0
  794. package/packs/writing/checks/no-pseudo-wisdom.json +18 -0
  795. package/packs/writing/checks/no-slop-words.json +18 -0
  796. package/packs/writing/checks/no-stock-connectors.json +18 -0
  797. package/packs/writing/checks/no-time-or-date.json +27 -0
  798. package/packs/writing/checks/no-trailing-ing.json +18 -0
  799. package/packs/writing/checks/no-vague-attribution.json +18 -0
  800. package/packs/writing/pack.json +43 -0
  801. package/packs/writing/rules/ascii-no-em-dash.md +21 -0
  802. package/packs/writing/rules/cut-the-padding.md +20 -0
  803. package/packs/writing/rules/direct-voice.md +22 -0
  804. package/packs/writing/rules/no-cargo-cult.md +16 -0
  805. package/packs/writing/rules/no-scaffolding.md +19 -0
  806. package/packs/writing/rules/no-stock-language.md +27 -0
  807. package/packs/writing/rules/no-time-or-date.md +18 -0
  808. package/packs/writing/rules/rhythm-like-talk.md +20 -0
  809. package/packs/writing/rules/write-from-your-own-corner.md +20 -0
  810. package/packs/writing/skills/argument-post/SKILL.md +28 -0
  811. package/packs/writing/skills/humanize/SKILL.md +28 -0
  812. package/packs/writing/skills/launch-post/SKILL.md +38 -0
  813. package/packs/writing/skills/pick-subreddit/SKILL.md +69 -0
  814. package/packs/writing/skills/post-voice/SKILL.md +22 -0
  815. package/packs/writing/skills/reddit-post/SKILL.md +63 -0
  816. package/packs/writing/skills/reddit-title/SKILL.md +23 -0
  817. package/packs/writing/skills/reply-moves/SKILL.md +40 -0
  818. package/packs/writing/skills/reply-stance/SKILL.md +23 -0
  819. package/packs/writing/skills/should-i-reply/SKILL.md +21 -0
  820. package/packs/zod/hooks/schemas-only.mjs +53 -0
  821. package/packs/zod/pack.json +44 -0
  822. package/packs/zod/rules/env-shapes-only.md +14 -0
  823. package/packs/zod/rules/zod-4-schemas.md +14 -0
  824. package/profiles/stellix.layout.json +315 -0
  825. package/profiles/sub37.layout.json +247 -0
  826. package/prompts/scan-review.md +40 -0
  827. package/prompts/survey.md +82 -0
@@ -0,0 +1,25 @@
1
+ {
2
+ "id": "zod-string-needs-max",
3
+ "why": "An unbounded z.string() accepts a 16 MB value into the document and the $jsonSchema derived from it has no maxLength either. Every string carries .max().",
4
+ "rule": ".claude/rules/schema-single-source-of-truth.md",
5
+ "concepts": [
6
+ "schemas"
7
+ ],
8
+ "exclude": [
9
+ "**/node_modules/**",
10
+ "**/dist/**",
11
+ "**/build/**",
12
+ "**/.next/**",
13
+ ".claude/**",
14
+ "**/.claude/**",
15
+ "**/*.test.*",
16
+ "**/*.spec.*",
17
+ "**/test/**",
18
+ "**/tests/**"
19
+ ],
20
+ "code": true,
21
+ "flags": "",
22
+ "pattern": "(?<!\\bz\\.record\\(\\s*)(?<!\\w_id:\\s{0,4})(?<!\\b_id:\\s{0,4})\\bz\\.string\\(\\)(?:\\.(?!(?:max|length|regex|uuid|datetime|email|url|ip|enum)\\b)\\w+\\([^()]*\\))*\\s*[,)\\]}]",
23
+ "bad": "cwd: z.string().min(1),\nhost: z.string(),",
24
+ "good": "cwd: z.string().min(1).max(4096),\nhost: z.string().max(253),\nhex: z.string().regex(HEX),\n_id: z.string(),\nsession_id: z.string(),\nfacts: z.record(z.string(), z.unknown()),"
25
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "id": "zod-v4-formats",
3
+ "why": "z.string().email()/.uuid()/.url()/.datetime()/.ip() are the deprecated Zod 3 spellings. Zod 4 has z.email(), z.uuid(), z.url(), z.iso.datetime(), z.ipv4().",
4
+ "rule": ".claude/rules/schema-single-source-of-truth.md",
5
+ "concepts": [
6
+ "js"
7
+ ],
8
+ "exclude": [
9
+ "**/node_modules/**",
10
+ "**/dist/**",
11
+ "**/build/**",
12
+ "**/.next/**",
13
+ ".claude/**",
14
+ "**/.claude/**"
15
+ ],
16
+ "code": true,
17
+ "pattern": "\\bz\\.string\\(\\)\\s*\\.(email|uuid|url|datetime|date|time|ip|ipv4|ipv6|emoji|cuid|ulid|base64)\\s*\\(",
18
+ "bad": "at: z.string().datetime(),\nmail: z.string().email(),",
19
+ "good": "at: z.iso.datetime(),\nmail: z.email(),",
20
+ "whenDep": {
21
+ "zod": 4
22
+ }
23
+ }
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "js-ts",
3
+ "version": "1.0.0",
4
+ "description": "JavaScript and TypeScript: strict types, no any, errors never swallowed, every promise handled, process lifecycle, schemas as the one source of truth, JSON only through one helper.",
5
+ "type": "stock",
6
+ "author": "claude-packs",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/TheDecipherist/claude-packs",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/TheDecipherist/claude-packs.git",
12
+ "directory": "packs/js-ts"
13
+ },
14
+ "keywords": [
15
+ "javascript",
16
+ "typescript"
17
+ ],
18
+ "engines": {
19
+ "claude-packs": ">=0.19.0"
20
+ },
21
+ "folders": {},
22
+ "concepts": {
23
+ "js": [
24
+ "**/*.js",
25
+ "**/*.mjs",
26
+ "**/*.cjs",
27
+ "**/*.ts",
28
+ "**/*.tsx",
29
+ "**/*.jsx"
30
+ ],
31
+ "ts": [
32
+ "**/*.ts",
33
+ "**/*.tsx"
34
+ ],
35
+ "js-tests": [
36
+ "**/*.test.ts",
37
+ "**/*.test.tsx",
38
+ "**/*.spec.ts",
39
+ "**/*.test.js",
40
+ "**/*.test.mjs"
41
+ ],
42
+ "tsconfig": [
43
+ "**/tsconfig*.json"
44
+ ],
45
+ "routes": [
46
+ "**/routes/**/*.ts",
47
+ "**/server/**/*.ts",
48
+ "**/app.ts",
49
+ "**/server.ts"
50
+ ],
51
+ "entry": [
52
+ "**/server.ts",
53
+ "**/server.js",
54
+ "**/server.mjs",
55
+ "**/src/index.ts",
56
+ "**/src/index.js",
57
+ "**/src/main.ts",
58
+ "**/src/app.ts",
59
+ "**/index.ts",
60
+ "**/bin/**",
61
+ "**/worker/**/index.*",
62
+ "**/*.worker.ts",
63
+ "**/lifecycle.*"
64
+ ],
65
+ "schemas": [
66
+ "**/schemas/**",
67
+ "**/schema/**",
68
+ "**/*.schema.ts",
69
+ "**/*.schema.js",
70
+ "**/models/**",
71
+ "**/types/**"
72
+ ],
73
+ "handlers": [
74
+ "**/routes/**",
75
+ "**/handlers/**",
76
+ "**/adapters/**",
77
+ "**/services/**",
78
+ "**/controllers/**",
79
+ "**/app/api/**"
80
+ ]
81
+ },
82
+ "skillsIn": null,
83
+ "hooks": {}
84
+ }
@@ -0,0 +1,66 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # Every await is handled somewhere on purpose: at a boundary, for cleanup, or to recover
8
+
9
+ A `try/catch` around every `await` is not the goal. One that only logs and rethrows doubles every log line, and one that returns `null` hides the failure. The goal is that **no rejection is ever unhandled**, and that each one is handled **in the one place that can do something about it**.
10
+
11
+ <constraints>
12
+ Always do:
13
+ - **Boundaries with no catcher of their own get a `try/catch` that logs with context and ends the unit of work cleanly:**
14
+ - `setTimeout`, `setInterval` and `setImmediate` callbacks;
15
+ - event handlers (`.on`, `.once`, `addEventListener`, stream and socket events);
16
+ - queue and change-stream consumers, cron jobs, MCP tool handlers (check what your SDK version does with a throw), CLI `main()`.
17
+ Wrap these with the project's `guarded(fn, log, what)` helper (`lib/guarded.ts`: create it if the project has none), which is the only place that writes that `try/catch`.
18
+ - **Boundaries that do catch** stay thin: Fastify route handlers just `await` and `throw`. Fastify's error handler (`setErrorHandler`) maps the error to a response and logs it once.
19
+ - **A resource that must be released** (a session, a lock, a file handle, a Mongo transaction, a Chrome) gets `try { … } finally { release }`, or `await using` when the resource supports it.
20
+ - **An operation you can actually recover from** (retry, fallback, a default for a missing optional) catches **only the error it can recover from**, narrowed with `instanceof` or a code, and rethrows everything else.
21
+ - **The process has a last line:** the entrypoint registers `process.on('unhandledRejection')` and `process.on('uncaughtException')`, which log with pino and exit non-zero, so a missed rejection is loud, never silent.
22
+
23
+ Never do:
24
+ - Pass an `async` function where nobody awaits it (`setInterval(async …)`, `emitter.on('x', async …)`, `arr.forEach(async …)`). The `async-callback-unguarded` check refuses it; wrap it in `guarded(…)`.
25
+ - Swallow: an empty `catch {}`, `.catch(() => {})`, `.catch(() => null)`. The `no-swallowed-errors` check refuses them.
26
+ - Wrap an await in `try/catch` only to log and rethrow. The boundary logs it.
27
+ </constraints>
28
+
29
+ ```ts
30
+ // lib/guarded.ts: the one place a "log and carry on" catch is written
31
+ export function guarded<A extends unknown[]>(fn: (...a: A) => Promise<unknown>, log: Logger, what: string) {
32
+ return (...a: A): void => {
33
+ let pending: Promise<unknown>;
34
+ try { pending = fn(...a); } // a sync throw before the first await
35
+ catch (err: unknown) { log.error({ err, what }, 'background task failed'); return; }
36
+ pending.catch((err: unknown) => log.error({ err, what }, 'background task failed'));
37
+ };
38
+ }
39
+ export function exitOnUnhandled(log: Logger): void { // call once, in the entrypoint
40
+ for (const ev of ['unhandledRejection', 'uncaughtException'] as const)
41
+ process.on(ev, (err: unknown) => { log.error({ err }, ev); process.exit(1); });
42
+ }
43
+
44
+ // NO: a rejection here is unhandled and, since Node 15, kills the process
45
+ setInterval(async () => { await sweepExpired(db); }, 60_000);
46
+
47
+ // YES
48
+ setInterval(guarded(() => sweepExpired(db), log, 'sweep expired sessions'), 60_000);
49
+
50
+ // Cleanup, not catching
51
+ const session = client.startSession();
52
+ try { await session.withTransaction(() => moveFunds(session, from, to, amount)); }
53
+ finally { await session.endSession(); }
54
+
55
+ // Recover from one thing only
56
+ try { return await cache.get(key); }
57
+ catch (err: unknown) {
58
+ if (err instanceof CacheUnavailableError) return await loadFromDb(key);
59
+ throw err;
60
+ }
61
+ ```
62
+
63
+ ## Checks
64
+ - `async-callback-unguarded`: an `async` function passed to a timer, an event handler or `forEach`.
65
+ - `no-swallowed-errors`: an empty `catch`, `.catch(() => {})`, `.catch(() => null | undefined)`.
66
+ - `no-floating-promises` (type-aware ESLint) catches the rest, which a regex can't see. Wire it into the edit hook where the project has ESLint.
@@ -0,0 +1,36 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # Environment variables only through one validated config
8
+
9
+ ## The law
10
+ `process.env` is read in exactly one file, `src/config.ts`. That file parses it with Zod at startup and exports a typed, frozen `config`. A missing or malformed variable crashes the boot with a clear message rather than failing later at the first request.
11
+
12
+ ```ts
13
+ // src/config.ts
14
+ const Env = z.object({
15
+ MONGODB_URI: z.string().url(),
16
+ PORT: z.coerce.number().int().default(3000),
17
+ GROVE_API_KEY: z.string().min(1),
18
+ });
19
+ export const config = Object.freeze(Env.parse(process.env));
20
+
21
+ // anywhere else
22
+ import { config } from './config.js';
23
+ ```
24
+
25
+ ## Never
26
+ - Hardcode a secret, key, token or connection string in source, even "temporarily".
27
+ - Read `process.env.X` inline elsewhere.
28
+
29
+ ## Check
30
+ ```js
31
+ // eslint-plugin-n
32
+ 'n/no-process-env': 'error',
33
+ // override for the one allowed file:
34
+ { files: ['src/config.ts'], rules: { 'n/no-process-env': 'off' } },
35
+ ```
36
+ Secrets: run `gitleaks git --pre-commit --staged` in the pre-commit hook.
@@ -0,0 +1,33 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # Errors are typed, thrown as Error, and never swallowed
8
+
9
+ ## The law
10
+ - Catch variables are `unknown`; narrow with `instanceof` before reading `.message`.
11
+ - Throw only `Error` instances (or subclasses), never strings or plain objects.
12
+ - A `catch` block either handles the error meaningfully, rethrows it with context (`new Error('...', { cause: err })`), or logs and rethrows. An empty catch is never allowed.
13
+ - In Fastify, throw and let the error handler map it to a response; don't build error responses ad hoc in every handler.
14
+
15
+ ```ts
16
+ try {
17
+ await saveOrder(order);
18
+ } catch (err: unknown) {
19
+ throw new Error(`saveOrder failed for ${order.id}`, { cause: err });
20
+ }
21
+ ```
22
+
23
+ ## Check
24
+ **Enforced:** the `no-swallowed-errors` lesson check refuses an empty `catch`, `.catch(() => {})` and `.catch(() => null)` at edit time. Where errors are handled at all, see `await-handled-at-a-boundary`.
25
+
26
+ ESLint, where the project has it:
27
+ ```js
28
+ 'no-empty': 'error',
29
+ '@typescript-eslint/only-throw-error': 'error',
30
+ '@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
31
+ 'prefer-promise-reject-errors': 'error',
32
+ ```
33
+ `useUnknownInCatchVariables` comes with `strict` in tsconfig (see tsconfig-strict).
@@ -0,0 +1,18 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # No source file over 300 lines
8
+
9
+ ## The law
10
+ A file holds one module with one responsibility, and never more than 300 lines. Before a file reaches the limit, split it by responsibility (types, schema, helpers, the main logic) into a folder with an `index.ts` that re-exports. Never split it arbitrarily into part1 and part2.
11
+
12
+ (The downloaded templates allowed 800 lines; this house limit replaces that.)
13
+
14
+ ## Check
15
+ ```js
16
+ 'max-lines': ['error', { max: 300, skipBlankLines: false, skipComments: false }],
17
+ ```
18
+ The existing edit hook that refuses oversized files remains the hard stop.
@@ -0,0 +1,34 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # Guard clauses over nesting
8
+
9
+ ## The law
10
+ Handle the invalid, empty and error cases first with early returns or throws. Then the main path runs unindented at the bottom. Max nesting depth is 3.
11
+
12
+ ```ts
13
+ // NO
14
+ function ship(order?: Order) {
15
+ if (order) {
16
+ if (order.paid) {
17
+ if (order.items.length) { return dispatch(order); }
18
+ }
19
+ }
20
+ }
21
+
22
+ // YES
23
+ function ship(order?: Order) {
24
+ if (!order) throw new Error('no order');
25
+ if (!order.paid) throw new Error('unpaid');
26
+ if (!order.items.length) return;
27
+ return dispatch(order);
28
+ }
29
+ ```
30
+
31
+ ## Check
32
+ ```js
33
+ 'max-depth': ['error', 3],
34
+ ```
@@ -0,0 +1,26 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # Anything repeated in JS or TS becomes a template: pick the form that fits the repeat
8
+
9
+ <constraints>
10
+ Always do:
11
+ - Match the repeat to its form:
12
+ - Markup used twice: one component, with what differs as props.
13
+ - A block with the same statements and other names: one function, with what differs as its parameters. `template-law` and `scan` list what differs.
14
+ - Handlers alike but for a few lines: one factory that returns the handler, each kind passing what is its own.
15
+ - The same wrapping around many functions (auth, retry, timing): one higher-order function.
16
+ - One call repeated with other arguments: an array of rows and one loop, typed with `satisfies`.
17
+ - Stateful logic shared between components: one hook.
18
+ - Export a helper from the module its users already import, and import it. Search before writing one.
19
+
20
+ Never do:
21
+ - Define `sleep`, `escapeHtml`, `formatDate` or the like again in a new file.
22
+ - Copy a route, a handler or a page to change a few lines.
23
+ </constraints>
24
+
25
+ ## Check
26
+ `template-law` refuses a new copy, a near copy or a function the repo already has. `make-it-a-template` walks the change.
@@ -0,0 +1,62 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # JSON goes in and out through one helper; a logger never throws
8
+
9
+ `JSON.stringify` **throws** on a circular reference, a `BigInt` or a `toJSON()` that throws. It silently turns an `Error` into `{}` and drops `undefined`. `JSON.parse` throws on any bad input. Data typed `unknown` (log fields, request bodies, Mongo documents, API responses) can contain any of these. A raw call is a crash waiting for the one value that triggers it, and a logger that crashes takes the request down with it.
10
+
11
+ <constraints>
12
+ Always do:
13
+ - **Logs:** use the structured logger, never `console` plus `JSON.stringify`. In Fastify that is pino: `request.log` / `fastify.log`, `log.info({ fields }, 'message')`, with errors under the `err` key so pino records name, message and stack. Pino serializes safely and never throws on odd values.
14
+ - **Everything else:** one file per project, `lib/json.ts` (create it if the project has none), holds the only `JSON.parse` and `JSON.stringify` calls:
15
+ - `toJson(value)` uses `safe-stable-stringify`: circular references become `"[Circular]"`, `BigInt` becomes a string, `Error` becomes `{ name, message, stack, cause }`. It returns a string and never throws.
16
+ - `parseJson(text, schema)` wraps `JSON.parse` in `try` and validates with the Zod schema. It returns `{ ok: true, value } | { ok: false, error }` and never throws.
17
+ - Check the current version of `safe-stable-stringify` and `pino` with `latest-versions` before adding them.
18
+
19
+ Never do:
20
+ - Call `JSON.parse` or `JSON.stringify` anywhere but `lib/json.ts` (tests and config files excepted). The `json-only-through-helper` check refuses it.
21
+ - Write a logger, error handler or response path that can throw. If logging fails, the request must still finish.
22
+ </constraints>
23
+
24
+ ```ts
25
+ // NO: throws on a BigInt, a circular object or a throwing toJSON; turns errors into {}
26
+ export function logLine(level: 'info' | 'warn' | 'error', fields: Record<string, unknown>): void {
27
+ console.log(JSON.stringify({ ts: new Date().toISOString(), level, service: 'admiralmcp-api', ...fields }));
28
+ }
29
+
30
+ // YES, in a Fastify service: the framework's logger
31
+ const app = Fastify({ logger: { base: { service: 'admiralmcp-api' } } });
32
+ request.log.warn({ jobId, err }, 'job retry');
33
+
34
+ // YES, outside Fastify: lib/json.ts is the only file that touches JSON
35
+ import { configure } from 'safe-stable-stringify';
36
+ const stringify = configure({ bigint: true, circularValue: '[Circular]' });
37
+ const errorsAsObjects = (_k: string, v: unknown) =>
38
+ v instanceof Error ? { name: v.name, message: v.message, stack: v.stack, cause: v.cause } : v;
39
+
40
+ export function toJson(value: unknown): string {
41
+ try {
42
+ return stringify(value, errorsAsObjects) ?? 'null';
43
+ } catch (err) {
44
+ return `{"unserializable":true,"reason":${JSON.stringify(String(err))}}`;
45
+ }
46
+ }
47
+
48
+ export type Parsed<T> = { ok: true; value: T } | { ok: false; error: string };
49
+ export function parseJson<T>(text: string, schema: z.ZodType<T>): Parsed<T> {
50
+ let raw: unknown;
51
+ try {
52
+ raw = JSON.parse(text);
53
+ } catch (err) {
54
+ return { ok: false, error: `not JSON: ${err instanceof Error ? err.message : String(err)}` };
55
+ }
56
+ const r = schema.safeParse(raw);
57
+ return r.success ? { ok: true, value: r.data } : { ok: false, error: r.error.message };
58
+ }
59
+ ```
60
+
61
+ ## Check
62
+ `.claude/checks/json-only-through-helper.json` refuses an edit that adds `JSON.parse(` or `JSON.stringify(` outside `**/lib/json.*`, tests and config files. If a raw call slips in by another route (`Response.json()` on unknown input, `structuredClone` of an unknown value, a `toJSON` that throws), add that shape to the check.
@@ -0,0 +1,34 @@
1
+ ---
2
+ # concepts: ts
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # Named constants, not magic numbers
8
+
9
+ ## The law
10
+ Any number with meaning (a timeout, limit, threshold, retry count, status code) gets a named constant that says what it is and its unit.
11
+
12
+ ```ts
13
+ // NO
14
+ setTimeout(retry, 30000);
15
+ if (items.length > 100) paginate();
16
+
17
+ // YES
18
+ const RETRY_DELAY_MS = 30_000;
19
+ const MAX_PAGE_SIZE = 100;
20
+ ```
21
+
22
+ ## Check
23
+ ```js
24
+ '@typescript-eslint/no-magic-numbers': ['error', {
25
+ ignore: [-1, 0, 1, 2],
26
+ ignoreArrayIndexes: true,
27
+ ignoreEnums: true,
28
+ ignoreNumericLiteralTypes: true,
29
+ ignoreReadonlyClassProperties: true,
30
+ ignoreTypeIndexes: true,
31
+ }],
32
+ { files: ['**/*.test.*', '**/*.spec.*'], rules: { '@typescript-eslint/no-magic-numbers': 'off' } },
33
+ ```
34
+ Turn off core `no-magic-numbers` when enabling the TS version.
@@ -0,0 +1,34 @@
1
+ ---
2
+ # concepts: ts
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # No `any`
8
+
9
+ ## The law
10
+ Never type anything as `any`. Use `unknown` for data you don't control yet, then narrow it (Zod parse, `instanceof`, type guard). Use a generic when the type depends on the caller.
11
+
12
+ ```ts
13
+ // NO
14
+ function handle(data: any) { return data.id; }
15
+
16
+ // YES
17
+ function handle(data: unknown) {
18
+ const { id } = IdSchema.parse(data);
19
+ return id;
20
+ }
21
+ ```
22
+
23
+ ## Exceptions
24
+ - Third-party type gaps: wrap the untyped call once in a typed adapter, put the single `any` there, and add an eslint-disable comment that gives the reason.
25
+
26
+ ## Check
27
+ ```js
28
+ '@typescript-eslint/no-explicit-any': 'error',
29
+ '@typescript-eslint/no-unsafe-assignment': 'error',
30
+ '@typescript-eslint/no-unsafe-member-access': 'error',
31
+ ```
32
+
33
+ ## Enforced
34
+ `.claude/checks/no-any.json` refuses new `: any`, `as any`, `<any>`, `any[]` and `Record<…, any>` in TypeScript (tests and `.d.ts` excepted).
@@ -0,0 +1,30 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # No `console.*` in application code
8
+
9
+ ## The law
10
+ Log through the app logger (Fastify's built-in pino: `request.log` in handlers, `app.log` elsewhere). That gives you levels, structured JSON and request IDs. Never leave `console.log` debugging behind.
11
+
12
+ ```ts
13
+ // NO
14
+ console.log('user created', user.id);
15
+
16
+ // YES
17
+ request.log.info({ userId: user.id }, 'user created');
18
+ ```
19
+
20
+ ## Exceptions
21
+ - CLI scripts and build tooling (`scripts/**`, `bin/**`), where stdout is the interface.
22
+
23
+ ## Check
24
+ ```js
25
+ 'no-console': 'error',
26
+ { files: ['scripts/**', 'bin/**'], rules: { 'no-console': 'off' } },
27
+ ```
28
+
29
+ ## Enforced
30
+ `.claude/checks/no-console-in-app.json` refuses new `console.*` calls in application code (tests, `bin/`, `scripts/`, `tools/` and CLIs excepted).
@@ -0,0 +1,31 @@
1
+ ---
2
+ # concepts: ts
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # Every promise is awaited, returned or explicitly voided
8
+
9
+ ## The law
10
+ A promise that is neither awaited, returned, nor handled is a silent failure: its rejection is lost and the code after it runs before it finishes. If fire-and-forget is truly intended, write `void task().catch(log)` so the intent is visible.
11
+
12
+ Never pass an async function where a sync callback is expected (`forEach`, event emitters, `setTimeout`), because its rejections vanish.
13
+
14
+ ```ts
15
+ // NO
16
+ users.forEach(async (u) => await notify(u));
17
+ saveAudit(entry);
18
+
19
+ // YES
20
+ await Promise.all(users.map((u) => notify(u)));
21
+ await saveAudit(entry);
22
+ ```
23
+
24
+ ## Check
25
+ **Enforced:** the `async-callback-unguarded` lesson check refuses an `async` function passed to a timer, an event handler or `forEach` (wrap it in `guarded(…)`, see `await-handled-at-a-boundary`). A promise that is simply not awaited needs types to see, so that part is ESLint's.
26
+
27
+ Needs type-aware linting (`parserOptions.projectService: true`):
28
+ ```js
29
+ '@typescript-eslint/no-floating-promises': 'error',
30
+ '@typescript-eslint/no-misused-promises': 'error',
31
+ ```
@@ -0,0 +1,28 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # Never mutate a function's inputs
8
+
9
+ ## The law
10
+ A function must not change the objects or arrays passed to it. Return a new value instead. Callers should never have their data changed under them.
11
+
12
+ ```ts
13
+ // NO
14
+ function rename(user: User, name: string) { user.name = name; return user; }
15
+
16
+ // YES
17
+ function rename(user: Readonly<User>, name: string): User {
18
+ return { ...user, name };
19
+ }
20
+ ```
21
+
22
+ ## Not covered
23
+ Building up a local array or object that the function itself created is fine. This law is about *inputs*, not a blanket ban on mutation (the source templates said "never mutate anything", which is impractical and was dropped).
24
+
25
+ ## Check
26
+ ```js
27
+ 'no-param-reassign': ['error', { props: true }],
28
+ ```
@@ -0,0 +1,30 @@
1
+ ---
2
+ # concepts: ts
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # No non-null `!` and no casting object literals
8
+
9
+ ## The law
10
+ - Never use the non-null assertion `x!`. Handle the `null`/`undefined` case with a guard, or throw.
11
+ - Never cast an object literal into a type (`{...} as User`). Annotate it instead (`const u: User = {...}`) so missing fields are caught.
12
+ - `as` on anything else needs a one-line comment saying why the compiler can't see it. Prefer a Zod parse or a type guard.
13
+
14
+ ```ts
15
+ // NO
16
+ const user = await findUser(id);
17
+ send(user!.email);
18
+
19
+ // YES
20
+ const user = await findUser(id);
21
+ if (!user) throw new Error(`user ${id} not found`);
22
+ send(user.email);
23
+ ```
24
+
25
+ ## Check
26
+ ```js
27
+ '@typescript-eslint/no-non-null-assertion': 'error',
28
+ '@typescript-eslint/consistent-type-assertions': ['error',
29
+ { assertionStyle: 'as', objectLiteralTypeAssertions: 'never' }],
30
+ ```
@@ -0,0 +1,24 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # One logger, configured once, with a request id on every line
8
+
9
+ "Log it" is not a standard. Without one, `console.error` satisfies every instruction and the deployment gets stderr soup with no level, no fields and no way to tie a 500 line to the response the user got.
10
+
11
+ <constraints>
12
+ Always do:
13
+ - One logger module per service (pino; Fastify's own `app.log`/`request.log` in a Fastify service) exporting a configured instance. Nothing else constructs a logger or imports the logging library.
14
+ - Structured JSON to stdout: level, timestamp, service name, request id. Stdout is what gets collected; file transports are wrong in a container.
15
+ - The request id is generated at ingress (or taken from the incoming header) and travels: every line in a request's lifetime carries it, and the 500 body returns it as the correlation id.
16
+ - Errors log under the `err` key so the stack is recorded, not only the message.
17
+ - Every suppressed-repeat path ("log once and go quiet") keeps a counter somewhere visible (a metric, a periodic re-log with the count, a health field): a subsystem broken for a week must not look like a quiet week.
18
+ - The logger never throws (`json-only-through-one-helper`): if logging fails, the request still finishes.
19
+
20
+ Never do:
21
+ - `console.*` in application code (`no-console-in-app`). Two exemptions, each marked with a comment so nobody deletes the rule: crash handlers (`uncaughtException`/`unhandledRejection`, where an async logger may not flush before exit) and pre-init boot lines that run before the logger exists.
22
+ - What a user typed at info level (query strings, form fields): attack forensics go to a dedicated level or field with retention thought through.
23
+ - A second logger instance, or a wrapper that swallows the level.
24
+ </constraints>
@@ -0,0 +1,20 @@
1
+ ---
2
+ # concepts: js
3
+ paths:
4
+ - "placeholder"
5
+ ---
6
+
7
+ # Every outbound call has a deadline, and a server stops cleanly
8
+
9
+ <constraints>
10
+ Always do:
11
+ - Pass `signal: AbortSignal.timeout(ms)` to `fetch`, and a timeout to every client.
12
+ - Give the work the deadline, so it stops when the wait does.
13
+ - Await `server.close()` before exit.
14
+
15
+ Never do:
16
+ - Use `Promise.race` as a timeout: it ends the wait, not the work.
17
+ </constraints>
18
+
19
+ ## Check
20
+ `fetch-needs-timeout`, `race-leaves-work-running`, `server-close-awaited`.