How-To

How to Review AI-Added Dependencies Before You Merge

A dependency review method for AI-written pull requests covering lockfiles, vulnerabilities, licenses, provenance, maintenance, and removal.

  • #ai-agents
  • #dependencies
  • #software-supply-chain
  • #licenses
  • #provenance

An AI coding agent can produce a clean-looking diff while quietly expanding the software supply chain. It may add a library because it remembers a familiar solution, regenerate a lockfile with hundreds of indirect changes, copy a package name that is one character away from the intended project, or declare the task complete without proving that the new code needs the dependency at all.

The review problem is therefore larger than “does the code compile?” A dependency change is a claim about architecture, identity, versions, security, legal permissions, build inputs, and future maintenance. Each claim needs evidence in the diff or in a primary source. Fluent explanations are not evidence.

This guide turns a recurring complaint about AI coding tools—extra changes, invented interfaces, and premature completion claims—into a dependency inspection method. It complements How to Review AI-Generated Code, which starts with task fit and behavioral correctness. Here the unit of review is every new, changed, or removed component in the resolved dependency graph.

The central rule is simple:

Do not approve the dependency because the agent sounds confident. Approve only the smallest dependency graph that is supported by inspectable change evidence.

This article does not decide who owns copyright in AI-generated code. That question depends on facts and law outside a package diff. The narrower review asks what changed, which third-party material entered the graph, what license and provenance records are available, and whether the repository can verify the resulting build.

The dependency change contract

Before reading package metadata, compare the pull request with the original task. A reviewer should be able to complete this sentence:

“To satisfy requirement X, this change uses component Y at resolved version Z, and the repository demonstrates that choice with evidence E.”

If X, Y, Z, or E is missing, the review is not ready for an approval decision. A passing test suite can show that observed behavior matched the tests. It does not prove that the package was necessary, correctly identified, appropriately licensed, maintained, or produced by the claimed build.

Review questionEvidence that can answer itEvidence that cannot answer it alone
Was a dependency required?Call sites, before-and-after design, rejected standard-library or existing-library optionAgent explanation saying the package is “best practice”
What package entered the graph?Manifest diff, lockfile diff, registry namespace, source-repository linkA similar-looking import name
What version will be used?Resolved lockfile entry or equivalent resolver outputA broad manifest range by itself
Is a known vulnerability reported?Advisory database result tied to the exact ecosystem, name, and version“No CVE found” without naming the data source and scan time
What license evidence exists?Package metadata, license file, SPDX identifier or expression, counsel-approved policy resultRepository topic, README badge, or assumption based on popularity
How was the artifact produced?Verifiable provenance or artifact attestation bound to a digestA release page saying “built securely”
Can it be removed?Reverted manifest and lockfile change plus tests or an isolated replacementAn agent’s claim that it is lightweight

GitHub’s supply-chain documentation distinguishes direct dependencies named by a project from transitive dependencies pulled in by those direct dependencies. Its dependency graph derives data from manifests and lockfiles, and it notes that build-time resolution can require dependency submission for a more complete graph. That distinction matters because a one-line manifest edit can produce a much larger effective change. Source: https://docs.github.com/en/code-security/concepts/supply-chain-security/supply-chain-security

Eight separate things reviewers must not collapse

The fastest way to miss risk is to treat “the dependency” as one object. Review it through eight separate lenses.

LensWhat it meansMinimum review record
Direct dependencyExplicitly requested by the project in a manifest or equivalentName, requested range, intended call site, owner
Transitive dependencyIntroduced through another componentParent path, resolved version, runtime or build role
ManifestHuman-authored intent and version constraintsExact changed lines and rationale
LockfileResolver-selected graph, often including integrity dataAdded, removed, and changed nodes; unexplained churn
Known vulnerabilityPublicly reported issue mapped to package identity and versionSource, query time, affected range, fix or mitigation
LicenseDeclared permissions and conditions for a componentIdentifier or text location, policy result, exceptions
MaintenanceEvidence about ongoing project stewardshipRelease history, repository activity, security policy, ownership changes
ProvenanceEvidence about where and how an artifact was builtSubject digest, signer or builder identity, source and workflow reference

Two more lenses cut across all eight:

  • Build-only exposure: A formatter, compiler plugin, bundler, code generator, test runner, or documentation tool may never ship in the runtime artifact, yet it can execute during a privileged build and influence the output. “Dev dependency” is a deployment label, not a security exemption.
  • Removal: The dependency should have an exit path. If its use can be replaced by a few stable lines, an existing project utility, or a platform API already in scope, the package may be unnecessary graph growth.

For agent permissions and tool boundaries around package operations, see Sandbox AI Coding Agents Without Blocking Useful Work and MCP Security Checklist. An agent that may edit source does not automatically need authority to install packages, execute package lifecycle scripts, publish artifacts, or change CI.

Manifest and lockfile are different evidence

A manifest records requested constraints and dependency categories. A lockfile records a resolver’s selected graph for a particular tool and format. Review both, because each can hide a different failure.

In the npm ecosystem, package.json expresses project metadata and dependency requests, while package-lock.json describes the exact generated tree so later installs can reproduce that tree. Cargo documents Cargo.toml as the manifest and Cargo.lock as exact dependency information. Python’s packaging specification defines pylock.toml for reproducible installation. NuGet can generate packages.lock.json containing the full dependency closure. Go uses go.mod for module requirements and go.sum for cryptographic hashes of direct and indirect module content. Maven resolves transitive dependencies from POM metadata and applies scopes. Official references appear in the Sources section.

EcosystemIntent or manifest evidenceResolution or integrity evidenceReview trap
npmpackage.jsonpackage-lock.json or the repository’s selected lock formatA small request can rewrite unrelated nodes if the wrong tool version is used
Pythonpyproject.toml or approved requirements inputpylock.toml or the repository’s established lock formatEnvironment markers and extras can change the graph by platform
RustCargo.tomlCargo.lockFeature flags can add code and transitive packages without a new top-level name
Gogo.modgo.sum plus the selected module graphA checksum proves content consistency, not suitability or license approval
Mavenpom.xml and dependency managementResolved dependency tree and repository metadataScope and exclusions can change what reaches compile, test, or runtime paths
NuGetProject PackageReference itemspackages.lock.json when enabledFloating versions can resolve differently until the graph is locked

The reviewer should reject unexplained lockfile churn. “The package manager did it” describes a mechanism, not a rationale. Ask why unrelated packages moved, whether the repository-standard tool and version produced the file, and whether the diff can be regenerated from only the intended manifest edit.

Do not hand-edit a lockfile merely to make the diff smaller. Regenerate it using the repository’s documented process in a controlled environment, then inspect the result. If the task does not authorize installation or external execution, the appropriate result is a blocked verification note, not a fabricated clean lockfile.

Direct and transitive dependencies need different questions

For a direct dependency, the primary question is necessity: why did the contributor choose this component? For a transitive dependency, the primary question is path: which parent introduced it, and is that path expected?

Dependency classQuestions to askTypical evidence
Direct runtimeIs there a real call site? Is an existing component sufficient? Is the API used actually present in the pinned version?Diff, local type information, official versioned documentation, focused tests
Direct developmentDoes it execute in build, test, generation, lint, or documentation? What permissions and inputs does it receive?Build configuration, lifecycle-script review, sandbox record
Transitive runtimeWhich direct parent requires it? Does it reach the shipped artifact?Lockfile parent path, bundler or packaging inventory, SBOM
Transitive buildDoes it execute or only supply data? Can it alter generated output?Build graph, resolved build inputs, provenance record
Optional or feature-gatedWhich feature, extra, platform marker, or profile activates it?Manifest feature configuration and environment matrix
Test-onlyCan it access secrets, network, repository write permissions, or release credentials in CI?Workflow permissions and test command boundary

Transitive does not mean unimportant. GitHub’s documentation says dependency review can show indirect changes represented in lockfiles, while its dependency graph documentation explains that dependencies resolved only during builds may require automatic or manual submission. Sources: https://docs.github.com/en/code-security/concepts/supply-chain-security/dependency-review and https://docs.github.com/en/code-security/concepts/supply-chain-security/dependency-graph-data

When an AI agent says “only one package was added,” count resolved nodes, not just manifest lines.

Known vulnerabilities: precise identity before severity

A vulnerability lookup is meaningful only when it binds four fields:

  1. ecosystem;
  2. normalized package name;
  3. resolved version or commit;
  4. advisory source and observation time.

OSV describes a schema that maps vulnerabilities to open-source package versions or commit hashes and aggregates sources that adopt the OSV format. GitHub compares dependency data with its advisory database for Dependabot alerts. A package-manager-native audit may add ecosystem-specific resolution. None of these sources can prove the absence of an undisclosed vulnerability.

ResultReviewer actionRequired note
Resolved version falls in an affected rangeReject or require a documented, tested mitigation and owner-approved exceptionAdvisory ID, affected range, reachable role, proposed fixed version
Advisory matches a name but not the ecosystemCorrect the identity before decidingWhy the original match was false
No known advisory is returnedContinue other checksSource and timestamp; state that the result covers known records only
Version is unresolvedStop the vulnerability decisionMissing lock or build-resolution evidence
Scanner cannot parse the ecosystem or fileUse an approved alternate source or manual lookupCoverage gap and remaining uncertainty
Advisory has no fixed versionConsider removal, isolation, or replacementExposure, compensating control, decision owner

Do not let an agent convert “the scanner returned zero findings” into “the package is secure.” The first is an observation about a data source at a time. The second is a conclusion the observation cannot support.

Use Machine Gates for AI Output for deterministic checks such as “every dependency diff has an advisory result.” Keep the qualitative decision—whether the component is necessary and whether the exposure is acceptable—with a responsible reviewer, as described in Human-in-the-Loop AI Agents.

SPDX provides a standard license list with identifiers, names, text, and canonical URLs, and its specification can represent software components, relationships, and licensing information. An SPDX identifier makes records easier to compare; it does not decide whether a license is compatible with your product, distribution model, linking method, or obligations.

For each new component:

  • locate the license declared in package metadata;
  • inspect the license file in the exact source or artifact version when available;
  • record an SPDX identifier or expression only when the evidence supports it;
  • note multiple licenses, exceptions, generated code, vendored components, and “license reference” cases;
  • apply the organization’s approved-license policy;
  • escalate ambiguity instead of asking the AI to invent a compatibility conclusion.
License evidence stateDecision postureWhy
Clear identifier and matching text, allowed by policyContinue to the rest of reviewIdentity still needs confirmation; license approval is not security approval
Multiple licenses with an explicit choiceRecord the selected expression and conditionsThe reviewer must know which option governs use
Metadata and repository text disagreeReject pending clarificationA badge or registry field cannot safely override conflicting text
No license evidenceReject normal consumptionPublicly readable source is not the same as permission to use
Custom terms or an SPDX LicenseRefEscalate to the designated legal or policy ownerAutomated classification is insufficient
Copyleft, source-offer, notice, patent, or network-use condition is relevantApply the organization’s distribution-specific processCompatibility depends on use and distribution facts

Keep this review focused on observable third-party inputs. Do not infer a broad copyright result for the AI-authored glue code. Record the human-authored task, agent output diff, subsequent human edits, tests, package licenses, source references, and build evidence. Those records are useful regardless of how a later legal analysis classifies the code.

Maintenance status is evidence, not a popularity contest

A maintained project can still be unsuitable, and a quiet project can be stable. Avoid one-number judgments. OpenSSF Scorecard evaluates repository security practices, but its own description frames scores as information for a consumer’s trust and risk decision, not a universal approval verdict. Source: https://openssf.org/scorecard/

Collect a small, reviewable maintenance record:

  • date and substance of the latest relevant release;
  • whether the source repository and package registry point to each other;
  • security policy or vulnerability reporting route;
  • response to recent security issues when applicable;
  • maintainer or namespace ownership changes;
  • supported runtime versions;
  • release and deprecation policy;
  • unresolved issues that match your intended use;
  • automated score or badge details, including the individual checks rather than only an aggregate.
SignalHelpful interpretationUnsafe shortcut
Recent releaseThe release process is active“Recent means secure”
Long gap with stable scopeMay be mature and intentionally quiet“Old means abandoned”
Many open issuesNeeds context about project size and triage“Issue count measures quality”
Security policyProvides a reporting route“A policy proves fast remediation”
OpenSSF Scorecard checksSurfaces repository practice evidence“A score above a chosen number auto-approves”
Ownership transferRequires identity and release-history scrutiny“The familiar package name is enough”

If maintenance evidence is weak but the dependency is small, the removal test becomes more important. The lowest-risk package may be the package you do not add.

Typosquatting and package identity

Typosquatting review begins before vulnerability and license review, because a correctly analyzed wrong package is still the wrong result. OpenSSF’s package repository security principles explicitly include steps to prevent typosquatting, such as namespacing or similar-name detection, as a package-repository capability. Source: https://repos.openssf.org/principles-for-package-repository-security.html

For every new name, compare:

  • exact spelling, separators, scope, and letter case used by the ecosystem;
  • registry publisher or organization;
  • source repository linked from the registry;
  • source repository’s link back to the registry;
  • expected documentation domain;
  • release history and first-publish date;
  • package contents and lifecycle scripts;
  • provenance or registry signature information when the ecosystem provides it.

Common warning patterns include a missing scope, swapped characters, singular versus plural, extra separators, a new package with the name of a familiar import, or metadata that points to a copied README but a different source repository. Do not ask the agent to “pick the closest name.” Ask it to show the exact primary-source identity.

npm documents provenance views that can expose build environment, workflow run, source commit, build file, and a transparency-log entry for packages published with provenance. npm also documents a signature and provenance audit command, but its prerequisites include installing dependencies. That command should therefore run only inside the repository’s approved dependency-verification process, not as an unapproved side effect of reviewing a name. Source: https://docs.npmjs.com/viewing-package-provenance/

Build-only dependencies are still supply-chain inputs

Runtime inventories often omit what made the artifact. That creates a blind spot for compilers, code generators, preprocessors, bundler plugins, test instrumentation, container builders, and downloaded scripts.

SLSA describes provenance as verifiable information about where, when, and how an artifact was produced. Its current specification separates build and source tracks and includes provenance among recommended attestation formats. GitHub artifact attestations are signed claims that can establish build provenance or associate an SBOM with an artifact. GitHub explicitly notes that attestations do not prove security; they provide information about where and how software was built. Sources: https://slsa.dev/spec/v1.2/ and https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations

Build-input questionEvidence to retain
What executed?Resolved package or tool identity and version
What source configured it?Reviewed build file and commit
What could it read?Checkout, environment, secrets, caches, and network policy
What could it write?Generated source, binary, package, image, or release asset
Which builder ran it?Builder identity and workflow run
Which inputs resolved at build time?Provenance resolvedDependencies, dependency submission, or equivalent inventory
Which output was produced?Subject name and cryptographic digest
Can a consumer verify it?Attestation verification result and trust policy

An SBOM and an attestation answer different questions. An SBOM inventories components and relationships. Provenance describes production. A signature or attestation binds a claim to an identity and artifact; the reviewer must still decide whether that identity and builder are trusted for this repository.

GitHub can export a repository dependency graph as an SPDX-compatible SBOM containing information such as versions, package identifiers, licenses, and transitive paths. It does not include downstream dependents. Source: https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/establish-provenance-and-integrity/export-dependencies-as-sbom

Six fictional pull requests and how to review them

The following pull requests are deliberately fictional. Package names use reserved example-style namespaces and must not be interpreted as real installation recommendations. The point is the review decision, not the package.

PRProposed changeEvidence presentedReviewer decision
PR 1: “Parse three config fields”Adds direct runtime package @example-labs/config-shape and 18 resolved nodesAgent says manual parsing is error-prone; no comparison with existing parserReject pending necessity proof; ask for the existing utility comparison and a no-new-dependency implementation
PR 2: “Upgrade HTTP helper”Changes one direct version and 47 lockfile nodesFocused tests pass; lockfile was produced with an unspecified tool versionReject the current artifact; regenerate with the documented tool, explain transitive changes, then rescan exact versions
PR 3: “Faster documentation build”Adds example-doc-transform as development-only with an install scriptBenchmark is local; workflow has write permission and a release tokenReject until the build is sandboxed, permissions are reduced, script content and provenance are reviewed, and benefit is reproduced
PR 4: “Add spreadsheet export”Adds example-sheet-writer; metadata says one license while source archive includes custom termsFeature tests passReject for conflicting license evidence; do not let behavioral tests override unresolved permission terms
PR 5: “Use familiar validation library”Adds exampl-validator, one character away from the task’s named componentRegistry page has a copied description and no verifiable source linkReject as an identity failure; do not install or execute it while investigating
PR 6: “Remove unused date utility”Deletes direct manifest entry but leaves imports and resolved transitive nodes through another packageAgent reports “dependency removed”Reject the completion claim; map remaining parent paths, remove or document call sites, and prove the shipped graph changed

PR 1: unnecessary direct dependency

Start at the call site. If the package is used for a stable, narrow operation already available in the language or repository, ask for the simpler change. The rejection is not “small packages are bad.” It is “the proposed graph growth has no demonstrated benefit.” If the dependency remains justified, record its exact API from official versioned documentation and add a focused test that would fail if the agent invented that API.

This is the dependency form of the phantom-convention problem described in How to Review AI-Generated Code: the agent reaches for a familiar public pattern even when the repository already has a local one.

PR 2: unexplained transitive churn

Review the manifest and lockfile separately. Confirm the direct requested range, the previous resolved version, the new resolved version, every parent path that materially changed, and the tool used to regenerate the lock. A test pass does not explain why 47 nodes changed. Require a reproducible diff produced from the intended edit.

PR 3: “development-only” execution

Inspect lifecycle scripts and workflow permissions before executing the package. A build tool can modify outputs or read credentials. Move the evaluation into a disposable environment with no production secrets, no publishing permission, and a network policy appropriate to the repository. If the task does not authorize execution, preserve the proposed diff as unverified and ask the authorized owner to run the documented check.

PR 4: conflicting license evidence

Stop. Do not average two license claims or ask the agent to choose the more permissive one. Record both sources, exact versions, and file paths, then route the conflict through the organization’s policy owner. Tests establish behavior, not permission.

PR 5: possible typosquat

Do not install the candidate to inspect it. Use registry metadata, source links, published archive inspection through an approved non-executing path, provenance, and namespace ownership. A copied README increases the need for identity proof. The safe outcome may be rejection without execution.

PR 6: false removal

“Removed from the manifest” and “absent from the resolved graph” are different states. Another direct component may still require the same package transitively. Separately check source imports, manifest intent, lockfile parent paths, bundled or packaged output, SBOM, and tests. The completion statement must match the strongest evidence available.

A review procedure for an AI-authored dependency PR

The sequence below is designed to stop cheap failures before expensive execution.

StageReviewer actionStop conditionOutput
1. ScopeCompare task, changed files, and claimed outcomeSurprising files or unrelated dependency editsScope discrepancy list
2. NecessityMap every direct dependency to a call site and requirementNo demonstrated need or existing component is sufficientNecessity note
3. IdentityVerify exact ecosystem, name, namespace, source, and publisherIdentity mismatch or suspected typosquatIdentity record
4. ResolutionInspect manifest intent and lockfile graphMissing resolution or unexplained churnDirect and transitive diff
5. SecurityQuery approved advisory sources for resolved versionsAffected version without accepted mitigationAdvisory record
6. LicenseMatch metadata, license text, SPDX expression, and policyMissing, conflicting, or disallowed evidenceLicense record
7. MaintenanceReview project stewardship and security practicesRisk exceeds repository policyMaintenance note
8. Build exposureInspect scripts, workflow permissions, and build-only toolsUnbounded execution or secret accessBuild-input map
9. ProvenanceVerify attestation and artifact digest when applicableClaim is unbound, invalid, or from an untrusted builderVerification result
10. BehaviorRun focused tests and end-to-end check in an approved environmentRequested behavior not provenTest evidence
11. RemovalTest whether the graph addition can be avoided or isolatedSimpler compliant solution existsKeep, replace, or remove decision
12. CompletionReconcile every claim with recorded evidence“Complete” exceeds what was verifiedAccurate review summary

At stage 1, use the same file-list discipline described in Debug Agent Instruction Conflicts and Write an AGENTS.md File for Coding Agents: explicit scope, approved commands, ownership, and completion evidence reduce the chance that a package operation becomes an unrelated refactor or release.

At stage 10, distinguish tests the agent wrote from independent tests. The author and its tests can share the same misunderstanding. Add at least one reviewer-selected assertion for the task’s most important boundary when risk warrants it.

For teams evaluating automated review products, AI Code Review Tools Compared explains where tool findings can help. Keep deterministic dependency-policy checks in machine gates, and do not replace accountable review with a second model’s prose.

Rejection conditions

Reject the pull request, or keep it explicitly unapproved, when any applicable condition below remains unresolved.

CategoryReject whenWhat would reopen review
ScopeDependency edit is unrelated to the stated requirementRevised scope or removal of the edit
NecessityNo call site or measurable benefit supports a new direct componentMinimal design comparison and focused evidence
IdentityPackage, publisher, source, or namespace cannot be matchedPrimary-source identity chain
TyposquattingName similarity or metadata conflict remains unexplainedVerified intended package and clean provenance
ResolutionNo exact deployed or built version can be determinedLockfile, build graph, or equivalent resolution
LockfileUnrelated churn cannot be reproduced or explainedRepository-standard regeneration and reviewed diff
VulnerabilityResolved version is affected and no accepted mitigation existsFixed version, removal, isolation, or approved exception
LicenseLicense is missing, contradictory, or outside approved policyReliable text and policy-owner decision
MaintenanceOwnership or release integrity changed without reviewVerified transfer, release history, and risk acceptance
Build executionPackage scripts or tools receive excessive permissionsSandbox and least-privilege workflow
ProvenanceArtifact claim cannot be verified against the expected identity and digestValid attestation under an approved trust policy
BehaviorFocused and end-to-end evidence does not support the requirementCorrected implementation and independent check
RemovalEquivalent existing code makes the package unnecessarySmaller implementation or documented tradeoff
CompletionSummary claims more than the evidence provesPrecise statement of verified and unverified work

Security scanners, SBOM exports, and attestations support these decisions; none grants blanket approval. GitHub’s artifact-attestation documentation explicitly says attestations do not guarantee security. OpenSSF Scorecard supplies signals rather than a universal verdict. SPDX standardizes records rather than issuing a legal compatibility decision.

When CI exists

Add deterministic checks to the pull request path without granting the agent broader authority:

  • fail on manifest changes without corresponding lockfile review where the ecosystem uses one;
  • produce a dependency diff showing direct and transitive additions, removals, and version changes;
  • query approved known-vulnerability sources using exact resolved identities;
  • enforce the organization’s license allow, review, and deny policy;
  • flag new package lifecycle scripts and build-tool execution;
  • produce or compare an SBOM when the release process supports one;
  • verify artifact attestations against the expected repository, workflow, builder, and digest;
  • run focused tests and the repository’s established verification suite;
  • require a human owner for exceptions;
  • retain machine-readable results with the reviewed commit.

Negative-test the gate. Feed it a fixture with a forbidden license, an affected version, a missing lockfile, an unexpected build script, and an invalid attestation. A check that has never been observed rejecting bad input is not yet trusted. Machine Gates for AI Output explains this fail-closed pattern in detail.

Keep package installation and build execution isolated from release credentials. GhostApproval: Which AI Coding Tools Were Affected? provides related context for why approval boundaries around tools matter, while Token Budgets and Circuit Breakers for AI Agents addresses runaway execution rather than dependency identity.

Manual review when there is no CI

No CI does not mean no process. It means the reviewer must create a dated evidence packet and avoid claiming automation that does not exist.

  1. Save the task text, changed-file list, and the contributor’s dependency rationale.
  2. Read the manifest diff without executing anything. List each direct addition, removal, requested range, feature, extra, scope, or environment marker.
  3. Read the lockfile diff as data. Count added, removed, and changed resolved nodes. Trace important transitive nodes to a direct parent.
  4. Verify package identity through official registry and linked source metadata. Check suspiciously similar names before any installation.
  5. Record license metadata and exact license-text location for the resolved version. Apply the organization’s policy; escalate ambiguity.
  6. Query approved advisory databases by ecosystem, exact name, and resolved version. Record the date and source.
  7. Review release history, security policy, maintainer changes, and relevant repository-security signals.
  8. Inspect package scripts and the project’s build configuration as text. Determine what would execute and what permissions it would receive.
  9. If an artifact and attestation already exist, verify their binding with an approved verifier and trust policy. Do not generate or upload artifacts merely to make the review look complete.
  10. Only when execution is authorized, use a disposable environment with no production secrets or publishing credentials. Follow the repository’s documented package-manager and test commands; do not substitute a remembered command.
  11. Exercise the changed behavior and add one reviewer-chosen check. Preserve command, environment, result, and limitations.
  12. Attempt the removal test: evaluate the smallest existing-library or platform alternative and compare the resulting graph and behavior.
  13. Write the verdict as “approved,” “rejected,” or “unverified,” followed by evidence and remaining risk. Do not use “complete” for checks that were not run.
Manual evidence fileContentsFreshness rule
Scope recordTask, changed files, authorized operationsSame proposed change
Graph recordDirect and transitive changes, parent pathsSame manifest and lockfile hashes
Advisory recordSource, time, exact identities, findingsRefresh before merge if graph or advisories changed
License recordMetadata, text location, SPDX expression, policy resultSame component version
Maintenance recordRepository, ownership, release and security signalsRecheck if release or owner changes
Build recordScripts, permissions, builder, inputs, output digestSame workflow and artifact
Test recordCommands, environment, outputs, skipped checksSame reviewed commit
Decision recordVerdict, approver, exception, expiry if anySuperseded by a newer review

This packet can later seed CI. Start with the facts that reviewers repeatedly collect rather than buying a broad scanner and assuming its default policy matches the repository.

SBOM, dependency graph, and attestation: what each can prove

ArtifactStrong useImportant limit
ManifestShows declared direct intent and constraintsDoes not necessarily show the exact resolved graph
LockfileShows a resolver-selected graph and often integrity dataDoes not establish necessity, license compatibility, or trusted production
Dependency graphSupports path and impact analysis across known dependenciesCoverage depends on detection and submitted build-time data
SBOMPortable inventory of components and relationshipsCan be incomplete or stale; does not itself prove artifact origin
Vulnerability reportMaps known records to identified versionsCannot cover undisclosed issues or fix identity errors
License reportNormalizes declared license dataCannot make a context-specific legal decision
ProvenanceDescribes how an artifact was produced and its inputsValue depends on completeness and trust in the builder
Artifact attestationBinds a signed claim to a subject digestA valid claim is not equivalent to secure or policy-compliant software
OpenSSF ScorecardSurfaces selected repository security practicesAggregate score is not an approval decision

NIST defines an SBOM as a formal record of software components and supply-chain relationships and recommends connecting SBOM repositories with vulnerability detection for ongoing risk awareness. NIST also cautions that retroactively generated SBOMs may not reproduce the exact dependencies used at build time. Source: https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity/software-supply-chain-security-guidance-20

That caution is especially relevant to AI-generated changes. If the agent edited a manifest but did not preserve the resolver, environment, and build evidence, a later inventory may describe a plausible graph rather than the graph that produced the artifact.

The completion statement reviewers should require

A useful completion statement is bounded:

The reviewed diff adds one direct build dependency and six resolved transitive dependencies. Package identity, resolved versions, license metadata, known-advisory results, lifecycle scripts, and the focused behavior test were reviewed against the cited evidence. Artifact provenance was not available, so production origin remains unverified. No publish, deploy, or package installation was performed as part of this review.

That statement is stronger than “all good” because another reviewer can challenge each clause. If the agent invented an API, a versioned official reference and focused test can expose it. If it made extra changes, the file and graph inventory can expose them. If it claimed removal, the resolved graph and SBOM can test the claim. If it claimed security, the statement forces the narrower language of known-advisory coverage and provenance evidence.

Use Agent Session Handoff Artifact Guide when a dependency review spans sessions. The handoff should preserve the exact reviewed commit, evidence timestamps, unresolved decisions, and commands that still require an authorized environment.

Frequently asked questions

1. Is a lockfile enough to approve a dependency?

No. A lockfile can identify resolved versions and graph relationships, but it does not prove that the package is necessary, correctly licensed for the use, maintained, free from known issues, or built by a trusted process.

2. Is a direct dependency riskier than a transitive dependency?

Not by definition. A direct dependency is easier to see and justify. A transitive component can still execute at runtime or build time, carry a relevant license, or contain a known vulnerability. Review path and role rather than assuming one class is safe.

3. Why review both the manifest and the lockfile?

The manifest shows requested intent; the lockfile shows selected resolution. Comparing them reveals overly broad ranges, unexpected transitive changes, resolver drift, and changes unrelated to the task.

4. Does a clean vulnerability scan prove the package is secure?

No. It means the selected data source did not return a matching known record for the queried identity at the observation time, assuming the scan covered the file and ecosystem correctly.

5. Should a “dev dependency” receive less scrutiny?

Its runtime exposure may be lower, but its build exposure can be high. Review whether it executes, which inputs and secrets it can read, what it can write, and whether it influences released artifacts.

6. What if the agent added a package but never imported it?

Reject the addition unless another evidenced mechanism requires it, such as a configured plugin. An unused direct package expands the graph without supporting the task and may indicate a partial or misdirected implementation.

7. What if the import exists but the API is unfamiliar?

Check official documentation for the exact resolved version and add a focused test. Do not accept an agent-generated link, remembered method name, or code comment as proof that the interface exists.

8. How do I review a suspected typosquat without installing it?

Compare registry namespace, publisher, linked source, reciprocal source link, release history, package archive metadata through an approved non-executing method, and available provenance. Identity review should precede execution.

9. Does an SPDX identifier settle license compatibility?

No. It standardizes identification. Compatibility and obligations depend on the license expression, product, use, modification, linking, distribution, and organizational policy. Escalate cases outside the approved policy.

10. What if registry metadata and the repository license disagree?

Stop approval and record the conflict. Use reliable evidence for the exact version and obtain a policy-owner decision. Do not choose the more convenient statement.

11. Is OpenSSF Scorecard a pass or fail gate?

It can support a policy when individual checks and thresholds are deliberately chosen, but the aggregate score should not substitute for component identity, necessity, vulnerability, license, and build review.

12. What does an SBOM add beyond the lockfile?

An SBOM can provide a portable inventory with standardized package identifiers, relationships, versions, license fields, and other metadata across ecosystems and artifacts. Its value depends on coverage, freshness, and connection to the artifact.

13. Does a valid artifact attestation prove the code is safe?

No. It proves that a signed claim about a particular subject verifies under the selected trust policy. Reviewers must still assess the builder, source, workflow, inputs, code, dependencies, and policy.

14. What if no CI exists?

Use the manual evidence packet in this guide. Keep inspection and execution separate, record sources and dates, run authorized tests in a disposable environment, and label unrun checks as unverified.

15. Should reviewers allow an agent to regenerate the lockfile automatically?

Only when the task authorizes package operations and the agent uses the repository’s documented tool and version in an appropriate sandbox. Otherwise, request the regeneration as a separate authorized verification step.

16. How can I tell whether a dependency is removable?

Map its call sites, compare with existing utilities and platform features, isolate the wrapper, and run the same focused behavior tests without it. Include transitive graph reduction and maintenance cost in the comparison.

17. What if a vulnerable transitive dependency has no fixed version?

Evaluate whether the direct parent can be upgraded, configured, replaced, or removed; whether the affected path is reachable; and whether an approved isolation or exception process exists. Record an owner and review date for any exception.

18. Can an AI agent make the final license decision?

It can collect and normalize evidence under a defined policy. It should not invent missing terms or make context-specific legal conclusions outside that policy. Route ambiguity to the designated human or organizational owner.

No. Preserve observable authorship and change records, third-party license evidence, prompts or task instructions where policy permits, human edits, and build provenance. A broad legal conclusion is outside this dependency review.

20. When is the dependency review complete?

When every applicable decision has evidence tied to the exact reviewed change, required checks have run in an authorized environment, unverified areas are named, and the verdict does not exceed that evidence.

Demand evidence for this guide

These primary sources demonstrate active institutional demand for dependency visibility, standardized inventories, repository security signals, and build provenance. They support the topic selection; they are not evidence that every repository needs every feature.

  1. GitHub provides dependency review specifically to show dependency changes and security impact in pull requests: https://docs.github.com/en/code-security/concepts/supply-chain-security/dependency-review
  2. NIST publishes software supply-chain guidance centered on SBOM transparency, provenance, and vulnerability response: https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity/software-supply-chain-security-guidance-20
  3. OpenSSF publishes package repository security principles covering authentication, provenance, vulnerability reporting, malware signals, and typosquatting defenses: https://repos.openssf.org/principles-for-package-repository-security.html
  4. SLSA maintains an industry-consensus specification for incrementally improving source and build supply-chain security: https://slsa.dev/spec/v1.2/

The editorial angle was also informed by an internal research memo summarizing user frustration with coding agents that make extra changes, invent interfaces, and overstate completion. Those qualitative complaints are used here only to choose review controls. Product facts in this article rely on the primary sources below.

Sources

Official and primary documentation checked on 2026-07-24:

  1. GitHub, supply-chain security overview, dependency graph, dependency review, Dependabot, and attestation concepts: https://docs.github.com/en/code-security/concepts/supply-chain-security/supply-chain-security
  2. GitHub, dependency graph concept: https://docs.github.com/en/code-security/concepts/supply-chain-security/dependency-graph
  3. GitHub, how the dependency graph recognizes manifest, lockfile, and submitted build-time data: https://docs.github.com/en/code-security/concepts/supply-chain-security/dependency-graph-data
  4. GitHub, dependency review and pull-request dependency diffs: https://docs.github.com/en/code-security/concepts/supply-chain-security/dependency-review
  5. GitHub, exporting an SPDX-compatible SBOM: https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/establish-provenance-and-integrity/export-dependencies-as-sbom
  6. GitHub, artifact attestations and provenance verification: https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations
  7. GitHub, dependency graph REST API surface: https://docs.github.com/en/rest/dependency-graph
  8. SPDX, project overview and standard purpose: https://spdx.dev/
  9. SPDX, current and previous specification versions: https://spdx.dev/use/specifications/
  10. SPDX, standardized license list and identifiers: https://spdx.org/licenses/
  11. OpenSSF, Scorecard project: https://openssf.org/scorecard/
  12. OpenSSF, principles for package repository security: https://repos.openssf.org/principles-for-package-repository-security.html
  13. OSV, vulnerability schema, database, and version-oriented query model: https://osv.dev/
  14. NIST, SBOM glossary definition: https://csrc.nist.gov/glossary/term/sbom
  15. NIST, software supply-chain and SBOM guidance: https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity/software-supply-chain-security-guidance-20
  16. SLSA, current Version 1.2 specification: https://slsa.dev/spec/v1.2/
  17. CycloneDX, Bill of Materials standard overview: https://cyclonedx.org/
  18. npm, package provenance display and verification prerequisites: https://docs.npmjs.com/viewing-package-provenance/
  19. npm, package-lock.json purpose and exact dependency tree: https://docs.npmjs.com/cli/v7/configuring-npm/package-lock-json/
  20. Python Packaging Authority, pylock.toml specification: https://packaging.python.org/en/latest/specifications/pylock-toml/
  21. Python Packaging Authority, dependency specifiers and environment markers: https://packaging.python.org/en/latest/specifications/dependency-specifiers/
  22. Python Packaging Authority, dependency groups for development and internal uses: https://packaging.python.org/en/latest/specifications/dependency-groups/
  23. Rust Cargo Book, dependencies and lockfile updates: https://doc.rust-lang.org/cargo/guide/dependencies.html
  24. Rust Cargo Book, Cargo.toml versus Cargo.lock: https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
  25. Go, modules reference for go.mod, go.sum, graph selection, and authentication: https://go.dev/ref/mod
  26. Apache Maven, transitive dependencies, scopes, and dependency management: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
  27. Microsoft NuGet, PackageReference and dependency locking: https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files
  28. Microsoft NuGet, package dependency resolution: https://learn.microsoft.com/en-us/nuget/concepts/dependency-resolution
  29. Microsoft NuGet, vulnerability information API: https://learn.microsoft.com/en-us/nuget/api/vulnerability-info

This article intentionally contains no affiliate links. It proposes no package installation, pull request creation, publication, deployment, or paid service.