Development Choices

Pin the Whole AI Agent Tool Runtime

Author
Drew YoungwerthSoftware Engineer
Published
Section
AI Agents
Length
7 min read3 sources cited

Pin every executable layer: the harness, tool adapters, transitive dependency tree, installer, container base, and external tool protocol versions. Commit the lockfile, but verify registries, builders, and artifact provenance separately. Move every update through human review and tests; never let the agent rewrite the dependencies that define its own execution.

Prerequisites

Before changing version constraints, identify the repository and build pipeline that produce the agent runtime. You need control of its dependency manifest, lockfile, container definition, tool-adapter configuration, tests, and release approvals. If separate teams own those pieces, name one release owner who can review them as a single execution surface.

Pin the complete execution surface

A manifest and lockfile resolve verified artifacts into an immutable runtime used by agent tools
Top-level version pins are not enough when tools load transitive code.
  1. Inventory everything that can change execution

    Start from the running process and work outward. Record the agent harness, every tool adapter, all transitive packages, the package installer, the language runtime, the container base, and each external tool protocol version. Include adapters loaded dynamically or installed in a sidecar: they still decide what the agent can execute.

    Do not stop after pinning the top-level application package. That package can remain unchanged while a permissive range resolves a different harness dependency or adapter dependency. A container build can also select a different base, and an external tool connection can begin speaking a protocol or exposing a schema the runtime was not tested against.

    The inventory should identify where each pin lives and who approves its change. Keep runtime boundaries aligned with your multi-tenant agent isolation design so that a shared adapter or base image is not overlooked simply because it runs outside the main process.

    This work costs engineering time up front, especially when dependencies are installed by several build systems. It is nevertheless the necessary first step: without the inventory, a reproducible top-level install can still produce a different complete runtime.

  2. Replace floating selections with reviewable pins

    Pin direct packages to the version policy your installer can enforce, then commit the resolved transitive tree. Pin the installer and runtime used to interpret that tree. Select the container base by immutable digest, with any human-readable tag retained only as documentation. For each external tool connection, record the protocol version and the tool schema or contract the adapter expects.

    Where a server offers version negotiation, accept only versions covered by tests. Where it does not offer a selectable version, treat a changed contract as an update that must pass the release lane rather than silently accepting it at runtime.

    Exact pins trade automatic uptake for controlled change. That is the right trade when a dependency helps determine which commands an unattended agent can run. It is the wrong boundary only for data that is deliberately fetched at runtime and validated as untrusted input; do not mislabel such data as an execution dependency to make the inventory look complete.

  3. Commit the lockfile, but do not treat it as a trust proof

    For npm, commit the root package-lock.json and make CI install from it. The npm v11 lockfile documentation, last edited October 4, 2025, says the file describes the exact generated dependency tree. Package records can include the resolved location and an integrity value for the unpacked artifact.

    That gives reviewers a concrete transitive diff and lets later installs request the same package artifacts. It does not prove that the installer is trustworthy, that the configured registry is the intended registry, or that the build environment has not been changed. Integrity data can show that fetched bytes match the recorded value; it cannot establish that the recorded artifact was safe or came from an approved build.

    Therefore pin the installer separately, configure the intended registry in the controlled build environment, and prevent the build from substituting an unreviewed registry configuration. Regenerate the lockfile only in the update lane. Reject an install that rewrites it during an ordinary build.

    A lockfile is also not a substitute for pinning the container base or protocol contract: neither is represented by the JavaScript dependency tree. Treat it as one record inside the larger runtime manifest.

  4. Build a test gate around the pinned runtime

    Run tests against the complete candidate image, not merely against application code on a developer machine. At minimum, exercise harness startup, adapter loading, tool discovery, protocol negotiation, permission boundaries, representative tool calls, failure handling, and shutdown. Compare the discovered tools and their input and output contracts with the reviewed snapshot.

    Add negative cases for missing permissions, malformed tool output, an unsupported protocol version, and a dependency or base-image digest that differs from the approved manifest. Keep result checks consistent with your policy for validating agent tool results before those results enter model context.

    These tests cost build time and maintenance whenever an adapter contract changes. A shallow smoke test is cheaper but is the wrong answer when an apparently compatible update changes a tool name, argument shape, or permission path. The test must cover the behavior the pin is intended to preserve.

  5. Verify provenance before approving an update

    Obtain provenance for each candidate artifact where its producer or package ecosystem supplies it, then verify it against expectations you control. The SLSA v1.2 artifact-verification procedure, reviewed August 26, 2026, calls for checking the provenance signature, matching its subject to the artifact digest, recognizing the builder identity, and comparing the build type and external parameters with expected values. It also describes recursive dependency checks as optional and potentially incomplete.

    Verification is a decision, not the presence of a provenance file. Fail the update when the signature is invalid, the artifact digest does not match, the builder is not trusted, or the declared build parameters fall outside the approved policy. Record the result with the dependency change. The related agent artifact provenance controls can use the same distinction between possessing a record and verifying it.

    Some dependencies will not provide usable provenance. Mark that gap in the review instead of converting absence into approval. The reviewer can then reject the dependency, isolate it more tightly, or accept the documented exposure under the project’s policy.

  6. Move pin updates through a separate release lane

    Make every version change a proposed release change: update the manifest, lockfile, base digest, or protocol contract in a branch; show the complete diff; run the runtime tests; verify available provenance; and require review before producing the deployable image. NIST’s Secure Software Development Framework version 1.1, published February 2022, defines secure development practices as additions to the software development lifecycle. Apply that boundary to agent-runtime dependencies rather than treating their updates as operational housekeeping.

    Keep the running agent outside this lane. It may report that a dependency is outdated or prepare a proposed change for review, but it must not install, approve, or deploy its own execution dependencies. Allowing self-update lets the agent replace the harness, adapter, or protocol implementation that constrains its behavior, bypassing the tests, provenance checks, and human approval that form the release boundary.

    Emergency updates can use an expedited review, but they still need a recorded diff, the relevant tests, provenance verification where available, and an identifiable approver. “Latest at startup” is not an emergency process; it is the absence of a release boundary.

  7. Deploy and compare the running runtime with the approved manifest

    Publish one manifest with the release that records the harness and adapter versions, lockfile identity, installer and runtime versions, container-base digest, and external protocol contracts. At startup or deployment, compare what will run with that manifest and stop the release on a mismatch.

    Retain the preceding approved manifest and image as the rollback target. Rollback must restore the whole execution surface; reverting only the application package while keeping a changed adapter, base, or protocol contract does not restore the previously reviewed runtime.

Expected result

Done means one approved manifest identifies every executable layer of the agent tool runtime, clean builds reproduce those selections, tests exercise the assembled image, and available provenance is verified against stated expectations. Dependency changes enter through a reviewed release lane. The running agent can neither alter those pins nor promote replacements into production.

Sources

  1. npm v11 lockfile documentationdocs.npmjs.com
  2. SLSA v1.2 artifact-verification procedureslsa.dev
  3. Secure Software Development Framework version 1.1csrc.nist.gov

See also