| namespace | aiwg |
| name | pnpm-release-age-gate |
| platforms | ["all"] |
| description | Configure pnpm's minimumReleaseAge gate (7-day default, 10-day high-sensitivity) plus blockExoticSubdeps for workspace-scope dep-source enforcement. Includes Corepack detection and lockfile-caveat warning. |
pnpm-release-age-gate
Use this skill when a user has chosen pnpm as their package manager
and wants to apply the same release-age-gate hardening that
npm-release-age-gate provides for npm. pnpm is often the preferred
baseline for new projects because minimumReleaseAge AND
blockExoticSubdeps can be enforced at the workspace level — npm
has no equivalent for the latter.
Triggers
- "pnpm release age gate"
- "pnpm minimumReleaseAge"
- "pnpm blockExoticSubdeps"
- "pnpm supply chain hardening"
- "configure pnpm 7 day gate"
Prerequisites
- pnpm v9.0+ installed (
pnpm --version)
package.json exists at repo root
If pnpm is below v9.0, the skill should refuse to proceed and direct
the user to upgrade — minimumReleaseAge was introduced in v9.0 and
older versions silently ignore it.
Configuration paths — pick one based on workspace shape
Option A — Single-package repo (most common)
Add the gate to .npmrc at repo root:
minimum-release-age=10080
block-exotic-subdeps=true
Option B — Multi-package workspace
Add the gate to pnpm-workspace.yaml:
packages:
- 'packages/*'
- 'apps/*'
minimumReleaseAge: 10080
blockExoticSubdeps: true
Workspace-scope is the pnpm advantage over npm — every nested package
inherits the gate without per-package config.
Option C — Operator-wide via pnpm global config
pnpm config set minimum-release-age 10080
pnpm config set block-exotic-subdeps true
Use this only when the entire dev machine should apply the gate
across all projects. Per-repo config (Option A or B) is preferred —
it travels with the repo and works in CI without machine setup.
Unit conversion reference
pnpm uses minutes for minimumReleaseAge:
| Days | Minutes value |
|---|
| 1 | 1440 |
| 7 (recommended default) | 10080 |
| 10 (high-sensitivity profile) | 14400 |
| 14 | 20160 |
| 30 | 43200 |
This differs from npm (min-release-age in days) and Bun
(install.minimumReleaseAge in seconds). Document the unit
inline when committing the config so future readers don't misread it.
Lockfile caveat
The gate must be active before pnpm install or pnpm update
resolves dependencies. If the existing pnpm-lock.yaml was generated
without the gate, the gate is checked on the NEXT resolution pass —
not retroactively against the lockfile.
To apply the gate retroactively:
rm pnpm-lock.yaml
pnpm install
This is destructive to existing pins and may pull in newer
intermediate versions. Coordinate with the team before running.
Corepack detection
Check whether the project pins a pnpm version via Corepack:
node -p "require('./package.json').packageManager"
Output like pnpm@9.15.0 means Corepack will use that exact version
in CI. The skill should:
- Confirm the pinned version is ≥ v9.0 (else flag — gate is silently ignored)
- Document the pinned version in the audit output
- Suggest a Corepack pin if the project doesn't have one yet:
corepack use pnpm@latest
Override policy
Genuine emergency overrides:
pnpm install <pkg>@<version> --ignore-min-release-age
Document every override with reason + sunset date. Overrides should
be reviewed quarterly.
CI integration
Add a verification step to the publish/build workflow:
- name: Verify pnpm gate active
run: |
set -euo pipefail
AGE=$(pnpm config get minimum-release-age 2>/dev/null || echo "0")
EXOTIC=$(pnpm config get block-exotic-subdeps 2>/dev/null || echo "false")
if [ "$AGE" -lt 10080 ] || [ "$EXOTIC" != "true" ]; then
echo "✗ pnpm gate not configured to baseline (minimumReleaseAge≥10080, blockExoticSubdeps=true)"
exit 1
fi
echo "✓ pnpm gate active: $AGE minutes, blockExoticSubdeps=$EXOTIC"
What to inspect during review
.npmrc OR pnpm-workspace.yaml for minimumReleaseAge and blockExoticSubdeps
package.json packageManager field for Corepack pin
- CI workflow has the verification step above
pnpm-lock.yaml was generated AFTER the gate was committed (timestamp check)
Output format
When auditing an existing pnpm project, produce a structured report
at .aiwg/security/working/pnpm-release-age-audit.md:
# pnpm Release-Age Gate Audit
**pnpm version**: <version> (Corepack pinned: yes/no)
**Workspace shape**: single-package / multi-package
**Gate active**: yes (10080 min) / yes (custom: <value>) / no
**blockExoticSubdeps**: true / false / unset
## Findings
### <severity> — <description>
- File: <path>
- Issue: <what's wrong>
- Fix: <exact change>
## Clean Checks
- ...
## Recommendations
- ...
See Also
References