Schema/PackageDefinition/eigenverft-module-package-definition-1.6.schema.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://eigenverft.local/schemas/eigenverft-module-package-definition-1.6.schema.json",
  "title": "Eigenverft module package definition document (wire format 1.6)",
  "$comment": "META: This file is the JSON Schema for INSTANCE documents (one package definition per file). It is not itself a package definition. Runtime validates instances with PowerShell (DefinitionSchema.ps1 + DefinitionSchema.Wire1_6.ps1). In 1.6 definitionPublication.publisherId + definitionPublication.definitionId is the durable package-definition identity. Endpoints are discovery locations only. Filenames are storage detail, though the recommended on-disk layout under an endpoint root is <publisherId>/<definitionId>.json.",
  "description": "AUTHOR TASK - Produce or edit one complete package-definition JSON object for Eigenverft.Manifested.Package. Required logical order: schemaVersion, definitionPublication, display, dependencies, artifacts, discovery, packageOperations. Use schemaVersion exactly 1.6.\n\nPUBLICATION: definitionPublication.publisherId is the trusted maintainer namespace for this definition (for shipped definitions: Eigenverft). definitionPublication.definitionId is the machine package definition id used by Invoke-Package. Increment definitionPublication.definitionRevision for every meaningful JSON change, including same-day quick fixes. publishedAtUtc is audit metadata only; revision is the update key within one publisher/definition.\n\nDEPENDENCIES: dependencies is required but may be []. dependency.publisherId is optional; omit it to let Invoke-Package resolve by trusted publisher conflict policy, or include it to pin one publisher.\n\nCOMMON TRAPS: root repositoryId and root definitionId are retired; download candidates need sourceId+sourcePath (or artifact sourcePath) OR direct url/urlTemplate; GitHub release sources require real release assets and releaseTag; NSIS and Inno Setup are different install kinds; package-managed shims and installer-managed PATH should be chosen deliberately.",
  "x-eigenverftAgentHint": "If you are an LLM or autonomous coding agent: create or edit a package-definition INSTANCE JSON file that conforms to this schema and DefinitionSchema.Wire1_6.ps1. Shipped examples live under Endpoint/Defaults/Eigenverft. Prefer the endpoint-relative on-disk layout <publisherId>/<definitionId>.json, but keep definitionPublication.definitionId authoritative. Always include definitionPublication and bump definitionRevision for definition changes.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schemaVersion",
    "definitionPublication",
    "display",
    "dependencies",
    "artifacts",
    "discovery",
    "packageOperations"
  ],
  "properties": {
    "$comment": {
      "type": "string",
      "description": "Optional free-text note stored inside the INSTANCE package definition JSON; safe for human changelog-style remarks. Runtime ignores it."
    },
    "$schema": {
      "type": "string",
      "description": "Optional. In instance documents set to ../../../Schema/PackageDefinition/eigenverft-module-package-definition-1.6.schema.json (relative to Endpoint/Defaults/Eigenverft) so editors attach validation; runtime ignores."
    },
    "schemaVersion": {
      "type": "string",
      "const": "1.6",
      "description": "Must be the literal string 1.6. This is the only supported package-definition wire version for new documents."
    },
    "definitionPublication": {
      "$ref": "#/$defs/definitionPublication",
      "description": "Maintainer publication metadata for this package definition. Used for publisher filtering, local definition storage, and revision-aware update diagnostics."
    },
    "display": {
      "$ref": "#/$defs/display",
      "description": "Human-readable names and summaries for logs and UI; does not affect install mechanics."
    },
    "dependencies": {
      "type": "array",
      "description": "Required array (may be empty []). Lists other package definitions that must reach Assigned before this one. publisherId is optional; omit it for trusted publisher conflict policy, include it to pin one publisher. Do not use retired repositoryId or repositorySourceId on dependency objects.",
      "items": {
        "$ref": "#/$defs/dependency"
      }
    },
    "artifacts": {
      "$ref": "#/$defs/artifacts",
      "description": "Acquisition and selection: declare targets (per OS/CPU), releases with versions and hashes, artifact file names, and download sources. This block answers what to download and which release applies to which machine."
    },
    "discovery": {
      "$ref": "#/$defs/discovery",
      "description": "Discovery facts used by assignment, readiness, PATH/shims, adoption, and removal. discovery.presence proves assigned state; discovery.existingInstall locates existing external/package-owned installs for reuse, adoption, or installer-backed removal."
    },
    "packageOperations": {
      "$ref": "#/$defs/packageOperations",
      "description": "Desired-state machine: compatibility policy, assigned (how to install and register PATH/shims), removed (policy, delete operation, cleanup). This block answers how the engine mutates the machine."
    }
  },
  "$defs": {
    "identifier": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]*$",
      "description": "Portable id segment. Keep ids stable and avoid spaces so paths, inventory keys, and cross-definition references stay predictable."
    },
    "publisherIdentifier": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[A-Za-z][A-Za-z0-9_.-]*( [A-Za-z0-9_.-]+)*$",
      "description": "Package-definition maintainer namespace. Human team names such as My Team are allowed; spaces must separate non-empty words. This is distinct from compact definitionId values."
    },
    "display": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "default"
      ],
      "properties": {
        "default": {
          "$ref": "#/$defs/displayEntry"
        }
      }
    },
    "definitionPublication": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "publisherId",
        "publisherName",
        "definitionId",
        "definitionRevision",
        "publishedAtUtc"
      ],
      "properties": {
        "publisherId": {
          "$ref": "#/$defs/publisherIdentifier",
          "description": "Maintainer namespace for this definition, e.g. Eigenverft (shipped module defaults) or My Team. Not the upstream app vendor."
        },
        "publisherName": {
          "type": "string",
          "minLength": 1
        },
        "definitionId": {
          "$ref": "#/$defs/identifier",
          "description": "Primary package definition id within this publisher namespace. This does not need to match the filename; Invoke-Package resolves by this JSON value."
        },
        "definitionRevision": {
          "type": "integer",
          "minimum": 1,
          "description": "Monotonic maintainer revision for this definition JSON. Increment for every meaningful definition change."
        },
        "publishedAtUtc": {
          "type": "string",
          "format": "date-time",
          "description": "UTC timestamp when this definition revision was published. Audit metadata only; revision is the update key."
        }
      }
    },
    "displayEntry": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "name",
        "publisher",
        "corporation",
        "summary"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "publisher": {
          "type": "string",
          "minLength": 1
        },
        "corporation": {
          "type": "string",
          "minLength": 1
        },
        "summary": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "dependency": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "definitionId"
      ],
      "properties": {
        "publisherId": {
          "$ref": "#/$defs/publisherIdentifier",
          "description": "Optional publisher namespace pin for this dependency. Omit to use trusted publisher conflict policy."
        },
        "definitionId": {
          "$ref": "#/$defs/identifier",
          "description": "Package definition id to assign before this package."
        }
      }
    },
    "artifacts": {
      "type": "object",
      "$comment": "AUTHOR FOCUS: Define everything needed to select and download the right binary for each machine class. targets[] = one row per selectable lane (releaseTrack + artifactDistributionVariant + constraints). releases[] = version rows with targetArtifacts keyed by target id and optional upstreamRelease. sources = named download roots used by acquisitionCandidates. Generators: add a target per OS/CPU you support, then a release row per shipped version with matching hashes.",
      "additionalProperties": false,
      "required": [
        "targets",
        "releases",
        "sources"
      ],
      "properties": {
        "$comment": {
          "type": "string"
        },
        "targets": {
          "type": "array",
          "minItems": 1,
          "description": "Selectable artifact target lanes such as stable windows_amd64 or stable q8-0.",
          "items": {
            "$ref": "#/$defs/artifactTarget"
          }
        },
        "releases": {
          "type": "array",
          "minItems": 1,
          "description": "Concrete release/version facts and per-target artifact trust metadata.",
          "items": {
            "$ref": "#/$defs/artifactRelease"
          }
        },
        "sources": {
          "type": "object",
          "description": "Definition-local artifact sources referenced by acquisition candidates and upstreamRelease.",
          "additionalProperties": {
            "$ref": "#/$defs/artifactSourceEndpoint"
          }
        }
      }
    },
    "artifactTarget": {
      "type": "object",
      "$comment": "artifactDistributionVariant is intentionally long because it is not only platform. It can represent platform packaging, CPU/GPU build, model quantization, installer edition, or another distributed artifact form.",
      "additionalProperties": false,
      "required": [
        "id",
        "releaseTrack",
        "artifactDistributionVariant",
        "constraints",
        "versionSelection"
      ],
      "properties": {
        "$comment": {
          "type": "string"
        },
        "id": {
          "$ref": "#/$defs/identifier",
          "description": "Artifact target id used as key in artifacts.releases[].targetArtifacts."
        },
        "releaseTrack": {
          "type": "string",
          "minLength": 1,
          "description": "Update lane such as stable."
        },
        "artifactDistributionVariant": {
          "type": "string",
          "minLength": 1,
          "description": "The distributed artifact form for this target, for example windows_amd64, win32-x64, q8-0, or cpu-x64."
        },
        "constraints": {
          "$ref": "#/$defs/constraints",
          "description": "Machine constraints used to decide whether this target is selectable."
        },
        "versionSelection": {
          "$ref": "#/$defs/versionSelection",
          "description": "How the runtime selects a release from artifacts.releases for this target."
        },
        "fileNameTemplate": {
          "type": "string",
          "minLength": 1,
          "description": "Default package file or asset name template for this target. Omit for operations such as npmMaterializedInstallGlobalPackage that do not acquire one authored raw package file."
        },
        "acquisitionCandidates": {
          "$ref": "#/$defs/acquisitionCandidates",
          "description": "Default ordered candidates used to acquire the raw artifact for this target. Omit when assignment does not need a package file."
        }
      }
    },
    "constraints": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "Matched against the resolved runtime context for the machine running the package engine (not expressed as a closed enum in JSON Schema). Use the same tokens the engine emits: os is compared to Platform (e.g. windows, linux, macos); cpu is compared to Architecture (e.g. x64, arm64, x86). Matching is case-insensitive. Each array must list at least one token; the engine accepts the target if the actual value equals any listed entry.",
      "required": [
        "os",
        "cpu"
      ],
      "properties": {
        "os": {
          "type": "array",
          "minItems": 1,
          "description": "Allowed platform tokens for this artifact target. Compared case-insensitively to the engine Platform value (see runtime context).",
          "items": {
            "type": "string",
            "minLength": 1
          }
        },
        "cpu": {
          "type": "array",
          "minItems": 1,
          "description": "Allowed CPU architecture tokens for this artifact target. Compared case-insensitively to the engine Architecture value.",
          "items": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    },
    "versionSelection": {
      "type": "object",
      "$comment": "latestByVersion selects from this definition's artifacts.releases. It is not a network latest lookup.",
      "additionalProperties": false,
      "required": [
        "strategy",
        "allowPrerelease"
      ],
      "properties": {
        "strategy": {
          "type": "string",
          "enum": [
            "latestByVersion"
          ]
        },
        "allowPrerelease": {
          "type": "boolean"
        }
      }
    },
    "artifactRelease": {
      "type": "object",
      "$comment": "This is the fast update surface for maintainers: add a release with version, release tracks, upstream release tag, and per-target hashes.",
      "additionalProperties": false,
      "required": [
        "version",
        "releaseTracks",
        "targetArtifacts"
      ],
      "properties": {
        "$comment": {
          "type": "string"
        },
        "version": {
          "type": "string",
          "minLength": 1,
          "description": "Package version used for selection, paths, validation tokens, and inventory."
        },
        "releaseTracks": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "minLength": 1
          }
        },
        "upstreamRelease": {
          "$ref": "#/$defs/upstreamRelease",
          "description": "Optional upstream release metadata shared by target artifacts in this release."
        },
        "targetArtifacts": {
          "type": "object",
          "minProperties": 1,
          "description": "Concrete artifact facts keyed by artifacts.targets[].id.",
          "additionalProperties": {
            "$ref": "#/$defs/targetArtifact"
          }
        }
      }
    },
    "upstreamRelease": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "Conditional requirements: when sourceId resolves to a source whose kind requires a fixed upstream tag (for example githubRelease), the runtime expects releaseTag to be populated. JSON Schema cannot express that dependency here; validate combinations against Wire1_6 or follow existing definitions.",
      "required": [
        "sourceId"
      ],
      "properties": {
        "sourceId": {
          "$ref": "#/$defs/identifier",
          "description": "Key into artifacts.sources for shared upstream metadata on this release row."
        },
        "releaseTag": {
          "type": "string",
          "minLength": 1,
          "description": "Upstream release tag or version label used when resolving downloads from the referenced source (required in practice when that source kind needs a tag; see artifacts.sources[].kind in the same document)."
        }
      }
    },
    "targetArtifact": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "artifactId"
      ],
      "properties": {
        "artifactId": {
          "type": "string",
          "minLength": 1,
          "description": "Stable selected-artifact id written into results and inventory."
        },
        "fileName": {
          "type": "string",
          "minLength": 1,
          "description": "Exact package file or asset name override for this release/target."
        },
        "sourcePath": {
          "type": "string",
          "description": "Optional source-relative path override for this release/target."
        },
        "acquisitionCandidates": {
          "$ref": "#/$defs/acquisitionCandidates",
          "description": "Optional acquisition candidate override for this release/target."
        },
        "url": {
          "type": "string",
          "description": "Optional direct artifact URL template. Prefer candidate.urlTemplate for per-source policy; use this only when the artifact itself owns the full URL."
        },
        "urlTemplate": {
          "type": "string",
          "description": "Optional direct artifact URL template using tokens such as {version}, {releaseTag}, {releaseTrack}, and {artifactDistributionVariant}."
        },
        "contentHash": {
          "$ref": "#/$defs/contentHash",
          "description": "Trust boundary for fixed package files."
        },
        "publisherSignature": {
          "$ref": "#/$defs/publisherSignature",
          "description": "Publisher signature requirement for executable artifacts when fixed hashes are unsuitable."
        }
      }
    },
    "acquisitionCandidates": {
      "type": "array",
      "minItems": 1,
      "description": "Ordered candidates used to acquire raw package files. Lower searchOrder runs first.",
      "items": {
        "$ref": "#/$defs/acquisitionCandidate"
      }
    },
    "acquisitionCandidate": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "searchOrder",
            "verification"
          ],
          "properties": {
            "kind": {
              "const": "packageDepot"
            },
            "searchOrder": {
              "type": "integer",
              "minimum": 0
            },
            "verification": {
              "$ref": "#/$defs/verification"
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "searchOrder",
            "verification"
          ],
          "properties": {
            "kind": {
              "const": "download"
            },
            "sourceId": {
              "$ref": "#/$defs/identifier",
              "description": "Required when resolving through artifacts.sources + sourcePath. Omit for direct url/urlTemplate downloads."
            },
            "sourcePath": {
              "type": "string",
              "description": "Source-relative path appended to artifacts.sources[sourceId].baseUri. May also be supplied by targetArtifacts[].sourcePath."
            },
            "url": {
              "type": "string",
              "description": "Direct absolute download URL. Mutually exclusive with sourceId/sourcePath."
            },
            "urlTemplate": {
              "type": "string",
              "description": "Direct absolute download URL template with {version}, {releaseTag}, {releaseTrack}, and {artifactDistributionVariant}. Mutually exclusive with sourceId/sourcePath."
            },
            "searchOrder": {
              "type": "integer",
              "minimum": 0
            },
            "verification": {
              "$ref": "#/$defs/verification"
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "sourcePath",
            "searchOrder",
            "verification"
          ],
          "properties": {
            "kind": {
              "const": "filesystem"
            },
            "sourceId": {
              "$ref": "#/$defs/identifier"
            },
            "sourcePath": {
              "type": "string"
            },
            "searchOrder": {
              "type": "integer",
              "minimum": 0
            },
            "verification": {
              "$ref": "#/$defs/verification"
            }
          }
        }
      ]
    },
    "verification": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "mode"
      ],
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "required",
            "optional",
            "none"
          ]
        }
      }
    },
    "artifactSourceEndpoint": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "baseUri"
          ],
          "properties": {
            "kind": {
              "const": "download"
            },
            "baseUri": {
              "type": "string",
              "minLength": 1
            }
          }
        },
        {
          "type": "object",
          "$comment": "GitHub field names are prefixed with github to avoid confusion with package repository ids.",
          "additionalProperties": false,
          "required": [
            "kind",
            "githubOwner",
            "githubRepository"
          ],
          "properties": {
            "kind": {
              "const": "githubRelease"
            },
            "githubOwner": {
              "type": "string",
              "minLength": 1
            },
            "githubRepository": {
              "type": "string",
              "minLength": 1
            }
          }
        }
      ]
    },
    "discovery": {
      "type": "object",
      "$comment": "Discovery groups the facts used to prove package presence and to locate existing installs. It is shared by readiness, PATH/shim generation, adoption/reuse, and safe removal.",
      "additionalProperties": false,
      "required": [
        "presence",
        "existingInstall"
      ],
      "properties": {
        "$comment": {
          "type": "string"
        },
        "presence": {
          "$ref": "#/$defs/discoveryPresence",
          "description": "Post-install proof: files, directories, commands, and optional registry/metadata checks under the resolved install directory. Must align with assigned.install layout or readiness and removal checks will fail."
        },
        "existingInstall": {
          "$ref": "#/$defs/discoveryExistingInstall",
          "description": "How to detect installs that were not created by this package inventory (adoption/reuse/removal). Use enabled:false and empty searchLocations/installRootRules when this package never adopts external trees."
        }
      }
    },
    "discoveryPresence": {
      "type": "object",
      "$comment": "Presence discovery describes what proves presence, not where to fetch or how to install. Relative file/tool probes are resolved from the effective assigned install directory root; powerShellModules probes are checked through Windows PowerShell 5.1 and do not require an installDirectory.",
      "additionalProperties": false,
      "required": [
        "files",
        "directories",
        "commands",
        "apps",
        "metadataFiles",
        "signatures",
        "fileDetails",
        "registry",
        "powerShellModules"
      ],
      "properties": {
        "$comment": {
          "type": "string"
        },
        "files": {
          "type": "array",
          "description": "Relative file paths that must exist under the install root (slash-separated segments are fine; the engine normalizes).",
          "items": {
            "type": "string"
          }
        },
        "directories": {
          "type": "array",
          "description": "Relative directory paths that must exist under the install root.",
          "items": {
            "type": "string"
          }
        },
        "commands": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/presenceCommand"
          }
        },
        "apps": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/presenceApp"
          }
        },
        "metadataFiles": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/metadataFileProbe"
          }
        },
        "signatures": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/signatureProbe"
          }
        },
        "fileDetails": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/fileDetailsProbe"
          }
        },
        "registry": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/registryProbe"
          }
        },
        "powerShellModules": {
          "type": "array",
          "description": "PowerShell module presence probes executed through Windows PowerShell 5.1. Use for powershellModuleInstaller readiness/adoption without requiring an installDirectory.",
          "items": {
            "$ref": "#/$defs/powerShellModuleProbe"
          }
        }
      }
    },
    "presenceCommand": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "name",
        "relativePath",
        "requiredForState",
        "exposeCommand"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "relativePath": {
          "type": "string",
          "minLength": 1,
          "description": "Executable path relative to the install root (for example python.exe or bin/code.cmd)."
        },
        "requiredForState": {
          "type": "boolean"
        },
        "exposeCommand": {
          "type": "boolean"
        },
        "stateChecks": {
          "type": "array",
          "description": "Optional command invocations used to validate runtime behavior. When any property is set, the runtime uses the check; leaving every property out means the check is skipped for that entry.",
          "items": {
            "$ref": "#/$defs/commandStateCheck"
          }
        }
      }
    },
    "presenceApp": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "name",
        "relativePath",
        "requiredForState",
        "exposeApp"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "relativePath": {
          "type": "string",
          "minLength": 1
        },
        "requiredForState": {
          "type": "boolean"
        },
        "exposeApp": {
          "type": "boolean"
        }
      }
    },
    "commandStateCheck": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "Optional subprocess check: when used, the engine runs the discovered command with optional arguments, matches stdout/stderr against outputPattern when provided, and may compare captured text to expectedValue. All properties are optional at the schema level; practical checks usually supply at least arguments or outputPattern - mirror a working definition if unsure.",
      "properties": {
        "arguments": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "outputPattern": {
          "type": "string"
        },
        "expectedValue": {
          "type": "string"
        }
      }
    },
    "metadataFileProbe": {
      "type": "object",
      "additionalProperties": true,
      "$comment": "additionalProperties allows forward-compatible metadata keys beyond relativePath; only keys understood by the engine have effect - treat unknown keys as documentation until Wire1_6 recognizes them.",
      "required": [
        "relativePath"
      ],
      "properties": {
        "relativePath": {
          "type": "string"
        }
      }
    },
    "signatureProbe": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "relativePath",
        "requireValid",
        "subjectContains"
      ],
      "properties": {
        "relativePath": {
          "type": "string"
        },
        "requireValid": {
          "type": "boolean"
        },
        "subjectContains": {
          "type": "string"
        }
      }
    },
    "fileDetailsProbe": {
      "type": "object",
      "additionalProperties": true,
      "$comment": "Same forward-compat pattern as metadataFileProbe: relativePath is required; other properties enable structured Win32 version resource checks when supported.",
      "required": [
        "relativePath"
      ],
      "properties": {
        "relativePath": {
          "type": "string"
        },
        "fileVersion": {
          "type": "string"
        },
        "productVersion": {
          "type": "string"
        },
        "productName": {
          "type": "string"
        },
        "fileDescription": {
          "type": "string"
        }
      }
    },
    "registryProbe": {
      "type": "object",
      "additionalProperties": false,
      "description": "Probes Windows registry values under one or more key paths. When expectedValue is omitted, the probe only requires the value to exist.",
      "required": [
        "paths",
        "valueName"
      ],
      "properties": {
        "paths": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          },
          "description": "Registry key paths to inspect (first successful read wins)."
        },
        "valueName": {
          "type": "string"
        },
        "operator": {
          "type": "string",
          "description": "String comparison operator when expectedValue is set. Supported: =, == (case-insensitive equality), !=, and version compares >, >=, <, <= after parsing both sides as version text."
        },
        "expectedValue": {
          "type": "string",
          "description": "Optional template-expanded expected content; omit to require only that the value exists."
        }
      }
    },
    "powerShellModuleProbe": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "name",
        "requiredVersion",
        "scope",
        "requiredForState"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "description": "PowerShell module name, for example PowerShellGet."
        },
        "requiredVersion": {
          "type": "string",
          "minLength": 1,
          "description": "Exact module version that must be visible to Windows PowerShell 5.1."
        },
        "scope": {
          "type": "string",
          "enum": [
            "CurrentUser",
            "AllUsers"
          ]
        },
        "requiredForState": {
          "type": "boolean"
        },
        "requireNuGetProvider": {
          "type": "boolean",
          "default": false,
          "description": "When true, readiness/adoption also requires the NuGet PackageManagement provider. Use for PackageManagement bootstrap."
        }
      }
    },
    "discoveryExistingInstall": {
      "type": "object",
      "$comment": "Existing install discovery is shared by assignment/adoption and removal. Give search locations stable ids so removal operations can reference the same registry/path discovery data.",
      "additionalProperties": false,
      "required": [
        "enabled",
        "searchLocations",
        "installRootRules"
      ],
      "properties": {
        "$comment": {
          "type": "string"
        },
        "enabled": {
          "type": "boolean",
          "description": "When false, discovery is disabled and searchLocations/installRootRules are ignored at runtime; the schema still requires those arrays to be present (use empty arrays)."
        },
        "searchLocations": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/existingInstallSearchLocation"
          }
        },
        "installRootRules": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/installRootRule"
          }
        }
      }
    },
    "existingInstallSearchLocation": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": [ "id", "kind", "searchOrder", "name" ],
          "properties": {
            "id": { "$ref": "#/$defs/identifier" },
            "kind": { "const": "command" },
            "searchOrder": { "type": "integer", "minimum": 0 },
            "name": { "type": "string", "minLength": 1, "description": "Executable command name resolved as an application from PATH." }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [ "id", "kind", "searchOrder", "path" ],
          "properties": {
            "id": { "$ref": "#/$defs/identifier" },
            "kind": { "const": "path" },
            "searchOrder": { "type": "integer", "minimum": 0 },
            "path": { "type": "string", "minLength": 1, "description": "Concrete file path to probe." }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [ "id", "kind", "searchOrder", "path" ],
          "properties": {
            "id": { "$ref": "#/$defs/identifier" },
            "kind": { "const": "directory" },
            "searchOrder": { "type": "integer", "minimum": 0 },
            "path": { "type": "string", "minLength": 1, "description": "Concrete install directory path to probe." }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [ "id", "kind", "searchOrder", "paths", "installDirectorySource" ],
          "properties": {
            "id": { "$ref": "#/$defs/identifier", "description": "Stable id so removal can reference this uninstall-registry source." },
            "kind": { "const": "windowsUninstallRegistryKey" },
            "searchOrder": { "type": "integer", "minimum": 0 },
            "paths": {
              "type": "array",
              "minItems": 1,
              "items": { "type": "string", "minLength": 1 },
              "description": "Direct registry key paths such as HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Example."
            },
            "installDirectorySource": {
              "type": "string",
              "enum": [ "installLocation", "displayIcon", "displayIconDirectory", "uninstallString", "uninstallStringDirectory" ]
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [ "id", "kind", "searchOrder", "rootPaths", "displayNamePatterns", "installDirectorySource" ],
          "properties": {
            "id": { "$ref": "#/$defs/identifier", "description": "Stable id so removal can reference this uninstall-registry search." },
            "kind": { "const": "windowsUninstallRegistrySearch" },
            "searchOrder": { "type": "integer", "minimum": 0 },
            "rootPaths": {
              "type": "array",
              "minItems": 1,
              "items": { "type": "string", "minLength": 1 },
              "description": "Uninstall registry roots to enumerate, for example HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall."
            },
            "displayNamePatterns": {
              "type": "array",
              "minItems": 1,
              "items": { "type": "string", "minLength": 1 },
              "description": "Wildcard patterns matched against DisplayName after template expansion, for example 7-Zip {version}*."
            },
            "publisherPatterns": {
              "type": "array",
              "items": { "type": "string", "minLength": 1 },
              "description": "Optional wildcard patterns matched against Publisher after template expansion."
            },
            "installDirectorySource": {
              "type": "string",
              "enum": [ "installLocation", "displayIcon", "displayIconDirectory", "uninstallString", "uninstallStringDirectory" ]
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [ "id", "kind", "searchOrder", "name", "requiredVersion" ],
          "properties": {
            "id": { "$ref": "#/$defs/identifier", "description": "Stable id for this PowerShell module discovery entry." },
            "kind": { "const": "powershellModule" },
            "searchOrder": { "type": "integer", "minimum": 0 },
            "name": { "type": "string", "minLength": 1 },
            "requiredVersion": { "type": "string", "minLength": 1 },
            "scope": {
              "type": "string",
              "enum": [ "CurrentUser", "AllUsers" ],
              "default": "CurrentUser"
            },
            "requireNuGetProvider": {
              "type": "boolean",
              "default": false,
              "description": "When true, adoption requires the NuGet PackageManagement provider in addition to the exact module."
            }
          }
        }
      ],
      "description": "Existing install search location. Use command/path/directory for portable tools, windowsUninstallRegistryKey or windowsUninstallRegistrySearch for installer-owned applications, and powershellModule for exact module adoption."
    },
    "installRootRule": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "Maps a discovered candidate file path to an install root. Today the engine implements match.kind=fileName with match.value equal to the leaf file name (case-insensitive); other match shapes are reserved. installRootRelativePath is joined relative to the directory containing the matched file (use . for the parent directory itself).",
      "required": [
        "match",
        "installRootRelativePath"
      ],
      "properties": {
        "match": {
          "type": "object",
          "additionalProperties": false,
          "required": [ "kind", "value" ],
          "properties": {
            "kind": { "const": "fileName" },
            "value": { "type": "string", "minLength": 1 }
          },
          "description": "Supported shape in Wire1_6: { \"kind\": \"fileName\", \"value\": \"example.exe\" }."
        },
        "installRootRelativePath": {
          "type": "string",
          "description": "Relative path from the discovered file's directory to the install root."
        }
      }
    },
    "packageOperations": {
      "type": "object",
      "$comment": "AUTHOR FOCUS: assigned chooses install engine (expandArchive, npmMaterializedInstallGlobalPackage, powershellModuleInstaller, nsisInstaller, innoSetupInstaller, msiInstaller, runInstaller, placePackageFile) and must agree with discovery.presence. removed must undo ownership safely (inventory row, shims, delete directory or installer uninstaller). policy sets compatibility and ownership rules before install.",
      "additionalProperties": false,
      "required": [
        "policy",
        "assigned",
        "removed"
      ],
      "properties": {
        "$comment": {
          "type": "string"
        },
        "policy": {
          "$ref": "#/$defs/packageOperationPolicy"
        },
        "assigned": {
          "$ref": "#/$defs/assignedOperation"
        },
        "removed": {
          "$ref": "#/$defs/removedOperation"
        }
      }
    },
    "packageOperationPolicy": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "ownershipPolicy",
        "compatibility"
      ],
      "properties": {
        "ownershipPolicy": {
          "$ref": "#/$defs/ownershipPolicy"
        },
        "compatibility": {
          "$ref": "#/$defs/compatibility"
        }
      }
    },
    "assignedOperation": {
      "type": "object",
      "$comment": "Assigned receives a selected artifact and makes the package ready. Artifact lookup stays under artifacts.",
      "additionalProperties": false,
      "required": [
        "install",
        "readyStateCheck",
        "pathRegistration",
        "versionUpdatePolicy"
      ],
      "properties": {
        "$comment": {
          "type": "string"
        },
        "install": {
          "$ref": "#/$defs/assignInstallOperation"
        },
        "readyStateCheck": {
          "$ref": "#/$defs/readyStateCheck"
        },
        "pathRegistration": {
          "$ref": "#/$defs/pathRegistration"
        },
        "versionUpdatePolicy": {
          "$ref": "#/$defs/versionUpdatePolicy"
        }
      }
    },
    "assignInstallOperation": {
      "oneOf": [
        {
          "$ref": "#/$defs/assignExpandArchive"
        },
        {
          "$ref": "#/$defs/assignNpmMaterializedInstallGlobalPackage"
        },
        {
          "$ref": "#/$defs/assignPlacePackageFile"
        },
        {
          "$ref": "#/$defs/assignNsisInstaller"
        },
        {
          "$ref": "#/$defs/assignInnoSetupInstaller"
        },
        {
          "$ref": "#/$defs/assignMsiInstaller"
        },
        {
          "$ref": "#/$defs/assignPowerShellModuleInstaller"
        },
        {
          "$ref": "#/$defs/assignRunInstaller"
        }
      ]
    },
    "assignExpandArchive": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "installDirectory follows the same root rules as other assigned operations: expand environment variables, normalize slashes, and if not absolute, prefix with preferredTargetInstallRootDirectory. expandedRoot names the directory inside the archive that becomes the logical payload root after extraction.",
      "required": [
        "kind",
        "installDirectory",
        "expandedRoot",
        "createDirectories"
      ],
      "properties": {
        "kind": {
          "const": "expandArchive"
        },
        "installDirectory": {
          "type": "string",
          "description": "Target install directory template (supports tokens such as {definitionId}, {releaseTrack}, {version}, {artifactDistributionVariant})."
        },
        "expandedRoot": {
          "type": "string",
          "description": "Path inside the expanded archive that anchors relative discovery paths (often a single folder like tools)."
        },
        "createDirectories": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "assignNpmMaterializedInstallGlobalPackage": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "Depot-backed npm adapter. Authors provide the normal npm packageSpec; the engine materializes npm metadata and platform-compatible tarballs before running npm offline.",
      "required": [
        "kind",
        "installerCommand",
        "packageSpec",
        "installDirectory"
      ],
      "properties": {
        "kind": {
          "const": "npmMaterializedInstallGlobalPackage"
        },
        "installerCommand": {
          "type": "string"
        },
        "packageSpec": {
          "type": "string"
        },
        "installDirectory": {
          "type": "string",
          "description": "Target directory template for the npm global package layout (same path rules as expandArchive.installDirectory)."
        }
      }
    },
    "assignPlacePackageFile": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "kind",
        "installDirectory",
        "targetRelativePath"
      ],
      "properties": {
        "kind": {
          "const": "placePackageFile"
        },
        "installDirectory": {
          "type": "string",
          "description": "Destination directory template for the copied artifact (same path rules as expandArchive.installDirectory)."
        },
        "targetRelativePath": {
          "type": "string",
          "description": "Relative path within the install directory where the package file is written."
        }
      }
    },
    "assignNsisInstaller": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "NSIS-only installer adapter. NSIS requires the target directory argument last and unquoted, usually /D=<installDirectory>. Do not use this for Inno Setup; use innoSetupInstaller.",
      "required": [
        "kind",
        "installDirectory",
        "commandArguments",
        "targetDirectoryArgument"
      ],
      "properties": {
        "kind": {
          "const": "nsisInstaller"
        },
        "installDirectory": {
          "type": "string"
        },
        "installerKind": {
          "const": "nsis"
        },
        "uiMode": {
          "type": "string"
        },
        "elevation": {
          "$ref": "#/$defs/elevationMode"
        },
        "timeoutSec": {
          "type": "integer",
          "minimum": 1
        },
        "commandArguments": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "targetDirectoryArgument": {
          "type": "object",
          "additionalProperties": false,
          "required": [ "enabled", "prefix" ],
          "properties": {
            "enabled": { "type": "boolean" },
            "prefix": { "type": "string", "minLength": 1, "description": "Usually /D=. The engine appends the install directory unquoted and last." }
          },
          "description": "NSIS target directory argument. If enabled, the engine appends {prefix}{installDirectory} as the final argument without quotes."
        },
        "successExitCodes": {
          "$ref": "#/$defs/exitCodes"
        },
        "restartExitCodes": {
          "$ref": "#/$defs/exitCodes"
        }
      }
    },
    "assignInnoSetupInstaller": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "Inno Setup installer adapter. Common silent args are /VERYSILENT /NORESTART /SUPPRESSMSGBOXES and optional /MERGETASKS=... . Target directory is passed as /DIR=\"<installDirectory>\" when targetDirectoryArgument.enabled=true.",
      "required": [
        "kind",
        "installDirectory",
        "commandArguments",
        "targetDirectoryArgument"
      ],
      "properties": {
        "kind": {
          "const": "innoSetupInstaller"
        },
        "installDirectory": {
          "type": "string"
        },
        "uiMode": {
          "type": "string"
        },
        "elevation": {
          "$ref": "#/$defs/elevationMode"
        },
        "timeoutSec": {
          "type": "integer",
          "minimum": 1
        },
        "commandArguments": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "targetDirectoryArgument": {
          "type": "object",
          "additionalProperties": false,
          "required": [ "enabled", "prefix", "quoteValue" ],
          "properties": {
            "enabled": { "type": "boolean" },
            "prefix": { "type": "string", "minLength": 1, "description": "Usually /DIR=." },
            "quoteValue": { "type": "boolean", "description": "Usually true for Inno Setup because install paths commonly contain spaces." }
          }
        },
        "successExitCodes": {
          "$ref": "#/$defs/exitCodes"
        },
        "restartExitCodes": {
          "$ref": "#/$defs/exitCodes"
        }
      }
    },
    "assignMsiInstaller": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "MSI installer adapter. The engine stages the .msi, invokes %SystemRoot%\\System32\\msiexec.exe directly, and appends the configured public property for installDirectory when enabled. This install kind requires normal package-file acquisition.",
      "required": [
        "kind",
        "installDirectory",
        "commandArguments",
        "targetDirectoryProperty"
      ],
      "properties": {
        "kind": {
          "const": "msiInstaller"
        },
        "installDirectory": {
          "type": "string"
        },
        "uiMode": {
          "type": "string"
        },
        "elevation": {
          "$ref": "#/$defs/elevationMode"
        },
        "timeoutSec": {
          "type": "integer",
          "minimum": 1
        },
        "commandArguments": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Arguments appended after /i <staged.msi>, typically /qn and /norestart."
        },
        "targetDirectoryProperty": {
          "type": "object",
          "additionalProperties": false,
          "required": [ "enabled", "name" ],
          "properties": {
            "enabled": { "type": "boolean" },
            "name": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]*$", "description": "MSI public property receiving installDirectory, for example INSTALLDIR." }
          }
        },
        "successExitCodes": {
          "$ref": "#/$defs/exitCodes"
        },
        "restartExitCodes": {
          "$ref": "#/$defs/exitCodes"
        }
      }
    },
    "assignRunInstaller": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "kind",
        "targetKind",
        "installerKind",
        "uiMode",
        "elevation",
        "timeoutSec",
        "commandArguments",
        "successExitCodes",
        "restartExitCodes"
      ],
      "properties": {
        "kind": {
          "const": "runInstaller"
        },
        "targetKind": {
          "type": "string",
          "enum": [
            "directory",
            "machinePrerequisite"
          ]
        },
        "installerKind": {
          "type": "string"
        },
        "uiMode": {
          "type": "string"
        },
        "elevation": {
          "$ref": "#/$defs/elevationMode"
        },
        "timeoutSec": {
          "type": "integer",
          "minimum": 1
        },
        "logRelativePath": {
          "type": "string"
        },
        "commandArguments": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "successExitCodes": {
          "$ref": "#/$defs/exitCodes"
        },
        "restartExitCodes": {
          "$ref": "#/$defs/exitCodes"
        }
      }
    },
    "assignPowerShellModuleInstaller": {
      "type": "object",
      "additionalProperties": false,
      "$comment": "Depot-backed PowerShell module adapter. The selected artifact must be the module .nupkg; the engine stages it under PackageInstallStage\\Nuget and installs from a temporary local PSRepository using Windows PowerShell 5.1. Do not use this as an online Install-Module wrapper.",
      "required": [
        "kind",
        "moduleName",
        "requiredVersion"
      ],
      "properties": {
        "kind": {
          "const": "powershellModuleInstaller"
        },
        "moduleName": {
          "type": "string",
          "minLength": 1,
          "description": "PowerShell module name inside the .nupkg, for example PowerShellGet."
        },
        "requiredVersion": {
          "type": "string",
          "minLength": 1,
          "description": "Exact module version to install from the local PSRepository."
        },
        "scope": {
          "type": "string",
          "enum": [
            "CurrentUser",
            "AllUsers"
          ],
          "default": "CurrentUser"
        },
        "allowClobber": {
          "type": "boolean",
          "default": false
        },
        "skipPublisherCheck": {
          "type": "boolean",
          "default": false
        },
        "timeoutSec": {
          "type": "integer",
          "minimum": 1,
          "default": 600
        }
      }
    },
    "readyStateCheck": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "use",
        "expectedVersion",
        "require"
      ],
      "properties": {
        "use": {
          "const": "discovery.presence"
        },
        "expectedVersion": {
          "type": "string"
        },
        "require": {
          "$ref": "#/$defs/presenceRequirementFlags"
        }
      }
    },
    "versionUpdatePolicy": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "whenAssigned",
        "onSameSelectedVersion",
        "onNewSelectedVersion"
      ],
      "properties": {
        "whenAssigned": {
          "const": "trackSelectedVersion"
        },
        "onSameSelectedVersion": {
          "const": "reuseOrRepair"
        },
        "onNewSelectedVersion": {
          "type": "string",
          "enum": [
            "replacePackageOwnedInstall",
            "fail"
          ]
        }
      }
    },
    "removedOperation": {
      "type": "object",
      "$comment": "Removal references discovery.presence/discovery.existingInstall instead of duplicating discovery facts. Policy decides what ownership classes may be touched.",
      "additionalProperties": false,
      "required": [
        "policy",
        "operation",
        "absenceVerification",
        "postRemoveCleanup"
      ],
      "properties": {
        "$comment": {
          "type": "string"
        },
        "policy": {
          "$ref": "#/$defs/removePolicy"
        },
        "operation": {
          "$ref": "#/$defs/removeOperation"
        },
        "absenceVerification": {
          "$ref": "#/$defs/absenceVerification"
        },
        "postRemoveCleanup": {
          "$ref": "#/$defs/postRemoveCleanup"
        }
      }
    },
    "removePolicy": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "whenNotInInventory",
        "allowedInventoryOwnershipKinds",
        "allowUntrackedExternalRemoval",
        "removeDependencies"
      ],
      "properties": {
        "whenNotInInventory": {
          "type": "string",
          "enum": [
            "succeed",
            "fail"
          ]
        },
        "allowedInventoryOwnershipKinds": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "PackageInstalled",
              "PackageApplied",
              "AdoptedExternal"
            ]
          }
        },
        "allowUntrackedExternalRemoval": {
          "type": "boolean",
          "description": "High-risk opt-in. When false, removal never deletes an external install discovered live without inventory."
        },
        "removeDependencies": {
          "type": "boolean",
          "description": "Whether removing this package should also remove dependencies. Expected false for v1."
        }
      }
    },
    "removeOperation": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "pathSource"
          ],
          "properties": {
            "kind": {
              "const": "deleteInstallDirectory"
            },
            "pathSource": {
              "const": "inventory.installDirectory",
              "description": "Delete the install directory tracked in inventory, not a newly computed directory from current config. After deletion, the engine prunes empty parent directories: up to preferredTargetInstallRootDirectory when the path is under that root, otherwise up to the path's volume or UNC share root (never removing that root; stops at the first non-empty parent)."
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "commandSource",
            "commandArguments",
            "elevation",
            "timeoutSec",
            "successExitCodes",
            "restartExitCodes",
            "uiMode"
          ],
          "properties": {
            "kind": {
              "type": "string",
              "enum": [ "nsisUninstaller", "innoSetupUninstaller", "msiUninstaller" ]
            },
            "commandSource": {
              "$ref": "#/$defs/uninstallCommandSource"
            },
            "commandArguments": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "elevation": {
              "$ref": "#/$defs/elevationMode"
            },
            "timeoutSec": {
              "type": "integer",
              "minimum": 1
            },
            "successExitCodes": {
              "$ref": "#/$defs/exitCodes"
            },
            "restartExitCodes": {
              "$ref": "#/$defs/exitCodes"
            },
            "uiMode": {
              "type": "string"
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind"
          ],
          "properties": {
            "kind": {
              "const": "none"
            }
          }
        }
      ]
    },
    "uninstallCommandSource": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "use",
        "searchLocationId",
        "registryValueOrder"
      ],
      "properties": {
        "use": {
          "const": "discovery.existingInstall"
        },
        "searchLocationId": {
          "$ref": "#/$defs/identifier",
          "description": "Id of an discovery.existingInstall.searchLocations entry."
        },
        "registryValueOrder": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "enum": [
              "QuietUninstallString",
              "UninstallString"
            ]
          }
        }
      }
    },
    "absenceVerification": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "use",
        "require"
      ],
      "properties": {
        "use": {
          "const": "discovery.presence"
        },
        "require": {
          "$ref": "#/$defs/presenceRequirementFlags"
        }
      }
    },
    "postRemoveCleanup": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "packageInventoryRecord",
        "generatedShims",
        "pathEntries",
        "workDirectories"
      ],
      "properties": {
        "packageInventoryRecord": {
          "type": "boolean"
        },
        "generatedShims": {
          "type": "boolean"
        },
        "pathEntries": {
          "type": "boolean"
        },
        "workDirectories": {
          "type": "boolean"
        }
      }
    },
    "presenceRequirementFlags": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "files",
        "directories",
        "commands",
        "apps",
        "metadataFiles",
        "signatures",
        "fileDetails",
        "registry",
        "powerShellModules"
      ],
      "properties": {
        "files": {
          "type": "boolean"
        },
        "directories": {
          "type": "boolean"
        },
        "commands": {
          "type": "boolean"
        },
        "apps": {
          "type": "boolean"
        },
        "metadataFiles": {
          "type": "boolean"
        },
        "signatures": {
          "type": "boolean"
        },
        "fileDetails": {
          "type": "boolean"
        },
        "registry": {
          "type": "boolean"
        },
        "powerShellModules": {
          "type": "boolean"
        }
      }
    },
    "pathRegistration": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "mode"
          ],
          "properties": {
            "mode": {
              "const": "none"
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "mode",
            "source"
          ],
          "properties": {
            "mode": {
              "type": "string",
              "enum": [
                "user",
                "machine"
              ]
            },
            "source": {
              "$ref": "#/$defs/pathRegistrationSource"
            }
          }
        }
      ]
    },
    "pathRegistrationSource": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "use"
          ],
          "properties": {
            "kind": {
              "const": "shim"
            },
            "use": {
              "const": "discovery.presence.commands"
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "value"
          ],
          "properties": {
            "kind": {
              "type": "string",
              "enum": [
                "commandEntryPoint",
                "appEntryPoint",
                "installRelativeDirectory"
              ]
            },
            "value": {
              "type": "string",
              "minLength": 1
            }
          }
        }
      ]
    },
    "ownershipPolicy": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "allowAdoptExternal",
        "upgradeAdoptedInstall",
        "requirePackageOwnership"
      ],
      "properties": {
        "allowAdoptExternal": {
          "type": "boolean"
        },
        "upgradeAdoptedInstall": {
          "type": "boolean"
        },
        "requirePackageOwnership": {
          "type": "boolean"
        }
      }
    },
    "compatibility": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "checks"
      ],
      "properties": {
        "checks": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/compatibilityCheck"
          }
        }
      }
    },
    "compatibilityCheck": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "operator",
            "value"
          ],
          "properties": {
            "kind": {
              "const": "osVersion"
            },
            "operator": {
              "type": "string",
              "description": "Version comparison operator for the host OS version string. Supported: =, ==, !=, >, >=, <, <= (same rules as package selection compatibility)."
            },
            "value": {
              "type": "string",
              "description": "Expected OS version text compared against Environment.OSVersion."
            },
            "onFail": {
              "$ref": "#/$defs/onFail",
              "description": "When omitted, failed checks default to fail behavior in the engine."
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "operator",
            "value"
          ],
          "properties": {
            "kind": {
              "type": "string",
              "enum": [
                "physicalMemoryGiB",
                "videoMemoryGiB",
                "physicalOrVideoMemoryGiB"
              ]
            },
            "operator": {
              "type": "string",
              "description": "Numeric comparison operator for GiB thresholds. Supported: =, ==, !=, >, >=, <, <=."
            },
            "value": {
              "type": "number",
              "description": "Threshold in gibibytes (GiB), compared against detected memory for the machine."
            },
            "onFail": {
              "$ref": "#/$defs/onFail",
              "description": "When omitted, failed checks default to fail behavior in the engine."
            }
          }
        }
      ],
      "$comment": "This oneOf currently covers osVersion and memory GiB checks implemented in Wire1_6; additional compatibility kinds may appear in definitions before this schema lists them - extend the schema when adding new kinds."
    },
    "onFail": {
      "type": "string",
      "description": "Compatibility check handling when a check fails. When omitted on a check object, the engine defaults to fail.",
      "enum": [
        "fail",
        "warn"
      ]
    },
    "contentHash": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "algorithm",
        "value"
      ],
      "properties": {
        "algorithm": {
          "type": "string",
          "description": "Hash algorithm used to verify a fixed package file. sha512 is supported for ecosystems such as .NET whose official release metadata publishes SHA512 package hashes.",
          "enum": [
            "sha256",
            "sha512"
          ]
        },
        "value": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "publisherSignature": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "kind",
        "requireValid",
        "subjectContains"
      ],
      "properties": {
        "kind": {
          "const": "authenticode"
        },
        "requireValid": {
          "type": "boolean"
        },
        "subjectContains": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "elevationMode": {
      "type": "string",
      "enum": [
        "none",
        "required",
        "auto"
      ]
    },
    "exitCodes": {
      "type": "array",
      "items": {
        "type": "integer"
      }
    }
  }
}