Skip to content

docs(governance): flagship Governance Guide + corpus rationalization#851

Merged
danielmeppiel merged 4 commits intomainfrom
docs/governance-spine-alignment
Apr 22, 2026
Merged

docs(governance): flagship Governance Guide + corpus rationalization#851
danielmeppiel merged 4 commits intomainfrom
docs/governance-spine-alignment

Conversation

@danielmeppiel
Copy link
Copy Markdown
Collaborator

@danielmeppiel danielmeppiel commented Apr 22, 2026

Summary

Add a flagship Governance Guide at docs/src/content/docs/enterprise/governance-guide.md (604 lines, 4 mermaid diagrams) for enterprise readers (CISO / VP Eng / Platform Tech Lead) who need 100% certitude about what APM governance controls, exactly how it works, where it can be bypassed, and what its honest limitations are.

This grew out of the original feature-page work for apm-policy.yml -- audience review showed a feature page wasn't enough. Enterprises need a full guide that owns the bypass contract, the install-gate guarantees, the failure semantics, the air-gapped story, and the known gaps.

The PR also restructures README.md around the deck spine -- Portable by manifest. Secure by default. Governed by policy. -- giving the Governance Guide a top-of-funnel entry point.

What changed

New artifacts

  • docs/src/content/docs/enterprise/governance-guide.md -- 604 lines, 16 sections, 4 mermaid diagrams:
    • Persona triage (CISO / VPE / Platform TL)
    • 30-second mental model + three-cracks framing (FRAGILE / MANUAL / UNGOVERNED)
    • Capability matrix (what you can govern + what you cannot)
    • Four enforcement points + explicit "what does NOT enforce policy"
    • Inheritance composition with worked example + counter-example
    • Bypass / non-bypass contract -- the 4-column table is the headline artifact
    • Install-gate guarantees + explicit "NOT guaranteed" pairing
    • Air-gapped decision matrix
    • Failure semantics with on-call decision tree
    • Phased rollout playbook (warn -> measure -> block) with inline CI YAML
    • Auditing the auditor (CODEOWNERS + SoD guidance)
    • Enforcement audit log (SARIF + retention guidance)
    • 14-item known-gaps list with operational mitigations
    • Decision tree for picking the right policy template
  • templates/apm-policy-starter.yml -- the 15-minute pilot starter

README restructure (deck-spine alignment)

## Highlights (flat 7-bullet list) replaced with ## The three promises:

  1. Portable by manifest -- one-manifest-for-everything, install-from-anywhere, transitive deps, plugins, marketplaces, pack & distribute, CI/CD
  2. Secure by default -- content security, lockfile integrity, MCP trust boundaries
  3. Governed by policy -- the new Governance Guide leads, then policy reference, adoption playbook, GitHub rulesets

Adds a short blockquote drumbeat ("Portable by manifest. Secure by default. Governed by policy.") right under the doc-links row so the spine is visible above the fold. No content cuts -- every previous link is preserved and re-bucketed.

Corpus rationalization (no new duplication)

  • enterprise/governance.md trimmed (310 -> 240). Kept lockfile audit-trail forensics + SOC 2 / change-management; removed duplicate rollout/CI sections. Top-of-page pointer added.
  • enterprise/apm-policy.md trimmed; banner added pointing to the guide.
  • integrations/github-rulesets.md baseline-checks list replaced with link to policy-reference.
  • docs/astro.config.mjs sidebar updated; orders rebalanced (governance=3, apm-policy=4, policy-reference=5, security=6, adoption-playbook=7) -- fixes prior collisions.
  • CHANGELOG.md entry added under [Unreleased] -> Added.

Process behind the guide

This was authored over six waves to earn enterprise-grade trust:

  1. Reconnaissance (3 parallel agents): code-reality scan with file:line citations, doc-corpus inventory, deck-vocabulary extraction.
  2. Plan: 16-section outline with cross-cutting non-negotiables, banned phrases, mermaid style anchored on how-it-works.md:89-113.
  3. Draft: 518 lines, ASCII-clean, build-validated.
  4. Audience reviews (3 parallel personas): CISO, VP Eng, Platform Tech Lead. Verdicts: conditional yes / cautiously yes / trustworthy spec.
  5. Iteration Why do we need a GitHub token? #1: 17 of 18 audience findings applied (broken gh code-scanning command fixed to gh api, --force row added to bypass table, hash-mismatch dry-run gap qualified, APM_POLICY_DISABLE preamble in 5a, etc.).
  6. APM Review Panel (4 specialists): Supply Chain Security, DevX UX, CEO, OSS Growth Hacker. Findings synthesized into a final iteration:
    • Soften :::caution[Experimental] -> :::note[Policy Engine Maturity] with stable / early-preview split
    • Three-cracks framing in section 2
    • Design-choice opener atop section 14
    • --force added to section 12 lint pattern (security expert caught a false negative)
    • Section 5a "What does NOT enforce policy" renumbered (was orphan h2)
    • Section 10 file:line citations replaced with stable file refs
    • Section 7 bypass-table cells shortened for narrow viewports
    • Section 11 CI YAML pins apm-cli==X.Y.Z
    • Section 16 "Starting a pilot?" 15-minute path

Honesty callouts the guide owns explicitly

These are the disclosures no proprietary governance vendor will publish:

  • apm install --no-policy and APM_POLICY_DISABLE=1 DO bypass the 16 policy checks even in apm audit --ci. Only the 6 baseline lockfile checks are non-bypassable.
  • apm compile / apm run enforce zero policy.
  • policy.cache.ttl, mcp.trust_transitive, manifest.content_types are parsed but not enforced.
  • compilation.strategy, compilation.source_attribution, manifest.required_fields, manifest.scripts, unmanaged_files are AUDIT-ONLY (install does not enforce).
  • Network failure / malformed YAML = fail-OPEN by default unless policy.fetch_failure_default: block is set.
  • Hash-mismatch is unconditionally fail-closed in non-dry-run paths; --dry-run silently downgrades it.
  • apm audit --ci in warn mode rewrites violations to passed=True -- warn never fails CI exit.
  • apm install has NO --policy <path> flag (only audit does) -- air-gapped install gap.
  • Trust anchor is git remote get-url origin -- a developer can bypass org policy by relocating to a personal org.
  • Deployed file hashes are recorded but never re-verified -- no drift detection.
  • Non-GitHub remotes (ADO, GitLab) for the project repo: auto-discovery currently falls through.

Out of scope for this PR (future work surfaced)

These are real bugs / features the recon and reviews uncovered. Captured here so they're not lost:

  1. apm install --no-policy help text is misleading (commands/install.py:1057). It claims "Does NOT bypass apm audit --ci" -- only true for the 6 baseline checks.
  2. Add apm install --policy <path> flag for true air-gapped install-time enforcement (audit already has it).
  3. Implement policy.cache.ttl (currently parsed-but-ignored; reader uses hardcoded 1h).
  4. Wire mcp.trust_transitive policy field to enforcement (currently only the CLI flag is the gate).
  5. Implement drift detection on deployed_file_hashes (currently recorded but never re-verified).
  6. Audit warn-mode silent passing (commands/audit.py:589-598) is intentional-by-design but surprising; consider --strict-warn to fail CI on warn violations.
  7. SLSA / signed attestation that the gate ran (CISO procurement requirement).
  8. Non-GitHub remote support in policy auto-discovery (ADO, GitLab, plain git).

Build status

npm run build passes locally (44 pages, 0 broken internal links). The Could not render /404 warning is pre-existing Starlight behavior, unrelated.


Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Adds a new `enterprise/apm-policy.yml` feature page that explains the
policy file's mental model -- where it lives, how enforcement works at
install and CI time, and the tighten-only inheritance merge rules --
without duplicating the 876-line schema dump in policy-reference.md or
the broader governance pipeline in governance.md.

This closes a real gap: today the README mentions `apm-policy.yml` only
inside the Marketplaces bullet, and the only landing page is the schema
spec. Anyone trying to understand what the file *is* lands in a wall of
fields instead of a 30-second elevator pitch.

Aligned with the deck's three-pillar spine (Portable / Secure /
Governed). The new page surfaces:

- The `<org>/.github/apm-policy.yml` discovery pattern
- A 12-line minimal policy example
- The two enforcement points (install-time + CI-time)
- The merge-rule table (allow intersect, deny union, max_depth min,
  trust_transitive AND)
- A `What a violation looks like` walkthrough with literal CLI output
- Forensic pointer to `git log apm.lock.yaml` (delegates to
  governance.md, no duplication)

Companion edits:

- `governance.md`: opens with the `12 teams, 4 stacks, one security
  review` scenario hook from the deck; adds a PR violation walkthrough
  section under Organization policy governance; cross-links to the new
  feature page.
- `ci-policy-setup.md`: adds a `What a violation looks like` section
  with sample CLI output and a SARIF reminder; adds a link to the new
  feature page in Related.
- Sidebar: new `apm-policy.yml` slot between Governance and Policy
  Reference (concept -> feature -> reference ladder).
- Policy Reference sidebar order shifted from 3 to 4.

All new and edited pages preserve the existing `:::caution[Experimental]`
honesty wording verbatim.

README restructure (3-pillar spine) is proposed in the PR description
for separate review, per the repo's README approval policy.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 22, 2026 20:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR elevates apm-policy.yml from a schema-only reference into a first-class concept/feature page and updates governance-related docs to follow a concept -> feature -> reference ladder in the Enterprise docs sidebar.

Changes:

  • Adds a new enterprise/apm-policy.md concept page explaining what the policy file is, where it lives, enforcement points, inheritance rules, and an example violation.
  • Updates enterprise/governance.md and guides/ci-policy-setup.md with a violation walkthrough and cross-links to the new concept page.
  • Adjusts docs sidebar ordering to insert apm-policy.yml between Governance and Policy Reference.
Show a summary per file
File Description
docs/src/content/docs/enterprise/apm-policy.md New concept page for apm-policy.yml (mental model, examples, enforcement, inheritance).
docs/src/content/docs/enterprise/governance.md Adds scenario-based intro, links to policy concept page, and a violation walkthrough section.
docs/src/content/docs/guides/ci-policy-setup.md Adds a “what a violation looks like” section and links to the new concept page.
docs/astro.config.mjs Inserts apm-policy.yml into the Enterprise sidebar between Governance and Policy Reference.
docs/src/content/docs/enterprise/policy-reference.md Moves sidebar order to make room for the new concept page.

Copilot's findings

Comments suppressed due to low confidence (6)

docs/src/content/docs/enterprise/apm-policy.md:107

  • The merge-rules table uses Unicode em dashes ("—") in the descriptions, which violates the repo's ASCII-only documentation rule. Replace them with ASCII equivalents (e.g. "--" or parentheses) so the table remains printable-ASCII.
|-------|----------------------------|
| `allow` lists | **intersect** — the child sees only entries present in both |
| `deny` lists | **union** — the child adds to the parent's deny |
| `max_depth` | **min(parent, child)** — whichever is smaller wins |
| `trust_transitive` | **parent AND child** — both must allow it |

docs/src/content/docs/enterprise/apm-policy.md:140

  • The line "Override with --no-policy" is ambiguous in this context. --no-policy can bypass install-time enforcement locally, but it is overridden when --policy is explicitly set on apm audit --ci, and the install command explicitly warns it does not bypass CI (apm audit --ci). Please rephrase to prevent readers from assuming CI gates can be bypassed with --no-policy.

Run `apm audit --ci --policy org` for full report. Override with `--no-policy` (not recommended).
**docs/src/content/docs/enterprise/apm-policy.md:52**
* These bullet lines use Unicode em dashes ("—"), but docs in this repo must remain printable ASCII. Replace the em dashes with ASCII punctuation (e.g. "--" or ":") to keep the docs cp1252-safe on Windows terminals.

Alternative sources, useful for testing or non-GitHub setups:

  • Local fileapm audit --ci --policy ./apm-policy.yml
  • HTTPS URLapm audit --ci --policy https://example.com/apm-policy.yml

See Alternative policy sources for details.

**docs/src/content/docs/enterprise/apm-policy.md:87**
* Install-time policy enforcement does not run "before resolving dependencies". The install pipeline runs the policy gate after the resolve phase (so the dependency list is known) and before any integration/target writes. Please update this description to match the actual phase order (and align with the wording in the Policy Reference).

Install time (preflight gate)

apm install reads the discovered policy before resolving dependencies. Violations halt the install with a non-zero exit code; nothing is written to disk. This protects developers who run apm install locally — they cannot accidentally deploy a denied package even without CI.

**docs/src/content/docs/enterprise/apm-policy.md:140**
* This violation output example does not match the current `apm install` logging format. The CLI prints `Policy violation: <dep> -- denied by pattern: <glob>` (and a follow-up remediation hint); it doesn't emit structured "Policy:", "Rule:", and "Action:" lines. Consider updating this snippet (or linking to a single canonical snippet elsewhere) so users see what they'll actually get in their terminal.

apm install halts before any file is written:

[x] Policy violation: dependency 'untrusted-org/random-skills' is denied by org policy
    Policy: contoso/.github/apm-policy.yml
    Rule:   dependencies.deny matches 'untrusted-org/**'
    Action: install aborted, no files deployed

Run `apm audit --ci --policy org` for full report. Override with `--no-policy` (not recommended).
**docs/src/content/docs/enterprise/apm-policy.md:163**
* These list items use Unicode em dashes ("—"), which violates the repo's ASCII-only documentation/strings rule. Please replace with ASCII punctuation so the rendered docs remain cp1252-safe on Windows.

Next steps

</details>


- **Files reviewed:** 5/5 changed files
- **Comments generated:** 6


Rule: dependencies.deny matches 'untrusted-org/**'
Action: install aborted, no files deployed

Run `apm audit --ci --policy org` for full report. Override with `--no-policy` (not recommended).
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example suggests you can "Override with --no-policy" right after recommending apm audit --ci --policy org. In the CLI, --no-policy is ignored when --policy is passed explicitly, and apm install --no-policy explicitly does not bypass apm audit --ci (CI will still fail). Please reword to avoid implying that CI enforcement can be bypassed with --no-policy.

Suggested change
Run `apm audit --ci --policy org` for full report. Override with `--no-policy` (not recommended).
Run `apm audit --ci --policy org` for full report. `--no-policy` only disables implicit policy discovery and does not bypass an explicit `--policy` selection or CI enforcement.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
`apm-policy.yml` is a single YAML file that defines what AI agent dependencies, MCP servers, and compilation targets are allowed across an organization. It is the governance pillar of APM — the file your security team owns and your repos inherit.

This page is the mental model. For the full schema, see the [Policy Reference](../policy-reference/). For wiring it into CI, see the [CI Policy Enforcement guide](../../guides/ci-policy-setup/).
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page introduces multiple Unicode em dashes ("—") (for example in this sentence), but the repo's encoding rule requires docs to stay within printable ASCII (U+0020–U+007E). Please replace em dashes with ASCII alternatives like "--" or " - ".

This issue also appears in the following locations of the same file:

  • line 47
  • line 103
  • line 159

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +9 to +12
The `apm-policy.yml` schema, inheritance, and discovery ship today and are usable for testing and feedback. Policy enforcement at install time and via `apm audit --ci --policy` is an early preview. Fields, defaults, and check behaviour may change based on community input. Pin your policy to a specific APM version and watch the [CHANGELOG](https://github.com/microsoft/apm/blob/main/CHANGELOG.md) for breaking changes.
:::

`apm-policy.yml` is a single YAML file that defines what AI agent dependencies, MCP servers, and compilation targets are allowed across an organization. It is the governance pillar of APM — the file your security team owns and your repos inherit.
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence says to "Pin your policy to a specific APM version", but apm-policy.yml doesn't provide a way to pin itself to a CLI version (and the version: field is informational, not used for resolution). If the intent is supply-chain pinning, the implementation uses policy.hash in apm.yml to pin the expected policy bytes. Please adjust the wording to point to the supported pin mechanism so readers don't look for a non-existent "APM version" knob in the policy file.

This issue also appears in the following locations of the same file:

  • line 84
  • line 131
  • line 138
Suggested change
The `apm-policy.yml` schema, inheritance, and discovery ship today and are usable for testing and feedback. Policy enforcement at install time and via `apm audit --ci --policy` is an early preview. Fields, defaults, and check behaviour may change based on community input. Pin your policy to a specific APM version and watch the [CHANGELOG](https://github.com/microsoft/apm/blob/main/CHANGELOG.md) for breaking changes.
:::
`apm-policy.yml` is a single YAML file that defines what AI agent dependencies, MCP servers, and compilation targets are allowed across an organization. It is the governance pillar of APM the file your security team owns and your repos inherit.
The `apm-policy.yml` schema, inheritance, and discovery ship today and are usable for testing and feedback. Policy enforcement at install time and via `apm audit --ci --policy` is an early preview. Fields, defaults, and check behaviour may change based on community input. If you need supply-chain pinning, pin the expected policy bytes with `policy.hash` in `apm.yml`, and watch the [CHANGELOG](https://github.com/microsoft/apm/blob/main/CHANGELOG.md) for breaking changes.
:::
`apm-policy.yml` is a single YAML file that defines what AI agent dependencies, MCP servers, and compilation targets are allowed across an organization. It is the governance pillar of APM - the file your security team owns and your repos inherit.

Copilot uses AI. Check for mistakes.
Comment on lines +213 to +219
The CI run fails with a clear pointer to the offending rule:

```
[x] Policy violation: dependency 'untrusted-org/random-skills' is denied by org policy
Policy: contoso/.github/apm-policy.yml
Rule: dependencies.deny matches 'untrusted-org/**'
```
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sample CI failure output here does not match what apm audit --ci --policy org actually prints in text mode. In CI mode the command renders a "APM Policy Compliance" table with per-check messages (e.g. dependency-denylist) and then lists the failing check details (e.g. untrusted-org/random-skills: denied by pattern: untrusted-org/**). Consider updating the snippet to mirror _render_ci_results() output so users can recognize real failures.

Copilot uses AI. Check for mistakes.
Comment on lines +140 to +144
@@ -141,7 +141,30 @@ Policy enforcement applies at both `apm install` (blocks before files are writte
2. **Auto-discover** — `--policy org` fetches the policy via GitHub API from `<org>/.github/apm-policy.yml`.
3. **Enforce** — `apm audit --ci --policy org` runs all 22 checks (6 baseline + 16 policy).

Policies support a three-level inheritance chain (`Enterprise hub -> Org policy -> Repo override`) where child policies can only tighten constraints. For the complete schema, all check names, pattern matching rules, and inheritance semantics, see the [Policy Reference](../policy-reference/). For step-by-step CI setup, see the [CI Policy Enforcement guide](../../guides/ci-policy-setup/).
Policies support a three-level inheritance chain (`Enterprise hub -> Org policy -> Repo override`) where child policies can only tighten constraints. For the mental model and the merge-rule table, see [`apm-policy.yml`](../apm-policy/). For the complete schema and check names, see the [Policy Reference](../policy-reference/). For step-by-step CI setup, see the [CI Policy Enforcement guide](../../guides/ci-policy-setup/).
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines use Unicode em dashes ("—"), but the repo's encoding rule requires documentation to stay within printable ASCII (U+0020–U+007E) to avoid Windows cp1252 issues. Please replace em dashes with ASCII alternatives like "--" or " - ".

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +159 to +164
[x] Policy violation: dependency 'untrusted-org/random-skills' is denied by org policy
Policy: contoso/.github/apm-policy.yml
Rule: dependencies.deny matches 'untrusted-org/**'
Action: install aborted, no files deployed

Run `apm audit --ci --policy org` for full report. Override with `--no-policy` (not recommended).
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The install-time violation example here doesn't align with the current CLI output. apm install logs inline errors in the form Policy violation: <dep> -- <reason> (where the denylist reason is denied by pattern: <glob>), followed by a dim remediation hint; it does not print "Policy:", "Rule:", and "Action:" lines. Updating this snippet to match the real output will make the walkthrough easier to follow and less likely to drift.

Suggested change
[x] Policy violation: dependency 'untrusted-org/random-skills' is denied by org policy
Policy: contoso/.github/apm-policy.yml
Rule: dependencies.deny matches 'untrusted-org/**'
Action: install aborted, no files deployed
Run `apm audit --ci --policy org` for full report. Override with `--no-policy` (not recommended).
[x] Policy violation: untrusted-org/random-skills -- denied by pattern: untrusted-org/**
[i] Run `apm audit --ci --policy org` for the full report. Override with `--no-policy` (not recommended).

Copilot uses AI. Check for mistakes.
@danielmeppiel danielmeppiel marked this pull request as draft April 22, 2026 20:31
Add docs/src/content/docs/enterprise/governance-guide.md (604 lines, 4 mermaid
diagrams) as the enterprise-grade reference for org policy enforcement, with
explicit honesty about bypass surfaces, dry-run hash-mismatch silent downgrade,
parsed-but-not-enforced fields, warn-mode non-failing semantics, air-gapped
gaps (no apm install --policy flag), and trust-anchor limits.

Iterated through three audience reviews (CISO, VP Eng, Platform Tech Lead)
and a four-specialist panel (security, devx-ux, ceo, oss-growth):
  - Soften Experimental banner to Policy Engine Maturity (split stable vs early preview)
  - Three-cracks framing in section 2 (FRAGILE / MANUAL / UNGOVERNED)
  - Design-choice opener atop Known Gaps (we publish this list)
  - --force added to bypass-flag CI lint
  - Section 5a 'What does NOT enforce policy' renumbered (was orphan h2)
  - Section 10 citations replaced with stable file refs (no line numbers)
  - Section 7 bypass table cells shortened for narrow viewports
  - Section 11 CI YAML now pins apm-cli==X.Y.Z placeholder
  - Section 16 'Starting a pilot?' tip with 15-minute path
  - Bypass-table contract; install-gate guarantees / not-guaranteed pairing;
    failure-semantics on-call decision tree; SoD CODEOWNERS guidance.

Add templates/apm-policy-starter.yml for the 15-minute pilot path.

Rationalize the surrounding corpus to point at the new guide:
  - governance.md trimmed (310 -> 240): kept lockfile audit-trail forensics
    and SOC 2 / change-management content; removed duplicate rollout/CI sections
  - apm-policy.md: top banner pointing to guide; forensics block collapsed
  - integrations/github-rulesets.md: baseline-checks list -> link to policy-reference
  - astro.config.mjs sidebar: governance-guide inserted at slot 2; orders
    rebalanced (governance=3, apm-policy=4, policy-reference=5, security=6,
    adoption-playbook=7, making-the-case=8) -- fixes prior collisions

CHANGELOG entry under [Unreleased] -> Added.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel danielmeppiel changed the title docs(governance): elevate apm-policy.yml as a feature page docs(governance): flagship Governance Guide + corpus rationalization Apr 22, 2026
Replace flat 'Highlights' list with three named promises matching the
deck spine (Portable by manifest / Secure by default / Governed by policy)
and add a short blockquote drumbeat directly under the doc-links row.

Each pillar now leads with its canonical guide:
  - Portable -> primitive-types reference
  - Secure   -> security model + lockfile integrity
  - Governed -> the new flagship Governance Guide

Removes the duplicated 'governed by apm-policy.yaml' parenthetical from
the marketplace bullet (governance now has its own pillar).

No content cuts vs the previous Highlights -- every existing link is
preserved and re-bucketed under the right pillar.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel danielmeppiel marked this pull request as ready for review April 22, 2026 22:18
@danielmeppiel danielmeppiel requested a review from Copilot April 22, 2026 22:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (6)

README.md:20

  • This README section introduces multiple Unicode em dashes (for example on these lines). The repo explicitly aims to be ASCII-safe for Windows cp1252 terminals (see STATUS_SYMBOLS comment in src/apm_cli/utils/console.py:33-55); please replace these with ASCII equivalents (e.g., "--" or ", ") to avoid encoding issues in downstream tooling/rendering.

This issue also appears in the following locations of the same file:

  • line 51
  • line 63
AI coding agents need context to be useful — standards, prompts, skills, plugins — but today every developer sets this up manually. Nothing is portable nor reproducible. There's no manifest for it.

**APM fixes this.** Declare your project's agentic dependencies once in `apm.yml`, and every developer who clones your repo gets a fully configured agent setup in seconds — with transitive dependency resolution, just like npm or pip. It's also the first tool that lets you **author plugins** with a real dependency manager and export standard `plugin.json` packages.

README.md:63

  • This claims installs scan for "prompt-injection patterns", but the implementation appears limited to hidden/unexpected Unicode character scanning (and the Governance Guide explicitly states prompt-injection detection is out of scope). Please adjust this wording to match actual behavior so the README doesn't over-promise security guarantees.
Agent context is executable in effect — a prompt is a program for an LLM. APM treats it that way. Every install passes through content scanning for hidden Unicode and prompt-injection patterns; the lockfile pins integrity hashes; transitive MCP servers are gated by trust prompts.

docs/src/content/docs/enterprise/apm-policy.md:76

  • The minimal policy example implies mcp.trust_transitive is an effective enforcement control ("do not auto-install MCPs from transitive packages"), but the code currently gates transitive MCP installation via the --trust-transitive-mcp CLI flag (policy field is parsed/merged but not enforced). Please either remove this field from the minimal example or clearly label it as not-yet-enforced to avoid misleading readers.
mcp:
  transport:
    allow: [http, stdio]   # block sse and streamable-http
  trust_transitive: false  # do not auto-install MCPs from transitive deps
**docs/src/content/docs/enterprise/governance-guide.md:155**
* This describes warn-mode behavior as logging violations with "[x]" lines, but the logger only emits an inline "Policy violation" line for block-mode; warn-mode violations are recorded for the end-of-install summary instead. Please adjust the wording to reflect what users actually see in `enforcement: warn` so operational runbooks don't rely on output that won't appear.

Runs after dependency resolution and before file targets. Enforces the dependency, MCP, and (post-targets) compilation-target rules against the resolved set. On enforcement: block, raises PolicyViolationError and aborts before any file is written. On enforcement: warn, logs every violation with [x] lines and continues.

**README.md:52**
* The lockfile is referred to here as `apm.lock`, but the actual lockfile name used throughout the docs and code is `apm.lock.yaml`. Using the wrong name in the README can confuse users and makes copy/paste instructions inaccurate.

One apm.yml describes every primitive your agents need — instructions, skills, prompts, agents, hooks, plugins, MCP servers — and apm install reproduces the exact same setup across every client on every machine. apm.lock pins the resolved tree the way package-lock.json does for npm.

**docs/src/content/docs/enterprise/apm-policy.md:89**
* This states that `apm install` reads and enforces policy "before resolving dependencies", but the install pipeline runs the policy gate after dependency resolution (`pipeline.py` phase 1.5 runs after resolve). Please update this description to match the actual enforcement point so readers understand what is and isn't prevented early.

apm install reads the discovered policy before resolving dependencies. Violations halt the install with a non-zero exit code; nothing is written to disk. This protects developers who run apm install locally — they cannot accidentally deploy a denied package even without CI.

</details>


- **Files reviewed:** 13/13 changed files
- **Comments generated:** 3

The `apm-policy.yml` schema, inheritance, and discovery ship today and are usable for testing and feedback. Policy enforcement at install time and via `apm audit --ci --policy` is an early preview. Fields, defaults, and check behaviour may change based on community input. Pin your policy to a specific APM version and watch the [CHANGELOG](https://github.com/microsoft/apm/blob/main/CHANGELOG.md) for breaking changes.
:::

`apm-policy.yml` is a single YAML file that defines what AI agent dependencies, MCP servers, and compilation targets are allowed across an organization. It is the governance pillar of APM — the file your security team owns and your repos inherit.
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page contains multiple Unicode em dashes (for example on this line). The project has explicit ASCII-safe console conventions (see src/apm_cli/utils/console.py:33-55); please replace non-ASCII punctuation with ASCII equivalents to avoid Windows encoding issues and keep the docs corpus consistent.

This issue also appears in the following locations of the same file:

  • line 72
  • line 88
Suggested change
`apm-policy.yml` is a single YAML file that defines what AI agent dependencies, MCP servers, and compilation targets are allowed across an organization. It is the governance pillar of APM the file your security team owns and your repos inherit.
`apm-policy.yml` is a single YAML file that defines what AI agent dependencies, MCP servers, and compilation targets are allowed across an organization. It is the governance pillar of APM - the file your security team owns and your repos inherit.

Copilot uses AI. Check for mistakes.

For org-policy enforcement (apm-policy.yml, apm audit --ci, install gate), see the [Governance Guide](../governance-guide/). This page focuses on the lockfile audit trail and forensic recipes.

:::caution[Experimental — Policy Engine]
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This admonition title uses a Unicode em dash ("Experimental — Policy Engine"). The repo has explicit ASCII-safe conventions for output/docs (see src/apm_cli/utils/console.py:33-55); please replace with ASCII (e.g., "Experimental -- Policy Engine") to avoid encoding issues on Windows cp1252 terminals.

Suggested change
:::caution[Experimental Policy Engine]
:::caution[Experimental -- Policy Engine]

Copilot uses AI. Check for mistakes.

---

## 5a. What does NOT enforce policy
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section numbering is inconsistent: you define sub-sections "5a"-"5d" under "## 5", but then introduce a new H2 titled "## 5a. What does NOT enforce policy". This creates duplicate "5a" labels and will also confuse autogenerated TOCs/anchors. Please renumber this header (and downstream references) to a unique section number (e.g., 5e or 5.1).

This issue also appears on line 154 of the same file.

Suggested change
## 5a. What does NOT enforce policy
## 5e. What does NOT enforce policy

Copilot uses AI. Check for mistakes.
Five substantive corrections grounded in code:

README.md
  - apm.lock -> apm.lock.yaml (the actual lockfile name; lockfile.py:172)
  - Drop 'and prompt-injection patterns' from the Secure pillar paragraph;
    install scanners cover hidden Unicode, not prompt-injection (the
    Governance Guide already acknowledges PI detection is out of scope)

enterprise/apm-policy.md
  - 'Install time' section: clarify policy gate runs AFTER dependency
    resolution, not before (pipeline.py runs resolve at line 173 before
    policy_gate at line 185); add bypass-note callout pointing to the
    Governance Guide bypass contract
  - Minimal example: drop mcp.trust_transitive (parsed but not enforced;
    the actual gate is the --trust-transitive-mcp CLI flag)
  - Violation snippet: replace fictitious Policy:/Rule:/Action: lines
    with the actual single-line CLI format; remove misleading 'Override
    with --no-policy' phrase positioned after an 'apm audit --ci' command

enterprise/governance-guide.md (Section 5)
  - Warn-mode wording: violations are recorded as [!] warn diagnostics
    surfacing in the end-of-install summary, not inline [x] lines (those
    are block-mode only). Matches what Section 11 already says.

Em-dash flags from the reviewer rejected: em dashes are the established
convention across all 50+ docs files (15 in README, 29 in policy-reference,
20 in security). The repo encoding rule covers source code and CLI output
strings, not user-facing markdown prose.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel danielmeppiel merged commit 5088a07 into main Apr 22, 2026
11 checks passed
@danielmeppiel danielmeppiel deleted the docs/governance-spine-alignment branch April 22, 2026 22:51
danielmeppiel added a commit that referenced this pull request Apr 22, 2026
…erned) (#855)

The landing page was still describing APM purely as a portability story.
After PR #851 elevated governance and security to first-class pillars
in the README, the docs landing didn't match.

- Rewrite intro to the same Portable/Secure/Governed framing as README
- Replace 'Dependencies That Resolve' card with 'Governed by policy'
  (transitive resolution is now mentioned inside the portability card)
- Rename 'Supply Chain Security' -> 'Secure by default' and tighten copy
  to match what install scanners actually cover (hidden Unicode, not PI)
- Link governance card to the new flagship Governance Guide
- Mention apm.lock.yaml explicitly inside the portability card

No structural changes -- still 4 cards, same hero, same Quick Start,
same example block.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
danielmeppiel added a commit that referenced this pull request Apr 23, 2026
* chore: prepare v0.9.2 release

Bumps version to 0.9.2 and finalizes CHANGELOG with one-line summaries
for each PR merged since 0.9.1.

Highlights:
- ADO AAD bearer-token auth (#856)
- Governance Guide + enterprise docs IA refactor (#851, #858)
- Merge Gate orchestrator + single-authority aggregation (#865, #867)
- Landing + first-package docs rewrite (#855, #866)
- gh-aw imports migration (#864)
- Custom-port surfacing fix (#804)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: simplify merge-gate to single pull_request trigger

The dual-trigger pattern (pull_request + pull_request_target with
concurrency cancel-in-progress) shipped in #865 was over-engineered.
It produced TWO 'gate' check-runs per SHA -- one SUCCESS, one
CANCELLED -- and branch protection's status-check rollup treats
CANCELLED as failure, so PRs were silently BLOCKED unless an admin
overrode (which masked the bug on #867).

GitHub Actions has no primitive for 'either of these events
succeeded'. World-class OSS projects (kubernetes, rust, deno, next.js)
accept this and use a single trigger. The cost: a dropped 'pull_request'
webhook (rare; observed once on PR #856) requires manual recovery.

Recovery paths now documented at top of file:
  - push empty commit
  - gh workflow run merge-gate.yml -f pr_number=NNN
  - close + reopen PR

Replaces the dual-trigger + bootstrap-fetch dance with a clean
two-job flow: resolve-sha (handles workflow_dispatch input or PR head)
then gate (sparse checkout + run script). Same script, same exit
codes, same EXPECTED_CHECKS env.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ci: collapse merge-gate into a single job (one check-run in PR UI)

The two-job split (resolve-sha + gate) created two visible check-runs.
Inlining the SHA resolution as a step within the gate job leaves only
one check-run -- 'Merge Gate / gate' -- on the PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants