# pnpm 12.11 Lets npm Dependencies Carry Agent Skills: After Approving Once, What Should You Check on Upgrade?

> Canonical: https://vxi.me/en/posts/pnpm-agent-skills-approval-scope/
> Locale: en-us
> Published: 2026-10-13
> Updated: 2026-10-13
> Markdown: https://vxi.me/en/posts/pnpm-agent-skills-approval-scope.md

# pnpm 12.11.0 Skills Permissions in Practice: What Does “Approve Once” Actually Mean?

**Description:** Based on the pnpm v12.11.0 source code and version-pinned documentation, this article examines the discovery scope, approval and linking behavior of Skills, then uses an independent synthetic model to test key branches and help developers assess dependency upgrades and permission management.

## Discovery and Permission Boundaries

At first, I thought the question was fairly simple: if a dependency adds a `SKILL.md`, pnpm either puts it in the Agent directory during installation or ignores it completely. But as I traced through the pinned pnpm 12.11.0 source, I found that there are several steps in between: discovery, permission checks, and linking. Those boundaries are what matter when deciding what “approve once” means.

I started by tracing the discovery logic, assuming that any Skill file in the dependency tree would enter the approval flow. But the scan turned out to be narrower: pnpm checks the direct dependencies of each workspace importer in the lockfile and scans only one level of Skills directories. Indirect dependencies aren’t part of this discovery path, so “a file exists in the dependency tree” and “pnpm will discover it” are not equivalent.

Next, I looked separately at installation, linking, and Agent loading. The package’s files may already be present in the dependency directory; the permission state determines whether pnpm creates a symbolic link to the target directory; after that, whether Claude Code or another Agent reads the Skill, and how it handles it, is up to that client. The pnpm source handles linking—it does not parse or execute Skill contents.

The permission branches include pending approval, denied, and approved states. Approval is handled at the package level, and `pnpm approve` covers both build scripts and Skills permissions; it does not mean each file is reviewed individually. Build script permissions and `permissions.skills` are separate permission surfaces. Approval of a package’s build scripts does not mean its Skill contents have been reviewed separately.

The point I had to stop and verify was the scope of approval. The official v12.11.0 documentation says that a single package-level approval covers all Skills in that dependency and carries over to later versions. When upgrading, watch for changes to instructions in the new version: the existing approval may still apply, even if the new version adds or rewrites a Skill.

When multiple eligible versions are available in the workspace, the source selects the highest installed eligible registry version. This affects which content is actually linked, so checking only the version range in `package.json` is not enough. To determine what an Agent might read after an upgrade, you also need to check the package version that was actually selected and the Skills it contains.

The target directory is subject to specific conditions, too. In v12.11.0, pnpm checks the `CLAUDECODE`, `CURSOR_AGENT`, and `GEMINI_CLI` environment variables, or for Agent Skills directories already present in the workspace; `skills.dirs` can explicitly override this. An empty explicit configuration disables Skills. If no target directory is detected automatically during approval, pnpm raises a no-target error.

```yaml
# pnpm-workspace.yaml
skills:
  dirs:
    - .claude/skills
    - .cursor/skills
```

I also initially assumed that revoking permission would remove the contents of the associated directories as well. The source and the independent filesystem model show a narrower boundary: links created by pnpm are removed, while manually created local Skills are left alone; a target path occupied by a real directory is not replaced. Branches involving package removal or a missing target directory should also be understood in terms of their respective link-cleanup and error-handling logic.

## Synthetic Model and Test Results

To make these branches more concrete, I wrote an independent synthetic filesystem model using the Node 22.16.0 standard library. It creates temporary fake dependencies, synthetic `SKILL.md` files, and symbolic links, then computes content fingerprints. The eight scenarios cover pending approval, denial, approval, a new Skill added after an upgrade, revocation, a path conflict, an indirect dependency only, and the absence of an automatically detected target directory.

All eight scenarios covered by the model passed. In the upgrade scenario, the content fingerprint changed and a second Skill link appeared. On my first run, one scenario failed because I used “expected link count is zero” to determine whether an approved Skill existed, incorrectly treating “no target directory” as a failure. After tracking the number of approved Skills separately, all eight scenarios passed on the next run.

## Repository Checks and Scope

When checking a repository, you can start with `pnpm permissions` or `pnpm permissions list` to review permissions, then compare them with the workspace configuration. After upgrading a dependency, inspect the Skills files in the new version and review the differences. Projects that are more concerned about instruction drift can pin dependency versions and compare `SKILL.md` files in CI.

```sh
pnpm permissions
pnpm permissions list
```

### Boundaries / Limitations

This analysis uses the pnpm v12.11.0 source code and version-pinned documentation as its baseline. Testing was done with a synthetic model running independently under Node and covers filesystem behavior. The model does not invoke the pnpm CLI, perform real installations or updates, or connect to an Agent. Client-side discovery and execution rules may also change with each client’s version. Environment detection changes in pnpm 12.11.1 should not be attributed retroactively to 12.11.0. The scope of trust for future versions that comes with package-level approval is a design boundary to consider during upgrade reviews.

**References:** [pnpm v12.11.0 source code](https://github.com/pnpm/pnpm/tree/v12.11.0) · [pnpm v12.11.0 documentation](https://github.com/pnpm/pnpm/tree/v12.11.0/docs)
