diff --git a/.github/workflows/platform-ci.yml b/.github/workflows/platform-ci.yml
index b9d3acf..a2434db 100644
--- a/.github/workflows/platform-ci.yml
+++ b/.github/workflows/platform-ci.yml
@@ -24,6 +24,7 @@ jobs:
!site/**
!node_modules/**
!.venv/**
+ !CHANGELOG.md
yaml-lint:
name: YAML lint
diff --git a/decisions/0003-maproom-iic-canon.md b/decisions/0003-maproom-iic-canon.md
new file mode 100644
index 0000000..7f646b7
--- /dev/null
+++ b/decisions/0003-maproom-iic-canon.md
@@ -0,0 +1,65 @@
+# ADR 0003 — MAPROOM framework & IIC canon centralization
+
+- **Status**: Proposed
+- **Date**: 2026-04-12
+- **Deciders**: @kristopherjturner
+
+## Context
+
+MAPROOM — the contract-testing framework that asserts a live target (cluster, host pool, tenancy, fleet) matches an expected shape encoded as a JSON fixture — currently lives in [`azurelocal-S2DCartographer/tests/maproom/`](https://github.com/AzureLocal/azurelocal-S2DCartographer/tree/main/tests/maproom). The IIC canon (`iic-org.json`, `iic-cluster-01.json`, `iic-networks.json`) — the canonical test data representing the fictional Infinite Improbability Corp environment — lives alongside it.
+
+Three problems today:
+
+1. **Framework is repo-locked.** A second consumer (`azurelocal-ranger`) exists; a third (`azurelocal-avd`, `azurelocal-sofs-fslogix`, etc.) is blocked on "go copy the framework, maybe." Forking the framework into each repo recreates the drift problem [ADR-0002](./0002-standards-single-source.md) just solved for standards.
+2. **IIC canon is repo-locked.** Same problem. Every consumer wants to assert "my cluster matches the IIC canonical shape"; none can without vendoring the canon.
+3. **Framework is S2D-shaped.** MAPROOM's vocabulary (pools, tiers, volumes, witness, fault domains) encodes cluster-fabric assumptions that don't fit non-fabric consumers (AVD host pools, FSLogix profile fleets, VM-conversion inventories, Nutanix source manifests).
+
+TRAILHEAD (scenario runner for user journeys) has the same shape of problem but smaller surface — it's templated enough today that centralizing it is straightforward; the open questions are about MAPROOM.
+
+## Decision
+
+**Proposed** — not yet accepted. The shape of the decision:
+
+1. Move MAPROOM framework → [`platform/testing/maproom/framework/`](../testing/maproom/). Ship as PowerShell module `AzureLocal.Maproom` (manifest + `.psm1`). Consumers reference by module name.
+2. Move TRAILHEAD harness + templates → [`platform/testing/trailhead/`](../testing/trailhead/). Consumers reference by path or, if module-shaped content emerges, `AzureLocal.Trailhead` sibling module.
+3. Move IIC canon → [`platform/testing/iic-canon/`](../testing/iic-canon/). Consumers reference canonical fixtures by path; additional per-domain canons (AVD, FSLogix, Nutanix) land here as they're authored, not in consumer repos.
+4. Publish schemas under [`platform/testing/maproom/schema/`](../testing/maproom/): `fixture.schema.json`, `iic-canon.schema.json`. All consumer fixtures validate against these in CI.
+5. Framework surface (what primitives `AzureLocal.Maproom` exposes) is **under classification review** in platform issue [#3](https://github.com/AzureLocal/platform/issues/3). This ADR is blocked on that issue — Phase 2 implementation does not start until classification lands.
+
+## Consequences
+
+### Positive
+
+- One canonical MAPROOM implementation; no per-repo forks.
+- IIC canon is genuinely canonical — the same JSON powers every consumer's contract tests.
+- Schema-gated fixtures catch drift between consumers and framework at PR time.
+- Non-S2D consumers become plausible — the classification work (issue #3) ensures the framework surface actually fits their shapes.
+
+### Negative
+
+- Consumers pay a coupling cost — bumping `AzureLocal.Maproom` is a platform PR, and consumers see the new version on schedule, not on demand.
+- Module-based distribution means consumers need either a Git-referenced install or (eventually) PSGallery publication. Phase 2 uses Git reference; PSGallery is deferred until the public surface stabilizes.
+- Decoupling the framework from S2D-specific assumptions is non-trivial and is the actual design work — captured in issue [#3](https://github.com/AzureLocal/platform/issues/3).
+
+### Neutral
+
+- `azurelocal-S2DCartographer` becomes the first migration — its current `tests/maproom/` is the reference implementation being ported, and once ported it becomes the first consumer of the centralized framework.
+- `azurelocal-ranger` becomes the **second** consumer, deliberately chosen — two consumers is the minimum signal that the framework isn't secretly S2DCartographer-shaped.
+
+### Affected repos / owners
+
+- **`AzureLocal/platform`**: gains `testing/maproom/`, `testing/trailhead/`, `testing/iic-canon/`. Phase 2 work.
+- **`azurelocal-S2DCartographer`**: existing `tests/maproom/` is re-pointed at the platform module. Local copy of framework code is deleted; fixtures + tests remain.
+- **`azurelocal-ranger`**: switches to consuming platform MAPROOM. Second-consumer validation.
+- **All other product repos**: opt in as their use case matures; required testing surface is documented in [Testing Standards](../standards/testing.mdx).
+
+## Alternatives considered
+
+- **Keep MAPROOM in S2DCartographer, let consumers reference it directly.** Rejected — same drift pattern standards had; cross-repo references are fragile and discoverability is poor.
+- **Fork MAPROOM into each consuming repo.** Rejected — this is the current state and is exactly what's not working.
+- **Publish `AzureLocal.Maproom` to PSGallery in v1.** Rejected for now — surface will churn during Phase 2; PSGallery deferred until v0.3 at earliest, probably v1.0.
+- **Generalize the framework in-place (inside `azurelocal-S2DCartographer`).** Rejected — the repo's identity is S2D, not platform tooling; generalization would make the repo's purpose less clear.
+
+## Status
+
+Proposed 2026-04-12. Blocked on issue [#3](https://github.com/AzureLocal/platform/issues/3) — classification rubric for testing toolsets must land before this ADR can be accepted. Phase 2 implementation does not start until that resolves.
diff --git a/standards/automation.mdx b/standards/automation.mdx
new file mode 100644
index 0000000..713d6cd
--- /dev/null
+++ b/standards/automation.mdx
@@ -0,0 +1,70 @@
+# Automation Interoperability
+
+> **Canonical reference:** [Scripting Framework (full)](https://azurelocal.cloud/standards/scripting/scripting-framework)
+> **Applies to:** All AzureLocal repositories
+> **Last Updated:** 2026-03-17
+
+---
+
+## Overview
+
+This standard defines how multiple automation tools (Terraform, Bicep, ARM, PowerShell, Ansible) interoperate across AzureLocal solutions. All tools share a single configuration source and must produce identical infrastructure.
+
+---
+
+## Config Flow
+
+```mermaid
+flowchart TB
+ A["config/variables/variables.yml
(single source of truth)"] --> B[Terraform .tfvars]
+ A --> C[Bicep .bicepparam]
+ A --> D[ARM parameters.json]
+ A --> E[PowerShell ConvertFrom-Yaml]
+ A --> F[Ansible group_vars]
+ B --> G[Identical Infrastructure]
+ C --> G
+ D --> G
+ E --> G
+ F --> G
+```
+
+---
+
+## Deployment Path Matrix
+
+| Tool | Azure Resources | Configuration | Monitoring | Scaling |
+|------|:---:|:---:|:---:|:---:|
+| **Terraform** | ✅ | Delegates | ✅ | ✅ |
+| **Bicep** | ✅ | Delegates | ✅ | ✅ |
+| **ARM** | ✅ | Delegates | ✅ | — |
+| **PowerShell** | ✅ | ✅ | ✅ | ✅ |
+| **Ansible** | ✅ | ✅ | ✅ | ✅ |
+
+:::warning[Delegates]
+"Delegates" means the IaC tool provisions Azure resources but does not configure the guest OS or application layer. A separate tool (PowerShell or Ansible) handles guest configuration.
+:::
+
+---
+
+## Interoperability Rules
+
+1. **Single source of truth** — `config/variables/variables.yml` is the only config file. All tool-specific parameter files are derived.
+2. **Identical output** — Given the same config, every tool must produce the same infrastructure.
+3. **Idempotency** — All scripts and templates must be safe to re-run.
+4. **Error handling** — Every tool must validate config before executing changes.
+5. **Logging** — All operations logged to `./logs/` with consistent format.
+
+---
+
+## Variable Path Contract
+
+Scripts must use variable paths that exist in the schema. See the [Variable Standards](variables) for naming rules and the [Variable Reference](variables) for the complete catalog.
+
+---
+
+## Related Standards
+
+- [Scripting Standards](scripting)
+- [Infrastructure Standards](infrastructure)
+- [Solution Standards](solutions)
+- [Variable Standards](variables)
\ No newline at end of file
diff --git a/standards/documentation.mdx b/standards/documentation.mdx
new file mode 100644
index 0000000..ec2f6e0
--- /dev/null
+++ b/standards/documentation.mdx
@@ -0,0 +1,75 @@
+# Documentation Standards
+
+> **Canonical reference:** [Documentation Standards (full)](https://azurelocal.cloud/standards/documentation/documentation-standards)
+> **Applies to:** All AzureLocal repositories
+> **Last Updated:** 2026-03-17
+
+---
+
+## Principles
+
+| Principle | Rule |
+|-----------|------|
+| Documentation-First | Document **before** implementing. Keep docs current with code. |
+| Single Source of Truth | One authoritative document per topic. Cross-reference, don't duplicate. |
+| Audience-Aware | Write for operators, developers, or executives — with appropriate depth. |
+| Actionable | Step-by-step procedures, examples, prerequisites, and outcomes. |
+
+---
+
+## File Naming
+
+| Type | Convention | Pattern | Example |
+|------|-----------|---------|---------|
+| Directories | lowercase-with-hyphens | `^[a-z][a-z0-9-]*$` | `guides/`, `reference/` |
+| Markdown (docs/) | lowercase with hyphens | `*.md` | `deployment-guide.md` |
+| Root files | UPPERCASE | — | `README.md`, `CHANGELOG.md`, `CONTRIBUTING.md` |
+| PowerShell scripts | PascalCase | `Verb-Noun.ps1` | `Deploy-Solution.ps1` |
+| Config files | lowercase-with-hyphens | — | `variables.example.yml` |
+
+---
+
+## MkDocs Material Conventions
+
+This repo uses **MkDocs Material** with the following conventions:
+
+- **Admonitions**: Use `!!! note`, `!!! warning`, `!!! danger`, `!!! info`, `!!! tip`
+- **Code blocks**: Always include a language identifier (e.g., ` ```powershell `, ` ```yaml `)
+- **Code copy**: Enabled via `content.code.copy`
+- **Mermaid diagrams**: Supported via `pymdownx.superfences` custom fence
+- **Tables**: Use standard Markdown tables
+- **Tabs**: Use `=== "Tab Name"` via `pymdownx.tabbed`
+
+---
+
+## Frontmatter & Metadata
+
+Every documentation page should include:
+
+```markdown
+# Page Title
+
+> Brief one-line description of the page's purpose.
+
+---
+```
+
+---
+
+## Fictional Company — Infinite Improbability Corp (IIC)
+
+All examples must use IIC. See the [Examples & IIC Policy](examples) page for the full reference card.
+
+| Never Use | Use Instead |
+|-----------|-------------|
+| `contoso`, `fabrikam`, `northwind` | Infinite Improbability Corp |
+| `example.com`, `test.com` | `improbability.cloud` |
+| Real customer names | IIC naming patterns |
+
+---
+
+## Related Standards
+
+- [Naming Conventions (full reference)](https://azurelocal.cloud/standards/documentation/naming-conventions)
+- [Badge Library](https://azurelocal.cloud/standards/documentation/badge-library)
+- [Scripting Standards](scripting)
\ No newline at end of file
diff --git a/standards/examples.mdx b/standards/examples.mdx
new file mode 100644
index 0000000..bcf24de
--- /dev/null
+++ b/standards/examples.mdx
@@ -0,0 +1,104 @@
+# Examples & IIC Policy
+
+> **Canonical reference:** [Fictional Company Policy (full)](https://azurelocal.cloud/standards/fictional-company-policy)
+> **Applies to:** All AzureLocal repositories
+> **Last Updated:** 2026-03-17
+
+---
+
+## Policy
+
+All examples, sample configurations, and walkthroughs use **one** fictional company: **Infinite Improbability Corp (IIC)**.
+
+:::warning[Mandatory]
+Never use `contoso`, `fabrikam`, `adventure-works`, `woodgrove`, `example.com`, or any real customer name.
+ **IIC only** — in every repo, every example, every sample config.
+:::
+
+---
+
+## IIC Reference Card
+
+| Attribute | Value |
+|-----------|-------|
+| **Full Name** | Infinite Improbability Corp |
+| **Abbreviation** | IIC |
+| **Domain (public)** | `improbability.cloud` / `iic.cloud` |
+| **Domain (on-prem AD)** | `iic.local` |
+| **NetBIOS Name** | `IMPROBABLE` |
+| **Entra ID Tenant** | `improbability.onmicrosoft.com` |
+| **Email Pattern** | `user@improbability.cloud` |
+
+---
+
+## AzureLocal Naming Patterns
+
+### Azure Resources
+
+| Resource | Pattern | Example |
+|----------|---------|---------|
+| Resource Group | `rg-iic--<##>` | `rg-iic-platform-01` |
+| Virtual Network | `vnet-iic--<##>` | `vnet-iic-compute-01` |
+| Subnet | `snet-iic-` | `snet-iic-management` |
+| Network Security Group | `nsg-iic-` | `nsg-iic-compute` |
+| Key Vault | `kv-iic-` | `kv-iic-platform` |
+| Storage Account | `stiic<##>` | `stiicdata01` |
+| Log Analytics | `law-iic--<##>` | `law-iic-monitor-01` |
+| Managed Identity | `id-iic-` | `id-iic-deploy` |
+
+### Active Directory
+
+| Resource | Pattern | Example |
+|----------|---------|---------|
+| OU path | `OU=,OU=Servers,DC=iic,DC=local` | — |
+| Service account | `svc.iic.` | `svc.iic.deploy` |
+| Group | `grp-iic-` | `grp-iic-admins` |
+
+### IP Addresses
+
+| Network | Range | Usage |
+|---------|-------|-------|
+| Management | `10.0.0.0/24` | Node management |
+| Compute | `10.0.2.0/24` | Workload traffic |
+
+---
+
+## Real Identities
+
+| Name | Usage |
+|------|-------|
+| **Azure Local Cloud** | Community project, GitHub org, `azurelocal.cloud` |
+| **Hybrid Cloud Solutions** | Author/maintainer LLC, script headers, copyright |
+
+---
+
+## Usage Examples
+
+### In `config/variables/variables.example.yml`
+
+```yaml
+subscription:
+ subscription_id: "00000000-0000-0000-0000-000000000000"
+ tenant_id: "00000000-0000-0000-0000-000000000000"
+ location: "eastus"
+
+security:
+ keyvault_name: "kv-iic-platform"
+
+azure_local:
+ resource_group: "rg-iic-platform-01"
+ cluster_name: "azlocal-iic-01"
+```
+
+### In Documentation
+
+> Infinite Improbability Corp deploys Azure Local clusters using IIC naming patterns,
+> with all configuration driven from a single `config/variables/variables.yml` file.
+
+---
+
+## Enforcement
+
+- **PR review**: Reviewers flag any use of `contoso`, `fabrikam`, or other non-IIC names
+- **Config validation**: `variables.example.yml` uses IIC naming in all placeholders
+- **CI**: Vale linting rules flag non-IIC fictional company names (when configured)
\ No newline at end of file
diff --git a/standards/index.mdx b/standards/index.mdx
new file mode 100644
index 0000000..26073c1
--- /dev/null
+++ b/standards/index.mdx
@@ -0,0 +1,47 @@
+---
+title: "Standards"
+sidebar_label: "Standards"
+sidebar_position: 10
+description: "Standards and conventions"
+---
+
+# Standards
+
+This repository follows the **org-wide AzureLocal standards** maintained on the central documentation site.
+
+:::info[Central Standards]
+The full standards suite is at [azurelocal.cloud/standards](https://azurelocal.cloud/standards/).
+ This section provides the key rules adapted for this solution.
+:::
+
+---
+
+## Standards Pages
+
+| Standard | Local Page | Central Reference |
+|----------|-----------|------------------|
+| Documentation | [Documentation Standards](documentation) | [Full Reference](https://azurelocal.cloud/standards/documentation/documentation-standards) |
+| Repository Management | [Repository Management Standard](repository-management) | [Full Reference](https://azurelocal.cloud/standards/repository-management/) |
+| Scripting | [Scripting Standards](scripting) | [Full Reference](https://azurelocal.cloud/standards/scripting/scripting-standards) |
+| Variables | [Variable Standards](variables) | [Full Reference](https://azurelocal.cloud/standards/variable-management/) |
+| Naming Conventions | [Naming Conventions](naming) | [Full Reference](https://azurelocal.cloud/standards/documentation/naming-conventions) |
+| Solutions | [Solution Standards](solutions) | [Full Reference](https://azurelocal.cloud/standards/solutions/solution-development-standard) |
+| Infrastructure | [Infrastructure Standards](infrastructure) | [Full Reference](https://azurelocal.cloud/standards/infrastructure/) |
+| Automation | [Automation Interoperability](automation) | [Full Reference](https://azurelocal.cloud/standards/scripting/scripting-framework) |
+| Examples & IIC | [Examples & IIC](examples) | [Full Reference](https://azurelocal.cloud/standards/fictional-company-policy) |
+
+---
+
+## References
+
+- [Variable Reference](variables) — Per-variable catalog for this repo
+- [Repository Structure](https://azurelocal.cloud/standards/repo-structure) — Required file layout
+- [Repository Management Standard](repository-management) — Portfolio-level governance and repo-management contract
+
+---
+
+## Repo-Specific Conventions
+
+- **IaC tooling**: Terraform, Bicep, ARM, PowerShell, Ansible
+- **Config contract**: runtime `config/variables/variables.yml`, template `config/variables/variables.example.yml`, schema `config/variables/schema/variables.schema.json`, bootstrap policy defined in [Variable Standards](variables)
+- **Fictional company**: Infinite Improbability Corp (IIC) — see [IIC Policy](examples)
\ No newline at end of file
diff --git a/standards/infrastructure.mdx b/standards/infrastructure.mdx
new file mode 100644
index 0000000..9c54cfe
--- /dev/null
+++ b/standards/infrastructure.mdx
@@ -0,0 +1,151 @@
+# Infrastructure Standards
+
+> **Canonical reference:** [Infrastructure Standards (full)](https://azurelocal.cloud/standards/infrastructure/)
+> **Applies to:** All AzureLocal repositories
+> **Last Updated:** 2026-04-02
+
+---
+
+## Overview
+
+Standards for Infrastructure as Code (IaC), Terraform state management, and deployment processes for AzureLocal solutions.
+
+---
+
+## Infrastructure Types
+
+All infrastructure is classified by type. These are the **only** valid infrastructure types, defined in the [master registry](https://github.com/AzureLocal/azurelocal-toolkit/blob/main/config/variables/schema/master-registry.yaml):
+
+| Type | Description | Repository |
+|------|-------------|------------|
+| `azure_local` | Azure Local hyper-converged clusters | `azurelocal-toolkit` |
+| `avd_azure` | Azure Virtual Desktop in Azure cloud | `azurelocal-avd` |
+| `avd_azure_local` | Azure Virtual Desktop on Azure Local | `azurelocal-avd` |
+| `sofs_azure_local` | Scale-Out File Server on Azure Local | `azurelocal-sofs-fslogix` |
+| `aks_azure_local` | Azure Kubernetes Service on Azure Local | `azurelocal-toolkit` |
+| `loadtools` | Performance and load testing tools | `azurelocal-loadtools` |
+| `vm_conversion` | VM generation conversion toolkit | `azurelocal-vm-conversion-toolkit` |
+| `copilot` | AI-assisted operations | `azurelocal-copilot` |
+
+---
+
+## Infrastructure Pipeline
+
+```mermaid
+flowchart LR
+ A[Generate Variables] --> B[Validate Config]
+ B --> C[Plan Infrastructure]
+ C --> D[Review Changes]
+ D --> E[Apply Changes]
+ E --> F[Update State]
+```
+
+---
+
+## State Management
+
+| Principle | Rule |
+|-----------|------|
+| Remote state | Store Terraform state in Azure Storage Account |
+| State locking | Enable locking during all operations |
+| Backup | Regular state file backups before destructive operations |
+| Naming | `-.tfstate` (e.g., `platform-prod.tfstate`) |
+
+---
+
+## IaC Tool Parity
+
+All tools must produce **identical infrastructure** when given the same configuration values:
+
+| Tool | Primary Format | State Management |
+|------|---------------|-----------------|
+| Terraform | `.tf` / `.tfvars` | Remote state in Azure Storage |
+| Bicep | `.bicep` / `.bicepparam` | ARM deployment history |
+| ARM | `.json` | ARM deployment history |
+| PowerShell | `.ps1` | Config-driven, logged |
+| Ansible | `.yml` | Inventory-based |
+
+---
+
+## Deployment Phases
+
+| Phase | Scope | Tools |
+|-------|-------|-------|
+| Phase 1: Azure Foundation | Resource groups, networking, Key Vault, storage | Terraform, Bicep, ARM |
+| Phase 2: Compute & Workload | VMs, clusters, workload deployment | Terraform, PowerShell |
+| Phase 3: Configuration | Guest config, monitoring, policies | PowerShell, Ansible |
+
+---
+
+## Toolkit Repository Structure
+
+The `azurelocal-toolkit` repository is the reference implementation. All other repos follow the same top-level layout where applicable.
+
+```
+azurelocal-toolkit/
+├── config/
+│ ├── azure/ # ARM templates, discovery, iDRAC, service principals, utilities
+│ └── variables/ # Variable system (see Variable Standards)
+│ ├── variables.example.yml # Template (committed)
+│ ├── variables.yml # Your config (gitignored)
+│ ├── reports/ # Generated validation reports
+│ ├── schema/ # JSON Schema, master registry, alias/drift policy files
+│ └── scripts/ # Validation and generation scripts
+├── docs/ # Repo-local documentation
+├── logs/ # Runtime logs (gitignored)
+├── pipelines/ # CI/CD pipeline definitions
+├── repo-management/ # Planning docs, ADRs, decision logs
+├── scripts/
+│ ├── common/ # Shared modules: ansible, arm-templates, bicep, terraform
+│ ├── deploy/ # Task scripts — mirrors docs/implementation structure (see below)
+│ ├── handover/
+│ │ ├── customer-transfer/ # Handover checklists and artifacts
+│ │ └── documentation/ # Generated customer-facing docs
+│ ├── lifecycle/
+│ │ ├── operations/ # Day-2 operational scripts
+│ │ └── updates/ # Patch and update automation
+│ ├── tools/ # Contributor tooling (script templates, install helpers)
+│ └── validation/ # Health checks and test suites
+│ ├── arc-tests/
+│ ├── cluster-health/
+│ ├── network-tests/
+│ ├── storage-tests/
+│ └── workload-tests/
+├── src/ # IaC source: ansible, arm-templates, bicep, terraform
+├── styles/ # Shared style/lint config
+├── tests/ # Automated test harness
+└── tools/ # Repo-level tools (Generate-SolutionConfig.ps1, planning/)
+```
+
+### `scripts/deploy/` Task Contract
+
+Every task folder under `scripts/deploy/` mirrors the path of its corresponding doc in `docs/implementation/` and contains exactly three subdirectories:
+
+```
+scripts/deploy////
+├── azurecli/ # Azure CLI scripts (.ps1 using az commands, or .sh)
+├── bash/ # Pure Bash scripts (.sh)
+└── powershell/ # PowerShell scripts (.ps1)
+```
+
+Top-level parts and their phases:
+
+| Part | Phases |
+|------|--------|
+| `01-cicd-infra` | `phase-01-cicd-setup` |
+| `02-azure-foundation` | `phase-01-landing-zones`, `phase-02-resource-providers`, `phase-03-rbac-permissions`, `phase-04-azure-management-infrastructure`, `phase-05-identity-security` |
+| `03-onprem-readiness` | `phase-01-active-directory`, `phase-02-enterprise-readiness`, `phase-03-network-infrastructure` |
+| `04-cluster-deployment` | `phase-01-hardware-provisioning`, `phase-02-os-installation`, `phase-03-os-configuration`, `phase-04-arc-registration`, `phase-05-cluster-deployment`, `phase-06-post-deployment` |
+| `05-operational-foundations` | `phase-01-sdn-deployment`, `phase-02-monitoring-observability`, `phase-03-backup-dr`, `phase-04-security-governance`, `phase-05-licensing-telemetry` |
+| `06-testing-validation` | *(tasks directly under part)* |
+| `07-validation-handover` | *(tasks directly under part)* |
+
+---
+
+## Related Standards
+
+- [Infrastructure Generation & Deployment Process](https://azurelocal.cloud/standards/infrastructure/infrastructure-generation-deployment-process)
+- [State Management](https://azurelocal.cloud/standards/infrastructure/state-management)
+- [Solution Development Standard](solutions)
+- [Variable Standards](variables) — includes master registry and infrastructure type definitions
+- [Automation Interoperability](automation)
\ No newline at end of file
diff --git a/standards/naming.mdx b/standards/naming.mdx
new file mode 100644
index 0000000..417ed4b
--- /dev/null
+++ b/standards/naming.mdx
@@ -0,0 +1,65 @@
+# Naming Conventions
+
+> **Canonical reference:** [Naming Conventions (full)](https://azurelocal.cloud/standards/documentation/naming-conventions)
+> **Applies to:** All AzureLocal repositories
+> **Last Updated:** 2026-03-17
+
+---
+
+## File & Directory Naming
+
+| Type | Convention | Pattern | Example |
+|------|-----------|---------|---------|
+| Directories | lowercase-with-hyphens | `^[a-z][a-z0-9-]*$` | `getting-started/` |
+| Markdown (docs/) | lowercase with hyphens | `*.md` | `deployment-guide.md` |
+| Root files | UPPERCASE | — | `README.md`, `CHANGELOG.md` |
+| PowerShell scripts | PascalCase | `Verb-Noun.ps1` | `Deploy-Solution.ps1` |
+| Config files | lowercase-with-hyphens | — | `variables.example.yml` |
+
+---
+
+## Azure Resource Naming
+
+All resources follow the [IIC naming patterns](examples). For comprehensive CAF-aligned naming patterns used in Azure Local deployments, see [Planning: Naming Standards](../planning/01-naming-standards.mdx):
+
+| Resource Type | Pattern | Example |
+|--------------|---------|---------|
+| Resource Group | `rg-iic--<##>` | `rg-iic-platform-01` |
+| Virtual Network | `vnet-iic--<##>` | `vnet-iic-compute-01` |
+| Network Security Group | `nsg-iic-` | `nsg-iic-management` |
+| Key Vault | `kv-iic-` | `kv-iic-platform` |
+| Storage Account | `stiic<##>` | `stiicdata01` |
+| Log Analytics | `law-iic--<##>` | `law-iic-monitor-01` |
+
+---
+
+## Variable Naming
+
+| Rule | Standard | Example |
+|------|----------|---------|
+| YAML sections | `snake_case` | `azure_local`, `networking` |
+| YAML keys | `snake_case` | `subscription_id`, `resource_name` |
+| Pattern | `^[a-z][a-z0-9_]*$` | — |
+| Max length | 50 characters | — |
+
+---
+
+## Git Branch Naming
+
+| Pattern | Usage | Example |
+|---------|-------|---------|
+| `main` | Default branch | — |
+| `feature/` | New features | `feature/add-validation` |
+| `fix/` | Bug fixes | `fix/config-parsing` |
+| `docs/` | Documentation | `docs/deployment-guide` |
+| `infra/` | CI/CD | `infra/add-pester-tests` |
+
+---
+
+## Related Standards
+
+- [Planning: Naming Standards](../planning/01-naming-standards.mdx) — Full CAF-aligned naming conventions for Azure Local deployments
+- [Full Naming Conventions](https://azurelocal.cloud/standards/documentation/naming-conventions)
+- [Repository Structure](https://azurelocal.cloud/standards/repo-structure)
+- [Documentation Standards](documentation)
+- [Examples & IIC](examples)
\ No newline at end of file
diff --git a/standards/new-repo-setup.mdx b/standards/new-repo-setup.mdx
new file mode 100644
index 0000000..90f4c72
--- /dev/null
+++ b/standards/new-repo-setup.mdx
@@ -0,0 +1,261 @@
+# New Repository Setup Runbook
+
+> **Applies to:** All AzureLocal repositories
+> **Companion reading:** [Repository Management Standard](./repository-management.mdx)
+
+This runbook walks through every step required to set up a new AzureLocal repository from scratch, in order. Complete each step before proceeding to the next.
+
+---
+
+## Prerequisites
+
+- GitHub organisation admin or write access to the `AzureLocal` organisation
+- `gh` CLI installed and authenticated (`gh auth status`)
+- Maintainer access to the [Azure Local Solutions project board](https://github.com/orgs/AzureLocal/projects/3)
+
+---
+
+## Step 1 — Create the Repository
+
+1. Go to [github.com/organizations/AzureLocal/repositories/new](https://github.com/organizations/AzureLocal/repositories/new).
+2. Set **Repository name** using the `azurelocal-` convention (e.g. `azurelocal-monitoring`).
+3. Set **Visibility** to **Public**.
+4. **Do not** initialise with a README, .gitignore, or licence — you will add these in Step 3.
+5. Click **Create repository**.
+
+---
+
+## Step 2 — Clone and Initialise Locally
+
+```bash
+git clone https://github.com/AzureLocal/.git
+cd
+```
+
+---
+
+## Step 3 — Add Required Root Files
+
+All AzureLocal repositories must contain the following files in the root:
+
+| File | Purpose |
+|------|---------|
+| `README.md` | Project overview, prerequisites, and quickstart |
+| `CONTRIBUTING.md` | Local contribution guidelines (can reference org defaults) |
+| `LICENSE` | MIT licence |
+| `CHANGELOG.md` | Release history, starting with `## [Unreleased]` heading |
+| `.gitignore` | Language/tool-appropriate ignore rules |
+
+Copy `CONTRIBUTING.md` and `LICENSE` from any existing AzureLocal repo, or use the [org-level templates](https://github.com/AzureLocal/.github).
+
+---
+
+## Step 4 — Create the Directory Structure
+
+Minimum required directories:
+
+```
+/
+├── docs/ # Documentation source
+├── .github/
+│ └── workflows/ # GitHub Actions workflows (see Step 6)
+└── repo-management/
+ ├── setup.md # Repo-specific setup notes
+ └── automation.md # CI/CD and workflow documentation
+```
+
+If the solution uses infrastructure configuration, also add:
+
+```
+├── config/
+│ ├── variables.example.yml
+│ └── schema/
+│ └── variables.schema.json
+```
+
+---
+
+## Step 5 — Add the Solution Label to the Project Board
+
+Each repo's issues are tagged with a solution label so the shared project board can route them. Check whether a label for this solution already exists:
+
+```bash
+gh label list --repo AzureLocal/.github
+```
+
+If a `solution/` label does not already exist, create it across all repos where needed using the org label sync workflow, or add it manually:
+
+```bash
+gh label create "solution/" --color "#0075ca" --repo AzureLocal/
+```
+
+---
+
+## Step 6 — Add the Three Shared Workflows
+
+Create `.github/workflows/` and add slim callers for the three reusable org workflows.
+
+### `add-to-project.yml`
+
+Replace `` with the repo's issue prefix (e.g. `MON`, `BCDR`) and `` with the project board option ID for this solution (look these up in `AzureLocal/.github/.github/workflows/reusable-add-to-project.yml`).
+
+```yaml
+name: Add to Project
+
+on:
+ issues:
+ types: [opened, labeled]
+ pull_request:
+ types: [opened, labeled]
+
+jobs:
+ call-shared:
+ uses: AzureLocal/.github/.github/workflows/reusable-add-to-project.yml@main
+ with:
+ id-prefix:
+ solution-option-id: ''
+ secrets: inherit
+```
+
+### `release-please.yml`
+
+```yaml
+name: Release Please
+
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ call-shared:
+ uses: AzureLocal/.github/.github/workflows/reusable-release-please.yml@main
+ secrets: inherit
+```
+
+### `validate-repo-structure.yml`
+
+```yaml
+name: Validate Repo Structure
+
+on:
+ pull_request:
+ branches: [main]
+
+jobs:
+ call-shared:
+ uses: AzureLocal/.github/.github/workflows/reusable-validate-structure.yml@main
+```
+
+---
+
+## Step 7 — Add `release-please-config.json`
+
+```json
+{
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
+ "release-type": "simple",
+ "bump-minor-pre-major": true,
+ "changelog-sections": [
+ { "type": "feat", "section": "Features" },
+ { "type": "fix", "section": "Bug Fixes" },
+ { "type": "docs", "section": "Documentation" },
+ { "type": "chore", "section": "Chores", "hidden": false }
+ ]
+}
+```
+
+---
+
+## Step 8 — Add Repository Topics
+
+Topics make the repository discoverable on GitHub and signal at a glance what the solution covers. Set them in **Settings → General → Topics**, or via the `gh` CLI:
+
+```bash
+gh api --method PUT repos/AzureLocal//topics \
+ --input - <<'EOF'
+{"names":["azure-local","azure-stack-hci","azurelocal","azure-arc","powershell","infrastructure-as-code",""]}
+EOF
+```
+
+**Required topics for every AzureLocal repo:**
+
+| Topic | Purpose |
+|-------|---------|
+| `azure-local` | Primary product name |
+| `azure-stack-hci` | Legacy/alias for discoverability |
+| `azurelocal` | Org tag |
+| `azure-arc` | Platform dependency |
+| `powershell` | Primary scripting language |
+| `infrastructure-as-code` | Deployment model |
+
+**Add solution-specific topics** on top of the required set. Examples:
+
+| Repo | Additional topics |
+|------|-------------------|
+| azurelocal-avd | `avd`, `azure-virtual-desktop`, `virtual-desktop`, `fslogix` |
+| azurelocal-sofs-fslogix | `sofs`, `scale-out-file-server`, `fslogix`, `storage` |
+| azurelocal-ranger | `discovery`, `assessment`, `readiness` |
+| azurelocal-nutanix-migration | `nutanix`, `migration`, `hyper-v` |
+| azurelocal-training | `training`, `lab`, `learning` |
+| azurelocal-loadtools | `load-testing`, `performance-testing`, `benchmarking` |
+| azurelocal-vm-conversion-toolkit | `vm-migration`, `gen1`, `gen2`, `hyper-v` |
+| azurelocal-copilot | `github-copilot`, `ai`, `copilot-instructions`, `developer-tools` |
+
+---
+
+## Step 9 — Configure Branch Protection
+
+In **Settings → Branches**, add a protection rule for `main`:
+
+| Setting | Value |
+|---------|-------|
+| Require a pull request before merging | ✅ (1 approval) |
+| Require CODEOWNERS review | ✅ |
+| Dismiss stale reviews on push | ✅ |
+| Require status checks to pass | ✅ — add repo-specific check |
+| Require branches to be up to date | ✅ |
+| Do not allow bypassing the above settings | ❌ (admins can bypass) |
+| Allow force pushes | ❌ |
+| Allow deletions | ❌ |
+
+---
+
+## Step 10 — Add the `ADD_TO_PROJECT_PAT` Secret
+
+The add-to-project workflow requires a PAT with `project` scope.
+
+```bash
+gh secret set ADD_TO_PROJECT_PAT --repo AzureLocal/
+```
+
+Paste the shared org PAT when prompted. This token is managed by org admins — contact them if you do not have it.
+
+---
+
+## Step 11 — Add the Repository to This Standards Page
+
+Open a PR on `azurelocal.github.io` to:
+
+1. Add a row for the new repository in the [Repository Management Standard](./repository-management.mdx) portfolio table.
+2. If the solution has a dedicated page on the docs site, add a navigation entry in `docusaurus.config.js`.
+
+---
+
+## Checklist
+
+```
+[ ] Repository created under AzureLocal org
+[ ] Required root files present (README, CONTRIBUTING, LICENSE, CHANGELOG, .gitignore)
+[ ] docs/ and .github/workflows/ directories created
+[ ] repo-management/setup.md and automation.md created
+[ ] solution/ label created
+[ ] add-to-project.yml slim caller added (correct prefix and solution-option-id)
+[ ] release-please.yml slim caller added
+[ ] validate-repo-structure.yml slim caller added
+[ ] release-please-config.json added
+[ ] Repository topics set (required + solution-specific)
+[ ] Branch protection configured for main
+[ ] ADD_TO_PROJECT_PAT secret set
+[ ] Repository listed in repository-management.mdx
+```
diff --git a/standards/repository-management.mdx b/standards/repository-management.mdx
new file mode 100644
index 0000000..8e28f47
--- /dev/null
+++ b/standards/repository-management.mdx
@@ -0,0 +1,510 @@
+# Repository Management Standard
+
+> **Canonical reference:** [Repository Management Standard (full)](https://azurelocal.cloud/standards/repository-management/)
+> **Applies to:** All AzureLocal repositories
+> **Last Updated:** 2026-04-03
+
+---
+
+## Overview
+
+This standard defines how the AzureLocal repositories are managed as a coordinated portfolio.
+
+Each repository is a **standalone deliverable** with its own README, issues, releases, workflows, and branch protections. At the same time, each repository participates in a shared governance model where `azurelocal.github.io` acts as the central source for standards, portfolio-level guidance, and shared repository management practices.
+
+The intent is to avoid two failure modes:
+
+1. treating every repo as completely independent and allowing standards drift
+2. treating every repo as if it were just a subfolder of the docs repo
+
+The correct model is: **independent repositories, centrally governed standards**.
+
+---
+
+## Portfolio Model
+
+### Repository Roles
+
+| Repository Type | Role | Notes |
+|-----------------|------|-------|
+| `azurelocal.github.io` | Central standards, documentation portal, and governance source | Holds canonical standards and shared repo governance references |
+| `azurelocal-toolkit` | Reference implementation and shared automation toolkit | Primary implementation repo for deployment, validation, and automation assets |
+| Solution repositories | Standalone solution delivery repos | Must be independently usable while following org-wide standards |
+| Supporting repositories | Utilities, training, migration, demos, or experiments | May have lighter content, but still follow the governance baseline |
+
+### Governance Principle
+
+All repositories must be understandable and usable on their own, but they must not invent their own governance model.
+
+The central repository governance source is:
+
+- standards and governance guidance in `azurelocal.github.io`
+- shared labels and repo rules in `.github/`
+- portfolio-level planning and cross-repo coordination in `repo-management/`
+
+---
+
+## Repo Management Contract
+
+Every repository must have a root-level `repo-management/` folder.
+
+This folder is for **repository operations and planning**, not published product documentation.
+
+### Standard Layout
+
+| Path | Purpose |
+|------|---------|
+| `repo-management/README.md` | Overview of the folder and links to key docs |
+| `repo-management/setup.md` | How this repo is configured: branch protection, labels, secrets, CODEOWNERS, and how to replicate it |
+| `repo-management/automation.md` | Every GitHub Actions workflow documented: what it does, why it exists, triggers, secrets required |
+| `repo-management/scripts/` | Helper scripts used for repo-management or governance tasks |
+
+### Allowed Content
+
+The `repo-management/` folder documents **how the repo works** — its configuration, automation, and operational setup. It is the reference a maintainer needs to understand, operate, or replicate this repository.
+
+The `repo-management/` folder must not become a replacement for:
+
+- `README.md` at the repo root
+- canonical standards under `standards/`
+- published user-facing documentation in repos that use GitHub Pages
+- work-item tracking (use GitHub Projects for that)
+
+---
+
+## Standards vs Repo Management
+
+Use the following split consistently:
+
+| Location | Purpose |
+|----------|---------|
+| `standards/` | Canonical rules and standards that multiple repos are expected to follow |
+| `repo-management/` | Planning, governance operations, scripts, roadmaps, checklists, and repo-local execution artifacts |
+| `README.md` | Primary entry point for humans using the repo |
+| `docs/` | Published documentation only, when the repo actually uses a docs site |
+
+If a document describes rules that all repos should follow, it belongs in `standards/`.
+
+If a document describes how a specific repo is being organized, tracked, migrated, or improved, it belongs in `repo-management/`.
+
+---
+
+## Baseline Requirements For All Repositories
+
+Unless explicitly exempted, every repository should follow the baseline below.
+
+### Core Repo Files
+
+- `README.md`
+- `CONTRIBUTING.md`
+- `CHANGELOG.md`
+- `LICENSE`
+- `.github/CODEOWNERS`
+- `.github/pull_request_template.md` or equivalent PR template
+- `.github/ISSUE_TEMPLATE/` set
+- `release-please-config.json`
+- `.release-please-manifest.json`
+- `repo-management/README.md`
+
+### GitHub Governance
+
+- `main` branch protected
+- admins allowed to bypass when needed for urgent maintenance or portfolio management
+- required review and status checks configured where appropriate
+- CODEOWNERS aligned to the shared ownership model
+- labels synchronized to the central label set
+
+### Release Automation
+
+- release-please configured
+- changelog generated from conventional commits
+- tags and releases consistent with org conventions
+
+### Pages / Documentation Expectations
+
+| Repo Type | Expectation |
+|-----------|-------------|
+| `azurelocal.github.io` | Docusaurus-based central portal |
+| `azurelocal-toolkit` | No repo-local docs site; root README is primary documentation |
+| Most solution repos | MkDocs + GitHub Pages enabled |
+| Minimal/supporting repos | May omit docs site if a docs site adds no value, but must still have a complete README |
+
+### Workflow Expectations
+
+Most repositories should include automation for:
+
+- release-please
+- docs deployment when the repo has a docs site
+- linting or validation workflows appropriate to the repo type
+- repo structure validation where useful
+
+---
+
+## Exceptions And Special Cases
+
+### `azurelocal.github.io`
+
+This repo is not just another solution repo. It is the central docs and standards authority.
+
+Special responsibilities:
+
+- maintain canonical standards
+- maintain shared label and repo governance references
+- host central docs and portfolio guidance
+- drive cross-repo governance changes
+
+### `azurelocal-toolkit`
+
+This repo is the implementation and automation reference repo.
+
+Special responsibilities:
+
+- hold shared automation assets
+- act as the primary implementation reference
+- keep the root README as the primary user-facing entry point
+- avoid carrying a repo-local docs site just for symmetry
+
+---
+
+## Documentation Responsibilities
+
+The following rules apply to repo documentation:
+
+1. The root `README.md` must explain the repo clearly on its own.
+2. User-facing published docs belong in `docs/` only if that repo actually operates a docs site.
+3. Governance and planning artifacts belong in `repo-management/`.
+4. Cross-repo rules belong in `standards/`.
+5. A repo must not depend on hidden tribal knowledge from another repo to be understandable.
+
+---
+
+## Branch Protection Model
+
+The standard default for AzureLocal repositories is:
+
+- protect `main`
+- require reviews where appropriate
+- require status checks where appropriate
+- prevent casual direct pushes
+- allow administrator bypass for controlled maintenance and portfolio management work
+
+This balances governance with operational reality for a small centrally managed portfolio.
+
+---
+
+## CODEOWNERS Model
+
+All repositories should use a substantially similar CODEOWNERS structure unless there is a real reason to diverge.
+
+The objective is consistency of ownership, not needless uniqueness.
+
+At minimum:
+
+- every repo must have a `.github/CODEOWNERS`
+- ownership should reflect the actual maintainers
+- shared governance repos should not use a radically different ownership pattern without justification
+
+---
+
+## Repo Management Scripts
+
+`repo-management/scripts/` is the approved place for scripts that support repository governance and maintenance, for example:
+
+- repo audit scripts
+- branch protection validation helpers
+- label sync helpers
+- documentation sync helpers
+- migration scripts for folder structure or standards adoption
+
+These scripts should not be mixed into product/runtime automation folders unless they are actually part of the solution runtime.
+
+---
+
+## Issue Management Model
+
+Issues are the primary unit of planned work across the AzureLocal portfolio. Labels alone are not the planning model. Labels, project board fields, milestones, tracker issues, and dependencies each serve a distinct purpose.
+
+### Labels
+
+Labels classify **what kind of work** an issue represents. They are defined centrally in `.github/labels.yml` and synced to all repos.
+
+Every issue should have:
+
+- exactly one `type/*` label (mutually exclusive — what kind of work)
+- exactly one `priority/*` label
+- one `solution/*` label where applicable (which repo or solution area)
+
+Labels do not replace project board fields, milestones, or relationship tracking. They exist for filtering, automation, and consistent classification.
+
+The `type/*` labels are the canonical work categories:
+
+| Label | Meaning |
+|-------|---------|
+| `type/feature` | New feature or capability |
+| `type/bug` | Something isn't working |
+| `type/docs` | Documentation only |
+| `type/infra` | CI/CD, workflows, repo config |
+| `type/refactor` | Code improvement, no behavior change |
+| `type/security` | Security fix or hardening |
+| `type/question` | Question or discussion |
+
+The `priority/*` labels are the canonical priority levels:
+
+| Label | Meaning |
+|-------|---------|
+| `priority/critical` | Must fix immediately |
+| `priority/high` | Next sprint |
+| `priority/medium` | Planned |
+| `priority/low` | Nice to have |
+
+The `status/*` labels are supplementary. The project board is the primary status tracker:
+
+| Label | Meaning |
+|-------|---------|
+| `status/blocked` | Blocked by dependency |
+| `status/needs-info` | Waiting for more information |
+| `status/wontfix` | Declined |
+
+GitHub's default labels (`bug`, `enhancement`, `documentation`, etc.) are tolerated but not used as the primary classification. Use `type/*` labels instead.
+
+### GitHub Project Board
+
+All AzureLocal repos participate in the shared org-level project board: [AzureLocal Projects #3](https://github.com/orgs/AzureLocal/projects/3).
+
+The project board tracks portfolio-wide status and provides custom fields:
+
+| Field | Populated From | Purpose |
+|-------|---------------|---------|
+| **ID** | Auto-set by workflow | Repo-prefixed issue number (e.g. `DOCS-14`, `RANGER-5`) |
+| **Solution** | `solution/*` label | Which solution area the issue belongs to |
+| **Priority** | `priority/*` label | Priority level |
+| **Category** | `type/*` label | Work category |
+
+The `add-to-project.yml` workflow automatically adds issues and PRs to the project board and maps labels to project fields. Every repo that participates in the shared board must have this workflow and the `ADD_TO_PROJECT_PAT` secret.
+
+### Milestones
+
+Milestones group issues by **delivery phase** within a single repo. They answer "when does this land?" rather than "what kind of work is this?"
+
+Milestones are per-repo. They are not shared across repos.
+
+Each repo should define milestones that match its delivery phases. Examples:
+
+- `Planning` — planning, architecture, and design work
+- `Documentation Foundation` — core docs and public story
+- `V1` — first release
+- `Post-V1` — extensions, future scope, and backlog
+
+Rules for milestones:
+
+- every issue that represents planned delivery work should have a milestone
+- governance and housekeeping issues may omit milestones if they are not tied to a release phase
+- do not create milestones for abstract categories — milestones represent delivery phases, not work types
+
+### Tracker Issues
+
+Tracker issues are umbrella issues that group related child issues for rollup and visibility. They answer "what is the overall status of this workstream?"
+
+Rules for tracker issues:
+
+- a tracker issue should contain a tasklist of child issue references
+- tracker issues do not replace real child issues — each child issue must be independently actionable
+- tracker issues should not carry their own implementation work
+- use tracker issues for workstreams like "documentation rollout" or "v1 collector delivery" that span multiple concrete issues
+
+### Dependencies and Relationships
+
+When issues must be completed in a specific order, express that dependency explicitly.
+
+Rules for dependencies:
+
+- if issue B depends on issue A being done first, say so in the body of issue B: `Depends on #A`
+- if an issue is blocked, add the `status/blocked` label and note what it is blocked on
+- cross-repo dependencies use the full reference format: `AzureLocal/other-repo#N`
+- do not rely on issue ordering or numbering to imply sequencing — make it explicit in the issue body
+
+### Minimum Issue Metadata
+
+When creating a new issue, provide at minimum:
+
+- a clear title
+- one `type/*` label
+- one `priority/*` label
+- a `solution/*` label if the issue is solution-specific
+- a milestone if the issue represents planned delivery work
+- a body that explains what the issue is, what the scope is, and what done looks like
+
+---
+
+## Release and Changelog Model
+
+All AzureLocal repositories use [release-please](https://github.com/googleapis/release-please) for automated release management and changelog generation.
+
+### Required Files
+
+Every repo that uses release-please must have:
+
+- `CHANGELOG.md` — maintained by release-please, do not edit manually
+- `release-please-config.json` — release-please configuration
+- `.release-please-manifest.json` — version tracking manifest
+- `.github/workflows/release-please.yml` — the workflow that runs release-please
+
+### How It Works
+
+1. Contributors use [conventional commits](https://www.conventionalcommits.org/) when committing to `main`.
+2. Release-please reads commit messages and maintains an open release PR that updates `CHANGELOG.md` and bumps the version.
+3. When the release PR is merged, release-please creates a GitHub release and tag.
+
+### Conventional Commit Types
+
+| Commit Prefix | Changelog Section | Release-Please Label |
+|---------------|------------------|---------------------|
+| `feat:` | Features | `feat` |
+| `fix:` | Bug Fixes | `fix` |
+| `docs:` | Documentation | `docs` |
+| `chore:` | Miscellaneous | `chore` |
+| `infra:` | Infrastructure | `infra` |
+
+### Maintainer Responsibilities
+
+- use conventional commit prefixes consistently
+- do not manually edit `CHANGELOG.md` — let release-please manage it
+- review and merge release PRs when they appear
+- if a release PR is stale or incorrect, close it and let release-please regenerate on next push
+
+### Exceptions
+
+Repos that are purely documentation, experimental, or have no versioned release artifact may omit release-please with a documented justification in `repo-management/README.md`.
+
+---
+
+## Workflow Patterns
+
+AzureLocal repositories share a common set of GitHub Actions workflows. Some are canonical patterns that every applicable repo should use. Others are repo-local adaptations.
+
+### Canonical Workflows
+
+These workflows should be present in every qualifying repo:
+
+| Workflow | Required When | Purpose |
+|----------|--------------|---------|
+| `release-please.yml` | All repos with versioned releases | Automated changelog and release management |
+| `add-to-project.yml` | All repos participating in the shared project board | Adds issues/PRs to the org project and sets custom fields |
+
+### Standard Patterns
+
+These workflows follow a standard pattern but are adapted per repo type:
+
+| Workflow | Required When | Adaptation |
+|----------|--------------|-----------|
+| Docs deployment (`deploy-docs.yml` or `deploy.yml`) | Repos with a docs site | MkDocs vs Docusaurus, path filters, Python vs Node.js |
+| Validation (`validate.yml` or `validate-repo-structure.yml`) | Recommended for all repos | Adjusted for repo type: MkDocs build, module manifest, structure checks |
+| Label sync (`sync-labels.yml`) | Central repo only | Applies `.github/labels.yml` to this repo; downstream repos receive labels via sync or manual application |
+
+### Repo-Local Workflows
+
+Repos may have additional workflows specific to their solution type (e.g., PowerShell module validation, test execution). These are valid but should be documented in the repo's `repo-management/automation.md`.
+
+### Required Secrets
+
+| Secret | Used By | How To Provision |
+|--------|---------|-----------------|
+| `ADD_TO_PROJECT_PAT` | `add-to-project.yml` | Classic PAT with `project` scope, org-owner role. Set as a repo secret. |
+| `GITHUB_TOKEN` | All other workflows | Built-in. No provisioning needed. |
+
+---
+
+## New Repository Onboarding
+
+When creating a new repository in the AzureLocal organization, follow this sequence:
+
+### 1. Create the repository
+
+- create the repo under the `AzureLocal` org
+- initialize with `main` as the default branch
+
+### 2. Add core files
+
+- `README.md`
+- `CONTRIBUTING.md`
+- `CHANGELOG.md`
+- `LICENSE`
+- `.gitignore`
+
+### 3. Add GitHub governance files
+
+- `.github/CODEOWNERS`
+- `.github/PULL_REQUEST_TEMPLATE.md`
+- `.github/ISSUE_TEMPLATE/` set (bug, feature, docs templates at minimum)
+
+### 4. Add release automation
+
+- `release-please-config.json`
+- `.release-please-manifest.json`
+- `.github/workflows/release-please.yml`
+
+### 5. Add project integration
+
+- `.github/workflows/add-to-project.yml` — copy from an existing repo and update the ID prefix in the `Set ID field` step
+- add the `ADD_TO_PROJECT_PAT` secret to the repo settings
+- if the repo needs a new `solution/*` label, add it to the central `.github/labels.yml` first, then add the mapping to the `add-to-project.yml` workflow
+
+### 6. Add labels
+
+- allow `sync-labels.yml` to push labels from the central repo, or manually apply labels from `.github/labels.yml`
+
+### 7. Add validation
+
+- add a validation workflow appropriate to the repo type
+- for MkDocs repos: validate MkDocs build
+- for PowerShell module repos: validate module manifest and import
+- for structure validation: check required files and directories
+
+### 8. Add docs deployment (if applicable)
+
+- add a docs deployment workflow for MkDocs or Docusaurus
+- enable GitHub Pages in repo settings (source: GitHub Actions)
+
+### 9. Enable branch protection
+
+- protect `main`
+- require PR reviews
+- require status checks where applicable
+- allow admin bypass
+
+### 10. Add repo-management documentation
+
+- `repo-management/README.md`
+- `repo-management/setup.md` — document the actual configuration applied in steps 1–9
+- `repo-management/automation.md` — document every workflow in the repo
+
+### 11. Create milestones
+
+- create milestones matching the repo's delivery phases
+- assign existing issues to appropriate milestones
+
+---
+
+## Design Rule For Future Changes
+
+When adding a new repo-level practice, ask:
+
+1. Is this a rule all repos should follow?
+2. Is this a planning or operational artifact for one repo?
+3. Is this user-facing documentation?
+
+Then place it accordingly:
+
+- org-wide rule: `standards/`
+- repo operations artifact: `repo-management/`
+- end-user content: `README.md` or published `docs/`
+
+---
+
+## Related References
+
+- [Infrastructure Standards](infrastructure)
+- [Automation Interoperability](automation)
+- [Documentation Standards](documentation)
+- [Variable Standards](variables)
+- [Solution Development Standards](solutions)
diff --git a/standards/scripting.mdx b/standards/scripting.mdx
new file mode 100644
index 0000000..ff11bf0
--- /dev/null
+++ b/standards/scripting.mdx
@@ -0,0 +1,100 @@
+# Scripting Standards
+
+> **Canonical reference:** [Scripting Standards (full)](https://azurelocal.cloud/standards/scripting/scripting-standards)
+> **Applies to:** All AzureLocal repositories
+> **Last Updated:** 2026-04-01
+
+---
+
+## Script Naming
+
+| Script Type | Pattern | Example |
+|-------------|---------|---------|
+| PowerShell Core | `Verb-Noun.ps1` | `Deploy-Solution.ps1` |
+| Azure PowerShell | `Verb-AzResource.ps1` | `New-AzKeyVault.ps1` |
+| Azure CLI (PowerShell) | `az-verb-resource.ps1` | `az-deploy-resource.ps1` |
+| Azure CLI (Bash) | `az-verb-resource.sh` | `az-deploy-resource.sh` |
+| Standalone (no config) | `Verb-Noun-Standalone.ps1` | `Deploy-Solution-Standalone.ps1` |
+| Remote/orchestration | `Invoke-.ps1` | `Invoke-Deployment.ps1` |
+
+---
+
+## Config-Driven vs Standalone
+
+| Mode | Config File | Dependencies | Use Case |
+|------|-------------|-------------|----------|
+| Config-driven (Options 2-4) | `config/variables/variables.yml` | Config loader, helpers, Key Vault | Multi-environment automation, CI/CD |
+| Standalone (Option 5) | Inline `#region CONFIGURATION` | None | Demos, single-use, external sharing |
+
+### Config-Driven Rules
+
+- Read all values from `config/variables/variables.yml` — never hardcode
+- Accept `-ConfigPath` parameter (auto-discover if not provided)
+- Use helper functions: `ConvertFrom-Yaml`, `Resolve-KeyVaultRef`, logging
+- If runtime config is missing, auto-create it from `config/variables/variables.example.yml` before parsing
+
+### Required Bootstrap Sequence
+
+For every config-driven entry point:
+
+1. Resolve repository runtime config path (`config/variables/variables.yml`).
+2. Check for runtime config file.
+3. If missing, locate template at `config/variables/variables.example.yml`.
+4. Create directories as needed and copy template to runtime path.
+5. Continue execution; fail only when no template is present.
+
+### Standalone Rules
+
+- All variables in `#region CONFIGURATION` block at top
+- Variable names match `variables.yml` paths (e.g., `$subscription_id`)
+- Zero external dependencies — copy, paste, run
+
+---
+
+## `Invoke-` Script Requirements
+
+### Required Parameters
+
+| Parameter | Type | Default | Purpose |
+|-----------|------|---------|---------|
+| `-ConfigPath` | `[string]` | `""` | Path to `variables.yml` |
+| `-Credential` | `[PSCredential]` | `$null` | Override credential resolution |
+| `-TargetNode` | `[string[]]` | `@()` (all) | Limit to specific node(s) |
+| `-WhatIf` | `[switch]` | `$false` | Dry-run mode |
+| `-LogPath` | `[string]` | `""` (auto) | Override log file path |
+
+All `Invoke-` scripts must use `[CmdletBinding()]` to enable `-Verbose` and `-Debug`.
+
+### Credential Resolution Order
+
+1. **`-Credential` parameter** — if passed, use immediately
+2. **Key Vault** — read from config; try `Az.KeyVault`, fall back to `az` CLI
+3. **Interactive prompt** — `Get-Credential` with username pre-filled
+
+---
+
+## Logging
+
+- Log to `./logs//.log`
+- Use `Write-Verbose` for detailed output
+- Log format: `[YYYY-MM-DD HH:MM:SS] [LEVEL] Message`
+
+---
+
+## Solution Script Conventions
+
+| Convention | Rule |
+|-----------|------|
+| IaC tools | Terraform, Bicep, ARM, PowerShell, Ansible |
+| Config source | `config/variables/variables.yml` (single source of truth) |
+| Parameter derivation | All tool-specific param files derived from central config |
+| Idempotency | All scripts must be safe to re-run |
+
+---
+
+## Related Standards
+
+- [PowerShell Organization Standard](https://azurelocal.cloud/standards/scripting/powershell-organization-standard)
+- [Scripting Framework](https://azurelocal.cloud/standards/scripting/scripting-framework)
+- [Bash Scripting Standards](https://azurelocal.cloud/standards/scripting/bash-scripting-standards)
+- [Automation Interoperability](automation)
\ No newline at end of file
diff --git a/standards/solutions.mdx b/standards/solutions.mdx
new file mode 100644
index 0000000..9f6bf66
--- /dev/null
+++ b/standards/solutions.mdx
@@ -0,0 +1,92 @@
+# Solution Development Standards
+
+> **Canonical reference:** [Solution Development Standard (full)](https://azurelocal.cloud/standards/solutions/solution-development-standard)
+> **Applies to:** All AzureLocal solution repositories
+> **Last Updated:** 2026-04-02
+
+---
+
+## Solution Repositories
+
+Each solution maps to an infrastructure type in the [master registry](./variables#infrastructure-types) and lives in its own repository:
+
+| Solution | Infrastructure Type | Repository |
+|----------|-------------------|------------|
+| Azure Local Platform | `azure_local` | [`azurelocal-toolkit`](https://github.com/AzureLocal/azurelocal-toolkit) |
+| Azure Virtual Desktop (cloud) | `avd_azure` | [`azurelocal-avd`](https://github.com/AzureLocal/azurelocal-avd) |
+| Azure Virtual Desktop (on-prem) | `avd_azure_local` | [`azurelocal-avd`](https://github.com/AzureLocal/azurelocal-avd) |
+| Scale-Out File Server / FSLogix | `sofs_azure_local` | [`azurelocal-sofs-fslogix`](https://github.com/AzureLocal/azurelocal-sofs-fslogix) |
+| AKS on Azure Local | `aks_azure_local` | [`azurelocal-toolkit`](https://github.com/AzureLocal/azurelocal-toolkit) |
+| Load Testing Tools | `loadtools` | [`azurelocal-loadtools`](https://github.com/AzureLocal/azurelocal-loadtools) |
+| VM Conversion Toolkit | `vm_conversion` | [`azurelocal-vm-conversion-toolkit`](https://github.com/AzureLocal/azurelocal-vm-conversion-toolkit) |
+| AI-Assisted Operations | `copilot` | [`azurelocal-copilot`](https://github.com/AzureLocal/azurelocal-copilot) |
+| Azure Local Ranger | `ranger` | [`azurelocal-ranger`](https://github.com/AzureLocal/azurelocal-ranger) |
+
+:::info[Non-IaC Solutions]
+Some solutions (e.g. Ranger, Copilot, Load Testing Tools) are operational or diagnostic tools rather than IaC deployment solutions. They follow the same repository management standards but the IaC tool support, parameter derivation, and multi-tool parity sections below do not apply. Their solution-specific architecture is documented in their own repos.
+:::
+
+---
+
+## IaC Tool Support
+
+Each tool must declare which deployment phases it supports:
+
+| Tool | Azure Resources | Configuration | Networking | Monitoring |
+|------|:---:|:---:|:---:|:---:|
+| **Terraform** | ✅ | Delegates | ✅ | ✅ |
+| **Bicep** | ✅ | Delegates | ✅ | ✅ |
+| **ARM** | ✅ | Delegates | ✅ | ✅ |
+| **PowerShell** | ✅ | ✅ | ✅ | ✅ |
+| **Ansible** | ✅ | ✅ | ✅ | ✅ |
+
+:::warning[Delegates]
+"Delegates" means the tool provisions Azure resources but does not configure the guest OS. A separate tool (PowerShell or Ansible) handles guest configuration.
+:::
+
+---
+
+## Parameter File Derivation
+
+All tool-specific parameter files MUST be derivable from `config/variables/variables.yml`:
+
+| Tool | Parameter File | Derivation |
+|------|---------------|------------|
+| Terraform | `src/terraform/terraform.tfvars` | Map YAML sections to HCL variables |
+| Bicep | `src/bicep/main.bicepparam` | Map YAML sections to Bicep parameters |
+| ARM | `src/arm/azuredeploy.parameters.json` | Map YAML sections to ARM parameter schema |
+| PowerShell | *(reads config directly)* | `ConvertFrom-Yaml` from config file |
+| Ansible | `src/ansible/inventory/hosts.yml` | Map YAML sections to `group_vars` |
+
+The central config is the **single source of truth**. Tool-specific files are convenience copies that should be regenerable.
+
+---
+
+## Conditional Resource Support
+
+| Tool | Mechanism | Example |
+|------|-----------|--------|
+| **Terraform** | `count` / `for_each` | `count = var.enable_feature ? 1 : 0` |
+| **Bicep** | `if` condition | `resource res '...' = if (enableFeature) { ... }` |
+| **ARM** | `condition` property | `"condition": "[equals(parameters('enableFeature'), 'true')]"` |
+| **PowerShell** | `switch` / `if` | `if ($config.feature_enabled) { ... }` |
+| **Ansible** | `when:` clause | `when: enable_feature == true` |
+
+All tools must produce **identical infrastructure** when given the same configuration values.
+
+---
+
+## Multi-Tool Parity
+
+- Every supported tool must cover the same set of resources
+- Tool-specific parameter files are derived from `config/variables/variables.yml`
+- CI tests validate that each tool's output matches the expected state
+- New resources added to one tool must be added to all supported tools
+
+---
+
+## Related Standards
+
+- [Infrastructure Standards](https://azurelocal.cloud/standards/infrastructure/)
+- [Variable Reference](variables)
+- [Scripting Standards](scripting)
\ No newline at end of file
diff --git a/standards/testing.mdx b/standards/testing.mdx
new file mode 100644
index 0000000..0fd0141
--- /dev/null
+++ b/standards/testing.mdx
@@ -0,0 +1,124 @@
+---
+title: "Testing Standards"
+sidebar_label: "Testing"
+sidebar_position: 90
+description: "MAPROOM fixtures, TRAILHEAD scenarios, and IIC canon — how AzureLocal repos test."
+---
+
+# Testing Standards
+
+> **Canonical reference:** this document.
+> **Applies to:** All AzureLocal repositories that ship executable code or infrastructure.
+> **Last Updated:** 2026-04-12
+
+Testing in AzureLocal is centralized. The frameworks, schemas, and canonical test data live in [`AzureLocal/platform/testing/`](https://github.com/AzureLocal/platform/tree/main/testing) and are consumed by every product repo. This standard defines **what each repo must test** and **which framework primitives it must use** — it does not re-describe the frameworks themselves (those have their own docs under [`docs/maproom/`](https://github.com/AzureLocal/platform/tree/main/docs/maproom) and [`docs/trailhead/`](https://github.com/AzureLocal/platform/tree/main/docs/trailhead) once Phase 2 ships).
+
+:::info[Phase status]
+Phase 1 (this document) establishes the **standard**. Phase 2 ships the **framework** (`AzureLocal.Maproom` PowerShell module, fixture + IIC schemas, TRAILHEAD harness). Until Phase 2 lands, repos continue to reference [`azurelocal-S2DCartographer/tests/maproom/`](https://github.com/AzureLocal/azurelocal-S2DCartographer/tree/main/tests/maproom) as the interim canonical implementation.
+:::
+
+---
+
+## Test classification
+
+Every test in an AzureLocal repo falls into exactly one of these classes. The class determines where the test lives, what harness runs it, and what a failure means.
+
+| Class | Purpose | Location | Harness |
+|-------|---------|----------|---------|
+| **unit** | Exercise a single function/cmdlet in isolation. No external state. | `tests/unit/` | Pester 5 (PowerShell) or pytest (Python) |
+| **contract** | Assert the shape of a cluster / tenant / fleet against a **MAPROOM fixture**. Fixture is authoritative; code conforms to it. | `tests/maproom/fixtures/` | `AzureLocal.Maproom` |
+| **integration** | Exercise module + live dependency (real cluster, real Azure tenant, real AD). Requires a provisioned lab. | `tests/integration/` | Pester 5 with lab config |
+| **scenario** (TRAILHEAD) | Scripted end-to-end walkthrough with pass/fail gates. User-journey shaped: "user does X, expects Y". | `tests/trailhead/` | TRAILHEAD harness (Phase 2) |
+| **drift-audit** | Assert a live environment still matches its MAPROOM fixture after time passes. Runs scheduled, not per-commit. | `tests/drift/` | `AzureLocal.Maproom` + scheduled workflow |
+
+:::warning[Classification under review]
+The five-class taxonomy above is the **current** rule. An open platform issue ([#3](https://github.com/AzureLocal/platform/issues/3)) is reviewing whether additional classes (compliance assertion, synthetic load, migration-inventory differ, repo conformance) should become first-class. Until that issue closes, treat anything outside the five classes as repo-local tooling — do not lift it into `platform/testing/` without ADR approval.
+:::
+
+---
+
+## MAPROOM — contract testing
+
+MAPROOM fixtures are JSON documents describing the **expected shape** of a target (cluster, host pool, profile-container fleet, migration source inventory). Code-under-test reads the fixture, introspects the real target, and asserts conformance.
+
+**Required for every repo that provisions or manages infrastructure.**
+
+### Required files per repo
+
+- `tests/maproom/fixtures/.json` — one fixture per logical target. Filename = target identifier.
+- `tests/maproom/.Tests.ps1` — Pester test that loads the fixture and runs conformance assertions.
+
+### Fixture schema
+
+Fixtures MUST validate against [`platform/testing/maproom/schema/fixture.schema.json`](https://github.com/AzureLocal/platform/tree/main/testing/maproom/schema) (ships in Phase 2). Until then, use the schema derived from `azurelocal-S2DCartographer/tests/maproom/schema/` and expect to migrate on Phase 2 cutover.
+
+### IIC canon as fixture source
+
+Cluster-shape fixtures that represent the canonical **Infinite Improbability Corp** environment (see [Examples & IIC Policy](examples)) live in [`platform/testing/iic-canon/`](https://github.com/AzureLocal/platform/tree/main/testing/iic-canon). Repos reference these by path; they do not copy them locally.
+
+Canonical IIC fixtures today:
+
+- `iic-org.json` — org-level identity, tenancy, domain structure
+- `iic-cluster-01.json` — primary HCI cluster shape
+- `iic-networks.json` — network topology (VLANs, subnets, NSGs)
+
+Additional IIC canons (AVD host pools, FSLogix profile maps, Nutanix source fleets) are pending classification in issue [#3](https://github.com/AzureLocal/platform/issues/3).
+
+---
+
+## TRAILHEAD — scenario testing
+
+TRAILHEAD scenarios are executable walkthroughs of a user journey end-to-end: **"a user does X in sequence, each step has an expected outcome, the scenario passes if every step's gate passes."**
+
+**Required for every repo that ships a user-facing workflow** (AVD logon, VM conversion run, migration rehearsal, demo deployment, training lab).
+
+### Required files per repo
+
+- `tests/trailhead/.trailhead.ps1` — one file per scenario. Parameterized, idempotent where possible.
+- `tests/trailhead/expected/.expected.json` — the pass/fail gates the scenario asserts at each step.
+
+### Naming
+
+Scenario filenames describe the journey, not the implementation: `new-avd-host-pool-deploy.trailhead.ps1`, not `test-avd-deploy.ps1`. The filename is user-documentation-quality.
+
+---
+
+## What every repo MUST have
+
+A conforming AzureLocal repo has, at minimum:
+
+- [ ] `tests/` directory at repo root
+- [ ] `tests/unit/` with at least one Pester/pytest test per shipped module
+- [ ] `tests/maproom/fixtures/` with at least one fixture if the repo provisions or manages infrastructure
+- [ ] `tests/trailhead/` with at least one scenario if the repo ships a user-facing workflow
+- [ ] CI workflow invoking `platform/.github/workflows/run-tests.yml` (Phase 3) — executes unit + contract tests on every PR
+- [ ] Scheduled workflow invoking `platform/.github/workflows/drift-audit.yml` weekly for repos with live environments
+
+Repos that are purely documentation (`azurelocal-training`, `azurelocal.github.io`, `demo-repository` when it stays demo-only) are exempt from the MAPROOM/TRAILHEAD requirements but still need unit tests for any embedded scripts.
+
+---
+
+## What does NOT belong in a product repo's `tests/`
+
+- **Copies of MAPROOM framework code.** Reference the platform module; don't vendor it.
+- **Copies of IIC canon fixtures.** Reference [`platform/testing/iic-canon/`](https://github.com/AzureLocal/platform/tree/main/testing/iic-canon) by path.
+- **Shared assertion helpers.** If two repos need the same helper, it belongs in `AzureLocal.Maproom`. Open a platform PR.
+- **Secrets or live-environment credentials.** Integration test config lives in the CI environment, not in-repo.
+
+---
+
+## Enforcement
+
+- **PR gate** — `Validate Repo Structure` (Phase 0, shipped) asserts `tests/` exists and is non-empty.
+- **PR gate** — `Run Tests` (Phase 3, pending) executes unit + contract tests on every PR.
+- **Weekly gate** — `Drift Audit` (Phase 4, pending) re-runs contract tests against live environments and opens an issue on divergence.
+- **Onboarding gate** — `New-AzureLocalRepo.ps1` (Phase 5, pending) scaffolds the required directories so no new repo ships without them.
+
+---
+
+## Changes to this standard
+
+Non-trivial edits require an ADR in [`decisions/`](https://github.com/AzureLocal/platform/tree/main/decisions). Current relevant ADRs:
+
+- [`0003-maproom-iic-canon.md`](https://github.com/AzureLocal/platform/blob/main/decisions/0003-maproom-iic-canon.md) — MAPROOM & IIC canon design (Proposed)
+- Classification rubric ADR — tracked in issue [#3](https://github.com/AzureLocal/platform/issues/3), number reserved for `0004-testing-toolset-classification.md`
diff --git a/standards/variables.mdx b/standards/variables.mdx
new file mode 100644
index 0000000..fe504be
--- /dev/null
+++ b/standards/variables.mdx
@@ -0,0 +1,481 @@
+# Variable Management
+
+> **Last Updated:** 2026-04-02
+> **Applies to:** All AzureLocal repositories
+> **Master Registry:** [`azurelocal-toolkit/config/variables/schema/master-registry.yaml`](https://github.com/AzureLocal/azurelocal-toolkit/blob/main/config/variables/schema/master-registry.yaml)
+
+---
+
+## How The Variable System Works
+
+Every AzureLocal repo uses a single YAML config file — `config/variables/variables.yml` — as input to all automation (Terraform, Bicep, PowerShell, Ansible). The file is not committed; you copy the template and fill it in.
+
+```
+ ┌──────────────────────────────┐
+ │ Master Registry (970+ vars) │
+ │ master-registry.yaml │
+ └──────────┬───────────────────┘
+ │ defines
+ ┌─────────────────────┼─────────────────────┐
+ ▼ ▼ ▼
+ variables.schema.json alias-policy.json legacy-compatible-roots.json
+ │
+ ▼
+ variables/variables.example.yml ──copy──▶ variables/variables.yml ──consumed by──▶ Scripts
+ │ │
+ ▼ ▼
+ CI validates (PR) CanonicalVariable.psm1 / canonical_variables.py
+ config-loader.ps1
+ registry-variable.ps1
+ Generate-SolutionConfig.ps1
+```
+
+---
+
+## Quick Start
+
+### 1. Copy the template
+
+```powershell
+# In any AzureLocal repo
+cp config/variables/variables.example.yml config/variables/variables.yml
+```
+
+### 2. Edit your values
+
+Open `config/variables/variables.yml` and replace the IIC (Infinite Improbability Corp) example values with your environment's actual values. The file is organized by the same sections as the master registry.
+
+### 3. Validate locally
+
+```powershell
+# From azurelocal-toolkit root
+pwsh config/variables/scripts/validate-variables.ps1 -StrictUnknown
+```
+
+### 4. Run your automation
+
+Scripts bootstrap automatically — if `config/variables/variables.yml` is missing, they copy from the template before continuing.
+
+---
+
+## Master Variable Registry
+
+The registry is the single source of truth for **every variable** across all repos:
+
+```
+azurelocal-toolkit/config/variables/schema/master-registry.yaml
+```
+
+It defines each variable's type, description, constraints, defaults, examples, and which infrastructure type(s) it belongs to. Schema files, documentation, and validation tooling are all derived from it.
+
+### Registry Structure (15 Sections)
+
+| # | Section | What It Contains |
+|---|---------|-----------------|
+| 1 | `_metadata` | Registry version, infrastructure scenario definitions |
+| 2 | `infrastructure_scenarios` | Infrastructure type definitions and variable group mappings |
+| 3 | `site` | Site code, name, location, environment, owner |
+| 4 | `environment` | Environment classification (dev/test/prod) |
+| 5 | `tags` | Azure resource tags |
+| 6 | `azure_platform` | Subscription, resource groups, platform config |
+| 7 | `identity` | Entra ID, service principals, managed identities |
+| 8 | `networking` | VNets, subnets, VLANs, DNS, logical networks |
+| 9 | `compute` | VMs, clusters (Azure Local, WSFC/SOFS), cluster nodes |
+| 10 | `storage_accounts` | Azure Storage accounts (witness, diagnostics) |
+| 11 | `cluster_shared_volumes` | S2D CSV volume definitions |
+| 12 | `marketplace_images` | Azure Marketplace VM image references |
+| 13 | `security` | Key Vault, certificates, Defender, policies |
+| 14 | `operations` | Monitoring, updates, backup/DR |
+| 15 | `devops` | GitLab, CI/CD pipeline config |
+
+### Infrastructure Types
+
+Each variable is scoped to one or more infrastructure types:
+
+| Type | Description | Repository |
+|------|-------------|------------|
+| `azure_local` | Azure Local hyper-converged clusters | `azurelocal-toolkit` |
+| `avd_azure` | Azure Virtual Desktop in Azure cloud | `azurelocal-avd` |
+| `avd_azure_local` | Azure Virtual Desktop on Azure Local | `azurelocal-avd` |
+| `sofs_azure_local` | Scale-Out File Server on Azure Local | `azurelocal-sofs-fslogix` |
+| `aks_azure_local` | AKS on Azure Local | `azurelocal-toolkit` |
+| `loadtools` | Performance and load testing tools | `azurelocal-loadtools` |
+| `vm_conversion` | VM generation conversion toolkit | `azurelocal-vm-conversion-toolkit` |
+| `copilot` | AI-assisted operations | `azurelocal-copilot` |
+
+### Supporting Schema Files
+
+| File | Purpose |
+|------|---------|
+| `master-registry.yaml` | Authoritative variable definitions (970+ variables) |
+| `variables.schema.json` | JSON Schema for CI validation of `variables.example.yml` |
+| `legacy-compatible-roots.json` | Roots allowed during migration (alias fallback) |
+| `canonical-drift-allowlist.json` | Paths temporarily allowed to drift from registry |
+| `alias-policy.json` | Alias lifecycle and expiry rules |
+
+All located in `azurelocal-toolkit/config/variables/schema/`.
+
+---
+
+## Config File Layout
+
+### Per-Repository Structure
+
+```
+config/
+└── variables/
+ ├── variables.example.yml # Template with IIC examples (committed)
+ ├── variables.yml # Your actual config (gitignored)
+ └── schema/
+ └── variables.schema.json # JSON Schema for CI validation
+```
+
+### Path Reference
+
+| Item | Canonical Path |
+|------|---------------|
+| Runtime config | `config/variables/variables.yml` |
+| Template | `config/variables/variables.example.yml` |
+| JSON Schema | `config/variables/schema/variables.schema.json` |
+| Legacy flat path (deprecated) | `config/variables.yml` |
+| Legacy template (deprecated) | `config/variables.example.yml` |
+
+### Bootstrap Policy
+
+All config-driven entry-point scripts must implement this sequence:
+
+1. Check for runtime config at `config/variables/variables.yml`.
+2. If missing, locate template at `config/variables/variables.example.yml`.
+3. Copy template to runtime path (create parent dirs if needed).
+4. Fail only if no template exists.
+
+---
+
+## Naming Rules
+
+| Rule | Standard | Example |
+|------|----------|--------|
+| Top-level sections | `snake_case` | `azure_local`, `networking` |
+| Keys within sections | `snake_case` | `subscription_id`, `resource_name` |
+| Pattern | `^[a-z][a-z0-9_]*$` | — |
+| Max length | 50 characters | — |
+| Booleans | Descriptive names | `monitoring_enabled: true` |
+| Secrets | `keyvault://` URI format | `keyvault://kv-iic-platform/admin-password` |
+
+### Canonical Prefixes
+
+The `wsfc_sofs_*` variable prefix is **canonical** and must not be renamed. These are consumed at runtime by `Deploy-SOFS-Azure.ps1`, `solution-sofs.yml`, and `variables.tf`.
+
+---
+
+## Secrets
+
+Secrets are never stored in plaintext — use Key Vault URI references:
+
+```yaml
+security:
+ admin_password: "keyvault://kv-iic-platform/admin-password"
+ domain_join_password: "keyvault://kv-iic-platform/domain-join"
+```
+
+Scripts resolve these at runtime via the `keyvault-helper.ps1` module.
+
+---
+
+## Validation
+
+### CI Pipeline (`validate-config.yml`)
+
+Every PR that touches `config/` triggers the validation workflow. It runs these checks in order:
+
+| Step | Script | What It Does |
+|------|--------|-------------|
+| 1. Registry structure | `validate-registry.ps1` | Verifies `_metadata` section exists, checks for duplicate key paths and alias conflicts |
+| 2. Variables vs registry | `validate-variables.ps1 -StrictUnknown` | Validates `variables.example.yml` against JSON Schema, then checks every variable path exists in the registry |
+| 3. Alias expiry | `check-alias-expiry.ps1` | Fails if any `expires_on` dates in alias entries have passed |
+| 4. YAML syntax | Python `yaml.safe_load` | Ensures the example file is parseable |
+
+### Running Validation Locally
+
+```powershell
+# From azurelocal-toolkit root — full validation suite
+pwsh config/variables/scripts/validate-registry.ps1
+pwsh config/variables/scripts/validate-variables.ps1 -StrictUnknown
+pwsh config/variables/scripts/check-alias-expiry.ps1
+```
+
+`validate-variables.ps1` produces reports in `config/variables/reports/`:
+
+| Report | Contents |
+|--------|----------|
+| `canonical-unknown-paths.csv` | Variable paths not found in the registry |
+| `canonical-unknown-summary.txt` | Summary with top unknown roots and counts |
+
+### What `-StrictUnknown` Does
+
+Without it, unknown paths are warnings. With `-StrictUnknown`, they fail the validation — this is the CI default.
+
+---
+
+## Reading Variables in Scripts
+
+### PowerShell: `CanonicalVariable.psm1`
+
+The primary module for reading variables with alias resolution from the master registry.
+
+**Location:** `azurelocal-toolkit/scripts/common/utilities/helpers/CanonicalVariable.psm1`
+
+```powershell
+Import-Module helpers/CanonicalVariable.psm1
+Initialize-CanonicalVariables
+
+# Read a value by dotted path
+$clusterName = Get-CanonicalVariable -Path 'compute.clusters.azure_local.azl_name'
+
+# Read with fallback default
+$env = Get-CanonicalVariable -Path 'site.environment' -Default 'dev'
+
+# Check if a path exists
+$exists = Test-CanonicalVariable -Path 'identity.azure_tenant_id'
+
+# Fail-fast: require multiple paths or throw
+Test-RequiredCanonicalVariables -Paths @(
+ 'site.environment',
+ 'azure_platform.tenant.id',
+ 'security.keyvault_name'
+) -ScriptName $MyInvocation.MyCommand.Name
+
+# Get all alias mappings
+$aliases = Get-CanonicalAliasMap
+```
+
+**Key behaviors:**
+- Auto-bootstraps from `config/variables/variables.example.yml` if `config/variables/variables.yml` is missing
+- Resolves aliases from the master registry (old path → canonical path)
+- Supports array indexing: `compute.cluster_nodes[0].hostname`
+- `Test-RequiredCanonicalVariables` throws with the full list of missing paths
+
+### Python: `canonical_variables.py`
+
+The Python equivalent for repos that use Python tooling.
+
+**Location:** `azurelocal-toolkit/config/variables/scripts/canonical_variables.py`
+
+```python
+from canonical_variables import CanonicalVariables
+
+cv = CanonicalVariables()
+
+# Read a value
+tenant_id = cv.get("identity.azure_tenant_id")
+
+# Read with default
+env = cv.get("site.environment", default="dev")
+
+# Check existence
+if cv.exists("security.keyvault_name"):
+ ...
+
+# Fail-fast on missing required values
+cv.require(
+ "identity.azure_tenant_id",
+ "security.keyvault_name",
+ caller="deploy-avd.py"
+)
+
+# Get alias map
+aliases = cv.alias_map
+```
+
+### PowerShell: `config-loader.ps1`
+
+Hierarchical config loader that merges environment + solution overrides.
+
+**Location:** `azurelocal-toolkit/scripts/common/utilities/helpers/config-loader.ps1`
+
+```powershell
+. helpers/config-loader.ps1
+
+# Load merged config (master → environment → solution overrides)
+$config = Get-MergedConfiguration -Environment "prod" -Solution "azure-local"
+
+# Access directly
+$tenantId = $config.azure_platform.tenant.id
+$kvName = $config.security.key_vaults.management.name
+```
+
+**Merge order (later wins):**
+1. Master registry defaults
+2. Environment config (`config/environments/{env}.yaml`)
+3. Solution config (`solutions/{solution}/config/solution.yaml`)
+
+### PowerShell: `registry-variable.ps1`
+
+Search and lookup helper for finding variables by name across the configuration.
+
+**Location:** `azurelocal-toolkit/scripts/common/utilities/helpers/registry-variable.ps1`
+
+```powershell
+. helpers/registry-variable.ps1
+
+# Search for variables containing "tenant"
+Find-RegistryVariable -VariableName "tenant"
+
+# Exact match
+Find-RegistryVariable -VariableName "tenant_id" -ExactMatch
+
+# Check if a path exists
+Test-RegistryVariablePath -Path "azure_platform.tenant.id"
+
+# Get a value by path
+$value = Get-RegistryVariableValue -Path "security.keyvault_name"
+```
+
+---
+
+## Generation & Transformation Tools
+
+### `Generate-SolutionConfig.ps1`
+
+Creates a solution-specific YAML config by combining `solutions.yaml` + master registry + environment infrastructure file.
+
+**Location:** `azurelocal-toolkit/tools/Generate-SolutionConfig.ps1`
+
+```powershell
+# Generate config for AVD on Azure Local in lab environment
+.\Generate-SolutionConfig.ps1 -Solution avd-azure-local -Environment azl-lab
+
+# Preview without writing
+.\Generate-SolutionConfig.ps1 -Solution sofs-azure-local -Environment azl-lab -WhatIf
+
+# Custom output path
+.\Generate-SolutionConfig.ps1 -Solution avd-azure-local -Environment azl-lab -OutputPath ./out/avd.yml
+```
+
+**What it does:**
+- Reads the solution definition from `solutions.yaml` to get required variable groups
+- Pulls actual values from `infrastructure-{env}.yml`
+- Validates required variables are present
+- Outputs to `solutions/{name}/solution-{name}.yml`
+
+### `Generate-ClusterConfigMD.ps1`
+
+Generates a human-readable markdown document from the infrastructure config — useful for review before deployment.
+
+**Location:** `azurelocal-toolkit/scripts/common/utilities/tools/Generate-ClusterConfigMD.ps1`
+
+```powershell
+# Generate from solution
+.\Generate-ClusterConfigMD.ps1 -Solution "azure-local"
+
+# Generate from specific file
+.\Generate-ClusterConfigMD.ps1 -InfrastructurePath .\infrastructure.yml
+```
+
+### `New-ScriptFromTemplate.ps1`
+
+Scaffolds new scripts following AzureLocal scripting standards, with proper config loading baked in.
+
+**Location:** `azurelocal-toolkit/scripts/tools/New-ScriptFromTemplate.ps1`
+
+```powershell
+# Config-driven script
+.\New-ScriptFromTemplate.ps1 -ScriptType AzurePowerShell -Name "New-AzKeyVault" -Description "Creates a Key Vault"
+
+# Standalone script (inline variables, no config dependency)
+.\New-ScriptFromTemplate.ps1 -ScriptType AzurePowerShell -Name "New-AzKeyVault" -Standalone
+```
+
+**Script types:** `PowerShell`, `AzurePowerShell`, `AzureCliPowerShell`, `AzureCliBash`, `InvokeScript`
+
+### `Convert-ToStandaloneScript.ps1`
+
+Takes a config-driven script and bakes in current config values to create a standalone version with no external dependencies.
+
+**Location:** `azurelocal-toolkit/scripts/tools/Convert-ToStandaloneScript.ps1`
+
+```powershell
+.\Convert-ToStandaloneScript.ps1 -SourceScript .\New-AzureLocalSP.ps1 -ConfigPath .\infrastructure.yml
+```
+
+---
+
+## Cross-Repo Analysis Tools
+
+These tools live in `azurelocal-toolkit/config/variables/scripts/` and operate across all repos in the workspace.
+
+### `inventory-repo-variables.ps1`
+
+Scans all repos for variable usage and produces a cross-repo inventory.
+
+```powershell
+.\inventory-repo-variables.ps1 -WorkspaceRoot "E:\git" -OutputRoot ".\reports"
+```
+
+**Outputs:**
+- `variable-inventory.csv` / `.json` — every variable path by repo and file
+- `variable-inventory-summary.txt` — counts per repo, unique paths
+
+### `build-mapping-report.ps1`
+
+Finds shared variables across repos and detects naming collisions.
+
+```powershell
+.\build-mapping-report.ps1 -InventoryCsv ".\reports\variable-inventory.csv"
+```
+
+**Outputs:**
+- `shared-key-paths.csv` — variable paths used in multiple repos
+- `leaf-collisions.csv` — same leaf name, different paths across repos
+- `canonical-mapping-template.csv` — template for mapping legacy → canonical
+
+### `classify-mapping-template.ps1`
+
+Classifies variables as canonical, legacy alias, or orphaned based on the mapping template.
+
+```powershell
+.\classify-mapping-template.ps1
+```
+
+**Outputs:**
+- `canonical-mapping-template-classified.csv` — each path classified as `canonical_candidate`, `alias_candidate`, or `orphaned_candidate`
+- `classification-summary.txt`
+
+---
+
+## Tool-Specific Parameter Derivation
+
+All tool-specific parameter files are derived from `config/variables/variables.yml`:
+
+| Tool | Parameter File | How |
+|------|---------------|-----|
+| Terraform | `src/terraform/terraform.tfvars` | Map YAML sections to HCL variables |
+| Bicep | `src/bicep/main.bicepparam` | Map YAML sections to Bicep parameters |
+| ARM | `src/arm/azuredeploy.parameters.json` | Map YAML sections to ARM parameter schema |
+| PowerShell | *(reads config directly)* | `CanonicalVariable.psm1` or `ConvertFrom-Yaml` |
+| Ansible | `src/ansible/inventory/hosts.yml` | Map YAML sections to `group_vars` |
+
+The central config is the **single source of truth**. Tool-specific files are convenience copies that should be regenerable from it.
+
+---
+
+## Per-Repo Automation Summary
+
+| Repo | Validation | Config Access | Schema |
+|------|-----------|--------------|--------|
+| `azurelocal-toolkit` | 7 PowerShell validators | CanonicalVariable, config-loader, registry-variable | master-registry.yaml |
+| `azurelocal-avd` | Python validator | CanonicalVariable, config-loader | variables.schema.json |
+| `azurelocal-sofs-fslogix` | Python validator | CanonicalVariable | variables.schema.json |
+| `azurelocal-loadtools` | Python validator | ConfigManager, StateManager | variables.schema.json |
+| `azurelocal-vm-conversion-toolkit` | Python validator | CanonicalVariable | variables.schema.json |
+| `azurelocal-copilot` | — | — | variables.example.yml |
+| `azurelocal-training` | — | — | — |
+
+---
+
+## Related Standards
+
+- [Infrastructure Standards](infrastructure) — infrastructure types and deployment phases
+- [Solution Development Standards](solutions) — solution-to-repo mapping and IaC tool parity
+- [Scripting Standards](scripting) — script structure and config loading patterns
+- [Automation Interoperability](automation) — cross-tool conventions
\ No newline at end of file
diff --git a/templates/_common/STANDARDS.md b/templates/_common/STANDARDS.md
new file mode 100644
index 0000000..a782ed2
--- /dev/null
+++ b/templates/_common/STANDARDS.md
@@ -0,0 +1,9 @@
+# Standards
+
+AzureLocal organization standards are maintained centrally in the [`AzureLocal/platform`](https://github.com/AzureLocal/platform) repository. This repo does **not** keep a local copy.
+
+- **Canonical source**: [`AzureLocal/platform/standards/`](https://github.com/AzureLocal/platform/tree/main/standards)
+- **Rendered for humans**: [azurelocal.cloud/standards](https://azurelocal.cloud/standards/)
+- **Governance**: [ADR-0002 — Standards as single source of truth](https://github.com/AzureLocal/platform/blob/main/decisions/0002-standards-single-source.md)
+
+Changes to any standard are PRs against `AzureLocal/platform`, not against this repo.