From b7a0e8b1630f7b7e900a27f0058dbc93ce4194e4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 11 Nov 2026 01:09:40 +0000 Subject: [PATCH] Reword JS runtime-order messages: bun, deno, pnpm, npm last resort State the JS runtime order as a preference (bun, then deno, then pnpm; npm only when bun, deno and pnpm are all impossible) instead of saying npm/Deno are banned. Message text and comments only; no rule logic changed. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_0136P7ZpE5cb1MCPbmPbDjHg --- lib/rules/cicd_rules.ex | 4 ++-- lib/rules/root_hygiene.ex | 4 +++- test/rules/cicd_rules_rescript_npm_js_test.exs | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/rules/cicd_rules.ex b/lib/rules/cicd_rules.ex index 829780e9..c1a20154 100644 --- a/lib/rules/cicd_rules.ex +++ b/lib/rules/cicd_rules.ex @@ -319,7 +319,7 @@ defmodule Hypatia.Rules.CicdRules do id: :nodejs_detected, glob: "package-lock.json", reason: - "npm lockfile banned -- use Bun (`bun install`, bun.lock; JS runtime order Bun > pnpm > npm, Deno banned 2026-09-22, standards docs/JS-RUNTIME-POLICY.adoc)", + "npm lockfile not permitted here -- use Bun (`bun install`, bun.lock). JS runtime preference order: bun, then deno, then pnpm; npm only as a last resort when bun, deno and pnpm are all impossible (standards docs/JS-RUNTIME-POLICY.adoc)", path_allow_prefixes: [ # (1a) VSCode extension host-required (/vscode/ as path segment) "/vscode/", @@ -477,7 +477,7 @@ defmodule Hypatia.Rules.CicdRules do id: :npx_in_workflow, pattern: ~r/(?:^|[\s;&|])(?:npx|npm[[:space:]]+run)\b/m, reason: - "npx / `npm run` banned in CI -- use `bunx` or `bun run` instead (npm banned 2026-05-25; Deno banned 2026-09-22, standards LANGUAGE-POLICY §1.3)", + "npx / `npm run` in CI -- use `bunx` or `bun run` instead. JS runtime preference order: bun, then deno, then pnpm; npm only as a last resort when bun, deno and pnpm are all impossible (standards LANGUAGE-POLICY §1.3)", applies_to: ["*.yml", "*.yaml", "*.sh", "Justfile", "Mustfile"], # The ban's own enforcers (echidna scripts/ban-npm.sh) name npx inside a # quoted grep pattern or an echo message; that is text, not execution. diff --git a/lib/rules/root_hygiene.ex b/lib/rules/root_hygiene.ex index d43b27db..8ae1058b 100644 --- a/lib/rules/root_hygiene.ex +++ b/lib/rules/root_hygiene.ex @@ -144,7 +144,9 @@ defmodule Hypatia.Rules.RootHygiene do action: :rename }, %{pattern: "Makefile", reason: "Use Justfile", severity: :medium, action: :replace}, - # JS runtime order is Bun > pnpm > npm; Deno is banned (2026-09-22). + # JS runtime preference order: bun, then deno, then pnpm; npm only as a last + # resort when bun, deno and pnpm are all impossible (a stated preference + # order, not extra toolchains to maintain). # Source: standards docs/JS-RUNTIME-POLICY.adoc "Hard Rules". Bun # lockfiles (bun.lock / bun.lockb) are permitted and expected, so they # are deliberately absent here: this list used to mark bun.lockb (and diff --git a/test/rules/cicd_rules_rescript_npm_js_test.exs b/test/rules/cicd_rules_rescript_npm_js_test.exs index 4cd07ba6..20cc9257 100644 --- a/test/rules/cicd_rules_rescript_npm_js_test.exs +++ b/test/rules/cicd_rules_rescript_npm_js_test.exs @@ -143,7 +143,7 @@ defmodule Hypatia.Rules.CicdRules.RescriptNpmJsTest do assert nj, "expected :nodejs_detected finding for non-exempt package-lock.json" assert length(nj.files) == 2 - # Deno is banned (2026-09-22); the remedy is Bun (JS-RUNTIME-POLICY). + # Remedy is Bun (preference order bun, deno, pnpm, npm last; JS-RUNTIME-POLICY). assert nj.reason =~ "use Bun" refute nj.reason =~ "use Deno" assert nj.reason =~ "JS-RUNTIME-POLICY"