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.
Adopt with
Section titled “Adopt with”extends: - alint://bundled/hygiene/lockfiles@v1lockfiles-no-nested-yarn
Section titled “lockfiles-no-nested-yarn”- kind:
file_absent - level:
warning
Nested
yarn.lockoutside the workspace root. This is usually a tooling mishap. If intentional, disable the rule.
lockfiles-no-nested-pnpm
Section titled “lockfiles-no-nested-pnpm”- kind:
file_absent - level:
warning
lockfiles-no-nested-npm
Section titled “lockfiles-no-nested-npm”- kind:
file_absent - level:
warning
lockfiles-no-nested-bun
Section titled “lockfiles-no-nested-bun”- kind:
file_absent - level:
warning
lockfiles-no-nested-cargo
Section titled “lockfiles-no-nested-cargo”- kind:
file_absent - level:
warning
Nested
Cargo.lock. Only the workspace-root Cargo.lock is honored by Cargo; nested ones drift and confuse contributors.
lockfiles-no-nested-poetry
Section titled “lockfiles-no-nested-poetry”- kind:
file_absent - level:
warning
lockfiles-no-nested-uv
Section titled “lockfiles-no-nested-uv”- kind:
file_absent - level:
warning
Source
Section titled “Source”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