Schema/PackageDefinition/eigenverft-module-package-definition-2.0.schema.json
|
{
"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://eigenverft.local/schemas/eigenverft-module-package-definition-2.0.schema.json", "title": "Eigenverft module package definition document (wire format 2.0)", "$comment": "META: JSON Schema for INSTANCE package-definition documents. Runtime validates with DefinitionSchema.ps1 + DefinitionSchema.Wire2_0.ps1. Schema 2.0 is a breaking artifact-file-set contract: a selected artifact owns zero files only for dynamic npm materialization, otherwise it owns one or more required artifactFiles.", "description": "AUTHOR TASK - Produce or edit one complete schemaVersion 2.0 package-definition JSON object. Read PackageDefinitionAuthoring.md first, then the schema root, artifacts/file definitions, the chosen install-operation definition, and one matching shipped example. A target selects a distribution. A release selects a version. artifactFiles lists every required file in that distribution. acquisitionCandidates are fallback ways to obtain one file. packageOperations.assigned.install.artifactFileId names the file consumed by a file-backed operation. Draft with definitionSignature.kind=unsigned; never invent signatureValue. Resolve and verify every artifact file before signing. Bump definitionRevision after meaningful changes.", "x-eigenverftAgentHint": "LLM/agent: use schemaVersion 2.0 only. Keep target and release artifactFiles keys identical. All declared files are required. Put reusable relativePathTemplate and acquisitionCandidates under the target file; put exact hashes, signatures, and optional release overrides under the release file. Every file-backed install operation requires artifactFileId. packageDepot, vendorDownload, and archiveEntry are fallback acquisition kinds for one file. Author unsigned drafts, validate, then sign as a separate maintainer step.", "type": "object", "additionalProperties": false, "required": [ "schemaVersion", "definitionPublication", "display", "dependency", "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 shipped instance documents set to ../../../Schema/PackageDefinition/eigenverft-module-package-definition-2.0.schema.json so editors attach validation; runtime ignores." }, "schemaVersion": { "type": "string", "const": "2.0", "description": "Must be the literal string 2.0. This breaking wire version models a selected artifact as a required artifact file set." }, "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." }, "classification": { "$ref": "#/$defs/classification", "description": "Optional purpose and product identity tags used by Search-Package. Does not affect install mechanics." }, "dependency": { "$ref": "#/$defs/dependencyModel", "description": "Required dependency model. dependency.requires lists package definitions that must reach Assigned before this one; dependency.policy declares peer-policy constraints evaluated by the dependency planner." }, "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" } } }, "classification": { "type": "object", "additionalProperties": false, "required": [ "tags" ], "properties": { "tags": { "type": "array", "minItems": 1, "uniqueItems": true, "description": "Lowercase hyphenated purpose/product search tags. Keep tags concise; do not duplicate platform, architecture, publisher, installer, or package-format fields.", "items": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" } } } }, "definitionPublication": { "type": "object", "additionalProperties": false, "required": [ "publisherId", "publisherName", "definitionId", "definitionRevision", "publishedAtUtc", "definitionSignature" ], "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." }, "depotNamespace": { "type": "string", "pattern": "^(?:[A-Za-z][A-Za-z0-9_-]*)?$", "description": "Optional stable publication-group namespace used as the first subdirectory under each package depot basePath. It prevents artifact-path collisions when catalogs or release groups reuse definition, track, version, and variant identities. When omitted or empty, the runtime uses the neutral namespace 'default'. Eigenverft shipped definitions use 'evf'." }, "definitionSignature": { "$ref": "#/$defs/definitionSignature", "description": "Catalog trust metadata for this file. Required on every 2.0 definition. Draft authoring: kind=unsigned (no signatureValue). Published strict catalogs: kind=signed after Sign-PackageDefinition or Resign-PackageDefinition. Do not hand-edit signatureValue." } } }, "definitionSignature": { "type": "object", "additionalProperties": false, "description": "Embedded catalog signature block. Agents author unsigned drafts; maintainers sign with Sign-PackageDefinition. signatureValue is excluded from canonical bytes when kind=signed.", "required": [ "kind", "format", "signedContent" ], "properties": { "kind": { "type": "string", "enum": [ "signed", "unsigned" ], "description": "unsigned = draft or migration placeholder while editing JSON (no signatureValue). signed = production catalog after Sign-PackageDefinition injected signatureValue and key metadata." }, "format": { "type": "string", "const": "embedded-json-rsa-sha256-v1", "description": "Fixed catalog signature format for 2.0. Required for both unsigned and signed kinds." }, "signedContent": { "type": "string", "const": "canonicalDefinitionExcludingSignatureValue", "description": "Declares that verification signs canonical JSON with signatureValue removed. Do not change." }, "keyThumbprint": { "type": "string", "pattern": "^[A-Fa-f0-9]{40,128}$", "description": "Hex thumbprint of the signing certificate. Present when kind=signed; set by Sign-PackageDefinition, not by draft authoring." }, "signerDisplayName": { "type": "string", "minLength": 1, "description": "Short display label for the signer. Present when kind=signed; set by signing tooling." }, "certificateSubject": { "type": "string", "description": "Optional X.509 subject for audit/UI when kind=signed." }, "certificatePem": { "type": "string", "minLength": 1, "description": "Optional public X.509 certificate PEM embedded by Sign-PackageDefinition. It lets clients verify an unknown signing key before asking or auto-importing local trust. Public material only; never place private keys here." }, "signedAtUtc": { "type": "string", "format": "date-time", "description": "UTC time when kind=signed was applied. Set by Sign-PackageDefinition." }, "signatureValue": { "type": "string", "contentEncoding": "base64", "description": "RSA-SHA256 signature over canonical definition bytes. Required when kind=signed. Never author or paste manually; use Sign-PackageDefinition." } }, "allOf": [ { "if": { "properties": { "kind": { "const": "signed" } }, "required": [ "kind" ] }, "then": { "required": [ "keyThumbprint", "signerDisplayName", "signedAtUtc", "signatureValue" ] } }, { "if": { "properties": { "kind": { "const": "unsigned" } }, "required": [ "kind" ] }, "then": { "not": { "anyOf": [ { "required": [ "signatureValue" ] }, { "required": [ "certificatePem" ] } ] } } } ] }, "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 } } }, "dependencyPolicy": { "type": "object", "additionalProperties": false, "properties": { "conflictsWith": { "type": "array", "items": { "$ref": "#/$defs/dependencyPolicyReference" }, "description": "Definitions that must not appear in the same approved dependency plan." }, "requiresAbsent": { "type": "array", "items": { "$ref": "#/$defs/dependencyPolicyReference" }, "description": "Definitions that must be absent from the approved plan and local assignment inventory." } }, "description": "Optional peer policy evaluated by the dependency planner before install/materialization. conflictsWith blocks incompatible planned peers; requiresAbsent blocks peers that are planned or already assigned locally." }, "dependencyPolicyReference": { "type": "object", "additionalProperties": false, "required": [ "definitionId" ], "properties": { "publisherId": { "$ref": "#/$defs/publisherIdentifier", "description": "Optional publisher namespace pin for the peer-policy reference." }, "definitionId": { "$ref": "#/$defs/identifier", "description": "Package definition id referenced by peer policy." }, "versionRange": { "$ref": "#/$defs/versionRange", "description": "Optional version range limiting the peer-policy match." } } }, "versionRange": { "type": "string", "minLength": 1, "pattern": "^(?:\\s*,?\\s*(?:>=|<=|==|=|>|<)?[^\\s,|*^~]+)+\\s*$", "description": "Comparator range string. Terms are whitespace or comma separated and ANDed; supported operators are =, ==, >, >=, <, <=; bare version means exact match." }, "artifacts": { "type": "object", "$comment": "AUTHOR FOCUS: targets[] selects a machine lane and declares reusable artifactFiles layout/acquisition. releases[] supplies exact per-version artifactFiles trust facts. Target and release file ids must match exactly. sources contains named download roots.", "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." }, "artifactFiles": { "$ref": "#/$defs/artifactFileTargetMap", "description": "Every required static file for this target, keyed by stable file id. Omit only for dynamic npm materialization." } } }, "artifactFileTargetMap": { "type": "object", "minProperties": 1, "propertyNames": { "$ref": "#/$defs/identifier" }, "additionalProperties": { "$ref": "#/$defs/artifactFileTarget" } }, "artifactFileTarget": { "type": "object", "additionalProperties": false, "required": [ "relativePathTemplate", "acquisitionCandidates" ], "properties": { "relativePathTemplate": { "type": "string", "minLength": 1, "description": "Artifact-root-relative materialized path template. It may include version/release tokens and subdirectories." }, "acquisitionCandidates": { "$ref": "#/$defs/acquisitionCandidates", "description": "Ordered fallback ways to materialize this one 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": "Selectable artifact identity used for latest selection, -PackageVersion pins, version ranges, install/depot paths, inventory currentVersion, and replace-vs-reuse decisions. Must be unique within the definition (case-insensitive)." }, "reportedVersion": { "type": "string", "minLength": 1, "description": "Optional version text reported by the installed application (for readiness expectedValue tokens). When omitted, the runtime treats reportedVersion as equal to version. Not a selector." }, "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. Validate combinations against Wire2_0 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." }, "artifactFiles": { "$ref": "#/$defs/artifactFileReleaseMap", "description": "Exact release facts keyed by the same file ids declared on the target. Omit only for dynamic npm materialization." } } }, "artifactFileReleaseMap": { "type": "object", "minProperties": 1, "propertyNames": { "$ref": "#/$defs/identifier" }, "additionalProperties": { "$ref": "#/$defs/artifactFileRelease" } }, "artifactFileRelease": { "type": "object", "additionalProperties": false, "properties": { "relativePath": { "type": "string", "minLength": 1, "description": "Exact artifact-root-relative path override for this release." }, "sourcePath": { "type": "string", "description": "Optional source-relative path override for this release file." }, "acquisitionCandidates": { "$ref": "#/$defs/acquisitionCandidates", "description": "Optional ordered candidate override for this release file." }, "url": { "type": "string", "description": "Optional direct URL owned by this release file." }, "urlTemplate": { "type": "string", "description": "Optional direct URL template owned by this release file." }, "contentHash": { "$ref": "#/$defs/contentHash", "description": "Content trust boundary for this exact file." }, "publisherSignature": { "$ref": "#/$defs/publisherSignature", "description": "Publisher signature requirement for this exact executable file." } } }, "acquisitionCandidates": { "type": "array", "description": "Ordered fallback candidates used to materialize one artifact file. 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": "vendorDownload" }, "sourceId": { "$ref": "#/$defs/identifier", "description": "Required when resolving through artifacts.sources + sourcePath. Omit for direct url/urlTemplate vendor 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 vendor/upstream URL. Mutually exclusive with sourceId/sourcePath." }, "urlTemplate": { "type": "string", "description": "Direct absolute vendor/upstream 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", "sourceArtifactFileId", "entryPath", "searchOrder", "verification" ], "properties": { "kind": { "const": "archiveEntry" }, "sourceArtifactFileId": { "$ref": "#/$defs/identifier", "description": "Another file in the selected artifact set whose archive contains entryPath." }, "entryPath": { "type": "string", "minLength": 1, "description": "Safe archive-relative path of the single file to extract." }, "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 Wire2_0 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 Wire2_0: { \"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 exactly one schema-defined install engine (expandArchive, npmMaterializedInstallGlobalPackage, powershellModuleInstaller, nsisInstaller, innoSetupInstaller, msiInstaller, runInstaller, placePackageFile) and must agree with discovery.presence. Do not mix fields from another install shape; additionalProperties=false is intentional. Use dedicated adapters for NSIS, Inno Setup, and MSI when their target-directory handling fits. Generic runInstaller is only a raw process launch shape and does not allow installDirectory. 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", "artifactFileId", "installDirectory", "expandedRoot", "createDirectories" ], "properties": { "kind": { "const": "expandArchive" }, "artifactFileId": { "$ref": "#/$defs/identifier", "description": "Required artifact file containing the archive to expand." }, "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", "artifactFileId", "installDirectory", "targetRelativePath" ], "properties": { "kind": { "const": "placePackageFile" }, "artifactFileId": { "$ref": "#/$defs/identifier", "description": "Required artifact file to place." }, "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", "artifactFileId", "installDirectory", "commandArguments", "targetDirectoryArgument" ], "properties": { "kind": { "const": "nsisInstaller" }, "artifactFileId": { "$ref": "#/$defs/identifier", "description": "Required NSIS executable artifact file." }, "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", "artifactFileId", "installDirectory", "commandArguments", "targetDirectoryArgument" ], "properties": { "kind": { "const": "innoSetupInstaller" }, "artifactFileId": { "$ref": "#/$defs/identifier", "description": "Required Inno Setup executable artifact file." }, "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", "artifactFileId", "installDirectory", "commandArguments", "targetDirectoryProperty" ], "properties": { "kind": { "const": "msiInstaller" }, "artifactFileId": { "$ref": "#/$defs/identifier", "description": "Required MSI artifact file." }, "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, "$comment": "Generic raw installer process launch. This shape intentionally does not own installDirectory. Do not add installDirectory or target-directory helper fields here; choose nsisInstaller, innoSetupInstaller, msiInstaller, expandArchive, or another schema-defined operation when the engine must manage an install directory. installerKind is descriptive/logging metadata only and does not create product-specific behavior.", "required": [ "kind", "artifactFileId", "targetKind", "installerKind", "uiMode", "elevation", "timeoutSec", "commandArguments", "successExitCodes", "restartExitCodes" ], "properties": { "kind": { "const": "runInstaller" }, "artifactFileId": { "$ref": "#/$defs/identifier", "description": "Required executable artifact file." }, "targetKind": { "type": "string", "description": "directory means the launched installer is expected to place payload under its own documented arguments, but this shape does not accept installDirectory. machinePrerequisite is for prerequisite installers where readiness can skip acquisition/install when already satisfied.", "enum": [ "directory", "machinePrerequisite" ] }, "installerKind": { "type": "string", "description": "Descriptive/logging label such as burn. It is not an adapter selector and does not permit properties outside assignRunInstaller." }, "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", "artifactFileId", "moduleName", "requiredVersion" ], "properties": { "kind": { "const": "powershellModuleInstaller" }, "artifactFileId": { "$ref": "#/$defs/identifier", "description": "Required PowerShell module nupkg artifact file." }, "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 Wire2_0; 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" } }, "dependencyRequirement": { "type": "object", "additionalProperties": false, "required": [ "definitionId" ], "properties": { "publisherId": { "$ref": "#/$defs/publisherIdentifier", "description": "Optional publisher namespace pin for this dependency. Omit to use catalog-trust conflict policy." }, "definitionId": { "$ref": "#/$defs/identifier", "description": "Package definition id to assign before this package." }, "versionRange": { "$ref": "#/$defs/versionRange", "description": "Optional dependency edge version range. Use comparator terms such as >=1.2.0 <2.0.0; terms separated by whitespace or comma are ANDed. Bare versions are exact matches." } }, "description": "Dependency edge reference used inside dependency.requires[]." }, "dependencyModel": { "type": "object", "additionalProperties": false, "required": [ "requires" ], "properties": { "requires": { "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 catalog-trust conflict policy, include it to pin one definitionPublication.publisherId. Do not use retired repositoryId or repositorySourceId on dependency objects.", "items": { "$ref": "#/$defs/dependencyRequirement" } }, "policy": { "$ref": "#/$defs/dependencyPolicy", "description": "Optional peer policy evaluated by the dependency planner before install/materialization." } } } } } |