Chapter 2

Lessons from Package Managers

Map package-manager concepts onto agent context so APM feels familiar rather than novel.

Objective

After this chapter you can map the six things npm, pip, and Cargo normalized — a manifest, a lockfile, version pinning, sources, provenance, and a repeatable restore — onto their agent-context analogues in APM, tell Microsoft's Agent Package Manager apart from the unrelated tools that share the name “apm,” and say honestly where the package-manager analogy stops holding.

Concept/Theory

What package managers actually normalized

Chapter 1 left application dependencies in their pre-package-manager state: copied lib/ folders, emailed zips, a README that listed “install these seven things first.” npm, pip, and Cargo did not simply automate the download. They normalized a pattern — six moves that turned dependencies from hand-copied files into declared, reviewable, reproducible project state. Those six moves are the whole lesson, and every one of them has a direct analogue in agent context:

  • Manifest — a file that declares what you intend to depend on.
  • Lockfile — a file that pins the exact resolved graph you actually got.
  • Version pinning — “some compatible version” becomes “this exact one.”
  • Sources / registries — a named place a dependency resolves from.
  • Provenance — knowing where each artifact came from and that it is intact.
  • Repeatable restore — one command reconstructs dependency state from a recorded result.

APM's own framing is that it “borrows the manifest-plus-lockfile shape from npm, pip, and cargo and applies it to the files that configure AI coding agents” (What is APM?). Here is the one-for-one map — each fundamental, its agent-context analogue, and the Chapter 1 property it protects:

The six package-manager fundamentals, mapped onto agent context and the property each protects.
Package-manager fundamental What it does (npm / pip / Cargo) Agent-context analogue Protects
Manifest Declares intended dependencies as reviewable state (package.json, requirements.txt, Cargo.toml) One declared file listing the skills, prompts, instructions, agents, plugins, and MCP servers a project needs Portability
Lockfile Pins the exact resolved graph so restores match (package-lock.json, Pipfile.lock, Cargo.lock) Resolved source identities and integrity records for managed context Reproducibility
Version pinning Turns “some compatible version” into “this exact one” Record the exact commit selected by a tag or branch, or choose an immutable commit directly Reproducibility
Sources / registries Where a dependency resolves from (npm registry, PyPI, crates.io) Where a primitive is fetched from Provenance / security
Provenance Know where each artifact came from and that it is intact (integrity hashes, signatures) Trace installed package files to recorded sources and integrity data Provenance / security
Repeatable restore One command rebuilds the exact environment (npm ci, hashed pip install) One declared setup restored in each supported harness's native form, not identical bytes across harnesses Portability + Reproducibility

Keep provenance's two questions separate: “Does this content match its record?” and “Do I trust its publisher?” A checksum detects changed bytes relative to trusted metadata; it neither authenticates a publisher nor proves instructions benign (APM's security boundaries).

The lesson isn't the downloader

It is tempting to summarize a package manager as “a downloader with a registry.” That misses the load-bearing part. Convenience was the hook; the durable contribution was the manifest-plus-lockfile contract — declared intent kept separate from a pinned, verifiable result. The registry is actually the most optional piece: npm, pip, and Cargo all resolve git and filesystem sources independently of any central index. A reader who remembers only “APM installs agent files” has taken the hook and dropped the lesson. The point is that context becomes declared, pinned, and reviewable like any other dependency.

Restoring unchanged intent is different from reconciling an edited declaration. Likewise, reporting newer content, choosing an allowed change, and checking integrity are separate jobs. A lockfile makes deliberate change reviewable; it does not prohibit change.

Agent context is where application code was before lockfiles

Naming the phase is what makes the fix feel inevitable rather than imposed. Agent context today sits exactly where application dependencies sat before npm, pip, and Cargo: essential to the work, shared across a team, but neither declared nor pinned — managed by copying files, pasting from wikis, and per-machine setup. APM names this gap directly: agent context is “essential to work, shared by teams, but often not declared or pinned,” and “there's no manifest for it” (microsoft/apm README). You have lived through the pre-lockfile era of application code and you know how it ended; that memory does the persuading.

Two cautions keep this honest. First, this is a maturity-phase claim, not an “APM is npm” claim — the category is genuinely young (SKILL.md, AGENTS.md, and MCP are still settling, and APM itself is pre-1.0 and ships often). Second, the common objection is “agent config is too new and too fluid to manage like a dependency.” The historical counter is that application dependencies were also fluid and fast-moving before manifests existed: declaring context is what creates stability, not something you wait for stability to earn.

In APM

The same shape, named in APM

The whiteboard analogy lands because APM deliberately transplants the manifest-plus-lockfile shape onto agent-configuration files (What is APM?). Four names carry the four fundamentals you most need to recognize now — syntax and flags arrive in later chapters:

  • apm.yml is the manifest: the human-authored declaration of intent. This is what carries Portability.
  • apm.lock.yaml is the lockfile: machine-generated, never hand-edited, recording resolved identities, integrity data, and deployment ownership. This carries Reproducibility.
  • For a Git source, owner/repo#<ref> selects a version ref: a tag, branch, or commit SHA. Think pkg@1.2.3, but remember that tags and branches can move. A full commit fixes the revision; the lock records the resolved commit — Reproducibility again.
  • Git is the default source, not a registry service. Local paths and experimental REST registries are other source choices. A configured default registry can route shorthand away from Git; an explicit git: declaration keeps it on Git (source routing). Knowing the source is half of Provenance / security.

Identity depends on the source: Git records a repository, commit, and any selected subpath; a local dependency records a path whose source must remain available; a registry package records an exact version and archive URL/checksum, not a Git SHA. New 0.31.0 locks omit generated_at, though legacy locks can retain it. Compare recorded state, not a clock (lockfile reference; Chapter 6).

If you already think in npm, pip, or Cargo terms, the whole vocabulary transfers with one lookup:

A conceptual lookup for APM 0.31.0; example evidence is labeled separately below.
You know… …in APM
package.json / requirements.txt / Cargo.toml apm.yml
package-lock.json / Cargo.lock apm.lock.yaml
pkg@1.2.3 version pin owner/repo#<ref> for Git (tag, branch, or SHA; lock the resolved result)
npmjs.com / PyPI / crates.io Git host by default; local paths or an explicitly enabled experimental REST registry are alternatives
npm view / pip index versions apm view <pkg> versions
npm outdated apm outdated
npm update / pip install -U apm update
npm audit apm audit (hidden-Unicode + lockfile integrity, not a CVE feed)
npm install (restore) apm install

Notice the bottom rows: apm outdated reports availability, apm update plans and applies constraint-respecting changes with consent, and apm audit checks the resulting state. apm view <pkg> versions lists Git refs or registry versions, depending on source routing. This chapter names the roles; Chapter 7 puts the lifecycle to work — including what apm audit does and does not check — and Chapter 8 covers the install-time security scan.

Registry reporting makes the distinction explicit: Current is locked, Wanted is the highest version allowed by the manifest constraint, and Latest is the highest published parseable semantic version, which can include a prerelease outside that constraint. In the controlled registry run, an exact 1.0.0 pin showed Current/Wanted 1.0.0 but Latest 2.0.0-beta.1; its update preview proposed no change. A newer release being reported does not authorize crossing the pin. Git-only reports do not add Wanted (reporting semantics).

When to use / pitfalls

First, make sure it's the right “apm”

Anika's question is the one to answer before any tutorial: several unrelated tools share the name apm (and the near-homophone aipm). Run the wrong pip install or follow the wrong docs and you land on an entirely different product, with a different manifest, scope, and trust model. Getting identity right is a prerequisite to everything else in this book.

Telling the “apm” names apart. Other-project fingerprints retain the July 2026 research snapshot.
Name Owner How you install / identify it Fingerprint What it actually is
Microsoft APM (this book) Microsoft — microsoft/apm PyPI apm-cli; docs microsoft.github.io/apm apm.yml + apm.lock.yaml + apm-policy.yml The manifest-driven dependency manager for agent context taught here
orthogonalhq/apm (same CLI name) Orthogonal (independent) github.com/orthogonalhq/apm; registry apm.orthg.nl apm-lock.json (no manifest) An unrelated skills installer that does ship a public central registry
TheLarkInn/aipm Sean Larkin (independent) github.com/TheLarkInn/aipm aipm.toml A different “AI plugin manager” (Rust), for skills, agents, MCP, and hooks
Application Performance Monitoring Many vendors n/a n/a The same acronym for an unrelated observability discipline (metrics, traces)
Atom Package Manager GitHub's retired Atom editor the apm command n/a A historical namesake; packages for the Atom editor, nothing to do with agents

The quickest proof they are separate projects, not forks of one, is the manifest split: apm-lock.json vs. aipm.toml vs. apm.lock.yaml. Community explainers publish dedicated disambiguation sections precisely because the confusion is real (a multi-way “APM” disambiguation).

Where the analogy breaks

The mapping is strong, but two asymmetries keep it honest — name both to a colleague so you don't over-claim.

A third honesty note sets up Part III. A Git dependency without a ref selects the default branch: without a lock, a fresh resolution can move. With unchanged Git declarations and a lock, normal apm install reuses the locked graph, including transitives. Edit the declared ref or version constraint, however, and normal install reconciles that new intent; update is not the only operation that can change resolution (install contract). Commit the manifest/lock pair and retain access to its sources — not “byte-for-byte, forever” without conditions. Chapter 6 makes the replay boundary concrete.

Worked example

The pin and the recorded result

Chapter 2 introduces no new Meridian manifest — that is deliberate; the team writes its first real apm.yml in Chapter 4. The one piece of syntax worth recognizing now is the version pin, so it looks familiar when it arrives: owner/repo#<ref>, where <ref> is a git tag, branch, or commit SHA. The original edition illustrated a tag selection this way:

Historical pin-syntax snapshot — the git-native form of pkg@1.2.3, not a current full-package install transcript. Original CLI stamp: apm v0.23.1 needs network
# owner/repo#<ref>  --  <ref> is a git tag, branch, or commit SHA
# Installs the public sample package pinned to exactly tag v1.0.0.
apm install microsoft/apm-sample-package#v1.0.0

And to discover which refs actually exist before you commit to one, apm view is the “versions” verb — the analogue of npm view / pip index versions:

List Git tags and branches: the observed result included v1.0.0 at fb285168, exit 0, with no default registry configured. apm v0.31.0 — observed 2026-09-15 needs network
# Lists available remote tags and branches for the package.
apm view microsoft/apm-sample-package versions

A configured default registry can redirect that shorthand version query; do not assume every versions response lists Git refs (version-query routing). For a small current install proof, reuse the book's backend/examples/updates/1.2/core/pinned-skill fixture. Its explicit Git declaration selects only style-checker at commit fb2851683be0e0e7711421d518bd8dba23b0b1f6, avoiding the full sample's floating transitive dependency. This is a practice fixture, not a new Meridian milestone.

Copy only that fixture's apm.yml into a fresh, short-path scratch directory outside the book checkout, starting without a lock or generated files. Using APM 0.31.0, run these two commands consecutively there. The first records a result; the second exercises unchanged-intent replay.

Install then replay the existing pinned-skill fixture. Both commands exited 0; the second preserved the complete lock bytes. apm v0.31.0 — fixture verified 2026-09-16 needs public Git access on a cold cache
apm install
apm install

The skill appeared at .agents/skills/style-checker/SKILL.md for Copilot/Cursor and .claude/skills/style-checker/SKILL.md for Claude. Its lock records the full commit, even though the skill's inventory version is unknown, and has no generated_at. That is the identity-and-content contract, not a timestamp test or proof of live harness behavior. Chapter 5 explains the complete fixture and its integrity checks; Chapter 4 is still where Meridian writes its own first manifest.

Recap & next

Recap

  • Package managers normalized six moves — manifest, lockfile, pinning, sources, provenance, repeatable restore — and each has a one-for-one agent-context analogue that protects a Chapter 1 property.
  • The load-bearing lesson is the manifest-plus-lockfile contract (declared intent vs. pinned result), not the downloader or the registry — the registry is the most optional part. Unchanged intent replays; edited intent asks install to reconcile a new result.
  • Agent context is in the pre-package-manager phase application code was in before lockfiles; that is a maturity-phase claim, and declaring context is what creates stability.
  • In APM the shape has names: apm.yml (manifest), apm.lock.yaml (lockfile), owner/repo#<ref> (Git ref selector), and source-specific identities for Git, local paths, or experimental registry packages. The outdated/update/audit trio and apm view … versions are named here and taught later.
  • Verify identity with the three-part tell (apm-cli + microsoft/apm + microsoft.github.io/apm, three-file model) so you don't install a different “apm.”
  • Two asymmetries: a shipped experimental registry client/API is not evidence of a public searchable Microsoft hub, and built-in apm audit is an integrity / hidden-Unicode check, not a CVE feed. Checksums are not publisher authentication.

Next

You now share the team's vocabulary for what APM manages. Next, learn what those managed things actually are: Chapter 3 — Primitives & Harnesses names the primitives (skills, prompts, instructions, agents, plugins, MCP servers) and shows how each maps onto the harnesses that read them.