Skip to content

feat(scripts): Ship ALZ Corp default governance baseline - #762

Merged
jonathan-vella merged 4 commits into
test/azure-mcp-3-e2efrom
feat/alz-corp-governance-baseline
Oct 13, 2026
Merged

jonathan-vella merged 4 commits into
test/azure-mcp-3-e2efrom
feat/alz-corp-governance-baseline

Conversation

@jonathan-vella

@jonathan-vella jonathan-vella commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Description

Replaces the committed real-tenant governance baseline with an offline-generated ALZ Corp default: the
root, landing_zones and corp archetypes of ALZ library platform/alz/2026.10.0, with built-in definitions from
Azure/azure-policy at a pinned commit. The generator reuses discover.discover through an offline REST adapter,
so classification matches a live run. The tenant collector workflow is unchanged, so adopters can still overwrite
the file with their own baseline.

Phase 0.45 now offers "Run live discovery" or "Use ALZ Corp default as assumed governance" when the target
subscription is absent. The default is labelled assumed in the artifacts, and the Step 3.5 review stays mandatory.

Type of Change

  • 🤖 Agent definition update (.github/agents/)
  • ⚙️ Configuration/workflow change

Token / latency impact

  • YES: one extra sentence in 04g-governance.agent.md; the new procedure lives in the on-demand baseline-check.md

Changes Made

  • New: scripts/generate_alz_baseline.py and tests; npm run generate:governance-baseline-alz
  • discover.py: evaluates if(contains(list,'type'),effect,'Disabled') and treats enforceSetting like Append
    (otherwise the set stays PARTIAL). Note collect-governance-baseline.ps1 mirrors discover.py and does not have this yet.
  • render_governance.py, render_cached_governance.py, governance_baseline.py (--alz-default)
  • Schemas: baseline_kind, alz_library_ref, azure_policy_ref, generated_at; source alz-corp-default
  • .github/data/governance-policy-baseline.json.gz regenerated: 75 assignments, 506 findings (83 blockers,
    220 auto-remediate, 203 informational from DoNotEnforce assignments); regeneration is byte-identical
  • Docs: 04g-governance.agent.md, baseline-check.md, governance-discovery.instructions.md

Validation

  • validate:governance-baseline, test:governance-baseline-python, test:governance-discovery, test:governance-baseline-loader,
    lint:governance-refs, validate:agents, validate:skills, lint:md, lint:json pass (183 pytest tests)
  • Docs: apex-docs#35; old tenant IDs remain in git history by decision
  • Decision: not porting the conditional-effect handling to collect-governance-baseline.ps1. Despite the earlier
    note, it does not mirror discover.py closely: it never resolves initiative member parameters or assignment
    parameter overrides, silently skips unclassifiable effects, and so never reports PARTIAL. It already ignores
    enforceSetting. Aligning the two collectors is a separate piece of work.

Replace the committed real-tenant baseline with an offline-generated ALZ Corp
default: the root, landing_zones and corp archetypes of the pinned
platform/alz/2026.10.0 library, resolved with built-in definitions from a
pinned azure-policy commit. The generator reuses discover.discover through an
offline REST adapter so classification matches a live run.

discover.py now evaluates the initiative member pattern
if(contains(list, type), effect, 'Disabled') and treats enforceSetting like
Append, so these definitions no longer leave discovery PARTIAL. Assignments
shipped as DoNotEnforce are kept as informational. The renderer labels the
result as assumed governance and stamps the render time, and the loader gains
--alz-default.
Phase 0.45 offers the user a choice between live discovery and the shipped ALZ
Corp default when the target subscription is absent from the baseline. Choosing
the default is recorded as assumed, labelled in the artifacts, and keeps the
Step 3.5 review mandatory. The discovery instructions carry the single
exception to the no-assumptions rule.
Copilot AI balanced review requested due to automatic review settings October 13, 2026 10:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The review found unresolved scope, provenance-validation, and collector-parity defects.

4 open findings
What changed in this PR

Ships an offline ALZ Corp governance baseline for projects without tenant discovery access.

Changes:

  • Adds deterministic ALZ baseline generation and provenance.
  • Supports explicit assumed-governance rendering.
  • Extends policy-effect resolution, schemas, documentation, and tests.
File Description
.github/​data/​governance-policy-baseline.json.gz Stores the generated ALZ baseline.
tools/​scripts/​audit-retirement-candidates.mjs Registers baseline generation ownership.
tools/​schemas/​governance-constraints.schema.json Allows the ALZ source type.
tools/​schemas/​governance-baseline.schema.json Adds ALZ provenance fields.
package.json Adds generation and test commands.
test_generate_alz_baseline.py Tests generation and rendering.
render_governance.py Labels assumed governance in previews.
render_cached_governance.py Handles ALZ baseline rendering.
governance_baseline.py Extracts the synthetic default entry.
generate_alz_baseline.py Generates the pinned offline baseline.
discover.py Resolves conditional effects.
baseline-check.md Documents default-baseline selection.
governance-discovery.instructions.md Permits the explicit assumed-governance exception.
04g-governance.agent.md Routes ALZ baselines through Phase 0.45.

🧠 Review effort: Balanced


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +250 to +256
conditional = _CONDITIONAL_EFFECT.fullmatch(value.strip())
if conditional:
container = normalized.get(conditional.group(1).lower())
chosen = normalized.get(conditional.group(3).lower())
if isinstance(container, list) and chosen is not None:
listed = {str(item).lower() for item in container}
return chosen if conditional.group(2).lower() in listed else conditional.group(4)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Not porting this here; the PowerShell collector has wider gaps than the conditional expression (member parameters, assignment overrides, PARTIAL reporting) and the shipped baseline comes from the Python path. Tracked in #763 so the collectors can be aligned as one change with a shared fixture test.

Comment on lines +258 to +263
if args.library_dir:
library_root = args.library_dir
else:
library_root = _extract(LIBRARY_URL, tmp_path / "lib", ("/platform/alz/",))
if args.builtins_dir:
builtins_dir = args.builtins_dir

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in b4e0872 (the commit subject there is stale; the content is the change below). --library-dir now requires --library-ref and --builtins-dir requires --azure-policy-ref, and a ref without its directory is rejected. The supplied refs flow into build_baseline, the top-level fields and the provenance, so a local tree can no longer be stamped with the pinned release. Covered by test_local_source_trees_require_explicit_refs.

Comment on lines +110 to +115
if envelope.get("source") == "alz-corp-default":
# Static policy set, evaluated now; the generation date says nothing about tenant freshness.
rendered_at = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
envelope["discovered_at"] = rendered_at
if isinstance(envelope.get("discovery_metadata"), dict):
envelope["discovery_metadata"]["discovered_at"] = rendered_at

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in b4e0872. render_cached_governance.py now requires --subscription <guid> for the alz-corp-default source (exit 2 with subscription-required otherwise), rebinds subscription_id and discovery_metadata.scope.subscription_id to it, and keeps the synthetic ID only as provenance.baseline_subscription_id. baseline-check.md documents the argument; tests cover the rebinding and the rejection cases.

Comment on lines +24 to +27
"baseline_kind": {
"type": "string",
"description": "Absent for a tenant baseline collected by the workflow. alz-corp-default marks the shipped, offline-generated ALZ Corp policy set, which is assumed governance and not verified against any tenant.",
"enum": ["alz-corp-default"]

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in b4e0872: governance-baseline.schema.json now has an allOf / if / then requiring alz_library_ref, azure_policy_ref and generated_at whenever baseline_kind is present. validate:governance-baseline still passes on the committed baseline.

Phase 0.45 offers the user a choice between live discovery and the shipped ALZ
Corp default when the target subscription is absent from the baseline. Choosing
the default is recorded as assumed, labelled in the artifacts, and keeps the
Step 3.5 review mandatory. The discovery instructions carry the single
exception to the no-assumptions rule.
@jonathan-vella
jonathan-vella merged commit d5ce899 into test/azure-mcp-3-e2e Oct 13, 2026
2 checks passed
@jonathan-vella
jonathan-vella deleted the feat/alz-corp-governance-baseline branch October 13, 2026 17:57
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