lpm trust
Inspect and clean the trustedDependencies allowlist.
lpm trust <subcommand>trustedDependencies (in package.json > lpm) is the allowlist that decides which packages may run lifecycle scripts under the default script-policy: deny. lpm trust is the inspection-and-cleanup tool for that list.
To add entries, use lpm approve-scripts (the interactive review flow). lpm trust is for everything that comes after — auditing the list and pruning stale entries.
Project trust only. lpm trust operates on package.json > lpm > trustedDependencies exclusively. Global trust lives in a separate file (~/.lpm/global/trusted-dependencies.json) and is managed through lpm approve-scripts --global — there is no lpm trust --global today. Under the hood the storage is independent: a global approval doesn't show up in lpm trust diff, and pruning the project list doesn't touch the global file.
Subcommands
| Subcommand | What it does |
|---|---|
diff | Show how the current trustedDependencies differs from the last install's snapshot |
prune | Remove entries whose package is no longer in the resolved tree |
lpm trust diff
lpm trust diff
lpm trust diff --assert-none
lpm trust diff --json
lpm --json trust diff --assert-noneRead-only. Compares the current package.json > lpm > trustedDependencies against the snapshot LPM took on the last lpm install. Surfaces three classes of change:
- Additions — entries that weren't there last install. Potential silent PR poisoning vector ("someone added
evil-packageto the trust list — was that reviewed?") - Removals — entries that were there but are now gone. Usually intentional cleanup, but worth a glance.
- Same-key binding changes — same
name@versionkey, but a differentintegrityorscriptHash. Indicates the package contents changed without a version bump (re-publish, tampering).
The snapshot lives at <project>/.lpm/trust-snapshot.json, written by every successful lpm install. If the project has never been installed with LPM, diff reports "no prior snapshot" and exits cleanly — there's no baseline to compare against yet.
trust diff is informational by default — it prints whatever it found. For a built-in CI gate, use --assert-none:
lpm trust diff --assert-noneThat exits non-zero when any added, removed, or changed entry is present.
If you still want machine-readable output for bots or logs, --json works with the same gate:
lpm trust diff --json --assert-noneThe JSON envelope: success, schema_version, command, assertion_failed, diff_count, snapshot_captured_at, current_binding_count, added[], removed[], changed[]. Each entry carries key (e.g., esbuild@0.25.1), previous, and current (the integrity / scriptHash before and after). When --assert-none fails in JSON mode, LPM emits this same single diff envelope with success: false, error_code: "trust_diff_assert_none", and exits non-zero.
| Flag | Effect |
|---|---|
--json | Machine-readable output for CI gating via jq |
--assert-none | Exit non-zero if any diff entries are present |
lpm trust prune
lpm trust prune # interactive — prompts before writing
lpm trust prune --dry-run # preview, don't write
lpm trust prune -y # skip the prompt (required on non-TTY / CI)
lpm trust prune --jsonRemoves trustedDependencies entries whose package isn't in the resolved tree anymore. "No longer in the tree" means: lpm.lock has zero entries with this name (regardless of version). Per-version drift on a name that's still installed is not considered stale — that's drift, handled by the install-time gate, not by prune.
Entries become stale when:
- A dep was removed from
package.jsonbut its trust entry stayed - A dep was renamed (the old name's pin is now orphaned)
- A dep was moved (e.g., from
dependenciestooptionalDependenciesand never reinstalled)
lpm trust prune reads lpm.lock to determine what's installed. If the lockfile is missing, the command exits with no lpm.lock found — run \lpm install` before pruning trust entries` — refusing to prune from an empty installed-set (which would mark everything stale).
The interactive prompt confirms the removal list before writing. In CI / non-TTY contexts, -y is required — without it, prune errors with lpm trust prune needs a TTY for confirmation. Pass \--yes` to ...`.
--dry-run runs the analysis normally but doesn't touch package.json.
The JSON envelope: success, schema_version, command, dry_run, mutated (the actual final state — false on --dry-run or no-op), stale_count, stale[] (the keys removed).
| Flag | Effect |
|---|---|
-y, --yes | Skip the confirmation prompt (required on non-TTY) |
--dry-run | Preview without writing |
--json | Machine-readable output |
CI usage
- run: lpm install --offline
- run: lpm trust diff --assert-none
- run: lpm trust prune --dry-run --json # informational — would prune anything?trust diff --assert-none is the built-in drift gate: fail the build if trustedDependencies changed since the last reviewed install. Add --json if you also want structured output in CI logs.
prune --dry-run is for hygiene reports only — it always exits zero. Gate it the same way if you want to fail on stale entries:
lpm trust prune --dry-run --json | jq -e '.stale_count == 0'See also
lpm approve-scripts— add entries to the trust listlpm rebuild— runs scripts for trusted packagespackage.json"lpm.trustedDependencies" — the file format