Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/rules/cicd_rules.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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)",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not advertise a fallback that the rule rejects

When bun, deno, and pnpm are all impossible, this diagnostic now tells the user that npm is an acceptable last resort, but check_commit_blocks/1 still unconditionally reports :nodejs_detected for any package-lock.json outside the fixed path allowlist; root hygiene also marks the lockfile high-severity/delete, and the similarly changed :npx_in_workflow rule still reports npm use. Thus following the new fallback guidance cannot make the scan pass. Either add an explicit last-resort exemption mechanism and explain it here, or avoid describing npm as usable.

Useful? React with 👍 / 👎.

path_allow_prefixes: [
# (1a) VSCode extension host-required (/vscode/ as path segment)
"/vscode/",
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 3 additions & 1 deletion lib/rules/root_hygiene.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/rules/cicd_rules_rescript_npm_js_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading