--- name: apex-azure-governance-discovery user-invocable: true disable-model-invocation: false argument-hint: "project, subscription scope and discovery or refresh" description: "**ANALYSIS SKILL** — Azure Policy discovery: effective assignments (incl. MG-inherited), definitions/exemptions, effect classification, emits governance-constraints JSON. WHEN: 'Azure policy discovery', 'effective policy assignments', 'governance constraints', '04g-Governance Phase 1', 'refresh governance JSON'. DO NOT USE FOR: artifact writing, architecture mapping." compatibility: Requires Node >=22, Azure CLI on PATH, read access to the target subscription. --- # Azure Governance Discovery Skill Replaces the legacy `governance-discovery-subagent` with deterministic scripts: live `scripts/discover.mjs` for Azure Policy REST discovery, and `scripts/import-reference-baseline.mjs` for no-subscription ALZ reference import. The parent agent invokes one script, reads one compact JSON status line, and avoids pulling raw Azure REST responses into LLM context. ## When to Use - Governance discovery for a project - Refreshing the governance snapshot after policy changes - Importing the reference baseline for greenfield projects without subscription access - Regenerating inputs for Step 4 (IaC Plan) and Step 5 (IaC Code) - Governance-first step 1.5 discovery before Architecture ## When NOT to Use - Writing `04-governance-constraints.md` — that stays in the parent agent - Cross-referencing architecture resources — parent-side LLM work - Challenger review orchestration — legacy parent-side work only - Any workflow that is not 04g-Governance ## Rules - **Stay deterministic** — the discovery script is a single batched REST traversal; no LLM calls, no retries that hide errors, no inferred policy effects - **Choose the baseline explicitly** — record `governance_baseline` as `live` after `discover.mjs`, or `reference` after `import-reference-baseline.mjs` - **Use compact status for routing**, then targeted envelope reads for decisions; recover all required evidence and diagnostics - **Schema compliance is mandatory** — envelope MUST conform to `tools/schemas/governance-constraints.schema.json` (`schema_version: governance-constraints-v1`) - **Reference is temporary** — the ALZ reference baseline can unblock Architecture, but live discovery MUST replace it before Step 4 / IaC Plan - **Governance-first has no Governance review** — Architecture owns the policy map and review coverage; legacy-order projects keep the old reconciliation path - **Property paths are always strings** — use `""` for unresolvable paths, never `null` - **Defender filtering is narrow** — the collector retains enforcement-bearing assignments; `--include-defender-auto` retains all - **Exit codes are contract** — `0` = COMPLETE, `1` = PARTIAL, `2` = FAILED; argparse errors also return nonzero. COMPLETE is collection status, not planning approval - **No artifact writing** — the script emits JSON + a `.preview.md`; the agent owns the final `04-governance-constraints.md` content and traffic-light rendering - **Reuse only current scoped evidence** — project, subscription, options, schema, COMPLETE status, valid TTL and exemptions must match - **Resolve confirmations before review** — all topics require current evidence-bound answers; unknowns block. See [inline resolution](references/inline-resolution-gate.md) ## Steps ### Live discovery ```bash node .github/skills/apex-azure-governance-discovery/scripts/discover.mjs \ --project my-project \ --out agent-output/my-project/04-governance-constraints.json ``` Flags: | Flag | Meaning | | ------------------------------ | ------------------------------------------------------------------ | | `--project ` | Required. Used only for cache key and provenance. | | `--out ` | Required. Full envelope written here (overwrites). | | `--subscription ` | Optional. `default` uses `az account show`. | | `--refresh` | Force re-discovery even if `` already exists. | | `--include-defender-auto` | Include Defender-for-Cloud auto-assignments (excluded by default). | ### Reference baseline import Use only when no subscription is available. The importer locates `references/alz-reference-baseline.json` relative to its own script; it does not depend on `PLUGIN_ROOT` or the caller's current working directory. ```bash node .github/skills/apex-azure-governance-discovery/scripts/import-reference-baseline.mjs \ --project my-project \ --out agent-output/my-project/04-governance-constraints.json ``` After import, record `governance_baseline = reference`. Before Step 4 / IaC Plan, replace it with live discovery and record `governance_baseline = live`. Exit codes: | Code | Meaning | | ---- | --------------------------------------------------------------- | | `0` | `COMPLETE` — discovery succeeded | | `1` | `PARTIAL` — partial data written; parent should surface to user | | `2` | `FAILED` — auth/network/permission error | | `2` | Invalid arguments (argparse), distinguished from failures by diagnostics | Stdout — always exactly one machine-readable JSON line first, optional human-readable preview after: ```json { "status": "COMPLETE", "cache_hit": false, "assignment_total": 247, "blockers": 18, "auto_remediate": 12, "exempted": 3, "out_path": "agent-output/my-project/04-governance-constraints.json" } ``` ## Output Contract The script writes a JSON envelope conforming to [`tools/schemas/governance-constraints.schema.json`](../../../tools/schemas/governance-constraints.schema.json) (`schema_version: governance-constraints-v1`). Each finding carries both `bicepPropertyPath` and `azurePropertyPath` (always strings — empty `""` when unresolvable, never `null`), plus `category`, `exemption`, and `classification` (`"blocker"` | `"auto-remediate"` | `"informational"`; exempted Deny/Modify blockers downgrade to `"informational"`). Top-level envelope also includes `policies` (alias of `findings`), `tags_required`, `allowed_locations`, and `discovery_metadata` (**L0 attestation envelope — MANDATORY**). For the full per-finding schema and additive fields, read [`references/schema.md`](references/schema.md). For the L0 envelope spec (shape, completeness-signature algorithm, end-of-discovery self-check, refresh handoff, consumer protocol, backward-compatibility rules), read [`references/l0-envelope.md`](references/l0-envelope.md). For the effect classification table and Defender-filter rationale, read [`references/effect-classification.md`](references/effect-classification.md). For the ALZ reference baseline generation/import contract, read [`references/reference-baseline.md`](references/reference-baseline.md). ### Preview Markdown The script also writes a sibling `.preview.md` file (e.g., `04-governance-constraints.preview.md`) with the H2 structure matching the apex-azure-artifacts template. The agent copies this to `04-governance-constraints.md` and annotates placeholder sections only. ## Reference Index References are split into two tiers so the agent loads only what it needs: **Load-always** (the minimum to drive the core workflow): - `references/terminal-commands.md` — pre-built batched commands (Cmd 1–8) for the entire phase. **Load-on-demand** (read only when the relevant decision point is reached): - `references/effect-classification.md` — effect-to-classification mapping, exemption downgrade, Defender filter rationale - `references/schema.md` — output JSON envelope, `findings[]` structure, additive fields - `references/l0-envelope.md` — canonical L0 envelope spec (shape, signature algorithm, self-check, refresh handoff, consumer protocol) - `references/inline-resolution-gate.md` — Phase 2.7 protocol + signature/TTL short-circuit - `references/baseline-check.md` — Phase 0.45 cached-baseline procedure - `references/policy-override-pattern.md` — structured `override` object shape - `references/resume-checks.md` — Phase 0.4 short-circuit conditions (signature, TTL, confirmations) - `references/discover-output.md` — `discover.mjs` stdout shape, exit codes, anti-patterns, discovery-signature persistence - `references/reference-baseline.md` — pinned ALZ reference baseline, Node generator/importer, and live replacement requirement ## Design Notes - The collector traverses paginated assignments, definitions, initiatives and exemptions, resolving referenced definitions as needed; do not assume a fixed call count. - Cache reuse checks project/subscription/options and COMPLETE envelope freshness, including positive TTL, nonfuture timestamp and still-valid scoped exemptions. `--arch` regenerates the preview from current architecture even on a cache hit. - Signature verification, confirmation bindings and current review inputs remain consumer gates; the collector's cache hit alone cannot attest them. - Filtering is based on assignment metadata and effective enforcement, not display-name claims. Review discovery_summary and diagnostics; do not claim an unmeasured reduction. ## Testing ```bash npm run test:governance-discovery-node # or npm run test:governance-discovery ``` Fixtures are built in the parity tests and simulate Azure REST responses through an injected runner — no Azure account required. The Python tests remain as contributor-only specification checks until the legacy implementation is retired.