Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions docs/src/content/docs/enterprise/enforce-in-ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@ jobs:

`microsoft/apm-action@v1` runs `apm install` by default, so by the time
`apm audit --ci` runs, the lockfile and deployed files are present.
That remains the right default for repos that gitignore their deployed
outputs, because `deployed-files-present` still expects those files on disk.
Use that default when CI needs to materialize deployed outputs.
Missing gitignored outputs do not fail `deployed-files-present`, so those
repos can also use audit-only CI. Without committed deployed bytes, that
pattern has reduced integrity and drift coverage.
Make this job a required status check via
[GitHub Rulesets](../github-rulesets/) and a violating PR cannot merge.

Expand All @@ -94,7 +96,8 @@ check then compares the freshly restored file against a hash that matches,
and the tampering goes undetected.

For repos that **commit** their deployed files, the CI gate can now run in
setup-only mode and still execute drift plus `config-consistency` from a cold
setup-only mode and still execute drift plus `config-consistency` and
`skill-subset-consistency` from a cold
cache. `apm audit --ci` self-hydrates a lock-pinned scratch install, compares
the tracked checkout against that replay, and never rewrites the working tree
or live `apm_modules/`.
Expand All @@ -120,7 +123,7 @@ jobs:

`setup-only: true` leaves every deployed file exactly as checked out.
`apm audit --ci` now self-hydrates its scratch replay from `apm.lock.yaml`,
so drift and `config-consistency` still run even when the checkout has no
so drift, `config-consistency`, and `skill-subset-consistency` still run even when the checkout has no
live `apm_modules/` tree. If the scratch replay itself cannot be materialized,
the audit fails closed instead of reporting a green skip. The
`content-integrity` check still verifies that every deployed file's SHA-256
Expand Down
13 changes: 11 additions & 2 deletions docs/src/content/docs/integrations/ci-cd.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,20 @@ provides the CLI, then run the full CI gate:

In setup-only CI, `apm audit --ci` now self-hydrates a lock-pinned scratch
install when `apm_modules/` is absent, so drift and `config-consistency`
still run without mutating the checkout. Repos that gitignore deployed
still run without mutating the checkout. `skill-subset-consistency` also
checks selected skills against this lock-pinned tree, not the absent checkout
dependencies. Invalid selections and manifest/lock mismatches still fail;
deployed-file integrity and drift checks still inspect the checkout when
outputs are committed.

Repos that gitignore deployed
outputs can still use the audit-only pattern: `deployed-files-present`
skips gitignored paths automatically, so a fresh checkout of a repo that
gitignores a deploy directory (e.g. `.agents/`) passes the check without
an `apm install` step. See
an `apm install` step. Note that `content-integrity` and drift have no
committed deployed bytes to compare in that case, so coverage is limited
to lockfile/subset consistency for gitignored deploy roots -- commit
deployed outputs if you need full integrity and drift coverage. See
[Audit-only CI pattern](../../enterprise/enforce-in-ci/#audit-only-ci-pattern)
for the full recipe and when to use each approach.

Expand Down
6 changes: 3 additions & 3 deletions docs/src/content/docs/reference/baseline-checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ the [policy schema](../policy-schema/).

### `skill-subset-consistency`

- **What it verifies.** That each `skills:` selection in `apm.yml` matches the `skill_subset` recorded in the lockfile, and that every recorded skill path exists in the resolved package tree.
- **Fails when.** The sorted manifest skill list differs from the sorted lockfile `skill_subset`, or a recorded subset path no longer maps to a deployable skill in the installed package.
- **What it verifies.** That each `skills:` selection in `apm.yml` matches the `skill_subset` recorded in the lockfile, and that every recorded skill path exists in the resolved package tree. When CI audit has prepared a lock-pinned scratch replay, this check uses its dependency tree instead of checkout-local `apm_modules/`; no checkout install is required.
- **Fails when.** The sorted manifest skill list differs from the sorted lockfile `skill_subset`, or a recorded subset path does not map to a deployable skill in the dependency tree being checked.
- **Remediation.** Run `apm install` to regenerate the lockfile against the current selection.

### `config-consistency`
Expand Down Expand Up @@ -153,7 +153,7 @@ the [policy schema](../policy-schema/).

## Run order and fail-fast

The aggregate runner in `run_baseline_checks` evaluates checks in this order: `manifest-parse` (only when `apm.yml` is unparseable), `lockfile-exists`, `ref-consistency`, `deployment-ledger-owners`, `deployed-files-present`, `no-orphaned-packages`, `skill-subset-consistency`, `config-consistency`, `content-integrity`, `includes-consent`. Drift is invoked separately by the audit command after the baseline batch, but in `--ci` mode it shares the same cold-cache scratch materialization with `config-consistency`.
The aggregate runner in `run_baseline_checks` evaluates checks in this order: `manifest-parse` (only when `apm.yml` is unparseable), `lockfile-exists`, `ref-consistency`, `deployment-ledger-owners`, `deployed-files-present`, `no-orphaned-packages`, `skill-subset-consistency`, `config-consistency`, `content-integrity`, `includes-consent`. Drift is invoked separately by the audit command after the baseline batch, but in `--ci` mode it shares the same cold-cache scratch materialization with `skill-subset-consistency` and `config-consistency`.

With fail-fast on (the default), the runner stops at the first failing check. `apm audit --ci --no-fail-fast` evaluates every check so the report lists every problem at once.

Expand Down
4 changes: 2 additions & 2 deletions docs/src/content/docs/reference/cli/audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ apm audit [PACKAGE] [OPTIONS]
`apm audit` is the explicit security and integrity tool. It runs in two modes:

- **Content scan mode** (default). Discovers recognized deployed primitives and checks applicable prompt content for hidden Unicode, including untracked primitives and recorded files outside currently selected target directories. It replays the install pipeline into a scratch tree to detect drift (hand-edits to deployed files, missing integrations, orphaned files vs the lockfile). Can also remediate regular prompt documents with `--strip` or scan an arbitrary file with `--file`.
- **CI gate mode** (`--ci`). Runs lockfile consistency checks plus drift in machine-readable form (text, JSON, or SARIF) suitable for branch-protection gates. When `apm_modules/` is absent but `apm.lock.yaml` is present, CI mode self-hydrates a lock-pinned scratch install for `config-consistency` and drift without mutating the checkout. Auto-discovers org policy from your project's git remote unless `--no-policy` is set.
- **CI gate mode** (`--ci`). Runs lockfile consistency checks plus drift in machine-readable form (text, JSON, or SARIF) suitable for branch-protection gates. When `apm_modules/` is absent but `apm.lock.yaml` is present, CI mode self-hydrates a lock-pinned scratch install for `skill-subset-consistency`, `config-consistency`, and drift without mutating the checkout. Auto-discovers org policy from your project's git remote unless `--no-policy` is set.

Global audit also checks resolved external deployment roots such as
`HERMES_HOME` and `CLAUDE_CONFIG_DIR`. Default audit compares tracked files in
Expand Down Expand Up @@ -285,7 +285,7 @@ as metadata repair; see [`apm prune`](../prune/#canonical-deployment-ownership).

### CI checks (`--ci`)

`--ci` runs the baseline lockfile consistency checks defined in `src/apm_cli/policy/ci_checks.py`: lockfile presence, canonical deployment-owner integrity (`deployment-ledger-owners`), ref consistency, deployed-files presence, no orphaned packages, skill-subset consistency, MCP config consistency, content integrity, and an advisory `includes` consent check. A lockfile is required when `apm.yml` declares APM or MCP dependencies. For an MCP-only project, normal [`apm install`](../install/#behavior) creates or repairs the resolved MCP lock state; frozen install fails without writing when that state is missing or stale. Content integrity scans hidden Unicode across the whole-project deployed-file scope and checks SHA-256 drift only where the lockfile provides a baseline. Drift replay runs alongside and contributes to the exit code unless `--no-drift` is set; `--no-drift` never disables hidden-Unicode scanning. On a cold cache, CI mode self-hydrates a scratch install from the lockfile pins instead of reporting a green skip, so setup-only CI can still catch stale committed deployed files without rewriting the checkout. Audit also reports `unrecorded` drift when replay produces governed files that no lockfile entry claims. Repos that gitignore deployed outputs still need those files present on disk for `deployed-files-present`, so the full-install CI pattern remains the right default there. With policy discovery active, declared policy rules are evaluated against the resolved manifest. See [Baseline CI checks](../../baseline-checks/) for the full reference.
`--ci` runs the baseline lockfile consistency checks defined in `src/apm_cli/policy/ci_checks.py`: lockfile presence, canonical deployment-owner integrity (`deployment-ledger-owners`), ref consistency, deployed-files presence, no orphaned packages, skill-subset consistency, MCP config consistency, content integrity, and an advisory `includes` consent check. A lockfile is required when `apm.yml` declares APM or MCP dependencies. For an MCP-only project, normal [`apm install`](../install/#behavior) creates or repairs the resolved MCP lock state; frozen install fails without writing when that state is missing or stale. Content integrity scans hidden Unicode across the whole-project deployed-file scope and checks SHA-256 drift only where the lockfile provides a baseline. Drift replay runs alongside and contributes to the exit code unless `--no-drift` is set; `--no-drift` never disables hidden-Unicode scanning. On a cold cache, CI mode self-hydrates a scratch install from the lockfile pins instead of reporting a green skip, so setup-only CI can still catch stale committed deployed files without rewriting the checkout. Audit also reports `unrecorded` drift when replay produces governed files that no lockfile entry claims. Missing gitignored deployed outputs do not fail `deployed-files-present`; audit-only CI can pass without them, but lacks deployed-byte integrity and drift coverage when no outputs are committed. Use full-install CI when those outputs need to be materialized. With policy discovery active, declared policy rules are evaluated against the resolved manifest. See [Baseline CI checks](../../baseline-checks/) for the full reference.

### Mutual exclusions

Expand Down
Loading
Loading