Verify Agent-Generated Dependencies Before You Merge
Last reviewed: 2026-08-07
Direct answer
Treat every dependency edit from a coding agent as a supply-chain change, even when the patch looks like a one-line import. Before merge, identify the package and requested reason, compare the manifest and lockfile as a pair, inspect the exact resolved artifacts and integrity metadata, run the repository’s clean-install and test commands, and retain a small, reviewable record of what was checked. GitHub’s dependency review documentation describes dependency review as a way to examine dependency changes in pull requests, including security and license considerations. Use that review as a gate, not as a substitute for understanding why the agent added the dependency.
The practical acceptance rule is simple: merge only when a human can answer four questions from the pull request and its evidence: What changed? Why was it needed? Where did each artifact come from? Can another checkout reproduce the same tree? If any answer is missing, pause the agent’s repair loop and request clarification.
Who this is for
This workflow is for teams that let coding agents edit application repositories, CI configuration, developer tooling, or deployment code. It is especially useful when an agent can run package managers, update lockfiles, or open pull requests without a developer watching every command. It applies to JavaScript projects using package.json and package-lock.json, but the review pattern generalizes to other ecosystems: compare the declared manifest with the resolver’s lockfile, verify the source and digest of each artifact, and make the installation test deterministic.
It is not a replacement for your package manager’s security tooling or your organization’s license policy. Instead, it gives reviewers a repeatable boundary around an agent’s authority. For a small, dependency-free code fix, use your normal change review. For a package addition or transitive graph rewrite, use the full workflow below.
Key takeaways
- Ask the agent to state the dependency intent before it edits a manifest: feature, bug fix, build step, or test-only support.
- Review
package.jsonandpackage-lock.jsontogether. npm says the lockfile describes the exact tree generated and is intended to be committed so teammates, deployments, and CI install the same dependencies (npm’s package-lock documentation ). - Treat a changed
resolvedlocation, integrity value, registry, git reference, install script, or dependency scope as a review item, not harmless formatting. - Use a clean, network-controlled install and the existing test and build commands before approval; record commands and outcomes without recording credentials or private URLs.
- Capture provenance facts in the pull request: package name, requested range, resolved version, source, integrity digest, lockfile version, agent run identifier, reviewer, and decision.
- Use GitHub dependency review and your normal vulnerability and license checks to surface risk; do not infer safety merely because installation succeeded.
- Escalate unexplained transitive additions, registry changes, digest changes, unverifiable artifacts, and repeated agent retries that produce different lockfiles.
Sources checked
The workflow is grounded in three public references checked for this article. GitHub’s Dependency review page
explains the pull-request review surface for dependency changes and the security and license questions it can expose. npm’s package-lock.json reference
states that the lockfile records the exact generated dependency tree, supports identical installs, improves source-control visibility, and includes fields such as resolved, integrity, and dependency metadata. SLSA’s requirements
organize expectations for producing and verifying provenance across build and source tracks. Those sources support the checks in this guide; repository-specific policy, package-manager behavior, and risk thresholds still require local confirmation.
Contract details to verify
Define the change boundary
Start with a bounded task brief. Ask the agent to name the package, the code path that needs it, the acceptable version range, the package-manager command it plans to run, and the files it may modify. Link the brief to the pull request. A useful scope note can follow the change-scope workflow for agent pull requests , while an evidence packet can follow the change evidence packet guide . Keep the request narrow enough that an unexpected package or registry is obvious.
Compare the manifest and lockfile
For each direct dependency, confirm that the manifest entry matches the intended scope: dependencies, devDependencies, optional, or peer. In the lockfile, trace the package’s path and every new transitive node. Compare the declared range with the resolved version and check whether the resolved field points to the expected registry or an approved git commit. Check integrity values where the package manager records them. npm documents that resolved identifies the fetched tarball or git URL and that integrity records a subresource-integrity digest; these are provenance evidence, not decorative fields.
Confirm that the lockfile format is one your supported package-manager version understands, and flag broad lockfile rewrites that are not explained by the task. A lockfile-only diff can be legitimate after a tool upgrade, but the reviewer should be able to explain every changed package, source, and digest. Ask the agent to produce a graph summary before it attempts a second regeneration.
Check execution behavior and policy
Inspect package-manager configuration, registry configuration, workspace definitions, lifecycle scripts, and CI installation flags at the same time. A package may run preinstall, install, or postinstall scripts; npm’s lockfile reference exposes a hasInstallScript indicator for package entries. Decide whether scripts are allowed in this repository and whether the new package actually needs them. The agent should not silently widen network access, add a new registry, or disable verification to make an install pass.
Use the repository’s supported clean-install command in an isolated checkout, with the lockfile-enforcing mode appropriate to that package manager. Then run the existing unit tests, static checks, and relevant build. Preserve the tool versions and platform assumptions in the evidence so another reviewer can reproduce the result.
Record a provenance contract
Capture a provenance tuple for every new direct package and any high-risk transitive package:
package = example-package
requested_range = ^4.2.0
resolved_version = 4.2.3
source_host = registry.npmjs.org
artifact_reference = [REDACTED]
integrity = sha512-[REDACTED]
lockfile_version = 3
manifest_scope = dependencies
install_scripts = reviewed
agent_run_id = run-[REDACTED]
reviewer = human-reviewer
verdict = pending
The placeholders are deliberate. Store an artifact URL only when it is public and approved; otherwise record a sanitized host or an internal evidence identifier. Never put access credentials, authorization material, passwords, or private registry details in a pull request, log, URL, or provenance field. A digest can identify an artifact without exposing how it was fetched. SLSA’s requirements provide a useful framing for treating provenance as information that can be produced and verified, rather than as an assertion embedded in a commit message.
Happy path: one controlled dependency addition
- The agent proposes
example-packagefor a named feature and stops after editing the manifest and lockfile. - The reviewer checks the diff, confirms the package is in the correct scope, and traces all newly introduced transitive entries.
- In an isolated checkout, the reviewer runs the repository’s documented clean install with the lockfile-enforcing mode, then runs unit tests, static checks, and the relevant build. Use the project’s package-manager command; do not invent a replacement that changes resolution behavior.
- GitHub’s dependency review result is inspected for vulnerability and license findings, and any organization policy checks are recorded.
- The reviewer compares the resulting lockfile and dependency tree with the pull request, records the provenance tuple, and marks the change approved only when the tree is reproducible.
A sanitized log can look like this:
{
"event": "dependency_review",
"run_id": "run-[REDACTED]",
"repository": "org/project",
"commit": "abc1234",
"package": "example-package",
"resolved_version": "4.2.3",
"source_host": "registry.npmjs.org",
"integrity_present": true,
"lockfile_version": 3,
"clean_install": "pass",
"tests": "pass",
"dependency_review": "no findings",
"license_check": "pass",
"decision": "approve"
}
Keep logs useful but minimal. A run identifier, commit, package coordinates, check statuses, and reviewer decision are enough to correlate evidence. Hash or redact paths and URLs that could disclose private repository structure. Retain complete command output in an access-controlled system if your policy requires it, but keep the pull-request summary safe to share.
Error path: provenance or reproducibility breaks
Stop the merge when the agent adds a package that is absent from the task brief, changes a registry host, replaces a registry tarball with a floating git branch, or changes an integrity value without a version change that explains it. Also stop when a clean install produces a different lockfile, when a package lifecycle script is newly introduced and unreviewed, or when GitHub dependency review reports a vulnerability or license conflict. Capture the failing check, exact file and entry, the agent’s stated rationale, and the last known-good commit. Re-run once in a clean checkout to rule out a transient cache issue; do not let the agent retry indefinitely. If the result remains unexplained, isolate the dependency change and escalate to the repository owner or security reviewer.
Failure modes
Manifest and lockfile drift. The agent edits package.json but leaves the lockfile stale, or regenerates the lockfile with a different package-manager version. Regenerate in a pinned environment and compare the complete graph, then commit only the intentional result.
Transitive surprise. A small direct addition pulls in many packages, optional platform variants, or a package with an install script. Require a graph diff and a reason for each high-risk node. A successful test run does not clear supply-chain risk.
Source substitution. A resolver changes from the approved registry to a mirror, URL, or git reference. Compare resolved locations and repository configuration, verify the source independently, and reject floating references.
Digest or artifact mismatch. The resolved version is unchanged but integrity or the fetched artifact changes. Treat it as a new artifact; investigate the registry record and retain both old and new evidence before considering an update.
Policy blind spot. Dependency review is not enabled for the repository, or its result is ignored because the agent opened the pull request. Enable the applicable GitHub control and make its result a required check, while keeping human review for intent and provenance.
Evidence leakage. Logs include private registry addresses, environment values, authorization material, or full workspace paths. Replace sensitive values with [REDACTED], retain restricted diagnostics separately, and review the sanitized record before posting it.
Retry divergence. Repeated agent attempts produce different ranges or lockfile graphs. Freeze the worktree, compare attempts, and ask for a deterministic command and environment. Divergence is a signal to escalate, not permission to choose the smallest diff.
FAQ
Should every transitive package get a manual review?
Review depth should follow risk and change size. Always account for the full graph, then manually inspect new transitive packages that introduce scripts, native code, unusual sources, elevated permissions, or license concerns. Automated dependency and vulnerability checks can prioritize the list, but they do not explain why the agent selected the dependency.
Is a lockfile enough to prove provenance?
No. A lockfile can record a resolved location and integrity digest and can make installs repeatable, but provenance also needs context: who or what requested the change, which source was approved, how it was verified, and which build or review produced the evidence. Use the lockfile as one durable input to that record.
What should happen when the package manager updates many unrelated entries?
Pause and split the work. Ask the agent to reproduce the intended change with the repository’s supported tool version, or open a separate maintenance update. A broad graph rewrite makes it difficult to attribute security, license, and behavior changes to the feature request.
Can an agent run the dependency review itself?
It can collect results, but a human should own the merge decision. Give the agent read-only checks and require it to report commands, versions, findings, and unresolved assumptions. Do not grant it authority to dismiss alerts, alter policy, or merge its own dependency change.
How should teams handle private packages?
Keep private registry addresses and credentials out of public article examples and pull-request summaries. Record only the approved source identifier and a redacted evidence reference in shared logs, and keep detailed access-controlled records under your organization’s policy.
Reader next step
Pick one repository where a coding agent can modify dependencies. Add a small review template with fields for package intent, manifest scope, resolved version, source host, integrity presence, lockfile version, clean-install result, dependency-review result, reviewer, and verdict. Run the happy path on a harmless test dependency, then deliberately exercise the error path with an unexplained registry or lockfile change in an isolated branch. Link the resulting evidence to your agent run evidence ledger , and make the approval rule explicit: no merge while provenance, reproducibility, or policy status is unknown.
For teams that route model traffic through a gateway, keep this dependency review independent from model selection and record the agent run context without exposing credentials. The next useful move is to turn the checklist into a required pull-request check and have a designated reviewer sign the final provenance record.