LPM-cli

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

SubcommandWhat it does
diffShow how the current trustedDependencies differs from the last install's snapshot
pruneRemove 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-none

Read-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-package to 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@version key, but a different integrity or scriptHash. 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-none

That 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-none

The 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.

FlagEffect
--jsonMachine-readable output for CI gating via jq
--assert-noneExit 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 --json

Removes 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.json but its trust entry stayed
  • A dep was renamed (the old name's pin is now orphaned)
  • A dep was moved (e.g., from dependencies to optionalDependencies and 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).

FlagEffect
-y, --yesSkip the confirmation prompt (required on non-TTY)
--dry-runPreview without writing
--jsonMachine-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