Skip to content

hygiene/lockfiles@v1

Lockfile discipline: exactly one package-manager’s lockfile per workspace, and lockfiles only at the workspace root. Nested lockfiles almost always indicate a tooling misconfiguration (e.g., a transitive install ran npm when the parent is pnpm) and cause version drift.

This ruleset only addresses the “where” question. The one-version rule (“every package.json has the same dependency version”) needs structured-query primitives and ships in a later release.

extends:
- alint://bundled/hygiene/lockfiles@v1

Nested yarn.lock outside the workspace root. This is usually a tooling mishap. If intentional, disable the rule.

Nested Cargo.lock. Only the workspace-root Cargo.lock is honored by Cargo; nested ones drift and confuse contributors.

The full ruleset definition is committed at crates/alint-dsl/rulesets/v1/hygiene/lockfiles.yml in the alint repo (the snapshot below is generated verbatim from that file).

# alint://bundled/hygiene/lockfiles@v1
#
# Lockfile discipline: exactly one package-manager's lockfile
# per workspace, and lockfiles only at the workspace root.
# Nested lockfiles almost always indicate a tooling
# misconfiguration (e.g., a transitive install ran npm when
# the parent is pnpm) and cause version drift.
#
# This ruleset only addresses the "where" question. The
# one-version rule ("every package.json has the same
# dependency version") needs structured-query primitives and
# ships in a later release.
version: 1
rules:
# --- Nested lockfiles ----------------------------------------------
- id: lockfiles-no-nested-yarn
kind: file_absent
paths:
include: "**/yarn.lock"
exclude: "yarn.lock"
level: warning
message: >-
Nested `yarn.lock` outside the workspace root. This is
usually a tooling mishap. If intentional, disable the rule.
- id: lockfiles-no-nested-pnpm
kind: file_absent
paths:
include: "**/pnpm-lock.yaml"
exclude: "pnpm-lock.yaml"
level: warning
- id: lockfiles-no-nested-npm
kind: file_absent
paths:
include: "**/package-lock.json"
exclude: "package-lock.json"
level: warning
- id: lockfiles-no-nested-bun
kind: file_absent
paths:
include: ["**/bun.lock", "**/bun.lockb"]
exclude: ["bun.lock", "bun.lockb"]
level: warning
- id: lockfiles-no-nested-cargo
# Library crates in a workspace don't ship their own
# Cargo.lock — Cargo itself ignores per-crate lockfiles
# inside a workspace. A nested Cargo.lock is almost always
# an accidentally-committed dev artefact.
kind: file_absent
paths:
include: "**/Cargo.lock"
exclude: "Cargo.lock"
level: warning
message: >-
Nested `Cargo.lock`. Only the workspace-root Cargo.lock
is honored by Cargo; nested ones drift and confuse
contributors.
- id: lockfiles-no-nested-poetry
kind: file_absent
paths:
include: "**/poetry.lock"
exclude: "poetry.lock"
level: warning
- id: lockfiles-no-nested-uv
kind: file_absent
paths:
include: "**/uv.lock"
exclude: "uv.lock"
level: warning