Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Design Principles

setup-cm is built around a small set of non-negotiable design principles. Understanding them makes the codebase easier to navigate and extend.

1. Desired-state stages, not scripts

Each stage is a Test / Apply / Verify triplet. The stage engine only runs Apply when Test reports NotCompliant, and only runs Verify after Apply succeeds. That engine contract makes a stage idempotent only when its Test is a real state probe. Acquire, SQL, MECM, Marker, and Health now meet that standard; the final live gate runs the same exact source twice to prove it. See Current LabZ1 Status.

2. Evidence is a first-class output

Every run writes structured JSON to a unique directory under evidenceRoot. Evidence is not an afterthought or a log file; it is the primary artifact that tells you what happened, when, and why. Both success and failure produce evidence.

3. Configuration is explicit and validated

The private YAML configuration declares operator-selectable deployment state. The Marker feature adds a compiled fixed LabZ1 contract, and release-critical evidence adds an exact source commit. Placeholder values are rejected when template is false; target and safety guardrails are rechecked before any provider action.

4. Media and secrets stay outside Git

The committed template contains only safe example metadata. Private source locations, actual installers, product keys, credentials, certificates, working configuration, and generated evidence never enter version control.

5. Lab-first, with explicit safety gates

The supported v1 topology is the single-box isolated LabZ1 environment. General configuration validation has an explicit production acknowledgement, but the Marker command and v1 acceptance remain fixed lab-only and do not support production targeting.

6. Provisioning is a separate concern

setup-cm does not create VMs, install Windows, or join domains. It assumes those prerequisites are met and focuses exclusively on Windows-side MECM configuration and validation. This boundary keeps the tool focused and reusable.

7. Testability at every layer

Every private function has a corresponding Pester 6 unit test. Mocks isolate Windows-specific APIs (registry, services, processes) so tests run on any platform. Integration tests validate the live lab only after unit tests pass.

8. Small, composable modules

Private functions live in src/SetupCm/Private/ and do one thing. Public entry points live in src/SetupCm/Public/ and orchestrate stages. Scripts in scripts/ are thin wrappers for agent execution. This separation keeps the module testable and the entry points predictable.