**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.
71
86%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Replaces the legacy governance-discovery-subagent with a deterministic script.
The skill exposes scripts/discover.py — a single batched REST traversal that
emits the schema-compliant 04-governance-constraints.json envelope. The parent
agent (04g-Governance) invokes it via run_in_terminal, reads a compact
one-line JSON status from stdout, and proceeds to artifact writing without ever
pulling raw Azure REST responses into LLM context.
04-governance-constraints.md — that stays in the parent agenttools/schemas/governance-constraints.schema.json (schema_version: governance-constraints-v1)"" for unresolvable paths, never null--include-defender-auto0 = COMPLETE, 1 = PARTIAL, 2 = FAILED, 3 = invalid args; the parent agent routes solely on these codes.preview.md; the agent owns the final 04-governance-constraints.md content and traffic-light rendering--refresh when policy state has changed; otherwise honor the existing JSONpython .github/skills/azure-governance-discovery/scripts/discover.py \
--project my-project \
--out agent-output/my-project/04-governance-constraints.jsonFlags:
| Flag | Meaning |
|---|---|
--project <name> | Required. Used only for cache key and provenance. |
--out <path> | Required. Full envelope written here (overwrites). |
--subscription <id|default> | Optional. default uses az account show. |
--refresh | Force re-discovery even if <out> already exists. |
--include-defender-auto | Include Defender-for-Cloud auto-assignments (excluded by default). |
Exit codes:
| Code | Meaning |
|---|---|
0 | COMPLETE — discovery succeeded |
1 | PARTIAL — partial data written; parent should surface to user |
2 | FAILED — auth/network/permission error |
3 | Invalid arguments |
Stdout — always exactly one machine-readable JSON line first, optional human-readable preview after:
{
"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"
}The script writes a JSON envelope conforming to
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.
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.
For the effect classification table and Defender-filter rationale, read
references/effect-classification.md.
The script also writes a sibling .preview.md file (e.g.,
04-governance-constraints.preview.md) with the H2 structure matching the
azure-artifacts template. The agent copies this to
04-governance-constraints.md and annotates placeholder sections only.
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 rationalereferences/schema.md — output JSON envelope, findings[] structure, additive fieldsreferences/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-circuitreferences/baseline-check.md — Phase 0.45 cached-baseline procedurereferences/policy-override-pattern.md — structured override object shapereferences/reconciliation-disposition.md — Phase 2.5 disposition rulesreferences/resume-checks.md — Phase 0.4 short-circuit conditions (signature, TTL, confirmations)references/discover-output.md — discover.py stdout shape, exit codes, anti-patterns, discovery-signature persistencepolicyAssignments?$filter=atScope(),
policyDefinitions (subscription + tenant built-ins), policySetDefinitions.
One more list for policyExemptions?$filter=atScope().<out> unless --refresh passed.properties.metadata.assignedBy == "Security Center")
are filtered by default — matches EPAC's default and trims typical tenant row
counts by 30-60%. Every filtered assignment is logged to stderr.pytest .github/skills/azure-governance-discovery/scripts/test_discover.py
# or
npm run test:governance-discoveryFixtures live in scripts/fixtures/ and simulate az rest responses via
subprocess.check_output monkeypatching — no Azure account required for tests.
05d7617
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.