Skip to content

release-age: track npm policy in a file, pnpm 12 config.yaml - #187

Merged
DJRHails merged 1 commit into
mainfrom
release-age-tracked
Oct 9, 2026
Merged

DJRHails merged 1 commit into
mainfrom
release-age-tracked

Conversation

@DJRHails

@DJRHails DJRHails commented Oct 9, 2026

Copy link
Copy Markdown
Owner

What

Follow-up to #185. npm's policy now lives in a tracked file instead of being written into ~/.npmrc by setup.sh, so tokens stay in the untracked user file and further npm policy is a file edit.

  • modules/release-age/npmrc (min-release-age=7) is linked to ~/.config/npm/npmrc. The only line setup.sh writes into ~/.npmrc is globalconfig=<that path>, which makes npm read the tracked file as its global config layer. The user file still wins on precedence, so setup.sh also removes the min-release-age=7 line the first revision wrote there, and fails with an explanation if the effective value is not 7 (link missing, or a different user-level value shadowing the policy).
  • pnpm 10 follows the same pointer, but npm warns on every call about a key it does not know, so pnpm's key cannot share that file. pnpm 10 keeps its pnpm config set -g path; pnpm 12 ignores the pointer and reads config.yaml, so a tracked pnpm-config.yaml (minimumReleaseAge: 10080) is linked to ~/.config/pnpm/config.yaml and ~/Library/Preferences/pnpm/config.yaml. On pnpm 12 config set -g finds the value already present and writes nothing.
  • README and the behaviour suite updated.

Verification

  • tests/release-age.test.sh (53 checks): the npm stub now resolves keys through the user file and then the file its globalconfig= names. Fresh host writes the pointer once and never the key; rerun writes nothing; a first-revision host loses the in-place line and keeps its token line; a different user-level value is kept and the run fails naming the override; an unlinked policy file fails naming the link; old npm / old pnpm / missing npm as before; npmrc carries only npm-known keys; every tracked file carries 7 days in its unit.
  • Against the real tools under a throwaway HOME seeded with a fake token and the first revision's line: setup wrote the pointer, deleted the old line, kept the token, npm config get min-release-age and pnpm config get minimum-release-age (pnpm 10.32) read 7 and 10080, the second run made no writes, and npm emits no warnings with the pointer in place.
  • Empirical checks behind the design: npm 11.19 honours globalconfig= set in the user file with user precedence intact and prefix unaffected; pnpm 10.32 resolves a week-old typescript@next through the pointer; pnpm 12.10 ignores the pointer, reads config.yaml, and resolves the same week-old build; npm warns Unknown global config "minimum-release-age" when pnpm's key is placed in the shared file.

via claude

@DJRHails
DJRHails merged commit f424464 into main Oct 9, 2026
1 check passed
@DJRHails
DJRHails deleted the release-age-tracked branch October 9, 2026 17:35

@DJRHails DJRHails left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Automated review: findings are posted inline. #187 was already merged, so the P2 fix is in a follow-up PR, #189. P3s are left for the author.

via gantry

Comment thread tests/release-age.test.sh
`~/.npmrc` is the pointer to the tracked one; put any further npm policy in
`npmrc`, not in setup. The user file still wins on precedence, so `setup.sh`
removes the copy of the key an earlier revision wrote there and fails if some
other value shadows the tracked one. `npm config set -g` now edits the

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

P3: docs. npm config set -g does edit the tracked file through the link, but it serialises the whole file and drops every comment. Checked on a copy: after npm config set -g fund=false, the file is just min-release-age=7 and fund=false, so the header explaining why pnpm's key must stay out is gone. Since the line just above says to put further policy in npmrc, maybe say to edit the file by hand, or warn that config set -g strips its comments.

via gantry

@DJRHails

DJRHails commented Oct 9, 2026

Copy link
Copy Markdown
Owner Author

Review Summary

#187 was already merged when the review ran, so the fix went into a follow-up PR, #189, instead of this branch. The core design checks out against the real tools in a throwaway HOME: npm honours a globalconfig= pointer set in the user file and reads min-release-age=7 through the link; pnpm 12.10 reads minimumReleaseAge: 10080 from the linked config.yaml; pnpm 10.32 with the pointer in place writes config set -g to its own ~/.config/pnpm/rc, not into the tracked npmrc, so npm stays warning-free. Bootstrap links files before it runs setup.sh, so the effective-value check is ordered correctly.

# Severity Finding Resolution
F1 P2 The test sandbox puts /usr/bin on PATH, so a system npm (NodeSource or Debian) answers the no-npm case and the suite fails. It runs as an unconditional pre-commit hook, so every commit on such a host is blocked. The bug dates from f7a6cc7 (#185). Fixed in #189 (d0a5734)
F2 P3 The README presents npm config set -g as the way to edit the tracked npmrc, but npm rewrites the file and drops its comments. Left for the author

Observation (P4): a host that ran #185 under pnpm 12 already has a real ~/.config/pnpm/config.yaml (written by config set -g), so the new link prompts or skips there. The gate still holds through that untracked copy.

Verified: bash tests/release-age.test.sh gave 1 failure before the fix (no-npm-message, with /usr/bin/npm 10.9.9 present) and all 54 checks after it. shellcheck is clean, shfmt -i 2 -d shows no diff, and the lefthook pre-commit suite passed on commit. The npm and pnpm behaviour above was checked with real npm 10.9.9, pnpm 12.10.1 and pnpm 10.32.0 (via corepack). Not verified: npm 11's behaviour, which is taken from the PR's own empirical checks. This repo has no CI check beyond this review.
Fix commit: d0a5734, on release-age-test-path (#189)
Reviewed head: b4d9a25

Verdict: approve

via gantry

DJRHails added a commit that referenced this pull request Oct 9, 2026
- F1 (P2, fixed): release-age.test.sh put /usr/bin on run_setup's PATH, so
  on a host with a system npm (NodeSource, Debian's npm) the real npm
  answered the no-npm case and the suite failed; it runs unconditionally
  as a pre-commit hook, so every commit on such a host was blocked. The
  sandbox now gets a filtered system bin dir without npm/npx/pnpm/pnpx/
  corepack. Origin: f7a6cc7 (#185).
- F2 (P3, left for the author): README presents npm config set -g as the
  way to edit the tracked npmrc, but npm rewrites it without its comments.
DJRHails added a commit that referenced this pull request Oct 9, 2026
uv records the user-level exclude-newer in uv.lock ([options]
exclude-newer-span), so the gate invalidates locks made without it
(`--locked` fails, `uv run` re-resolves) and locks re-made under it fail
`--locked` elsewhere. The README's "Lockfiles win" and uv.toml's
"versions already in uv.lock are kept" said otherwise.

The test-isolation fix originally in this change (PATH without the
system npm, sandboxed HOME) landed independently in #187; main's
version of tests/release-age.test.sh is kept.
DJRHails added a commit that referenced this pull request Oct 9, 2026
uv records the user-level exclude-newer in uv.lock ([options]
exclude-newer-span), so the gate invalidates locks made without it
(`--locked` fails, `uv run` re-resolves) and locks re-made under it fail
`--locked` elsewhere. The README's "Lockfiles win" and uv.toml's
"versions already in uv.lock are kept" said otherwise.

The test-isolation fix originally in this change (PATH without the
system npm, sandboxed HOME) landed independently in #187; main's
version of tests/release-age.test.sh is kept.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant