<?xml version="1.0"?>
<doc>
    <assembly>
        <name>Eryph.GuestServices.Provisioning</name>
    </assembly>
    <members>
        <member name="T:Eryph.GuestServices.Provisioning.Cli.CollectLogsCommand">
            <summary>
            Bundles state.json, the logs directory, the staged scripts directory and
            the agent's version info into a zip archive — the cloud-init
            <c>collect-logs</c> equivalent. Missing inputs are skipped silently so
            operators can run it at any point in the lifecycle.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Cli.ProvisioningPaths">
            <summary>
            Resolves the well-known paths the CLI needs to inspect or clean up.
            Centralised so reset / collect-logs / status all agree on where to look.
            Tests can override the root by setting <see cref="P:Eryph.GuestServices.Provisioning.Cli.ProvisioningPaths.RootOverride"/>.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Cli.ProvisioningPaths.InstanceRoot">
            <summary>
            Per-instance scope root. Mirrors cloud-init's
            <c>/var/lib/cloud/instance</c> — one directory per instance-id,
            containing the per-instance semaphore subdirectory plus any other
            instance-scoped artefacts we add later.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Cli.ProvisioningPaths.GlobalSemaphoreDir">
            <summary>
            Global semaphore directory hosting per-boot and per-once markers.
            Mirrors cloud-init's <c>/var/lib/cloud/sem</c>.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Cli.ProvisioningPaths.LastSeenBootFile">
            <summary>
            Marker file used by <c>BootSessionDetector</c> to remember the boot
            id of the previous run. Deleted on full reset so the next agent run
            treats itself as a new boot.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Cli.ResetCommand">
            <summary>
            Clears persistent provisioning state so the next agent run treats the
            guest as a fresh instance. Mirrors <c>cloud-init clean</c>:
            per-instance semaphores + state.json are always cleared; per-boot
            semaphores are cleared unless <c>--keep-per-boot</c> is passed; per-once
            semaphores survive unless <c>--reset-once</c> is passed.
            <c>--logs</c> and <c>--scripts</c> also wipe the corresponding directories
            under <c>%ProgramData%\eryph\provisioning</c>.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Cli.RunCommand">
            <summary>
            One-shot operator subcommand: runs the configured stages synchronously and
            exits. The Windows-service hosted run lives in <c>egs-service</c> (which
            embeds the provisioning library); this command always executes in-process
            and returns. Supports <c>--dry-run</c>, <c>--stage</c>, <c>--user-data</c>
            and <c>--instance-id</c> for operator workflows.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Cli.StatusCommand">
            <summary>
            Reads <c>state.json</c> and prints the agent's current status. Always
            reads from disk (never from an in-memory store) so the answer reflects
            what the next agent boot will see.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Cli.ValidateCommand">
            <summary>
            Parses a local cloud-config file and runs the same validators the agent
            uses at runtime, without applying anything. Useful in CI / authoring
            workflows: exit code 0 means the file is loadable and semantically valid,
            1 means validation failed, 2 means it couldn't even be parsed.
            <para>
            <c>--target windows|linux|all</c> opts into a platform-portability check
            driven by the source-generated <see cref="T:Eryph.GuestServices.CloudConfig.CloudConfigPlatformInventory"/>.
            Non-supported fields surface as Warnings (the YAML still parses, so exit
            code stays 0 — the warnings just flag non-portable usage to the author).
            </para>
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Cli.VersionCommand">
            <summary>
            Prints the agent assembly version (file + informational). Useful for
            debug reports and for the host-side tooling to confirm what's running.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Configuration.ProvisioningSettings">
            <summary>
            Tunables read from <c>egs-provisioning.json</c> next to the binary, or
            from <c>%ProgramData%\eryph\provisioning\settings.json</c>. Falls back
            to defaults when no file is present.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.ProvisioningSettings.DefaultUser">
            <summary>
            The image-baked default administrator concept. Layer 3 of
            <see cref="T:Eryph.GuestServices.Provisioning.Modules.IDefaultUserResolver"/>: the account that top-level
            shorthands (<c>ssh_authorized_keys</c>, <c>password</c>,
            <c>chpasswd</c>) target when the user-data declares no admin user.
            Mirrors cloud-init's <c>system_info.default_user</c>.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.ProvisioningSettings.Stages">
            <summary>
            Per-stage allowlist / denylist of modules. Keys are stage names
            (<c>"Local"</c>, <c>"Network"</c>, <c>"Config"</c>, <c>"Final"</c>;
            case-insensitive). When a stage is absent, all discovered modules
            for that stage run. See <see cref="T:Eryph.GuestServices.Provisioning.Configuration.StageSettings"/> for matching
            semantics. RFC 0009 — module-list split.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.UserDataSettings.MaxRecursionDepth">
            <summary>Maximum nesting depth for multipart / #include recursion.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.UserDataSettings.FetchTimeoutSeconds">
            <summary>Per-attempt timeout when fetching #include URLs.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.UserDataSettings.FetchMaxAttempts">
            <summary>Total attempts (initial + retries) when fetching #include URLs.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.UserDataSettings.FetchInitialBackoffSeconds">
            <summary>Initial backoff between #include retries. Doubles up to a 4s cap.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.UserDataSettings.FetchMaxBytes">
            <summary>
            Maximum size (in bytes) of a single #include response. A server that
            reports a larger <c>Content-Length</c>, or streams more bytes than this
            (lying about / omitting the header), aborts the fetch. Guards against a
            runaway or hostile URL exhausting memory. Default 10 MiB.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.DataSourceSettings.ReadinessTimeoutMinutes">
            <summary>
            Total wall-clock budget (in minutes) <see cref="T:Eryph.GuestServices.Provisioning.DataSources.DataSourceLocator"/>
            will spend across all probes — including <c>WaitForReady</c> backoffs — before
            giving up and returning <c>NoDataSource</c>. Mirrors cloud-init's per-datasource
            <c>wait_for_metadata_service</c> deadline but is global (one timer for the entire
            LocateAsync call), since we round-robin probes between sources rather than
            blocking on a single slow one. Default 15 minutes — covers Azure PA worst-case
            (large image / slow disk pushes the oobeSystem chain past 10 minutes), while
            still being short enough that a hung probe surfaces as a build failure within
            the typical CI cycle.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.DataSourceSettings.MinBackoffSeconds">
            <summary>
            Minimum backoff (seconds) between consecutive <c>WaitForReady</c> probes of the
            same source. The datasource's own <see cref="P:Eryph.GuestServices.Provisioning.DataSources.DataSourceProbeResult.WaitForReady.Backoff"/>
            is treated as a hint; the locator clamps it to [<see cref="P:Eryph.GuestServices.Provisioning.Configuration.DataSourceSettings.MinBackoffSeconds"/>,
            <see cref="P:Eryph.GuestServices.Provisioning.Configuration.DataSourceSettings.MaxBackoffSeconds"/>] and doubles after each retry. Default 1s.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.DataSourceSettings.MaxBackoffSeconds">
            <summary>
            Maximum backoff (seconds) between consecutive <c>WaitForReady</c> probes of the
            same source. Caps the exponential growth so we keep checking at least once a
            minute even on a long deadline. Default 60s.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.DataSourceSettings.DataSourceList">
            <summary>
            Ordered list of datasource names to probe (e.g.
            <c>["NoCloud","ConfigDrive","Azure"]</c>), mirroring cloud-init's
            <c>datasource_list</c>. When null/empty, all registered sources are probed in
            <see cref="P:Eryph.GuestServices.Provisioning.DataSources.IDataSource.Priority"/> order (default). When set, only the
            named sources are probed, <b>in the listed order</b>; names not matching a
            registered source are logged at Warning and ignored. Matching is case-insensitive
            on <see cref="P:Eryph.GuestServices.Provisioning.DataSources.IDataSource.Name"/>.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Configuration.StageSettings">
             <summary>
             Operator-controlled allowlist / denylist of modules for a single stage.
             Mirrors cloud-init's <c>cloud_init_modules</c> / <c>cloud_config_modules</c>
             / <c>cloud_final_modules</c> lists.
            
             Module-name matching is case-insensitive and tolerates the <c>Module</c>
             suffix (so both <c>"SetHostnameModule"</c> and <c>"SetHostname"</c>
             match the <see cref="T:Eryph.GuestServices.Provisioning.Modules.SetHostnameModule"/> type).
            
             Resolution order when both lists are set:
             1. Start with all discovered modules in the stage.
             2. If <see cref="P:Eryph.GuestServices.Provisioning.Configuration.StageSettings.EnabledModules"/> is non-null, narrow to that set.
             3. If <see cref="P:Eryph.GuestServices.Provisioning.Configuration.StageSettings.DisabledModules"/> is non-null, remove those.
            
             Unknown names are logged at Warning but do not fail the run — typo in a
             settings file should not crash provisioning.
             </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.StageSettings.EnabledModules">
            <summary>
            When set, only modules whose short class name (case-insensitive,
            optional <c>Module</c> suffix) appears here run in this stage.
            When null, all discovered modules are considered for this stage.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.StageSettings.DisabledModules">
            <summary>
            When set, modules whose short class name matches an entry are
            removed from the stage's run list (applied after
            <see cref="P:Eryph.GuestServices.Provisioning.Configuration.StageSettings.EnabledModules"/> if both are set).
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.ScriptSettings.PerInstanceDirectory">
            <summary>Directory where user-data scripts are staged before execution.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.ScriptSettings.ScriptTimeoutMinutes">
            <summary>Per-script execution timeout. Not enforced in v1; reserved for v2.</summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Configuration.RebootSettings">
            <summary>
            Loop-safety caps for the cloudbase-init "reboot-and-continue" (exit 1003)
            convention. Two independent guards (see docs/bugs/0001 "loop-safety"):
            <see cref="P:Eryph.GuestServices.Provisioning.Configuration.RebootSettings.MaxPerModule"/> bounds how often the StageRunner re-enters the
            same module, while <see cref="P:Eryph.GuestServices.Provisioning.Configuration.RebootSettings.MaxPerScript"/> bounds reboots for a single
            (ordinal, body-hash) script inside ScriptsUser. The per-script cap is the
            tighter inner guard; the per-module cap is the outer backstop. Defaults
            match the historical hard-coded values, so behaviour is unchanged unless
            configured.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.RebootSettings.MaxPerModule">
            <summary>Max times a single module may return RebootRequested before the run fails.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.RebootSettings.MaxPerScript">
            <summary>Max reboots a single (ordinal, body-hash) script may request before it fails.</summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Configuration.DefaultUserSettings">
            <summary>
            The image-baked default administrator. The <c>Name</c> is the cloud-init
            <c>system_info.default_user.name</c> analogue — the account top-level
            credential shorthands target when the user-data <c>users:</c> block does
            not declare an admin. <c>Groups</c> and <c>CreateIfMissing</c> let an image
            pre-declare how that account is provisioned when it has to be created.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.DefaultUserSettings.Name">
            <summary>
            The image-baked default admin name (cloud-init
            <c>system_info.default_user.name</c>). When null the resolver falls
            through to its <c>"Administrator"</c> fallback.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.DefaultUserSettings.Groups">
            <summary>
            Default groups for the default user. Null is treated as
            <c>["Administrators"]</c> by consumers.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.DefaultUserSettings.CreateIfMissing">
            <summary>
            When true, the default user is auto-created (and the top-level
            credentials applied to it) if no <c>users:</c> entry declares one.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.Boolean">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.DataSourceSettings">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.DefaultUserSettings">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.ProvisioningSettings">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.RebootSettings">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.ScriptSettings">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.StageSettings">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.UserDataSettings">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.DictionaryStringStageSettings">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.IReadOnlyListString">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.ListString">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.Int32">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.Int64">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.String">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.Default">
            <summary>
            The default <see cref="T:System.Text.Json.Serialization.JsonSerializerContext"/> associated with a default <see cref="T:System.Text.Json.JsonSerializerOptions"/> instance.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.GeneratedSerializerOptions">
            <summary>
            The source-generated options associated with this context.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.#ctor">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.#ctor(System.Text.Json.JsonSerializerOptions)">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Configuration.SettingsSerializerContext.GetTypeInfo(System.Type)">
            <inheritdoc/>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.DataSources.Azure.AzureImdsClient">
            <summary>
            Thin client around the Azure Instance Metadata Service. IMDS lives on the
            link-local 169.254.169.254 endpoint and requires the
            <c>Metadata: true</c> header (Azure rejects requests without it to prevent
            SSRF-style abuse from inside the VM). See RFC 0014 for the full policy
            (retry once on transient, 5s timeout, no auth on instance metadata).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.DataSources.Azure.AzureImdsClient.#ctor(Microsoft.Extensions.Logging.ILogger)">
            <summary>
            Production constructor: builds its own <see cref="T:System.Net.Http.HttpClientHandler"/>.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.DataSources.Azure.AzureImdsClient.#ctor(System.Net.Http.HttpMessageHandler,System.Boolean,System.TimeSpan,Microsoft.Extensions.Logging.ILogger)">
            <summary>
            Test seam: caller supplies a substituted <see cref="T:System.Net.Http.HttpMessageHandler"/>
            (e.g. an NSubstitute mock or a fake delegating handler).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.DataSources.Azure.AzureImdsClient.TryGetInstanceMetadataAsync(System.Threading.CancellationToken)">
            <summary>
            Performs one GET with one retry on transient failure. Returns null when
            IMDS is unreachable after both attempts — callers fall back to whatever
            they can scrape from the registry / ovf-env.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.DataSources.Azure.AzureOvfEnvParser">
            <summary>
            Parses Azure ConfigDrive <c>ovf-env.xml</c>. Public XML namespace is
            <c>http://schemas.microsoft.com/windowsazure</c>. We extract only the fields
            v1 actually consumes (HostName and CustomData); other elements are noted in
            RFC 0014 for later phases. Robust to either provisioning-configuration-set
            variant — Linux and Windows ship the same wrapping element shape.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.DataSources.Azure.AzureOvfEnv.CustomDataBase64">
            <summary>
            Raw base64 CustomData string as embedded in the XML. PA base64-decodes
            it once before writing <c>C:\AzureData\CustomData.bin</c>, so the
            canonical post-PA source is the file, not this property. The XML form
            is kept for the rare case where the ConfigDrive is still mounted when
            our agent reads it. CustomData is NOT encrypted at any layer — the
            <c>&lt;CertificateThumbprint&gt;</c> element under <c>&lt;UserPassword&gt;</c>
            in the same configset wraps AdminPassword, not CustomData (verified
            against cloud-init / WALinuxAgent / cloudbase-init in
            docs/research/azure-customdata-encryption.md).
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.DataSources.AzureDataSource">
             <summary>
             Azure datasource — coexists with Microsoft's Provisioning Agent (PA) and
             the long-running Windows Guest Agent (WinGA, <c>WindowsAzureGuestAgent.exe</c>)
             per RFC 0008 + RFC 0014. PA owns the first wireserver Ready POST during
             OOBE; WinGA owns every Ready/heartbeat/extension/telemetry call after that
             indefinitely. The wireserver channel is never idle on a Microsoft-Windows
             image, so we never touch it. We run after PA completes and consume:
            
               (a) <c>C:\AzureData\CustomData.bin</c> — PA base64-decodes the ovf-env
                   CustomData element and writes the bytes verbatim. Not encrypted at
                   any layer (verified, see docs/research/azure-customdata-encryption.md).
                   Surfaced as <see cref="P:Eryph.GuestServices.Provisioning.DataSources.DataSourceResult.UserData"/> directly.
               (b) IMDS at <c>169.254.169.254</c> for live <c>compute.*</c> fields.
                   Distinct from wireserver (<c>168.63.129.16</c>), which we do NOT call.
               (c) ovf-env.xml from a still-mounted ConfigDrive — fallback for cases
                   where PA hasn't yet ejected the drive (rare on Azure post-PA).
            
             We MUST NOT signal Ready to the wireserver, post telemetry, or call any
             other wireserver endpoint — PA + WinGA own that channel.
             </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.DataSources.AzureDataSource.#ctor(Eryph.GuestServices.Provisioning.DataSources.IVolumeProbe,Eryph.GuestServices.Provisioning.DataSources.IPlatformProbe,Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.DataSources.AzureDataSource})">
            <summary>
            Production constructor. Azure detection flows through the injected
            <see cref="T:Eryph.GuestServices.Provisioning.DataSources.IPlatformProbe"/> so the host platform of a CI agent can't
            flip the gate under test.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.DataSources.AzureDataSource.#ctor(Eryph.GuestServices.Provisioning.DataSources.IVolumeProbe,Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.DataSources.AzureDataSource},System.Func{Eryph.GuestServices.Provisioning.DataSources.Azure.AzureImdsClient},System.Func{System.String,System.Boolean},System.Func{System.String,System.Threading.CancellationToken,System.Threading.Tasks.Task{System.Byte[]}},System.Action{System.String},System.Func{System.String,System.Boolean},System.Action{System.String},System.Func{System.Boolean},System.Func{System.String},System.Func{System.String,System.String},System.String,System.Func{System.Boolean})">
            <summary>
            Test seam: injectable IMDS client + file IO. The hardware-detection
            probes (registry / chassis) are NOT injected — tests run on a non-Azure
            CI host where both miss, exercising the NotApplicable branch.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.DataSources.AzureDataSource.PaReadinessProbe">
            <summary>
            Result of the three-signal PA-readiness probe. <c>IsReady</c> is true
            iff Windows OOBE has completed (ImageState), the Azure Windows Guest
            Agent service is Running (PA→WinGA handoff), and PA has written
            <c>C:\AzureData\CustomData.bin</c>. Any miss yields a human-readable
            reason for the WaitForReady the locator surfaces in its retry loop.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.DataSources.AzureDataSource.PaReadinessProbe.#ctor(System.Boolean,System.String)">
            <summary>
            Result of the three-signal PA-readiness probe. <c>IsReady</c> is true
            iff Windows OOBE has completed (ImageState), the Azure Windows Guest
            Agent service is Running (PA→WinGA handoff), and PA has written
            <c>C:\AzureData\CustomData.bin</c>. Any miss yields a human-readable
            reason for the WaitForReady the locator surfaces in its retry loop.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.DataSources.ConfigDriveDataSource.NormalizePubkeyData(System.Text.Json.JsonElement)">
            <summary>
            Clones cloud-init <c>normalize_pubkey_data</c>
            (cloudinit/sources/helpers/openstack.py): falsy/empty -&gt; [];
            string -&gt; splitlines(); list/set -&gt; the list as-is; dict -&gt; for
            each value, a string is treated as a single entry and a list/set
            contributes each non-empty entry, all flattened into one list;
            anything else -&gt; []. Entries are trimmed and empties dropped.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.DataSources.DataSourceLocator">
             <summary>
             Discovers the active datasource in cloud-init's priority order. Differs from
             cloud-init's "block on each source in turn" loop in two ways, both deliberate:
            
             <list type="bullet">
               <item>
                 <description>The total budget (<see cref="P:Eryph.GuestServices.Provisioning.Configuration.DataSourceSettings.ReadinessTimeoutMinutes"/>)
                 is shared across all sources. We don't want a slow Azure PA to eat the whole
                 deadline while NoCloud is sitting there with the answer.</description>
               </item>
               <item>
                 <description>Sources that report <c>WaitForReady</c> are interleaved: we probe
                 lower-priority sources during the wait so a stuck high-priority source can't
                 starve us. cloud-init has the same problem but solves it with platform-specific
                 timeouts; we treat it uniformly. See RFC 0004.</description>
               </item>
             </list>
             </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.DataSources.DataSourceResult.SshPublicKeys">
            <summary>
            SSH public keys supplied by the datasource metadata, e.g. OpenStack
            ConfigDrive <c>public_keys</c>; applied to the resolved default user,
            merged with cloud-config <c>ssh_authorized_keys</c>. cloud-init parity:
            <c>get_public_ssh_keys()</c>.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.DataSources.IPlatformProbe">
            <summary>
            Cheap platform indicators used by lower-priority datasources to decline when
            a platform-native datasource owns the chain. Injected (rather than read
            statically) so the ambient host platform — notably an Azure-hosted CI build
            agent — cannot flip the datasource probes under test.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.DataSources.OverrideDataSource">
            <summary>
            A datasource that always reports Ready with caller-supplied user-data and
            instance-id. Used by the CLI <c>run --user-data &lt;path&gt;</c> and
            <c>run --instance-id &lt;id&gt;</c> options. Registered ahead of the
            auto-discovery chain so it wins.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.DataSources.OverrideDataSource.#ctor(System.String,System.Byte[])">
            <summary>
            A datasource that always reports Ready with caller-supplied user-data and
            instance-id. Used by the CLI <c>run --user-data &lt;path&gt;</c> and
            <c>run --instance-id &lt;id&gt;</c> options. Registered ahead of the
            auto-discovery chain so it wins.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.DataSources.PlatformProbe">
            <summary>
            Default <see cref="T:Eryph.GuestServices.Provisioning.DataSources.IPlatformProbe"/> implementation. Production callers go
            through the injected interface so an Azure-hosted CI agent's ambient signals
            can't flip the datasource probes; this class holds the real registry/chassis
            detection.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.DataSources.PlatformProbes">
            <summary>
            Cheap platform indicators used by lower-priority datasources to decline
            when a platform-native datasource owns the chain. This is belt-and-suspenders
            on top of <see cref="P:Eryph.GuestServices.Provisioning.DataSources.IDataSource.Priority"/> ordering: even if Azure's
            datasource hasn't been fully implemented yet, NoCloud / ConfigDrive defer
            when an Azure context is detected so we don't accidentally claim a disk
            that belongs to Azure's Provisioning Agent.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Hosting.ModuleRegistry">
            <summary>
            Explicit compile-time list of every <see cref="T:Eryph.GuestServices.Provisioning.Modules.IModule"/> implementation
            in this assembly. Trim-safe because every entry is a rooted
            <c>typeof(T)</c> reference — no reflection over the assembly is needed.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Hosting.ProvisioningContainerBuilder">
            <summary>
            Composition root used by every CLI subcommand. The legacy <c>Program.Main</c>
            hosted everything in one place; with subcommands we instead build the
            container per command so dry-run can swap out the OS implementation without
            touching the rest of the graph.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Hosting.ProvisioningContainerBuilder.RegisterInto(SimpleInjector.Container,Eryph.GuestServices.Provisioning.Hosting.ProvisioningContainerOptions)">
            <summary>
            Registers the provisioning library's services into an existing
            SimpleInjector container. Used by <c>egs-service</c> to graft
            provisioning into its own composition root without building a separate
            container per command.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Hosting.ProvisioningContainerOptions.DryRun">
            <summary>
            When true the OS write methods are intercepted (see DryRunWindowsOs),
            state.json is not persisted, and KVP reporting is disabled. Reads still
            flow through to the real guest so handlers observe accurate state.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Hosting.ProvisioningContainerOptions.OverrideDataSource">
            <summary>
            Optional priority-zero datasource used to inject user-data / instance-id
            from the CLI. Prepended ahead of the discovery chain.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Hosting.ProvisioningHostedService">
            <summary>
            Runs provisioning once at host startup and then stays idle for the lifetime
            of the host. Unlike the previous standalone <c>egs-provisioning.exe</c>, this
            hosted service does NOT stop the host on success — the embedding service
            (<c>egs-service</c>) keeps running so the SSH server and other long-lived
            responsibilities remain available. The only outcome that triggers a host
            shutdown is <see cref="T:Eryph.GuestServices.Provisioning.Stages.StageRunOutcome.RebootRequested"/>, which spawns
            <c>shutdown.exe</c> and asks the host to stop cleanly.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Hosting.ProvisioningHostedService.#ctor(Eryph.GuestServices.Provisioning.Stages.IStageRunner,Microsoft.Extensions.Hosting.IHostApplicationLifetime,Eryph.GuestServices.Core.IServiceControlFlags,Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Hosting.ProvisioningHostedService})">
            <summary>
            Runs provisioning once at host startup and then stays idle for the lifetime
            of the host. Unlike the previous standalone <c>egs-provisioning.exe</c>, this
            hosted service does NOT stop the host on success — the embedding service
            (<c>egs-service</c>) keeps running so the SSH server and other long-lived
            responsibilities remain available. The only outcome that triggers a host
            shutdown is <see cref="T:Eryph.GuestServices.Provisioning.Stages.StageRunOutcome.RebootRequested"/>, which spawns
            <c>shutdown.exe</c> and asks the host to stop cleanly.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.ApplyNetworkConfigModule">
            <summary>
            Applies cloud-init network-config (v1 or v2) to the Windows guest. Matches
            adapters by MAC address; falls back to no-op for any adapter we cannot
            resolve. See <c>docs/rfcs/0002</c> for the schema mapping.
            </summary>
            <remarks>
            The module is idempotent: a re-run with the same input produces the same
            final state. It runs in the Network stage (<see cref="F:Eryph.GuestServices.Provisioning.Stages.Stage.Network"/>)
            after <c>SetHostnameModule</c> (Order=1) so the hostname change isn't
            disturbed by a possible network drop during DHCP-to-static transitions.
            </remarks>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.ApplyNetworkConfigModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.ApplyNetworkConfigModule})">
            <summary>
            Applies cloud-init network-config (v1 or v2) to the Windows guest. Matches
            adapters by MAC address; falls back to no-op for any adapter we cannot
            resolve. See <c>docs/rfcs/0002</c> for the schema mapping.
            </summary>
            <remarks>
            The module is idempotent: a re-run with the same input produces the same
            final state. It runs in the Network stage (<see cref="F:Eryph.GuestServices.Provisioning.Stages.Stage.Network"/>)
            after <c>SetHostnameModule</c> (Order=1) so the hostname change isn't
            disturbed by a possible network drop during DHCP-to-static transitions.
            </remarks>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.DefaultUserResolver">
            <summary>
            Layered resolution of the provisioning default user. See
            <see cref="T:Eryph.GuestServices.Provisioning.Modules.IDefaultUserResolver"/> for the concept. The first layer that
            yields a name wins.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.DefaultUserResolver.#ctor(Eryph.GuestServices.Provisioning.Configuration.ProvisioningSettings,Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.DefaultUserResolver})">
            <summary>
            Layered resolution of the provisioning default user. See
            <see cref="T:Eryph.GuestServices.Provisioning.Modules.IDefaultUserResolver"/> for the concept. The first layer that
            yields a name wins.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.FileScriptCheckpointStore">
            <summary>
            File-backed checkpoint store. Layout mirrors the semaphore store —
            scripts.json lives next to the per-instance sem/ directory.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.GrowpartModule">
            <summary>
            Cloud-init <c>growpart</c> for Windows: grows targeted volumes into any
            unallocated space behind them. Mirrors cloud-init's schema
            (<c>mode</c>, <c>devices</c>) and cloudbase-init's behaviour of extending
            volumes via the storage WMI provider — see <c>CimStorage</c>.
            </summary>
            <remarks>
            Runs per-boot: the host can resize the underlying VHD between reboots,
            so a per-instance gate would miss the most common operator workflow.
            Cloud-init's cc_growpart is also <c>per-always</c>.
            </remarks>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.GrowpartModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.GrowpartModule})">
            <summary>
            Cloud-init <c>growpart</c> for Windows: grows targeted volumes into any
            unallocated space behind them. Mirrors cloud-init's schema
            (<c>mode</c>, <c>devices</c>) and cloudbase-init's behaviour of extending
            volumes via the storage WMI provider — see <c>CimStorage</c>.
            </summary>
            <remarks>
            Runs per-boot: the host can resize the underlying VHD between reboots,
            so a per-instance gate would miss the most common operator workflow.
            Cloud-init's cc_growpart is also <c>per-always</c>.
            </remarks>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.IDefaultUserResolver">
            <summary>
            Resolves the account that top-level cloud-config shorthands
            (<c>ssh_authorized_keys</c>, <c>password</c>, the <c>chpasswd</c> shorthand)
            target when they do not name a user explicitly. This is the configurable
            "default user" concept, the eryph analogue of cloud-init's
            <c>system_info.default_user</c>. It is SEPARATE from the OS-level built-in
            Administrator that <c>disable_root</c> targets. See RFC 0018.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.IDefaultUserResolver.Resolve(Eryph.GuestServices.CloudConfig.CloudConfig,Eryph.GuestServices.Provisioning.DataSources.DataSourceResult)">
            <summary>
            Returns the name of the account top-level shorthands should target.
            Never returns null/empty — the final layer is an <c>"Administrator"</c>
            fallback.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.IModuleContext.DataSource">
            <summary>
            Raw datasource metadata for modules that need more than the parsed
            <c>CloudConfig</c>. Consumed today by:
            <list type="bullet">
              <item><see cref="T:Eryph.GuestServices.Provisioning.Modules.LicensingModule"/> — checks
              <c>PlatformMetadata.CloudName == "azure"</c> to skip the activation
              path (Azure handles activation natively).</item>
              <item><see cref="T:Eryph.GuestServices.Provisioning.Modules.ApplyNetworkConfigModule"/> — reads
              <c>StructuredNetworkConfig</c> to apply v1/v2 network-config.</item>
              <item><c>ScriptsUserModule</c> — reads <c>InstanceId</c> for per-
              instance checkpoint storage.</item>
            </list>
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.IScriptCheckpointStore">
             <summary>
             Persists per-script execution state for <see cref="T:Eryph.GuestServices.Provisioning.Modules.ScriptsUserModule"/>
             across reboot-and-continue cycles. A script is identified by (ordinal,
             body-hash) so an operator edit that keeps the ordinal but changes the
             body re-runs cleanly.
            
             Storage layout: <c>%ProgramData%\eryph\provisioning\instance\&lt;id&gt;\scripts.json</c>.
             See docs/bugs/0001-scriptsusermodule-skips-queue-after-reboot.md.
             </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.IScriptCheckpointStore.LoadAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Returns the on-disk checkpoint for the given instance, or
            <see cref="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpoint.Empty"/> when no checkpoint has ever been
            written. Implementations MUST tolerate a missing / corrupt file by
            returning <c>Empty</c> rather than throwing — a damaged file should
            not block a fresh run.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.IScriptCheckpointStore.SaveAsync(System.String,Eryph.GuestServices.Provisioning.Modules.ScriptCheckpoint,System.Threading.CancellationToken)">
            <summary>
            Persists the checkpoint. Implementations MUST write atomically
            (.tmp + rename) so a torn write cannot leave stale partial state.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.IScriptCheckpointStore.ResetAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Wipes the checkpoint for the given instance. Called when the instance
            id changes (alongside per-instance semaphore reset).
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.LicensingModule">
            <summary>
            Activates Windows on the guest. Default-on behaviours (no <c>license:</c>
            block required):
            <list type="bullet">
              <item>Install the AVMA key for the guest's OS edition. On a Datacenter
              Hyper-V host this activates the VM immediately; on any other host the
              key sits dormant and does no harm — so AVMA-on-by-default is safe.</item>
              <item>Run <c>slmgr /rearm</c> if the active product is an evaluation
              edition. Non-eval guests skip rearm so no rearm slot is burned.</item>
            </list>
            On Azure, the activation path (product key / AVMA / KMS / activate) is
            skipped because Azure handles activation natively; rearm still runs on
            evaluation editions because Azure does not extend evaluation grace
            periods. <c>license.force: true</c> overrides the Azure skip.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.LicensingModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.LicensingModule})">
            <summary>
            Activates Windows on the guest. Default-on behaviours (no <c>license:</c>
            block required):
            <list type="bullet">
              <item>Install the AVMA key for the guest's OS edition. On a Datacenter
              Hyper-V host this activates the VM immediately; on any other host the
              key sits dormant and does no harm — so AVMA-on-by-default is safe.</item>
              <item>Run <c>slmgr /rearm</c> if the active product is an evaluation
              edition. Non-eval guests skip rearm so no rearm slot is burned.</item>
            </list>
            On Azure, the activation path (product key / AVMA / KMS / activate) is
            skipped because Azure handles activation natively; rearm still runs on
            evaluation editions because Azure does not extend evaluation grace
            periods. <c>license.force: true</c> overrides the Azure skip.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.NtpClientModule">
            <summary>
            Mirrors cloudbase-init's <c>NTPClientPlugin</c> and the
            platform-independent parts of cloud-init's <c>cc_ntp</c>: configures the
            Windows Time service (<c>w32time</c>) and seeds its manual peer list
            from <c>ntp.servers</c> + <c>ntp.pools</c>.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.NtpClientModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.NtpClientModule})">
            <summary>
            Mirrors cloudbase-init's <c>NTPClientPlugin</c> and the
            platform-independent parts of cloud-init's <c>cc_ntp</c>: configures the
            Windows Time service (<c>w32time</c>) and seeds its manual peer list
            from <c>ntp.servers</c> + <c>ntp.pools</c>.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.NullScriptCheckpointStore">
            <summary>
            In-memory checkpoint store used by <c>--dry-run</c>. Tracks executed
            scripts for the duration of the current process so a dry-run reflects
            "what would resume look like" without touching disk.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.PowerStateModule">
            <summary>
            Mirrors cloud-init's <c>cc_power_state_change</c>: at the END of
            provisioning, optionally reboot / poweroff / hibernate after a
            configured delay. Distinct from exit-1003 reboot-and-continue, which
            is MID-stage; this module fires after every other Final module has
            already done its work and recorded its semaphores.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.PowerStateModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.PowerStateModule})">
            <summary>
            Mirrors cloud-init's <c>cc_power_state_change</c>: at the END of
            provisioning, optionally reboot / poweroff / hibernate after a
            configured delay. Distinct from exit-1003 reboot-and-continue, which
            is MID-stage; this module fires after every other Final module has
            already done its work and recorded its semaphores.
            </summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Modules.RuncmdModule.RebootRequestedExitCode">
            <summary>
            Exit code reserved by the cloudbase-init "reboot and continue"
            convention. eryph guests follow the same contract.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpoint">
            <summary>
            Durable per-script execution record used by <see cref="T:Eryph.GuestServices.Provisioning.Modules.ScriptsUserModule"/>
            to resume after a 1003 reboot-and-continue without re-running already
            executed scripts. See docs/bugs/0001-scriptsusermodule-skips-queue-after-reboot.md.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpoint.RebootCounts">
            <summary>
            Per-script reboot quota: number of times a given (ordinal, body-hash)
            pair has been recorded as having returned 1003 without subsequent
            progress. Exceeding the configured quota is treated as a hard failure
            (loop-safety per docs/bugs/0001).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpoint.ComputeBodyHash(System.Byte[])">
            <summary>
            Stable hash of the script body. SHA-256 of the raw bytes — purely an
            identity key, never compared cryptographically.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.ScriptCheckpoint">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.ScriptCheckpointEntry">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.DictionaryStringInt32">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.IReadOnlyListScriptCheckpointEntry">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.Int32">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.String">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.Default">
            <summary>
            The default <see cref="T:System.Text.Json.Serialization.JsonSerializerContext"/> associated with a default <see cref="T:System.Text.Json.JsonSerializerOptions"/> instance.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.GeneratedSerializerOptions">
            <summary>
            The source-generated options associated with this context.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.#ctor">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.#ctor(System.Text.Json.JsonSerializerOptions)">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.ScriptCheckpointJsonContext.GetTypeInfo(System.Type)">
            <inheritdoc/>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.ScriptsUserModule">
            <summary>
            Cloud-init's <c>cc_scripts_user</c> equivalent. Runs in the Final stage,
            executes every <see cref="T:Eryph.GuestServices.Provisioning.UserData.ScriptPayload"/> collected by the user-data
            pipeline. Two-phase pattern: Config-stage modules stage files / config;
            this Final-stage module runs the user-supplied scripts after everything
            else is settled.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.ScriptsUserModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.ScriptsUserModule},Eryph.GuestServices.Provisioning.Configuration.ProvisioningSettings,Eryph.GuestServices.Provisioning.Reporting.IReportingDispatcher,Eryph.GuestServices.Provisioning.Modules.IScriptCheckpointStore)">
            <summary>
            Cloud-init's <c>cc_scripts_user</c> equivalent. Runs in the Final stage,
            executes every <see cref="T:Eryph.GuestServices.Provisioning.UserData.ScriptPayload"/> collected by the user-data
            pipeline. Two-phase pattern: Config-stage modules stage files / config;
            this Final-stage module runs the user-supplied scripts after everything
            else is settled.
            </summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Modules.ScriptsUserModule.RebootRequestedExitCode">
            <summary>
            Exit code reserved by the cloudbase-init "reboot and continue"
            convention. Same value the RuncmdModule honors.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Modules.ScriptsUserModule.MaxRebootsPerScript">
            <summary>
            Per-script reboot quota. A given (ordinal, body-hash) may request
            reboot at most this many times before we fail the module — guards
            against a broken installer that returns 1003 indefinitely.
            docs/bugs/0001 "loop-safety". Sourced from
            ProvisioningSettings.Reboot.MaxPerScript (default 2).
            </summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Modules.ScriptsUserModule.LogsDirectory">
            <summary>
            Directory where per-script stdout/stderr logs are written. One log
            file per script, named after the staged script (so an operator can
            trivially correlate <c>001-enable_rd.ps1</c> in the scripts dir with
            <c>001-enable_rd.ps1.log</c> in the logs dir).
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.SetLocaleModule">
            <summary>
            Implements cloud-init's <c>cc_set_locale</c> and <c>cc_keyboard</c> on
            Windows. The <c>locale</c> scalar (e.g. <c>de-DE</c>) drives culture,
            UI language and the user language list; <c>keyboard.layout</c> drives
            the input method tip. Changing the SYSTEM locale (Win32 ANSI codepage)
            requires a reboot — surfaced via <see cref="T:Eryph.GuestServices.Provisioning.Modules.ModuleOutcome.RebootRequested"/>.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.SetLocaleModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.SetLocaleModule})">
            <summary>
            Implements cloud-init's <c>cc_set_locale</c> and <c>cc_keyboard</c> on
            Windows. The <c>locale</c> scalar (e.g. <c>de-DE</c>) drives culture,
            UI language and the user language list; <c>keyboard.layout</c> drives
            the input method tip. Changing the SYSTEM locale (Win32 ANSI codepage)
            requires a reboot — surfaced via <see cref="T:Eryph.GuestServices.Provisioning.Modules.ModuleOutcome.RebootRequested"/>.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.SshModule">
            <summary>
            Cloud-init <c>cc_ssh</c> equivalent for the OS-level Win32-OpenSSH daemon
            at <c>C:\ProgramData\ssh\</c> (NOT the egs-service Hyper-V-socket transport).
            Covers host keys, the <c>sshd_config.d</c> drop-in (<c>ssh_pwauth</c>,
            <c>disable_root</c>), per-user/top-level <c>authorized_keys</c> and host-key
            fingerprint reporting. See RFC 0018.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.SshModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.SshModule},Eryph.GuestServices.Provisioning.Reporting.IReportingDispatcher,Eryph.GuestServices.Provisioning.Modules.IDefaultUserResolver)">
            <summary>
            Cloud-init <c>cc_ssh</c> equivalent for the OS-level Win32-OpenSSH daemon
            at <c>C:\ProgramData\ssh\</c> (NOT the egs-service Hyper-V-socket transport).
            Covers host keys, the <c>sshd_config.d</c> drop-in (<c>ssh_pwauth</c>,
            <c>disable_root</c>), per-user/top-level <c>authorized_keys</c> and host-key
            fingerprint reporting. See RFC 0018.
            </summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Modules.SshModule.DropInFileName">
            <summary>Drop-in file name under <c>sshd_config.d</c>.</summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Modules.SshModule.DefaultGenKeyTypes">
            <summary>
            Default host-key set when <c>ssh_genkeytypes</c> is not supplied.
            ed25519-first, DSA dropped (removed in OpenSSH 9.8). RFC 0018.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.SshModule.ProcessHostKeysAsync(Eryph.GuestServices.CloudConfig.CloudConfig,Eryph.GuestServices.Provisioning.Modules.IModuleContext,System.Threading.CancellationToken)">
            <summary>
            Host-key step. Returns whether the host-key material changed and the
            fingerprints that should be reported.
            </summary>
            <remarks>
            We have no OS primitive to enumerate existing host keys, so we cannot
            "generate only the missing types". Because the module is
            <see cref="F:Eryph.GuestServices.Provisioning.Stages.ModuleFrequency.PerInstance"/> it runs once per instance and
            the semaphore prevents re-runs — so unconditional generation on the
            first instance boot is correct and not repeated. Supplied
            <c>ssh_keys</c> are written verbatim; we have no fingerprints for them
            (that would need an OS call we don't have), so only the regenerated set
            is reported.
            </remarks>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.SshModule.WriteSuppliedHostKeysAsync(System.Collections.Generic.IReadOnlyDictionary{System.String,System.String},Eryph.GuestServices.Provisioning.Modules.IModuleContext,System.Threading.CancellationToken)">
            <summary>
            Writes the operator-supplied <c>ssh_keys</c> flat dict. Keys look like
            <c>rsa_private</c> / <c>rsa_public</c> / <c>ecdsa_private</c> / … —
            paired by the <c>&lt;type&gt;</c> prefix. A private without a matching
            public is tolerated (public line written as null); <c>dsa</c> is warned
            and skipped. Returns true if at least one key was written.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.SshModule.ProcessDropInAsync(Eryph.GuestServices.CloudConfig.CloudConfig,Eryph.GuestServices.Provisioning.Modules.IModuleContext,System.Threading.CancellationToken)">
            <summary>
            Builds and writes the <c>50-eryph.conf</c> drop-in. Returns true if a
            drop-in with at least one directive was written.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.SudoPolicy">
            <summary>
            Shared Windows-side interpretation of cloud-init's <c>sudo</c> field.
            Extracted from <see cref="T:Eryph.GuestServices.Provisioning.Modules.UsersGroupsModule"/> so the
            <see cref="T:Eryph.GuestServices.Provisioning.Modules.IDefaultUserResolver"/> and the SshModule answer the
            "is this user an administrator" question identically.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.SudoPolicy.IsSudoEnabled(System.Collections.Generic.IReadOnlyList{System.String})">
            <summary>
            Cloud-init's <c>sudo</c> is a string-or-list union; the schema carries
            it as <c>IReadOnlyList&lt;string&gt;?</c>. This Windows-side shim
            collapses the list to the binary "is this user an Administrator"
            answer because there is no Windows equivalent of per-rule sudoers
            semantics (NOPASSWD, runas restrictions, command lists).
            <para>
            Decision rule (locked by tests): the user is promoted to
            Administrators if at least one non-empty entry exists that is not the
            literal string <c>"false"</c> (case-insensitive, trimmed). An entry of
            <c>"false"</c> mixed with other entries does NOT veto promotion — any
            non-false entry wins. Empty / null / list-of-only-"false" → no
            promotion. Per-rule sudoers semantics are platform-irrelevant on
            Windows and intentionally not modeled.
            </para>
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.TimezoneModule">
            <summary>
            Implements cloud-init's <c>cc_timezone</c> on Windows. Accepts either an
            IANA timezone (<c>Europe/Berlin</c>) or a Windows timezone key name
            (<c>W. Europe Standard Time</c>) and applies it via <c>tzutil</c>. The
            IANA→Windows translation is done by <see cref="T:System.TimeZoneInfo"/>; .NET 8+
            ships the CLDR mapping in the runtime so we don't need our own table.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.TimezoneModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.TimezoneModule})">
            <summary>
            Implements cloud-init's <c>cc_timezone</c> on Windows. Accepts either an
            IANA timezone (<c>Europe/Berlin</c>) or a Windows timezone key name
            (<c>W. Europe Standard Time</c>) and applies it via <c>tzutil</c>. The
            IANA→Windows translation is done by <see cref="T:System.TimeZoneInfo"/>; .NET 8+
            ships the CLDR mapping in the runtime so we don't need our own table.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.WriteFilesDeferredModule">
            <summary>
            Final-stage counterpart to <see cref="T:Eryph.GuestServices.Provisioning.Modules.WriteFilesModule"/>. Picks up the
            <c>write_files</c> entries marked <c>defer: true</c> and applies them
            after users / groups / passwords have been processed. Cloud-init's
            equivalent runs in <c>cc_write_files_deferred.py</c> at the same place
            in the run.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Modules.WriteFilesDeferredModule.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Modules.WriteFilesDeferredModule})">
            <summary>
            Final-stage counterpart to <see cref="T:Eryph.GuestServices.Provisioning.Modules.WriteFilesModule"/>. Picks up the
            <c>write_files</c> entries marked <c>defer: true</c> and applies them
            after users / groups / passwords have been processed. Cloud-init's
            equivalent runs in <c>cc_write_files_deferred.py</c> at the same place
            in the run.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Modules.WriteFilesProcessor">
            <summary>
            Shared per-entry writer used by both <see cref="T:Eryph.GuestServices.Provisioning.Modules.WriteFilesModule"/>
            (Config stage, non-deferred entries) and
            <see cref="T:Eryph.GuestServices.Provisioning.Modules.WriteFilesDeferredModule"/> (Final stage, deferred entries).
            Returns <c>null</c> on success or a <see cref="T:Eryph.GuestServices.Provisioning.Modules.ModuleOutcome.Failed"/>
            when the entry must abort the module (path traversal); other failures
            (encoding, ACL) log and continue.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Reporting.Events.ReportingEvent.SshHostKeysReported">
            <summary>
            Carries the ssh host-key fingerprints produced by the SshModule so an
            operator console can display them (RFC 0018). Gated by the cloud-config
            <c>ssh.emit_keys_to_console</c> flag at the producing site.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Reporting.Events.ReportingEvent.SshHostKeysReported.#ctor(System.Collections.Generic.IReadOnlyList{Eryph.GuestServices.Provisioning.Windows.SshHostKeyFingerprint})">
            <summary>
            Carries the ssh host-key fingerprints produced by the SshModule so an
            operator console can display them (RFC 0018). Gated by the cloud-config
            <c>ssh.emit_keys_to_console</c> flag at the producing site.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetector">
            <summary>
            Compares the current boot id (via <see cref="T:Eryph.GuestServices.Provisioning.Semaphores.IBootClock"/>) with the
            last-seen value persisted at
            <c>%ProgramData%\eryph\provisioning\last-seen-boot.json</c>. When the
            values differ — or no marker exists yet — the call is reported as a
            "new boot" and the per-boot semaphores are cleared.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetector.IsNewBootAsync(System.Threading.CancellationToken)">
            <summary>
            Returns <c>true</c> when this run is the first observation of a new
            boot session (the marker is absent OR the recorded boot id differs
            from the current one) and <c>false</c> otherwise.
            <para>
            Failure handling: when <see cref="M:Eryph.GuestServices.Provisioning.Semaphores.IBootClock.GetCurrentBootId"/>
            throws, the decision depends on whether the marker exists:
            <list type="bullet">
              <item><b>Marker absent</b> → return <c>true</c>. This is the
              first-ever run on the machine, so per-boot modules should run.</item>
              <item><b>Marker present</b> → return <c>false</c> (fail closed).
              The marker proves this isn't first boot; if we cannot determine
              the current boot id we'd rather suppress per-boot modules than
              re-run them every cycle on a system where the boot-id source is
              chronically broken (e.g. WMI in a degraded state).</item>
            </list>
            </para>
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetectorJsonContext.BootMarker">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetectorJsonContext.DateTimeOffset">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetectorJsonContext.String">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetectorJsonContext.Default">
            <summary>
            The default <see cref="T:System.Text.Json.Serialization.JsonSerializerContext"/> associated with a default <see cref="T:System.Text.Json.JsonSerializerOptions"/> instance.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetectorJsonContext.GeneratedSerializerOptions">
            <summary>
            The source-generated options associated with this context.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetectorJsonContext.#ctor">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetectorJsonContext.#ctor(System.Text.Json.JsonSerializerOptions)">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetectorJsonContext.GetTypeInfo(System.Type)">
            <inheritdoc/>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Semaphores.FileSemaphoreStore">
            <summary>
            File-system semaphore store. Layout mirrors cloud-init:
            <list type="bullet">
              <item><c>%ProgramData%\eryph\provisioning\instance\&lt;instance-id&gt;\sem\&lt;module&gt;.per-instance</c></item>
              <item><c>%ProgramData%\eryph\provisioning\sem\&lt;module&gt;.per-boot</c></item>
              <item><c>%ProgramData%\eryph\provisioning\sem\&lt;module&gt;.per-once</c></item>
            </list>
            File contents are a JSON line with timestamp / instance / outcome for
            post-mortem inspection; gating is done on existence alone.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.SemaphoreStoreJsonContext.SemaphoreRecord">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.SemaphoreStoreJsonContext.DateTimeOffset">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.SemaphoreStoreJsonContext.String">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.SemaphoreStoreJsonContext.Default">
            <summary>
            The default <see cref="T:System.Text.Json.Serialization.JsonSerializerContext"/> associated with a default <see cref="T:System.Text.Json.JsonSerializerOptions"/> instance.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Semaphores.SemaphoreStoreJsonContext.GeneratedSerializerOptions">
            <summary>
            The source-generated options associated with this context.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.SemaphoreStoreJsonContext.#ctor">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.SemaphoreStoreJsonContext.#ctor(System.Text.Json.JsonSerializerOptions)">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.SemaphoreStoreJsonContext.GetTypeInfo(System.Type)">
            <inheritdoc/>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Semaphores.IBootClock">
            <summary>
            Exposes a "boot identifier" that changes whenever the host reboots.
            Pulled out behind an interface so <see cref="T:Eryph.GuestServices.Provisioning.Semaphores.BootSessionDetector"/> can
            be exercised with a fake clock in unit tests; the production
            implementation reads <c>Win32_OperatingSystem.LastBootUpTime</c>.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.IBootClock.GetCurrentBootId">
            <summary>
            Returns a stable, comparable identifier for the current boot. Two
            calls within the same boot return the same value; two calls across
            a reboot return different values.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Semaphores.IBootSessionDetector">
            <summary>
            Detects whether the current process is running in a different boot
            session than the last time the provisioning agent ran. Used to clear
            <see cref="F:Eryph.GuestServices.Provisioning.Stages.ModuleFrequency.PerBoot"/> semaphores at the start
            of each boot.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.IBootSessionDetector.IsNewBootAsync(System.Threading.CancellationToken)">
            <summary>
            Returns <c>true</c> the first time the agent observes a particular
            boot session; subsequent calls within the same boot return
            <c>false</c>. The implementation persists the last-observed boot
            marker so the detection survives agent restarts within a single boot.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore">
            <summary>
            Tracks per-module completion semaphores, mirroring cloud-init's
            <c>/var/lib/cloud/instance/sem/&lt;module&gt;.&lt;freq&gt;</c> and
            <c>/var/lib/cloud/sem/&lt;module&gt;.&lt;freq&gt;</c> layout.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore.ExistsAsync(System.String,Eryph.GuestServices.Provisioning.Stages.ModuleFrequency,System.String,System.Threading.CancellationToken)">
            <summary>
            Returns <c>true</c> when a marker exists for (module, frequency,
            instance) — meaning the module has been recorded in some terminal-ish
            state. Callers that need to distinguish <c>"completed"</c> from
            <c>"reboot-requested"</c> must use <see cref="M:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore.ReadOutcomeAsync(System.String,Eryph.GuestServices.Provisioning.Stages.ModuleFrequency,System.String,System.Threading.CancellationToken)"/>.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore.ReadOutcomeAsync(System.String,Eryph.GuestServices.Provisioning.Stages.ModuleFrequency,System.String,System.Threading.CancellationToken)">
            <summary>
            Returns the outcome string written by the most recent
            <see cref="M:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore.WriteAsync(System.String,Eryph.GuestServices.Provisioning.Stages.ModuleFrequency,System.String,System.String,System.Threading.CancellationToken)"/>, or <c>null</c> when no marker exists for
            (module, frequency, instance). The StageRunner uses this to skip on
            <c>"completed"</c> and resume on <c>"reboot-requested"</c>.
            docs/bugs/0001 documents the bug this method was introduced to fix.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore.WriteAsync(System.String,Eryph.GuestServices.Provisioning.Stages.ModuleFrequency,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Writes the marker file. Must be called BEFORE returning from a
            reboot-and-continue path, so the post-reboot pass does not re-run the
            module.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore.ListPerInstanceAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Lists the module keys that have a per-instance marker for the given
            instance. Used to project the <c>CompletedHandlers</c> view back into
            <c>state.json</c> for compatibility with v1 callers.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore.ClearPerInstanceAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Clears all per-instance markers for the given instance. Called when
            the instance-id changes (matches cloud-init wiping the instance
            directory between deploys).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore.ClearPerBootAsync(System.Threading.CancellationToken)">
            <summary>
            Clears all per-boot markers. Called at the start of every new boot
            session (see <c>IBootSessionDetector</c>).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore.ClearPerOnceAsync(System.Threading.CancellationToken)">
            <summary>
            Clears all per-once markers. Only invoked by an explicit operator
            action — <c>egs-tool reset --reset-once</c>.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Semaphores.NullSemaphoreStore">
            <summary>
            In-memory semaphore store used by <c>--dry-run</c>. Tracks completion
            for the duration of the current process so the StageRunner can observe
            its own progress, but never writes to disk. Mirrors the
            <see cref="T:Eryph.GuestServices.Provisioning.State.NullStateStore"/> pattern.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Semaphores.Win32BootClock">
            <summary>
            Reads <c>Win32_OperatingSystem.LastBootUpTime</c> via CIM. Chosen over
            the undocumented <c>HKLM\...\Session Manager\Memory Management\BootId</c>
            because LastBootUpTime is a documented Win32 property that is updated
            on every cold boot AND on resume-from-hibernate. The registry
            <c>BootId</c> is incremented on cold boot but the semantics around
            hibernate / fast-startup are not documented.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Serialization.CloudConfigSerializer">
             <summary>
             Deserializes cloud-config YAML and emits a complete "what did the YAML
             carry that the agent did not act on?" inventory at the right log levels:
            
             - Truly unknown keys (typos, vendor extensions) → Warning. The schema
               does not list them; most likely the operator made a mistake.
             - Acknowledged-but-no-op keys (Linux package managers, /etc/hosts
               management, deferred-implementation keys, future-module placeholders)
               → Information. They parse cleanly via the schema but produce no
               Windows behaviour. Operators need an audit trail without warning
               noise; cross-cloud YAML routinely carries these.
            
             Both halves live here because they are two sides of the same concern.
             The previous implementation split tier-2 into a fake `LinuxKeysModule`,
             which misled operators ("a module that handles Linux keys?") and pinned
             dead per-instance semaphore state for what is purely observational
             logging.
             </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Serialization.CloudConfigSerializer.#ctor(Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Serialization.CloudConfigSerializer})">
             <summary>
             Deserializes cloud-config YAML and emits a complete "what did the YAML
             carry that the agent did not act on?" inventory at the right log levels:
            
             - Truly unknown keys (typos, vendor extensions) → Warning. The schema
               does not list them; most likely the operator made a mistake.
             - Acknowledged-but-no-op keys (Linux package managers, /etc/hosts
               management, deferred-implementation keys, future-module placeholders)
               → Information. They parse cleanly via the schema but produce no
               Windows behaviour. Operators need an audit trail without warning
               noise; cross-cloud YAML routinely carries these.
            
             Both halves live here because they are two sides of the same concern.
             The previous implementation split tier-2 into a fake `LinuxKeysModule`,
             which misled operators ("a module that handles Linux keys?") and pinned
             dead per-instance semaphore state for what is purely observational
             logging.
             </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Stages.IStageRunner.RunStageAsync(Eryph.GuestServices.Provisioning.Stages.Stage,System.Threading.CancellationToken)">
            <summary>
            Runs only the requested stage (plus the mandatory data-source discovery
            pre-step). Other stages are skipped entirely. Useful for the CLI
            <c>run --stage</c> option so operators can re-run a single stage in
            isolation.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Stages.ModuleFrequency">
            <summary>
            How often a module is allowed to run, mirroring cloud-init's three
            frequencies. Stored as a semaphore on disk; <see cref="T:Eryph.GuestServices.Provisioning.Semaphores.ISemaphoreStore"/>
            gates execution before <c>IModule.ApplyAsync</c> is invoked.
            </summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Stages.ModuleFrequency.PerInstance">
            <summary>
            Runs once per instance-id. The common case: configuration that survives
            reboots but should re-apply if the instance is redeployed (instance-id
            changes). Semaphore lives at
            <c>%ProgramData%\eryph\provisioning\instance\&lt;instance-id&gt;\sem\&lt;module&gt;.per-instance</c>.
            </summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Stages.ModuleFrequency.PerBoot">
            <summary>
            Runs every boot. Semaphore lives at
            <c>%ProgramData%\eryph\provisioning\sem\&lt;module&gt;.per-boot</c>
            and is cleared at the start of every new boot session.
            </summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Stages.ModuleFrequency.PerOnce">
            <summary>
            Runs exactly once on this filesystem, regardless of instance-id changes.
            Semaphore lives at
            <c>%ProgramData%\eryph\provisioning\sem\&lt;module&gt;.per-once</c>
            and is never cleared automatically. Use for one-shot setup that must
            survive redeploys (e.g. seeding a host-only secret).
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Stages.StageAttribute.Frequency">
            <summary>
            How often the module is allowed to run. Defaults to
            <see cref="F:Eryph.GuestServices.Provisioning.Stages.ModuleFrequency.PerInstance"/>, matching cloud-init's default.
            Make this explicit on every module — the choice should be deliberate
            (per-instance config, per-boot housekeeping, per-once seed).
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.ProvisioningState">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.DictionaryStringInt32">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.HashSetString">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.DateTimeOffset">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.Int32">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.String">
            <summary>
            Defines the source generated JSON serialization contract metadata for a given type.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.Default">
            <summary>
            The default <see cref="T:System.Text.Json.Serialization.JsonSerializerContext"/> associated with a default <see cref="T:System.Text.Json.JsonSerializerOptions"/> instance.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.GeneratedSerializerOptions">
            <summary>
            The source-generated options associated with this context.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.#ctor">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.#ctor(System.Text.Json.JsonSerializerOptions)">
            <inheritdoc/>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.State.StateStoreJsonContext.GetTypeInfo(System.Type)">
            <inheritdoc/>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.State.NullStateStore">
            <summary>
            In-memory state store used by <c>--dry-run</c>. Keeps the current
            <see cref="T:Eryph.GuestServices.Provisioning.State.ProvisioningState"/> alive for the duration of the run so
            the stage runner can observe its own progress, but never touches disk.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.ProvisioningState.CompletedHandlers">
             <summary>
             Deprecated: kept for one release to ease the migration from the
             single-blob state file to per-module semaphores
             (<c>%ProgramData%\eryph\provisioning\instance\&lt;id&gt;\sem\&lt;module&gt;.per-instance</c>).
             On startup the stage runner reads any handler keys here, writes the
             equivalent per-instance semaphore files, then keeps the list in sync
             as a redundant view. New code should consult <c>ISemaphoreStore</c>
             directly. Remove this field once all rolled-out agents have migrated.
            
             Only handlers that have reached <c>Completed</c> appear here. A handler
             that returned <c>RebootRequested</c> shows up in <see cref="P:Eryph.GuestServices.Provisioning.State.ProvisioningState.PendingHandlers"/>
             until it completes its post-reboot resume. Pre-fix, both states were
             indistinguishable (docs/bugs/0001).
             </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.ProvisioningState.PendingHandlers">
            <summary>
            Handlers that have returned <see cref="T:Eryph.GuestServices.Provisioning.Modules.ModuleOutcome.RebootRequested"/>
            at least once and are still waiting to resume. Promoted to
            <see cref="P:Eryph.GuestServices.Provisioning.State.ProvisioningState.CompletedHandlers"/> on the run after the reboot if the
            re-entered module returns <see cref="T:Eryph.GuestServices.Provisioning.Modules.ModuleOutcome.Completed"/>.
            Distinct from <c>CompletedHandlers</c> so external consumers (eryph-genes
            Pester) can tell "all done" from "stuck pending reboot resume".
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.State.ProvisioningState.ModuleRebootCounts">
            <summary>
            Per-module count of how many times the StageRunner has seen a
            <see cref="T:Eryph.GuestServices.Provisioning.Modules.ModuleOutcome.RebootRequested"/> outcome for that
            module key on this instance. Capped via <see cref="!:StageRunner"/>'s
            per-module limit so a script that keeps returning 1003 fails the run
            instead of looping forever (docs/bugs/0001 "loop-safety").
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.UserData.ScriptKindDetector">
            <summary>
            Decides how a shell-script user-data part should be dispatched. Mirrors the
            real-world cloudbase-init dispatch rules (filename-led, NOT shebang-led)
            because the eryph gene corpus has been crafted around two cbi bugs:
            parts without <c>filename=</c> are dropped, and cbi ignores shebangs.
            See <c>docs/rfcs/0007-scripts-per-frequency-edge-cases.md</c> and the
            <c>cbi-compat-constraints</c> memory.
            </summary>
            <remarks>
            <para>Detection priority (Windows guest):</para>
            <list type="number">
              <item>filename extension (<c>.ps1</c>, <c>.cmd</c>/<c>.bat</c>; <c>.sh</c>
                    is recognised but resolved to <see cref="F:Eryph.GuestServices.Provisioning.UserData.ScriptKind.Other"/> on
                    Windows with a warning since no POSIX shell is available).</item>
              <item>shebang on the first non-empty body line (<c>#ps1_sysnative</c>,
                    <c>#ps1</c>; <c>#!/...</c> is recognised but resolved to
                    <see cref="F:Eryph.GuestServices.Provisioning.UserData.ScriptKind.Other"/> on Windows for the same reason).</item>
              <item>content-type parameter (<c>text/x-shellscript</c> falls back to
                    PowerShell on Windows with a warning logged).</item>
              <item>otherwise <see cref="F:Eryph.GuestServices.Provisioning.UserData.ScriptKind.Other"/> with a warning logged so
                    the operator can see the part was skipped — never a silent drop.</item>
            </list>
            </remarks>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.UserData.UserDataEncoding">
            <summary>
            UTF-8 decoding helper for user-data parts. PowerShell's
            <c>Set-Content -Encoding UTF8</c> writes a BOM-prefixed payload; if the
            BOM survives into the per-handler decode, YamlDotNet rejects the
            cloud-config (U+FEFF before <c>#cloud-config</c>), the include parser
            fails to recognise the marker (line no longer starts with
            <c>#include</c>), and the MIME parser misreads the first header line.
            Stripping the BOM here keeps every downstream parser on the same byte
            alignment as cloud-init's PyYAML, which ignores a leading BOM.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.UserData.UserDataEncoding.DecodeUtf8(System.Byte[])">
            <summary>Decode bytes as UTF-8, skipping a leading UTF-8 BOM if present.</summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.DryRunWindowsOs">
            <summary>
            Decorator over <see cref="T:Eryph.GuestServices.Provisioning.Windows.IWindowsOs"/> used by <c>egs-provisioning run --dry-run</c>.
            Read methods pass through to the wrapped implementation so handlers see the
            real guest state; write methods log a structured "DRY-RUN would..." message
            at Information level and return success-like values without mutating anything.
            </summary>
            <remarks>
            The decorator is registered with <see cref="T:Eryph.GuestServices.Provisioning.Windows.WindowsOs"/> as its inner
            dependency in production (see <c>ProvisioningContainerBuilder</c>). Tests
            substitute the inner <see cref="T:Eryph.GuestServices.Provisioning.Windows.IWindowsOs"/> to assert that write methods
            are intercepted.
            </remarks>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.DryRunWindowsOs.#ctor(Eryph.GuestServices.Provisioning.Windows.IWindowsOs,Microsoft.Extensions.Logging.ILogger{Eryph.GuestServices.Provisioning.Windows.DryRunWindowsOs})">
            <summary>
            Decorator over <see cref="T:Eryph.GuestServices.Provisioning.Windows.IWindowsOs"/> used by <c>egs-provisioning run --dry-run</c>.
            Read methods pass through to the wrapped implementation so handlers see the
            real guest state; write methods log a structured "DRY-RUN would..." message
            at Information level and return success-like values without mutating anything.
            </summary>
            <remarks>
            The decorator is registered with <see cref="T:Eryph.GuestServices.Provisioning.Windows.WindowsOs"/> as its inner
            dependency in production (see <c>ProvisioningContainerBuilder</c>). Tests
            substitute the inner <see cref="T:Eryph.GuestServices.Provisioning.Windows.IWindowsOs"/> to assert that write methods
            are intercepted.
            </remarks>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.IWindowsOs">
            <summary>
            Pure abstraction over the Windows guest OS operations needed by the
            provisioning handlers. The concrete implementation lives in
            <see cref="T:Eryph.GuestServices.Provisioning.Windows.WindowsOs"/>; tests substitute this interface.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.EnsureUserInAdministratorsAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Adds the user to the local Administrators group, looked up via the
            well-known SID <c>S-1-5-32-544</c> so the operation works on localized
            Windows installs (e.g. "Administradores" on Spanish Windows).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetFileOwnerAsync(System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Sets the owner (and optional group) of a file. Format: <c>"user"</c>,
            <c>"user:group"</c>. The group component is currently ignored on Windows.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetPosixPermissionsAsync(System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Translates a POSIX octal permission string (e.g. <c>"0644"</c>) into
            NTFS ACEs for owner / group / Everyone and applies them to the file.
            SYSTEM and Administrators retain FullControl (they're added/preserved
            in the DACL) so the agent and system processes can always read the
            file regardless of the POSIX bits. Cloudbase-init does the same.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetUserSshAuthorizedKeysAsync(System.String,System.Collections.Generic.IReadOnlyList{System.String},System.Threading.CancellationToken)">
            <summary>
            For users in the local Administrators group writes the keys to
            <c>%ProgramData%\ssh\administrators_authorized_keys</c> (per the
            Windows OpenSSH rules). For other users writes to
            <c>C:\Users\&lt;user&gt;\.ssh\authorized_keys</c>.
            </summary>
            <remarks>
            MERGE semantics (RFC 0018): the supplied keys are unioned with the
            existing file content, deduplicated by the normalized key body
            (<c>&lt;type&gt; &lt;base64&gt;</c>, ignoring the trailing comment).
            Existing line order is preserved; genuinely new keys are appended.
            An empty input with no existing file is a no-op (no empty file is
            created). ACL hardening is re-applied after the write.
            </remarks>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.IsSshdInstalledAsync(System.Threading.CancellationToken)">
            <summary>
            True when the Win32-OpenSSH <c>sshd</c> service is installed (its
            Win32_Service entry exists, regardless of run state).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.InstallOpenSshServerAsync(System.Threading.CancellationToken)">
            <summary>
            Installs the OpenSSH server capability
            (<c>Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0</c>)
            and sets the <c>sshd</c> service start mode to Automatic. No-op when
            sshd is already installed.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.RegenerateSshHostKeysAsync(System.Collections.Generic.IReadOnlyList{System.String},System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Generates ssh host keys for each requested type (validated against
            <c>{ed25519, ecdsa, rsa}</c>; <c>dsa</c> / unknown types are warned and
            skipped). RSA is generated at 3072 bits. When
            <paramref name="deleteExisting"/> is true the existing
            <c>ssh_host_*_key{,.pub}</c> files are removed first. Each private key
            is ACL-hardened. Returns the fingerprints of the keys produced.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.WriteSshHostKeyAsync(System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Writes an operator-supplied host key:
            <c>C:\ProgramData\ssh\ssh_host_&lt;keyType&gt;_key</c> (private PEM) and,
            when <paramref name="publicLine"/> is supplied, the matching
            <c>.pub</c>. The private key is ACL-hardened (owner SYSTEM;
            SYSTEM + Administrators FullControl).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.EnsureSshdConfigIncludeAsync(System.Threading.CancellationToken)">
            <summary>
            Idempotently ensures <c>C:\ProgramData\ssh\sshd_config</c> contains an
            uncommented <c>Include sshd_config.d/*.conf</c> directive at the top
            (so our drop-in's first-obtained-value settings win over shipped
            directives). Creates the <c>sshd_config.d</c> directory.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.WriteSshdDropInAsync(System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Writes a drop-in config file under
            <c>C:\ProgramData\ssh\sshd_config.d\&lt;dropInFileName&gt;</c> (UTF-8,
            LF line endings).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.RestartSshdAsync(System.Threading.CancellationToken)">
            <summary>
            Restarts the <c>sshd</c> service (stop + start) so it re-reads its
            config. Tolerates sshd not being installed (logs and returns).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.ResolveBuiltinAdministratorNameAsync(System.Threading.CancellationToken)">
            <summary>
            Resolves the on-disk name of the built-in Administrator account
            (RID 500) via its SID so the lookup survives a rename. Falls back to
            <c>"Administrator"</c> (with a Warning) when the SID cannot be resolved.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.TranslateUnixPath(System.String)">
            <summary>
            Translates a cloud-init style unix path to a Windows path. See the
            implementation header for the exact mapping.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.ExpandEnvironmentVariables(System.String)">
            <summary>
            Expands environment-variable references (e.g. <c>%ProgramData%</c>) in
            <paramref name="value"/>. Routed through the OS abstraction so modules
            stay host-OS independent — <c>Environment.ExpandEnvironmentVariables</c>
            is a no-op on non-Windows hosts, which silently breaks paths during
            tests. The production implementation calls the Win32 expander.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.GetSystemDriveLetter">
            <summary>
            Returns the system-drive letter (e.g. <c>'C'</c>) resolved from
            <c>%SystemDrive%</c>, uppercased. Null when it cannot be resolved.
            Routed through the OS abstraction so the value is mockable and the
            resolution does not depend on the host's environment.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.GetNetworkAdaptersAsync(System.Threading.CancellationToken)">
            <summary>
            Enumerates the network adapters on this guest. The result is intended
            for MAC-matching against cloud-init network-config and includes both
            physical and virtual adapters; callers should filter on
            <see cref="P:Eryph.GuestServices.Provisioning.Windows.NetworkAdapterInfo.IsPhysical"/> when only hardware NICs
            are relevant.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.EnableDhcpAsync(System.Int32,System.Threading.CancellationToken)">
            <summary>
            Puts the IPv4 client on the given adapter back into DHCP mode and
            removes any explicit static addresses / gateways carried over from a
            previous static configuration. Idempotent.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.DisableDhcpAsync(System.Int32,System.Threading.CancellationToken)">
            <summary>
            Switches the IPv4 client on the given adapter to manual addressing and
            removes any DHCP-leased addresses. Idempotent — calling twice is a no-op.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetStaticIpv4AddressesAsync(System.Int32,System.Collections.Generic.IReadOnlyList{System.String},System.Threading.CancellationToken)">
            <summary>
            Sets the IPv4 addresses on the given adapter so that the resulting set
            equals <paramref name="addresses"/>. Each entry is a CIDR string (e.g.
            <c>"10.0.0.5/24"</c>). Existing addresses that are not in the desired
            set are removed. Implies DHCP-off for IPv4.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetIpv4DefaultGatewayAsync(System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Sets the IPv4 default gateway on the given adapter. Removes any
            pre-existing default route on the same interface so the result is the
            single requested gateway. Pass null to clear the default route.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetDnsServersAsync(System.Int32,System.Collections.Generic.IReadOnlyList{System.String},System.Threading.CancellationToken)">
            <summary>
            Sets the DNS server list on the given adapter. Empty list resets the
            adapter to "obtain DNS automatically" (DHCP-driven). Address family is
            inferred from each entry.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.EnableDhcp6Async(System.Int32,System.Threading.CancellationToken)">
            <summary>
            IPv6 counterpart to <see cref="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.EnableDhcpAsync(System.Int32,System.Threading.CancellationToken)"/>: turns DHCPv6 on for
            the adapter and removes any explicit static IPv6 addresses carried over
            from a previous run. Idempotent.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.DisableDhcp6Async(System.Int32,System.Threading.CancellationToken)">
            <summary>
            IPv6 counterpart to <see cref="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.DisableDhcpAsync(System.Int32,System.Threading.CancellationToken)"/>: switches the IPv6
            client on the given adapter to manual addressing and removes any
            DHCPv6-leased addresses. Idempotent.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetStaticIpv6AddressesAsync(System.Int32,System.Collections.Generic.IReadOnlyList{System.String},System.Threading.CancellationToken)">
            <summary>
            Sets the IPv6 addresses on the given adapter so that the resulting set
            equals <paramref name="addresses"/>. Each entry is a CIDR string (e.g.
            <c>"2001:db8::1/64"</c>). Existing addresses that are not in the desired
            set are removed. Implies DHCPv6-off for the adapter.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetIpv6DefaultGatewayAsync(System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Sets the IPv6 default gateway on the given adapter. Removes any
            pre-existing default route on the same interface so the result is the
            single requested gateway. Pass null to clear the default route.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetInterfaceRoutesAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Eryph.GuestServices.CloudConfig.NetworkRoute},System.Threading.CancellationToken)">
            <summary>
            Applies the per-interface route list. Address family is inferred from
            each route's destination prefix (<c>":"</c> => IPv6, else IPv4). The
            implementation removes any existing routes on the interface that match
            a destination we're about to add (so re-runs with the same list produce
            the same end state). Empty list is a no-op.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetDnsSearchSuffixesAsync(System.Int32,System.Collections.Generic.IReadOnlyList{System.String},System.Threading.CancellationToken)">
            <summary>
            Applies cloud-init's per-interface DNS <c>search</c> list. On Windows
            the model is a compromise:
            <list type="bullet">
              <item>The first entry becomes the connection-specific suffix on the
              interface (the only per-NIC suffix Windows supports).</item>
              <item>Every entry is merged (deduped, order-preserving) into the
              machine-wide <c>SuffixSearchList</c> so resolvers actually consult them.</item>
            </list>
            Empty list is a no-op (we do NOT clear an operator-tuned search list).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetInterfaceMtuAsync(System.Int32,System.Int32,System.Threading.CancellationToken)">
            <summary>
            Sets the MTU on the given adapter (IPv4 + IPv6 interface). No-op when
            <paramref name="mtu"/> already matches the current value.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.ExtendVolumesAsync(System.Collections.Generic.IReadOnlySet{System.Char},System.Threading.CancellationToken)">
            <summary>
            Refreshes every disk's geometry (so a guest that booted after the host
            enlarged the underlying VHD picks up the new size — the GPT secondary
            header migration cbi does not perform) and then resizes every targeted
            partition to the maximum size the platform supports.
            <para>
            <paramref name="driveLetterFilter"/> is null when the caller wants every
            growable volume; otherwise it lists uppercase drive letters to target.
            Volumes without a drive letter are only considered when the filter is null.
            </para>
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.ConfigureNtpClientAsync(System.Boolean,System.Collections.Generic.IReadOnlyList{System.String},System.Threading.CancellationToken)">
            <summary>
            Configures the Windows Time service (<c>w32time</c>). When
            <paramref name="enabled"/> is true the service is set to
            <c>Automatic</c>, started, the SCM triggers are reset so it follows
            network availability (cloudbase-init parity), and the manual peer
            list is set to the union of <paramref name="peers"/>. When false
            the service is stopped and set to <c>Disabled</c>.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.SetRealTimeClockUtcAsync(System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Writes
            <c>HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal</c>.
            <c>true</c> tells Windows to interpret the real-time clock as UTC;
            <c>false</c> means "local time" (Windows default). Mirrors
            cloudbase-init's <c>set_real_time_clock_utc</c>.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.RearmLicenseAsync(System.Threading.CancellationToken)">
            <summary>
            Runs <c>slmgr /rearm</c>. Returns whether a reboot is required (per
            Microsoft docs the answer is always "yes" after a successful rearm,
            but the OS layer is authoritative — the module just relays).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.ResolveVolumeActivationKeyAsync(Eryph.GuestServices.Provisioning.Windows.VolumeActivationKeyType,System.Threading.CancellationToken)">
            <summary>
            Resolves the volume-activation key for the guest's current OS
            edition. Returns null when no key is known (unsupported OS family,
            non-Server SKU, or pre-2012R2 for AVMA). The module decides what to
            do with a null result — usually surface as failure with a hint.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.IsEvaluationLicenseAsync(System.Threading.CancellationToken)">
            <summary>
            True when the active Windows product is an evaluation edition (its
            SoftwareLicensingProduct entry carries TIMEBASED_EVAL or has a real
            EvaluationEndDate). Used by the licensing module to gate
            <c>slmgr /rearm</c> so non-eval guests don't burn a rearm slot.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.LicenseSpec">
            <summary>
            Resolved licensing state passed to <see cref="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.ApplyLicenseAsync(Eryph.GuestServices.Provisioning.Windows.LicenseSpec,System.Threading.CancellationToken)"/>.
            The module computes this from the cloud-config (auto-detecting AVMA / KMS
            keys against the OS edition) — by the time it reaches the OS layer all
            indirection (set_avma, set_kms) is gone, leaving only "what to apply".
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.LicenseSpec.ClearKmsHost">
            <summary>
            When true, clears the configured KMS host (<c>slmgr /ckms</c>) so
            DNS SRV auto-discovery takes over. Only honoured when
            <see cref="P:Eryph.GuestServices.Provisioning.Windows.LicenseSpec.KmsHost"/> is null — supplying both would be ambiguous.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.LicenseSpec.Activate">
            <summary>
            When true, run <c>slmgr /ato</c> after applying the key and KMS host.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.RearmResult.RebootRequired">
            <summary>
            Microsoft documents that <c>slmgr /rearm</c> requires a reboot for
            the extension to take effect. Always true after a successful rearm.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.VolumeActivationKeyType">
            <summary>
            Identifies the volume-activation key set to resolve against the guest's
            OS edition. Mirrors the two distinct tables cloudbase-init carries.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Licensing.CimLicensing">
            <summary>
            Thin wrapper around the <c>SoftwareLicensingProduct</c> WMI class —
            the same surface cloudbase-init queries to identify the active
            KMS-client product and its license family.
            </summary>
            <remarks>
            Windows ships a row per registered license entry. The one with
            <c>VOLUME_KMSCLIENT</c> in its Description AND a non-empty
            <c>PartialProductKey</c> is the "current" product — its
            <c>LicenseFamily</c> drives our AVMA/KMS table lookup.
            </remarks>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.Licensing.KmsClientProduct.EvaluationEndDate">
            <summary>
            WMI surfaces this as a CIM datetime string. The sentinel
            <c>16010101000000.000000-000</c> means "never expires" (i.e. a
            non-evaluation product). Any other value indicates an evaluation
            license whose <c>slmgr /rearm</c> matters.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Licensing.OsVersionDetector">
            <summary>
            Detects the Windows Server family by mapping
            <see cref="P:System.Environment.OSVersion"/> build numbers to an
            <see cref="T:Eryph.GuestServices.Provisioning.Windows.Licensing.OsVersionFamily"/>. .NET 5+ no longer clamps the manifest
            version so the real build number is available here without any P/Invoke.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Licensing.VolumeActivationKeys">
            <summary>
            Volume-activation product key tables. Verified against Microsoft Learn:
            <list type="bullet">
              <item>AVMA — <c>learn.microsoft.com/en-us/windows-server/get-started/automatic-vm-activation</c></item>
              <item>KMS — <c>learn.microsoft.com/en-us/windows-server/get-started/kms-client-activation-keys</c></item>
            </list>
            </summary>
            <remarks>
            These keys are <b>public</b>. Microsoft publishes them for the explicit
            purpose of letting volume-license customers activate Windows guests.
            They are not secrets and including them here is the same model
            cloudbase-init has shipped since 2017.
            </remarks>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Licensing.OsVersionFamily">
            <summary>
            Coarse OS-version bucket used to pick a volume-activation key table.
            .NET 5+ <c>Environment.OSVersion.Version</c> returns the real version
            (no longer manifest-clamped), so build-number discrimination is reliable.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.LocaleSpec">
            <summary>
            Desired locale / keyboard state passed to
            <see cref="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.ApplyLocaleAsync(Eryph.GuestServices.Provisioning.Windows.LocaleSpec,System.Threading.CancellationToken)"/>.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.LocaleSpec.Locale">
            <summary>
            BCP-47 culture name (e.g. <c>en-US</c>, <c>de-DE</c>). Applied to
            Set-Culture / Set-WinUILanguageOverride / Set-WinSystemLocale. Null
            leaves the existing values in place.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.LocaleSpec.KeyboardLayout">
            <summary>
            Keyboard input method as a BCP-47 culture or a <c>language:klid</c>
            pair (e.g. <c>0409:00000409</c>). Null lets the platform pick the
            default keyboard for <see cref="P:Eryph.GuestServices.Provisioning.Windows.LocaleSpec.Locale"/>.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.LocaleApplyResult">
            <summary>
            Outcome of an <see cref="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.ApplyLocaleAsync(Eryph.GuestServices.Provisioning.Windows.LocaleSpec,System.Threading.CancellationToken)"/> call. The
            <c>RebootRequired</c> bit is the only signal the module needs — it
            triggers <see cref="T:Eryph.GuestServices.Provisioning.Modules.ModuleOutcome.RebootRequested"/>.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.LocaleApplyResult.RebootRequired">
            <summary>
            True when the system locale (Win32 ANSI codepage) was changed and
            Windows needs a reboot for non-Unicode programs to pick it up.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.NetworkAdapterInfo">
            <summary>
            Snapshot of a Windows network adapter as needed by the network applier.
            Returned by <see cref="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.GetNetworkAdaptersAsync(System.Threading.CancellationToken)"/>. The MAC is
            normalised to a colon-separated lowercase form so callers can compare
            directly with cloud-init's <c>macaddress</c> field.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.NetworkAdapterInfo.InterfaceAlias">
            <summary>
            Cross-cmdlet identifier on Windows (e.g. "Ethernet", "Ethernet 2").
            Used to scope follow-up Set-* / New-* calls to the right adapter.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.NetworkAdapterInfo.InterfaceIndex">
            <summary>Stable index that survives renames; never zero.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.NetworkAdapterInfo.MacAddress">
            <summary>
            Canonical MAC: 12 lowercase hex digits separated by single colons.
            Empty if the adapter has no link-layer address (loopback, tunnel).
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.NetworkAdapterInfo.IsPhysical">
            <summary>
            True iff the adapter is "physical" in the MSFT_NetAdapter sense —
            hardware NIC backed by a driver, not a loopback / tunnel / virtual
            switch endpoint. The applier ignores non-physical adapters per RFC 0002.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.PosixPermissions">
            <summary>
            Translates POSIX file-permission octal triplets into Windows NTFS access
            rights. The cloud-config <c>write_files.permissions</c> field carries a
            Unix octal like <c>0644</c> that's meaningful on Linux but doesn't map
            natively to NTFS ACLs. Cloudbase-init applies a similar wrapper; we mirror
            the behavior so cloud-config authored for Linux behaves sensibly on Windows.
            </summary>
            <remarks>
            Mapping per POSIX triplet bit:
            <list type="bullet">
              <item><term>4 — read</term><description>FileSystemRights.Read + ReadPermissions + ReadAttributes</description></item>
              <item><term>2 — write</term><description>FileSystemRights.Write + ReadAndExecute-write peers</description></item>
              <item><term>1 — execute</term><description>FileSystemRights.ExecuteFile + ReadAndExecute</description></item>
            </list>
            Windows ACLs are richer than POSIX; this translation is intentionally lossy.
            Existing inherited ACEs (SYSTEM, Administrators) are preserved by the
            caller — this class only computes the new ACEs to ADD for the owner,
            primary group, and "Everyone".
            </remarks>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.PosixPermissions.TripletToRights(System.Int32)">
            <summary>Translates a POSIX triplet digit (0–7) to the NTFS rights equivalent.</summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.PosixPermissions.Parse(System.String)">
            <summary>
            Parses a POSIX octal permission string (e.g. <c>"0644"</c>, <c>"644"</c>,
            <c>"0o644"</c>) into the three triplets (owner, group, others).
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.PowerShellScriptWrapper">
            <summary>
            Pure string-building helpers for composing the <c>-Command</c> argument
            passed to <c>powershell.exe</c>. Kept platform-agnostic (no
            <see cref="T:System.Runtime.Versioning.SupportedOSPlatformAttribute"/>) so
            non-Windows-scoped callers (modules, tests) can invoke it without CA1416
            noise.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.PowerShellScriptWrapper.EscapeSingleQuoted(System.String)">
            <summary>
            Escapes a value for embedding in a PowerShell single-quoted string.
            PowerShell single-quoted strings escape an apostrophe by doubling it;
            there is no other special character to handle.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.PowerShellScriptWrapper.BuildScriptWrapper(System.String)">
            <summary>
            Builds the <c>-Command</c> argument that runs <paramref name="scriptPath"/>
            inside a UTF-8-configured PowerShell scope. The wrapper forces UTF-8 on
            every encoding hook PowerShell exposes BEFORE the user's script runs,
            so non-ASCII stdout/stderr survive .NET-side decoding with
            <c>StandardOutputEncoding = UTF8</c>.
            </summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Windows.PowerStateAction.Halt">
            <summary>
            Cloud-init's <c>halt</c> on Linux stops the CPU without powering off.
            Windows has no clean analogue; the module falls back to hibernate
            and logs a Warning when this is requested. Kept as a distinct enum
            value so the OS layer can act on the intent.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.PowerStateRequest">
            <summary>
            Resolved power-state request passed to <see cref="M:Eryph.GuestServices.Provisioning.Windows.IWindowsOs.RequestPowerStateAsync(Eryph.GuestServices.Provisioning.Windows.PowerStateRequest,System.Threading.CancellationToken)"/>.
            Cloud-init delays / messages / conditions are normalised before this record is built.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.PowerStateRequest.DelaySeconds">
            <summary>
            Seconds from now. The OS layer forwards this verbatim to
            <c>shutdown.exe /t</c>. The module enforces a minimum buffer
            (typically 5s) so the StageRunner has time to flush its semaphores
            before Windows starts tearing down the agent process.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.PowerStateRequest.Message">
            <summary>
            Operator-visible message. Truncated to 512 chars before being
            passed to <c>shutdown.exe /c</c>.
            </summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Windows.SetComputerNameResult.AlreadySet">
            <summary>The current name already matches the requested name.</summary>
        </member>
        <member name="F:Eryph.GuestServices.Provisioning.Windows.SetComputerNameResult.SetWithRebootPending">
            <summary>The name change was queued and will take effect after a reboot.</summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.SshHostKeyFingerprint">
            <summary>
            A generated / written ssh host key surfaced for operator reporting.
            Mirrors the shape <c>ssh-keygen -l</c> reports (the
            <c>&lt;bits&gt; SHA256:... &lt;comment&gt; (&lt;type&gt;)</c> line).
            </summary>
            <param name="KeyType">The host-key type — <c>ed25519</c>, <c>ecdsa</c>, <c>rsa</c>.</param>
            <param name="Fingerprint">The fingerprint in the <c>SHA256:...</c> form.</param>
            <param name="PublicKey">The full public-key line (<c>&lt;type&gt; &lt;base64&gt; &lt;comment&gt;</c>).</param>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.SshHostKeyFingerprint.#ctor(System.String,System.String,System.String)">
            <summary>
            A generated / written ssh host key surfaced for operator reporting.
            Mirrors the shape <c>ssh-keygen -l</c> reports (the
            <c>&lt;bits&gt; SHA256:... &lt;comment&gt; (&lt;type&gt;)</c> line).
            </summary>
            <param name="KeyType">The host-key type — <c>ed25519</c>, <c>ecdsa</c>, <c>rsa</c>.</param>
            <param name="Fingerprint">The fingerprint in the <c>SHA256:...</c> form.</param>
            <param name="PublicKey">The full public-key line (<c>&lt;type&gt; &lt;base64&gt; &lt;comment&gt;</c>).</param>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.SshHostKeyFingerprint.KeyType">
            <summary>The host-key type — <c>ed25519</c>, <c>ecdsa</c>, <c>rsa</c>.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.SshHostKeyFingerprint.Fingerprint">
            <summary>The fingerprint in the <c>SHA256:...</c> form.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.SshHostKeyFingerprint.PublicKey">
            <summary>The full public-key line (<c>&lt;type&gt; &lt;base64&gt; &lt;comment&gt;</c>).</summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.VolumeExtendResult">
            <summary>
            Outcome of attempting to extend one volume's hosting partition.
            Reported back to the module for logging; the module itself only cares
            about throw vs. no-throw.
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.VolumeExtendResult.DriveLetter">
            <summary>
            Uppercase drive letter when the volume is mounted on one, otherwise
            null (raw / hidden / unmounted volume).
            </summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.VolumeExtendResult.VolumeId">
            <summary>Stable WMI volume identifier — useful when there is no drive letter.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.VolumeExtendResult.SizeBefore">
            <summary>Partition size before the attempt (bytes).</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.VolumeExtendResult.SizeAfter">
            <summary>Partition size after the attempt (bytes). Equals SizeBefore when no growth was possible.</summary>
        </member>
        <member name="P:Eryph.GuestServices.Provisioning.Windows.VolumeExtendResult.Extended">
            <summary>True when SizeAfter &gt; SizeBefore.</summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Win32.Advapi32">
            <summary>
            P/Invoke surface for <c>advapi32.dll</c>. We only need
            <see cref="M:Eryph.GuestServices.Provisioning.Windows.Win32.Advapi32.LookupAccountSid(System.String,System.Byte[],System.Text.StringBuilder,System.UInt32@,System.Text.StringBuilder,System.UInt32@,Eryph.GuestServices.Provisioning.Windows.Win32.Advapi32.SID_NAME_USE@)"/> to translate well-known SIDs to the
            localized account name, e.g. the built-in Administrators group.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Win32.CimComputerSystem">
            <summary>
            Thin wrapper around <c>Win32_ComputerSystem.Rename</c> via CIM. Lives in
            its own file so the orchestrator in <see cref="T:Eryph.GuestServices.Provisioning.Windows.WindowsOs"/> stays clean.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Win32.CimNetworking">
            <summary>
            Thin wrappers around the NetTCPIP / NetAdapter CIM classes under
            <c>root\StandardCimv2</c>. These are the same classes that back the
            PowerShell NetTCPIP module (Get-NetAdapter, Set-NetIPInterface, ...) but
            without the powershell.exe startup cost.
            </summary>
            <remarks>
            We deliberately keep all CIM interaction in one place so the platform
            surface in <see cref="T:Eryph.GuestServices.Provisioning.Windows.WindowsOs"/> stays readable. Every public method
            here is idempotent: it inspects current state, computes the delta, and
            applies only the required changes. The CIM cmdlets themselves raise on
            "no-op" calls (e.g. removing a non-existent address), so the delta logic
            is what makes re-runs safe.
            </remarks>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Win32.CimService">
            <summary>
            Thin wrapper around Win32_Service CIM methods (ChangeStartMode,
            StartService, StopService). Cloudbase-init uses the SCM API directly
            via osutils.set_service_start_mode / start_service / stop_service —
            we mirror the same semantics without depending on sc.exe's argv-parsing
            quirks (the documented <c>start= value</c> syntax requires two adjacent
            argv tokens, which is fragile across .NET's ArgumentList serialiser).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.Win32.CimService.GetState(System.String)">
            <summary>
            Read the current <c>State</c> of a Win32_Service ("Running", "Stopped",
            "Start Pending", etc.). Returns null when the service is not installed.
            Used by AzureDataSource's PA-readiness gate to detect when WinGA has
            transitioned to Running, signalling PA has finished its OOBE chain.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Win32.CimStorage">
            <summary>
            Thin wrappers around the storage CIM provider under
            <c>root\Microsoft\Windows\Storage</c>. Same classes that back the
            PowerShell Storage module (<c>Update-Disk</c>, <c>Get-Partition</c>,
            <c>Resize-Partition</c>).
            </summary>
            <remarks>
            Why WSM and not VDS: cloudbase-init's VDS path hits a documented Windows
            disk-mgmt rounding bug (<c>VDS_E_EXTENT_SIZE_LESS_THAN_MIN</c>) that the
            WSM path side-steps because <c>MSFT_Partition.GetSupportedSize</c> already
            returns a size the platform promises to accept. WSM is available on every
            supported Windows Server release we care about (2012+).
            </remarks>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.Win32.CimStorage.UpdateDisks(Microsoft.Extensions.Logging.ILogger)">
            <summary>
            Calls <c>MSFT_Disk.Update</c> on every online, writable disk so the
            guest picks up new geometry after the host enlarged the VHD — without
            this, the GPT secondary header is still at the old end-of-disk and
            <c>GetSupportedSize</c> returns the pre-resize value.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.Win32.CimStorage.ExtendPartitions(System.Collections.Generic.IReadOnlySet{System.Char},Microsoft.Extensions.Logging.ILogger)">
            <summary>
            Enumerate every partition; if it qualifies for growth and its drive
            letter matches the (optional) filter, resize it to the platform's
            reported maximum supported size. Returns one result per
            resize-eligible partition (extended or not) so callers can log.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Win32.NetApi32">
            <summary>
            P/Invoke surface for <c>netapi32.dll</c>. Only the entries we actually
            call live here. All structures are marshalled as Unicode and use
            <c>LPWSTR</c> pointers for string members, matching the documented
            signatures of the underlying Net* APIs.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Win32.NetUserHelpers">
            <summary>
            Thin wrappers around the netapi32 user/group P/Invokes that surface
            failures as exceptions and free buffers reliably. Keeps the orchestration
            in <see cref="T:Eryph.GuestServices.Provisioning.Windows.WindowsOs"/> readable.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.Win32.WellKnownGroups">
            <summary>
            Resolves the localized name of well-known Windows groups via their SIDs.
            </summary>
        </member>
        <member name="T:Eryph.GuestServices.Provisioning.Windows.WindowsPath">
            <summary>
            Deterministic, host-OS-independent Windows path helpers. The provisioning
            agent runs on Windows but builds and reasons about Windows paths
            (drive-letter rooted, <c>\</c>-separated). <see cref="T:System.IO.Path"/>
            applies the *host* OS's separator semantics, so on a Linux build/test
            agent <c>Path.GetDirectoryName(@"C:\etc\foo")</c> returns <c>""</c> and
            <c>Path.Combine</c> joins with <c>/</c> — both wrong for the Windows paths
            the modules manipulate.
            </summary>
            <remarks>
            This type implements the Windows semantics directly so the modules behave
            identically regardless of the host the code runs (or is tested) on. It is
            intentionally narrow: it provides only the operations the modules and
            <see cref="M:Eryph.GuestServices.Provisioning.Windows.WindowsOs.TranslateUnixPath(System.String)"/> need. <c>/</c> is tolerated as a
            separator on input (cloud-init authors mix them) but output always uses
            <c>\</c>, matching <c>System.IO.Path</c>'s behaviour on Windows.
            </remarks>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.WindowsPath.GetDirectoryName(System.String)">
            <summary>
            Returns the directory portion of a Windows path, matching
            <c>System.IO.Path.GetDirectoryName</c>'s behaviour on Windows:
            <c>@"C:\etc\foo"</c> → <c>@"C:\etc"</c>, <c>@"C:\foo"</c> → <c>@"C:\"</c>,
            a bare root (<c>@"C:\"</c>) or a path with no parent → <c>null</c>.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.WindowsPath.Combine(System.String[])">
            <summary>
            Joins path parts with <c>\</c>. A part that is itself rooted (drive- or
            UNC-rooted) discards everything accumulated so far, matching
            <c>System.IO.Path.Combine</c> on Windows. Empty parts are skipped.
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.WindowsPath.GetFullPath(System.String)">
            <summary>
            Canonicalizes a drive-rooted or UNC Windows path against its own root
            using <c>\</c> semantics, WITHOUT consulting the host OS or current
            working directory (which <c>System.IO.Path.GetFullPath</c> does on
            non-Windows hosts). Resolves <c>.</c> segments and collapses redundant
            separators; <c>..</c> segments are resolved against the root and never
            allowed to escape it. Callers that must reject <c>..</c> outright should
            do so before calling this (see <see cref="M:Eryph.GuestServices.Provisioning.Windows.WindowsOs.TranslateUnixPath(System.String)"/>).
            </summary>
        </member>
        <member name="M:Eryph.GuestServices.Provisioning.Windows.WindowsPath.IsRooted(System.String)">
            <summary>
            True when the path begins with a drive root (<c>X:\</c> / <c>X:/</c>) or
            a UNC root (<c>\\</c>).
            </summary>
        </member>
    </members>
</doc>
