Chapter 11

Enterprise at Fleet Scale

Gate and govern APM usage across an organization without turning developer setup into a bottleneck.

Objective

After this chapter you can operate APM across a whole organization — not one repo, but a fleet. You will wire apm audit --ci into branch protection as a required, protected pull-request check (the integrity gate from Chapter 7 and policy gate from Chapter 9, re-run in CI as defence in depth), stand it up with microsoft/apm-action, route dependency traffic through an approved registry proxy where supported (or prepare an offline bundle handoff), publish and own an org apm-policy.yml baseline, and roll it all out with a measured adoption playbook. This is the capstone: it introduces no new property. Instead it asks whether the four you already know — Portability, Reproducibility, Provenance / security, and above all Governance — hold for every repo, enforced and operated at scale. Governance is the star of the chapter: the org’s policy must reach a protected enforcement point, not merely exist in a repository. This chapter targets apm v0.31.0, compared with the book’s v0.23.1 baseline. Policy enforcement remains early preview and dedicated registries remain experimental. Pin the CLI and integration independently, and distinguish install-time governance from the harness’s runtime controls (0.31.0 policy reference).

Concept/Theory

From “can this repo install?” to “can every repo install?”

A single team starts with a manifest, a lockfile, and a restore habit: apm.yml, apm.lock.yaml, and apm install. Everything in Chapters 5–9 answered a repo-sized question: does my project install, reproduce, stay current, stay safe, and stay within policy? An enterprise asks a different, larger question — the shift this whole chapter turns on: not “can this repo install?” but “can every repo install safely and predictably, without the platform team in the loop?”

That reframing surfaces five things the single-team story never forces you to build (Making the case):

  • Repeatable rollout — a runbook any team follows, not a hero who hand-holds each repo.
  • Policy ownership — a named, protected owner of the org’s apm-policy.yml.
  • Audit gates — a required CI check on every pull request, authoritative regardless of what a developer does locally.
  • Registry strategy — controlled, mirrored, and (when needed) offline dependency traffic.
  • Exception handling — a visible, reviewable way to grant a waiver.

The docs’ worked figure is a mid-to-large org: 50 repositories, 200 developers, five AI coding tools. Without central management a predictable failure set emerges — manual config drifting per repo, no audit trail (“what agent configuration was active at release 4.2.1?” has no answer), version drift between developers and CI, onboarding friction, and ungoverned dependencies: “the same problem regulated industries spent a decade solving for application code, now back in a new form” (Making the case). These are the Chapter 1 pains, multiplied by the repo count.

Two boundaries keep the rest of the chapter honest. First, consuming policy is not owning policy: a fleet team (including the original pilot) consumes the org policy discovered from its git remote — authorship lives in <org>/.github behind CODEOWNERS and branch protection, exactly the org-remote model from Chapter 1 and Chapter 9. Second, nothing here is a new property: fleet scale is Chapters 6–10 made repeatable, owned, gated, and measured. The common trap is to think “fleet scale is just the single-repo setup, copied N times” — but N copies without central ownership simply reproduce the drift problem at higher cost. The missing pieces are ownership, gates, a registry strategy, and exceptions, none of which a single repo ever needs.

In APM

The fleet gate: apm audit --ci

Run apm audit --ci on every pull request as defence in depth. It checks the manifest/lock relationship, recorded deployment ownership (deployment-ledger-owners), deployed content and consent, plus install-replay drift by default. A resolved policy adds the org’s Governance checks. Do not program against an “eight plus one” total: configuration, policy and early failures affect enumeration. Exit 1 means a blocking failure; exit 0 does not prove that policy was found, that every warning was absent, or that every runtime file was checked (baseline checks).

A cold runner is no longer a reason to suppress drift. With a reviewed manifest, lock and deployed files but no apm_modules or warm cache, 0.31.0 can hydrate lock-pinned sources in scratch without rewriting the checkout. The public-source probe succeeded; making that source unreachable failed closed with exit 1, not a green skip. Cold is therefore not synonymous with offline. Allow the necessary acquisition traffic rather than adding --no-drift to make the job green (recorded cold-run evidence; audit contract).

Authority comes from protecting the enforcement point, not from the letters --ci. Protect the workflow, reviewed manifest/lock and deployed files, selected policy source, credentials, environment, and ruleset bypass permissions. The CLI really accepts --no-policy; an explicit --policy beats that flag, but APM_POLICY_DISABLE=1 still suppresses even explicit policy in the observed 0.31.0 run, including with consumer fail-closed settings. A required GitHub Ruleset check only earns its guarantee when contributors cannot change or bypass those inputs. This is how you operationalize the Chapter 9 authority boundary.

Selected fleet-gate controls, inspected at APM 0.31.0. Local evidence and integration limits are separate.
Flag Job Fleet note
--policy <src> Explicit policy ref: org | owner/repo | https://… | local path [experimental]. Select a reviewed authority; omission uses org discovery. Explicit selection is not protection from every environment bypass.
--no-cache Force a fresh policy fetch Refreshes policy, not the package cache. Requires reachable policy infrastructure; see the consumer fail-closed setting below.
--no-policy Skip automatic policy discovery A real bypass of that layer, including in CI; baseline checks remain. Do not put it in the protected org gate.
--no-fail-fast Run every check even after one fails Use for fuller diagnostics; it does not expand the tool’s runtime coverage.
-f sarif|json, -o <path> Structured output; write to a file (format inferred from extension) SARIF feeds Code Scanning. Markdown is not supported in --ci mode.

Baseline integrity failures are independent of the policy’s warn/block dial, tying this gate back to Chapter 6. Make exceptions visible through a reviewed policy amendment at the authority that imposed the rule, not an environment switch hidden in one job. A child cannot lower an inherited block to warn. A deliberate --no-drift run reduces coverage; it is neither a repair nor the standard cold-runner setup.

microsoft/apm-action: the turnkey CI path

microsoft/apm-action supplies the CLI and optional project operations; it is not the authority itself. Pin the Action to its reviewed commit and set apm-version: '0.31.0'. The inspected v1.10.0 wrapper otherwise defaults to an older CLI. Its audit-report input runs bare, informational audit, not apm audit --ci; it is not the required gate (pinned Action dispatch).

Choose the job by what you are reviewing. Default mode runs ordinary apm install, which can repair deployed bytes before audit sees them. When committed deployed files are the review contract, setup-only: 'true' installs only the CLI, then an explicit audit examines those files. Cold scratch hydration means this pattern needs no mandatory --no-drift. Frozen installation is a separate, limited structural check (Chapter 5’s boundary), not an equivalent content audit.

Current source-grounded integrity sketch from backend/examples/updates/1.2/producer/ci/apm-audit.yml. SKIPPED-needs-network: no GitHub runner, authorized private-source access, or required-check/ruleset enforcement was exercised. This does not configure org policy. needs GitHub infrastructure target apm v0.31.0; Action v1.10.0
name: APM integrity audit
on:
  pull_request:
jobs:
  audit:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      - uses: microsoft/apm-action@d723bb64ed70c135bbaf87d126b721dd2dae0439 # v1.10.0
        with:
          setup-only: 'true'
          apm-version: '0.31.0'
      - name: Audit checked-out content
        run: apm audit --ci
        env:
          GITHUB_TOKEN: ${{ github.token }}

The repository token is not authorization to read every private repository in the organization. Configure access to the actual locked sources and policy authority separately. The same CLI gate can run in Azure Pipelines, GitLab CI or Jenkins; the wrapper is GitHub-specific, not the integrity concept (CI/CD integration).

Historical workflow sketches — APM 0.23.1, not refreshed runner evidence

These earlier install-then-audit and SARIF sketches retain their historical pins. The three files under backend/examples/ch11/workflows/ are unchanged documentation artifacts, including the old setup-only recipe. Do not copy their major-tag pinning or cold-cache drift-suppression advice as the current pattern. None was executed on a GitHub runner.

Historical backend/examples/ch11/workflows/apm-audit.yml, with explanatory comments corrected; no new execution. SKIPPED-needs-network: runner and ruleset access. needs networkapm v0.23.1 — historical
# .github/workflows/apm-audit.yml   -- SKIPPED-needs-network (the `apm audit --ci` it runs IS verified)
name: APM audit
on:
  pull_request:
    paths: ['apm.yml', 'apm.lock.yaml', '.apm/**', '.github/**', '.claude/**', '.cursor/**']
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: microsoft/apm-action@v1        # historical major tag, not an immutable Action pin
        with:
          apm-version: '0.23.1'              # pin the CLI for reproducible CI
      - run: apm audit --ci --no-cache       # verified gate: exit 0 clean / 1 on violation
        env:
          GITHUB_APM_PAT: ${{ secrets.APM_PAT }}   # must authorize the intended source

For findings to appear inline on the PR diff and in the repo’s Security tab, emit SARIF and upload it. The if: always() step is load-bearing — SARIF must upload even when the audit exits 1, or the failing run produces no Code Scanning entry:

Historical backend/examples/ch11/workflows/apm-audit-sarif.yml. SKIPPED-needs-network: GitHub runner, Code Scanning permissions and SARIF upload. needs networkapm v0.23.1 — historical
# .github/workflows/apm-audit-sarif.yml   -- SKIPPED-needs-network (documented)
jobs:
  audit:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write                 # required to upload SARIF to Code Scanning
    steps:
      - uses: actions/checkout@v4
      - uses: microsoft/apm-action@v1
        with: { apm-version: '0.23.1' }
      - name: Audit
        run: apm audit --ci --no-cache -o apm-audit.sarif   # format inferred from the .sarif extension
        env: { GITHUB_APM_PAT: '${{ secrets.APM_PAT }}' }
      - name: Upload SARIF
        if: always()                          # upload even on exit 1, or a failing run has no alert
        uses: github/codeql-action/upload-sarif@v3
        with: { sarif_file: apm-audit.sarif, category: apm-audit }

Current local evidence also includes a real SARIF report written with -o (ci-cold-sarif). Writing that report is not an upload test. Keep the upload eligible after a failing audit, as the historical if: always() example illustrates, and test Code Scanning permissions on your actual runner.

Registry strategy: proxy and air-gapped

A controlled acquisition path makes the lockfile contract operable behind an enterprise firewall. APM’s proxy controls are environment variables, not apm config keys: standardize them in CI secrets and dev containers. Do not infer that APM has only three accepted configuration keys from the defaults its config display happens to list; saved targets and gated registry settings also exist. These transport controls do not cover every APM network request (0.31.0 registry-proxy coverage).

Source-grounded proxy controls at APM 0.31.0. Corporate routing is SKIPPED-needs-network; local bundle evidence is separate.
Need Knob Note
Allow outbound traffic at the firewall HTTPS_PROXY / HTTP_PROXY / NO_PROXY Standard forward-proxy variables; validate both Git and HTTP acquisition paths in your environment.
Mirror covered Git-hosted archives PROXY_REGISTRY_URL Routes supported archive downloads through a mirror, such as an Artifactory GitHub remote; not policy or MCP traffic.
Authenticate to the mirror PROXY_REGISTRY_TOKEN Bearer token on proxy requests; independent of GITHUB_APM_PAT.
Refuse direct-VCS fallback (mandatory + auditable) PROXY_REGISTRY_ONLY=1 Refuses supported direct-VCS fallback. The lock records registry_prefix; directly pinned entries need reviewed re-resolution through the proxy.
Silence the plaintext-token warning on http:// PROXY_REGISTRY_ALLOW_HTTP=1 Use only inside an isolated network. (Deprecated ARTIFACTORY_* aliases still work with a warning.)
Offline artifact handoff Prepare a real bundle and its required tooling before disconnecting Chapter 10’s producer/consumer loop, with the one-shot limitations below.

The proxy is a route, not a trust anchor. Review the lockfile and its recorded content hashes, then verify the materialized result. Hashes detect changed bytes relative to trusted metadata; neither a mirror nor a hash authenticates the publisher. The GitHub archive proxy covers supported dependency and marketplace fetches, but not Azure DevOps dependency acquisition, MCP-registry traffic, or policy fetching. Those paths need their own connectivity and authorization.

A dedicated registry is a different package source, not this proxy. APM 0.31.0 ships experimental REST consumption/publication and an implementable HTTP API /v1. That does not establish a Microsoft-operated public searchable hub. OpenAPM’s deferred normative registry work is a standards boundary, not evidence that the client is absent. Meridian can continue using Git and curated marketplaces without adopting a registry server (experimental registries; implemented API).

Org policy at fleet scale

Scale the Chapter 9 ownership model, not copies of unowned policy. Meridian keeps meridian-finance/.github/apm-policy.yml behind CODEOWNERS and branch protection. In 0.31.0, GitHub discovery prefers <org>/.github-private/apm-policy.yml, then the .github, .apm and _apm repositories. GitLab uses the top-level group’s apm-policy project; Azure DevOps uses project apm, repository apm-policy, with legacy _apm/_apm fallback after a 404. Live private-host discovery remains SKIPPED-needs-network: no org repository or authorization was supplied (host-specific discovery).

Select an explicit, reviewed source when the gate must not depend on ambiguous discovery: --policy for CI audit, --policy-source for policy status. Record the canonical host/repository/path and, if pinning policy bytes, the consumer’s policy.hash SHA-256 from the reviewed raw file — not its display name/version or a package’s content_hash. GitHub/registry owner-repository policy matching uses canonical casing; refs, subpaths and MCP identities are not generally case-insensitive. Crucially, an unread remote fetch_failure: block cannot protect its own first fetch: set consumer policy.fetch_failure_default: block. Even a policy-byte hash mismatch only warned and exited 0 in the default-posture audit probe; the consumer block setting made it exit 1 (operations reference OP09.3; policy source and hash configuration).

Local inheritance now works. The tested extends: ./apm-policy.parent.yml retained parent restrictions: allow lists intersect, deny/require lists accumulate, and enforcement and fetch-failure posture tighten. Empty child lists do not erase inherited restrictions. Cold and warm HTTPS-loopback probes retained the same strict fields and TTL; the warm read made no further requests. This is local/loopback evidence, not a live org deployment (tighten-only implementation). If policy freshness itself must gate CI, inspect policy status --check too: the stale-cache probe failed that preflight while audit still evaluated cached rules successfully. Resolution status and rule compliance answer different questions.

When to use / pitfalls

Roll out in phases, measure by leading indicators

Rolling APM out to a fleet is a staged program, not a switch. The official adoption playbook is five phases, each with a single owner, a deliverable, and a gate to clear before advancing (Adoption playbook). The outline’s four-word mnemonic — pilot → measure → standardize → gate — maps directly onto them:

The five-phase adoption playbook. Each phase buys evidence the next one needs — do not skip phases. From the APM adoption playbook.
Phase Owner Gate to advance
Discover Platform team Shadow apm install --dry-run + apm audit on representative repos; answer “what breaks if we turn this on tomorrow, and for whom?”
Pilot One product team + platform Manifest, lockfile, CI audit, and policy in warn; two consecutive weeks of clean pilot CI with every warning triaged.
Harden Security + platform Flip warn → block, add the registry proxy, stand up marketplaces; a fresh repo installs against org policy + proxy with no manual help.
Scale Product teams (self-service) Platform is no longer in the critical path; new repos onboard from a checklist.
Sustain A named on-call Steady state: weekly drift triage, monthly lockfile review, quarterly marketplace refresh.

Success is measured by leading indicators, not package counts. The docs are explicit that “measuring apm.yml count and nothing else” is a vanity metric — a repo with a manifest but a failing audit or rising drift is not adopted, it is at risk. Watch audit pass rate, the drift trend (findings closed vs. opened), and marketplace uptake instead (Adoption playbook).

Pin the fleet’s targets, not an expanding default. Meridian keeps targets: [copilot, claude, cursor]. The 0.31.0 default-stable catalog now has nine targets, including grok-build; stable hermes, like agent-skills and antigravity, is explicit-only. grok-cloud remains experimental and outside that default set. Catalog support does not mean every primitive or native plugin works on every target (Chapter 3; 0.31.0 target matrix).

Worked example

Meridian’s four moves, in order. Rehearse the CLI locally, then validate the infrastructure separately. Current evidence comes from the existing fixtures and the content/research/updates/1.2/ reports named in the captions; these are not new Action or agent-runtime executions. Use short disposable copies with isolated user/config/cache state, not the book root. Here $Apm is the absolute prepared 0.31.0 executable, and APM_POLICY_DISABLE is absent.

Move 1 — rehearse the gate, including its cold-cache boundary

Reuse the already materialized backend/examples/updates/1.2/core/local-instruction fixture from Chapter 5, including its authored instruction, manifest and genuine lock. It has no remote dependencies, so this particular rehearsal is offline. It tests recorded local content, not org discovery.

Frozen restore and a separate integrity audit of the unchanged local fixture. Retained independent evidence: ch05-verification.md, local-local-instruction-frozen and local-local-instruction-audit, both exit 0; no new execution claimed here. apm v0.31.0 — verified 2026-09-16
& $Apm install --frozen
& $Apm audit --ci

A public dependency tests a different boundary. The producer probes used the immutable microsoft/apm-sample-package style-checker slice at fb2851683be0e0e7711421d518bd8dba23b0b1f6, with the genuine lock and deployed files. Removing modules and starting with an independent empty cache tested acquisition, not just replay from a warmed developer machine:

Observed APM 0.31.0 CLI outcomes, producer reference §8. Public hydration needs GitHub access; none is a GitHub Action run.
ProbeBoundary testedResult
ci-cold-audit No modules or warm cache; locked public source reachable Exit 0; scratch hydrated, checkout bytes and timestamps unchanged.
ci-unreachable-source Separate cold run; deliberately unreachable loopback proxy Exit 1 on hydration/replay failure; no green skip or checkout repair.
ci-tamper-audit Harmless ASCII edit to recorded deployed content Exit 1; changed bytes rejected.
ci-cold-sarif Clean audit with a SARIF output file Exit 0; real report written, no Code Scanning upload tested.
Historical comparison — the original 0.23.1 clean, direct and transitive runs

These July 2 recordings retain their original version, counts and cache-only wording. Setup fetched a public package over the network; the displayed audits then used warmed local state. They are not fresh-clone offline recipes or 0.31.0 results. The Could not determine org… warning explains why the clean scratch run did not enforce org policy, rather than demonstrating a production fail-closed gate.

Historical clean project, exit 0. The nine-check count describes this recording only. Transcript abbreviated; source: the original Ch11 reference, Feature 1a. apm v0.23.1 — not rerun at 0.31.0
$ apm audit --ci
  [!] Could not determine org from git remote; enforcement skipped (set policy.fetch_failure_default=block in apm.yml to fail closed)
  [>] Replaying install (cache-only)...  [+] Replayed 2 package(s)  [+] No drift detected

                           [>] APM Policy Compliance
  │ [+] │ lockfile-exists          │ Lockfile present                                  │
  │ [+] │ ref-consistency          │ All dependency refs match lockfile                │
  │ [+] │ deployed-files-present   │ All deployed files present on disk                │
  │ [+] │ no-orphaned-packages     │ No orphaned packages in lockfile                  │
  │ [+] │ skill-subset-consistency │ Skill subset selections match lockfile            │
  │ [+] │ config-consistency       │ No MCP configs to check                           │
  │ [+] │ content-integrity        │ No critical hidden Unicode or hash drift detected │
  │ [+] │ includes-consent         │ No local content deployed -- includes … skipped  │
  │ [+] │ drift                    │ no drift detected against lockfile                │

  [*] All 9 check(s) passed          # exit 0 -- 8 baseline checks + drift

The historical negative case used a block policy (enforcement: block, require_pinned_constraint: true) against an unpinned direct dependency on a bare #main branch. The dependency-pinned-constraint check fails and the gate exits 1 — a correctly protected required check would reject that result:

Historical explicit-policy audit of a bare-branch direct dependency: exit 1 on warmed local state. Source: original Ch11 reference, Feature 1b. Transcript abbreviated. apm v0.23.1 — not rerun at 0.31.0
$ apm audit --ci --policy ./pol-block.yml   # enforcement: block, require_pinned_constraint: true
  [>] Replaying install (cache-only)... [+] No drift detected
  ...                                        # baseline + policy checks run
  │     │ dependency-pinned-constraint │ 1 dependency(ies) use unbounded constraints
  │     │                              │ (hint: pin to a semver range, literal tag, or SHA) │
  │     │                              │   - microsoft/apm-sample-package: bare branch 'main' tracks a moving tip │

  [x] 1 of 18 check(s) failed          # exit 1 -- the required check blocks the PR

The same historical policy passed with a pinned direct dependency and an unpinned transitive declaration. Its higher count reflects enumeration without the earlier fail-fast stop, not a fixed current schema. The separate 0.31.0 coverage limits still apply.

Historical direct-only control: exit 0. Source: original Ch11 reference, Feature 1 empirical nuance; warmed state, not a cold offline promise. apm v0.23.1 — not rerun at 0.31.0
$ apm audit --ci --policy ./pol-block.yml   # DIRECT dep pinned to #v1.0.0; a transitive dep is unpinned
  │ [+] │ dependency-pinned-constraint │ All dependencies use pinned constraints │
  ...
  [*] All 29 check(s) passed          # exit 0 -- direct-only rule; count higher because nothing fails
                                      #          (fail-fast never trips; use --no-fail-fast for a full report)

Move 2 — make it required in CI (SKIPPED-needs-network)

Meridian starts with the current pinned integrity sketch, then configures its reviewed policy source and makes the job a required status check across all three product groups. Workflow ownership, runner environment and ruleset bypass permissions are part of that change. A local audit proves CLI behavior, not required-check enforcement or SARIF delivery; those need an authorized GitHub runner and repository settings.

Move 3 — route traffic through the approved proxy (SKIPPED-needs-network)

Meridian’s security org already mandates Artifactory for npm and PyPI, so APM joins the same operating model. The platform team pins these environment variables in CI secrets and the shared dev container — not in apm config — for consistent covered acquisition paths:

Current source-grounded routing sketch, not a refreshed infrastructure test. SKIPPED-needs-network: the fictional Artifactory/private proxy and credentials are unavailable. Evidence: producer reference §10 and the pinned proxy guide. needs corporate proxytarget apm v0.31.0
# SKIPPED-needs-network: pin in CI secrets / dev-container env, not `apm config`.
export HTTPS_PROXY="http://proxy.meridian.example:8080"
export PROXY_REGISTRY_URL="https://artifactory.meridian.example/artifactory/github-remote"
export PROXY_REGISTRY_TOKEN="$ARTIFACTORY_TOKEN"   # bearer token; independent of GITHUB_APM_PAT
export PROXY_REGISTRY_ONLY=1                        # refuse direct github.com fallback (mandatory + auditable)

apm install                                        # covered archive path only;
                                                   # separately review the lock and audit deployed content

For an offline handoff, use a real bundle, not the historical Chapter 10 manifest-only output. The current producer/local-bundle fixture adds dependencies: {}; its default-format ZIP actually installed and audited with exit 0 using explicit --target copilot,claude,cursor. Omitting that install flag selected only Copilot in the probe despite the consumer’s three-target manifest. This is a one-shot deployment: the lock records local deployed ownership, not a replayable archive dependency in apm.yml. Retain the artifact for reinstall (producer reference §3; bundle contract).

Provision the bundle, CLI and required policy inputs before disconnecting. The Action’s offline input only forwards to pack’s marketplace resolution; it does not make earlier CLI acquisition or installation air-gapped. Nor does an offline handoff make cold audit hydration or remote policy fetching unnecessary in every project.

Move 4 — publish and own the org baseline (SKIPPED-needs-network)

Finally the platform team lands the org apm-policy.yml in meridian-finance/.github, behind branch protection. This keeps the Chapter 9 ownership beat: product-group repos consume a reviewed authority. Local inheritance can be rehearsed without infrastructure; publishing that authority and verifying private-host discovery remain SKIPPED-needs-network.

Meridian’s fleet baseline, retained as a current source-grounded sketch using the operations schema fixture’s keys. SKIPPED-needs-network: no policy was published to the fictional organization, and no private discovery/permission chain was run. needs org repository accesstarget apm v0.31.0
# meridian-finance/.github/apm-policy.yml -- SKIPPED-needs-network (publication/discovery)
name: meridian-org-baseline
version: "1.0.0"
enforcement: block               # past the pilot: fail closed on violations
fetch_failure: block             # remote posture; does NOT secure an unread first fetch
dependencies:
  require_pinned_constraint: true   # bounded DIRECT declarations, not all transitive constraints
  allow:                            # only these sources (deny still wins)
    - meridian-finance/**
    - microsoft/**
    - github/awesome-copilot/**
  deny:
    - sketchy-org/**
compilation:
  target:
    allow: [copilot, claude, cursor]   # target rules live HERE, not a top-level `targets:` (Ch9)

Keep compilation.target.allow, not a top-level targets policy key: unknown top-level keys now warn; malformed known types are rejected by the parser. Do not use target rules alone to demonstrate blocking: the 0.31.0 plural-only target audit control passed where the singular-target control failed (policy-target-plural-audit/policy-target-singular-audit, operations reference OP09.1).

Add this policy-resolution posture to each consuming apm.yml, separately from the remote policy. Observed missing-org install/audit exits 1/1: policy-no-remote-failclosed-install/policy-no-remote-failclosed-audit; hash-mismatch audit exit 1: policy-pin-nonempty-mismatch-failclosed. Operations reference OP09.3; local/loopback evidence, not live org discovery. apm v0.31.0 — observed configuration
# apm.yml (consumer excerpt)
policy:
  fetch_failure_default: block

Rehearse effective policy in a materialized disposable copy of backend/examples/updates/1.2/operations/policy. Its child tries enforcement: warn and empty deny/require lists; its parent requires a deliberately absent package. Resolving that local chain succeeds, but auditing it must still block:

Local authority rehearsal after the fixture’s frozen materialization. Operations runner records local-parent-merged (exit 0) and child-cannot-clear-parent (expected exit 1); primary evidence: policy-local-inheritance-status/policy-local-inheritance-audit. These are recorded CLI observations, not an organization deployment. apm v0.31.0
& $Apm policy status --policy-source ./apm-policy.child.yml --json --check
& $Apm audit --ci --policy ./apm-policy.child.yml -f json

With the baseline in warn first, Meridian watches Code Scanning across the three groups for two sprints, remediates the top offenders, then flips to block — the same measured rollout as Chapter 9, now fleet-wide, with the pilot repo as the canary. Their status report to leadership is audit pass rate and drift trend, not “repos with a manifest.”

Recap & next

Recap

  • The question changes at scale. From “can this repo install?” to “can every repo install safely and predictably?” A fleet needs five things one team never forces: repeatable rollout, policy ownership, audit gates, a registry strategy, and exception handling. This is the capstone for Governance — enforced and operated across the org.
  • The fleet gate is apm audit --ci. The same integrity gate (Chapter 7) and policy gate (Chapter 9), operated as defence in depth. Protect the command, policy authority, environment and ruleset permissions; --ci does not neutralize bypasses. Cold scratch replay can fetch locked content and fails when that hydration cannot complete. Pin the Action and CLI independently.
  • Proxy routing is environment-variable driven. HTTPS_PROXY + PROXY_REGISTRY_URL + PROXY_REGISTRY_ONLY=1 route and mirror traffic; reviewed bundles support offline handoffs with one-shot deployment limits. Recorded hashes and ownership support Reproducibility; the proxy is neither a publisher signature nor a dedicated registry. Experimental registry implementation exists; a public hosted hub is not established by this evidence.
  • Adoption is change management. Discover → Pilot → Harden → Scale → Sustain, each with an owner, a deliverable, and a gate. Measure by leading indicators — audit pass rate, drift trend, marketplace uptake, setup time — not by manifest count, which is a vanity metric. Carrot before stick; a named on-call, never “the platform team.”
  • Mind the measured limits at apm v0.31.0. Pin constraints are direct-scoped; consumer fail-closed posture protects first policy resolution, not an environment-disabled gate. A green audit is not complete native MCP/runtime coverage. gh-aw imports isolated context, and the legacy Copilot pack’s shared-skill omission remains a real bug — the successful instruction control is not blanket compatibility.

Next

You have now consumed, locked, maintained, secured, governed, produced, and operated agent context across a fleet — the full arc from one repo to an organization. Chapter 12 — The Landscape & What’s Next steps back to place APM among the standards it builds on (AGENTS.md, Agent Skills, MCP, OpenAPM v0.1) and the roadmap ahead — distinguishing shipped experimental registry support from draft normative commitments — so you can decide what to adopt, watch, or build around.