Repository navigation
v1.0.0b7: Verified installation, guided AIO deployment and AIO 2608/2609
Pre-releaseHighlights
1. Install Site Ops from a release
Install Site Ops and use published Scale Kit content with your own Site inputs, without a repository clone. The bootstrap verifies the engine archive's provenance and payload, provisions native uv and managed Python with your consent, and installs the recorded dependency wheels. It runs as your ordinary user on Windows x64 or Linux x64 based on glibc.
Use the generated Install Site Ops section below for the exact package version, Windows and Linux commands, verification choices and source enrollment. The README also provides a short command that selects this release by tag and can enroll the official source in the same invocation. That route trusts HTTPS for the initial script. Choose the attestation verification route when your policy requires script provenance before it runs.
Source enrollment records the publisher you trust for 30 days. Azure login and deployment confirmation remain separate choices.
2. Deploy AIO from one cluster ID, with optional Secret Sync
The Arc cluster resource ID is the only required answer for guided AIO installation. Site Ops reads the cluster to derive the subscription, resource group, region and cluster name, and names the Site after the cluster in lowercase. To choose another name, or when the cluster's name is not a valid Site name, add --input siteName=<name>. Environment and country labels are optional.
Use an existing Arc cluster in its own resource group, Azure CLI 2.70.0 or newer signed in with deployment and role assignment permissions, and GitHub CLI 2.95 or a later 2.x release. Enroll official using the instructions below, then replace the cluster placeholder. This command installs AIO and enables Secret Sync together:
siteops deploy aio-install --source "official@v1.0.0b7" --input "cluster=<Arc-cluster-resource-ID>" --input enableSecretSync=true
Secret Sync requires the existing cluster to report an OIDC issuer and enabled workload identity. Omit --input enableSecretSync=true for AIO alone. Secret Sync is disabled by default.
For an existing AIO 2607, 2608 or 2609 instance, replace the instance placeholder and enable Secret Sync directly:
siteops deploy secretsync --source "official@v1.0.0b7" --input "instance=<AIO-instance-resource-ID>"
This route resolves the instance and its associated cluster, uses the actual instance name, and performs Secret Sync enablement without reinstalling or upgrading AIO. Add existingVault to use an existing Key Vault. Answer files and inline answers use the same typed input contract. A Site saved from those answers is an ordinary Site file, and later deployments from it use the saved values without reading the cluster again. See guided inputs.
3. Review a prepared plan and read deployment outcomes
Prepare an executable plan before deployment:
siteops plan aio-install --source "official@v1.0.0b7" --input "cluster=<Arc-cluster-resource-ID>"
plan validates inputs, resolves operations, compiles templates and checks the local tools those operations need. It performs no deployment writes. Supplying a resource ID authorizes bounded Azure reads to resolve the Site. Use --describe for the plan shape without compilation or tool checks.
In an interactive terminal, deploy shows its prepared plan, asks you to confirm, and executes that same plan. A separate plan invocation is a preview, not a saved execution artifact. Add --yes for CI, JSON output or other unattended deployment.
Verified packages deploy the templates their publisher compiled. A local workspace submits its Bicep source, and the plan records the compilation checked during preparation. Progress uses stderr, and final JSON output is one document on stdout. Results retain each Site's and operation's outcome, including partial failure, skipped work, cancellation and unconfirmed completion.
A successful deployment reports completed operations. Check AIO readiness and the workload's functional result separately before proceeding. See plan output, run output and check the result.
4. Browse, acquire and publish complete workspace packages
Keep your Site configuration separate from the content you consume. After enrolling official, acquire this release's workspace and inspect its deployment choices:
siteops --approved-source official project pin .\factory --release v1.0.0b7
siteops --approved-source official --project .\factory browse aio-installThe project pin selects an exact package and leaves your Sites unchanged. Package use verifies provenance, byte integrity, compatibility and current source policy. Add --offline-content to content commands in a pinned project to use cached package and proof bytes. This restricts content acquisition, not Azure reads or deployment.
browse shows requirements, effects, guides and typed input availability without loading Site values or invoking deployment tools. Remote browse --source reads published descriptions rather than deployable content.
Content authors generate a public content index with siteops -w workspaces\iot-operations index --public in a reviewed local checkout, then commit the generated files. Reviewed release declarations build and sign complete workspace packages, including compiled templates and their documentation. A signed engine reference identifies the exact engine selected for a content release. Source enrollment remains the consumer's decision. See projects, browsing and workspace packages.
5. Qualify the exact release candidate before publication
Publication requires passing acceptance for the exact frozen engine and workspace assets. Acceptance covers native installation, guided AIO alone, combined AIO and Secret Sync, Secret Sync on an existing instance, and one deployment across a fleet. Deployment cases check AIO pod readiness and confirm removal of the resources they created.
The publication approval remains separate, and the publisher verifies the bound acceptance receipt before creating a tag or release. Official releases require immutable tags and assets. Windows installation includes a standard user path, and installation checks include Ubuntu 26.04.
Deployment, infrastructure readiness, workload data delivery and Secret Sync materialization remain distinct outcomes. Acceptance checks deployment and readiness. Use the workload and Secret Sync guides for functional checks. See release acceptance.
6. Diagnose failures without publishing private values
Content errors carry stable codes such as content.duplicate-key and content.unknown-field, with fixed guidance and documentation links. Validation also emits structured JSON. From a matching local checkout:
siteops -w workspaces\iot-operations validate aio-install --output json --projection publishableDeployment results classify failed and unconfirmed logical operations, and include failure diagnostics beside the existing operation counts. Publishable output retains causes and allowlisted Azure codes while keeping Site values, paths and raw provider messages private. Azure Pipelines and GitHub Actions render these results with the same helper and preserve the operation's exit status through reporting and cleanup. See the diagnostic index.
7. Choose AIO 2609 or keep an explicit AIO release
AIO 2608 and 2609 configurations join the workspace. AIO 2609, which pins AIO 1.4.112, is the default for inherited Site settings and guided installation. AIO 2607 and 2608 remain selectable through properties.aioRelease or the guided aioRelease input. For example, add --input aioRelease=2608 to the installation command to select 2608 deliberately.
The 2608 and 2609 configurations supply WebAssembly graph controller MQTT trust settings and the OPC UA connector template. Install and upgrade create that template when OPC UA is enabled. With feature mode Disabled, they skip it. The legacy connectors feature supplies the mode when opcua is absent, and opcua takes precedence when both are present. Upgrade uses the existing instance's resolved features.
Use aio-upgrade to change an existing installation's AIO release. See AIO releases for pins, supported transitions and the AIO 2607 connector template limitation.
8. Compose catalog resource sets across a fleet
Select ordered resource sets for devices, assets and dataflows on each Site. Definitions compose by resource identity across the selected files. Assets can reference independently selected devices, and dataflows can reference endpoints and profiles from other sets. Duplicate writers and unresolved references are checked before deployment.
In a matching local checkout, a configured Site can select the shipped sets:
properties:
resourceSets:
devices:
- site-devices
assets:
- site-assets
dataflows:
- shared-mqtt-endpoint
- shared-dataflow-profile
- basic-routingFor a configured Site named plant-one that already runs AIO, review the effective composition:
siteops -w workspaces\iot-operations plan aio-resources -l name=plant-one --describeThe example device points at the OPC PLC simulator used by the samples. Use the sample setup or change its endpoint to your reachable server before applying it.
Local plans show source provenance, applied resources and resolved references. Explicit external assertions let a set describe a dependency managed elsewhere, with its reason retained locally. Those assertions describe expected resources rather than reading Azure to prove existence.
Catalog deployment creates or updates selected definitions. Deselecting a set leaves existing resources in place for deliberate removal. The resource catalog and the basic and composition samples show the full path from selection to workload checks.
Automation and operator controls
- Azure Pipelines can select an attested engine from a release tag or explicit release and source commit, while keeping caller content in its own checkout. Environment service connections and variable groups live in reviewed YAML.
- GitHub Actions uses full commit SHA references for external actions.
- Plain output uses ASCII markers, wraps to the terminal width and shows bounded progress while preparation or provider work continues.
sites --output yaml,sites --output jsonandsites --show-sourcessupport private inspection of resolved configuration and provenance.- AIO extension configuration overrides belong under the saved Site's
parametersmap. See configure the Site.
See CI/CD setup for engine selection, fleet targeting and diagnostic rendering in automation.
Upgrading
Read the v1.0.0b6 to v1.0.0b7 migration guide before updating existing workspaces, scripts or pipelines. It compares this release with v1.0.0b6. From an earlier release, start with the guide's section for the release after yours.
The breaking changes to check first are Site selected parameter paths and catalog resource set selections. Keep dynamic parameter paths relative and inside the workspace, with no .. segments. Replace scalar resource set selections with ordered lists, omit an area for no selection, and use [] to clear an inherited list. Remove the none selection, and give a directly attached dataflow parameter file the path and collections form shown in the migration guide.
The inherited AIO default changes from 2607 to 2609. Pin properties.aioRelease: "2607" to retain the v1.0.0b6 AIO release, or "2608" to select 2608. Use the upgrade operation for an existing instance.
Update automation to use plan in place of deploy --dry-run and plan --describe in place of validate --plan. Unattended deployment requires --yes. Review moved Manifest and resource set paths, the Azure CLI minimum, and matching pipeline templates and result helpers in the migration guide.
An Azure Pipelines pipeline that references the templates from another repository, for example with @scalekit, sets templateRepository to that repository resource's alias. Copied templates need the matching helper scripts from this release. See template repositories and copied templates.
Operational notes
- This is a Scale Kit beta release. The Site Ops source version remains
1.0.0b1, and the included engine artifact has a distinct build suffix. The generated installation section reports its exact package version. - If
siteopsis not found in a new terminal after installation, as is common on Windows, runuv tool update-shelland open a new terminal. Ifuvis not onPATH, run theuvin the command directory the installer prints. Before installing, remove an oldersiteops, such as a pip installation, so it does not take precedence. - Installation and source enrollment do not sign in to Azure or authorize resource changes. Planning with a resource ID performs bounded reads. Deployment requires its own confirmation and can incur Azure charges.
- Reapplying
aio-installcan overwrite instance settings. Select new clusters explicitly for installation, useaio-upgradefor upgrades, and usesecretsyncfor enablement on an existing instance. - Secret Sync enablement grants Key Vault roles to its managed identity. To manage the vault's secrets yourself, for example in the IoT Operations portal, assign your account a Key Vault data role such as Key Vault Secrets Officer.
- A Site name becomes part of its schema registry namespace, which must be unique in the Microsoft Entra tenant. Sites built from typed inputs scope that namespace to their resource group. Give a Site file you write yourself a name that no other Site in the tenant uses. See Site identity.
- Run the OPC UA solution sample from a local checkout of this release, with
siteops -w workspaces/iot-operations. The sample applies an OPC PLC simulator from a pinned public URL, and verified packages apply only the files they carry. - Failure or interruption can leave partial changes. Review the deployment result and provider state before retrying. Resource removal remains an explicit operator action.
Install Site Ops
Package version: 1.0.0b1+build.39340415211.1.g19c8fefb1080. Installing the CLI does not authenticate to Azure or deploy resources.
Already have uv
Use this route on a supported Windows x64 or Linux x64 host with uv 0.12.20 from an approved channel and a package index that serves the runtime dependencies as wheels. The command uses uv-managed CPython and can provision it when needed.
uv tool install "https://github.com/Azure/digital-ops-scale-kit/releases/download/v1.0.0b7/siteops-1.0.0b1+build.39340415211.1.g19c8fefb1080-py3-none-any.whl" --python 3.11.16 --managed-python --no-build --system-certsBootstrap without uv
Use this route when uv is not installed, or when you want the verified installation archive. It needs curl and GitHub CLI 2.95 or newer, never uses administrator rights, and asks before changing tools.
Linux x64 with glibc, including Ubuntu and Azure Cloud Shell:
(
set -euo pipefail
umask 077
download="$(mktemp -d)"
script="$download/siteops-bootstrap.sh"
trap 'rm -f -- "$script"; rmdir -- "$download"' EXIT
curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \
--tlsv1.2 --max-redirs 3 --max-time 120 --max-filesize 40936 \
--output "$script" 'https://github.com/Azure/digital-ops-scale-kit/releases/download/v1.0.0b7/siteops-bootstrap.sh'
[[ "$(wc -c < "$script")" -eq 40936 &&
"$(sha256sum < "$script" | cut -d ' ' -f 1)" == '84ea2f0ae53efe61018b8cb8834f0d27945d4ead176ccc98bc33f78840caa86b' ]] ||
{ echo "The bootstrap script differs from the reviewed release." >&2; exit 1; }
bash "$script" --release 'v1.0.0b7' --source-commit '19c8fefb1080f89eba31325449c77c4f00f93890' \
--repository 'Azure/digital-ops-scale-kit' --source-ref 'refs/heads/main' --caller 'release.yaml'
)Windows x64, PowerShell:
& {
$ErrorActionPreference = 'Stop'
Import-Module (Join-Path $PSHOME 'Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1')
$download = Join-Path $env:TEMP ('siteops-bootstrap-' + [guid]::NewGuid())
New-Item -ItemType Directory -Path $download | Out-Null
$script = Join-Path $download 'siteops-bootstrap.ps1'
try {
$sid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value
icacls $download /inheritance:r /grant:r "*${sid}:(OI)(CI)F" | Out-Null
if ($LASTEXITCODE -ne 0) { throw 'The download directory could not be protected.' }
& curl.exe --fail --silent --show-error --location --proto '=https' --proto-redir '=https' `
--tlsv1.2 --max-redirs 3 --max-time 120 --max-filesize 61220 `
--output $script 'https://github.com/Azure/digital-ops-scale-kit/releases/download/v1.0.0b7/siteops-bootstrap.ps1'
if ($LASTEXITCODE -ne 0) { throw 'The bootstrap script could not be downloaded.' }
if ((Get-Item -LiteralPath $script).Length -ne 61220 -or
(Get-FileHash -LiteralPath $script -Algorithm SHA256).Hash -ine '3c03d57da577e046055c3653e7dbb25d5e56cc4e476e68c280c7a423ce4707ec') {
throw 'The bootstrap script differs from the reviewed release.'
}
powershell.exe -NoProfile -ExecutionPolicy Bypass -File $script `
-Release 'v1.0.0b7' -SourceCommit '19c8fefb1080f89eba31325449c77c4f00f93890' `
-Repository 'Azure/digital-ops-scale-kit' -SourceRef 'refs/heads/main' -Caller 'release.yaml'
if ($LASTEXITCODE -ne 0) { throw 'Site Ops installation did not complete.' }
} finally {
if (Test-Path -LiteralPath $script) { Remove-Item -LiteralPath $script }
[IO.Directory]::Delete($download)
}
}Verify the script before it runs
Use these commands when your policy requires publisher provenance before any installer code runs. They download the script and its detached proof into a fresh private directory without a GitHub login. GitHub CLI then checks the proof against this release's publisher, source commit, signing workflow, calling workflow and runner class. The script runs only after every check passes. If a check fails, stop rather than changing these values.
Confirm that Azure/digital-ops-scale-kit is the publisher you intend. These checks prove that its workflows built the script, not that it is the right publisher. The installation guide explains each check.
Linux x64 with glibc:
(
set -euo pipefail
umask 077
tag='v1.0.0b7' sha='19c8fefb1080f89eba31325449c77c4f00f93890'
repository='Azure/digital-ops-scale-kit' source_ref='refs/heads/main'
signer="https://github.com/$repository/.github/workflows/_siteops-distribution.yaml@$source_ref"
builder="https://github.com/$repository/.github/workflows/release.yaml@$source_ref"
download="$(mktemp -d)"
script="$download/siteops-bootstrap.sh"
trap 'rm -f -- "$script" "$script.attestation.jsonl"; rmdir -- "$download"' EXIT
curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \
--tlsv1.2 --max-redirs 3 --max-time 120 --output "$script" \
'https://github.com/Azure/digital-ops-scale-kit/releases/download/v1.0.0b7/siteops-bootstrap.sh'
curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \
--tlsv1.2 --max-redirs 3 --max-time 120 --output "$script.attestation.jsonl" \
'https://github.com/Azure/digital-ops-scale-kit/releases/download/v1.0.0b7/siteops-bootstrap.sh.attestation.jsonl'
query="length > 0 and all(.[]; .verificationResult.mediaType == \"application/vnd.dev.sigstore.verificationresult+json;version=0.1\" and (.verificationResult.signature.certificate | .buildConfigURI == \"$builder\" and .buildConfigDigest == \"$sha\" and .runnerEnvironment == \"self-hosted\"))"
verified="$(gh attestation verify "$script" --bundle "$script.attestation.jsonl" \
--repo "$repository" --cert-identity "$signer" --source-ref "$source_ref" \
--source-digest "$sha" --signer-digest "$sha" \
--cert-oidc-issuer https://token.actions.githubusercontent.com \
--predicate-type https://slsa.dev/provenance/v1 --hostname github.com \
--digest-alg sha256 --format json --jq "$query")"
[[ "$verified" == true ]] || { echo "Script verification failed." >&2; exit 1; }
bash "$script" --release "$tag" --source-commit "$sha" \
--repository "$repository" --source-ref "$source_ref" --caller 'release.yaml'
)Windows x64, PowerShell:
& {
$ErrorActionPreference = 'Stop'
Import-Module (Join-Path $PSHOME 'Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1')
$tag = 'v1.0.0b7'; $sha = '19c8fefb1080f89eba31325449c77c4f00f93890'
$repository = 'Azure/digital-ops-scale-kit'; $sourceRef = 'refs/heads/main'
$signer = "https://github.com/$repository/.github/workflows/_siteops-distribution.yaml@$sourceRef"
$builder = "https://github.com/$repository/.github/workflows/release.yaml@$sourceRef"
$download = Join-Path $env:TEMP ('siteops-bootstrap-' + [guid]::NewGuid())
New-Item -ItemType Directory -Path $download | Out-Null
$script = Join-Path $download 'siteops-bootstrap.ps1'
$proof = $script + '.attestation.jsonl'
try {
$sid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value
icacls $download /inheritance:r /grant:r "*${sid}:(OI)(CI)F" | Out-Null
if ($LASTEXITCODE -ne 0) { throw 'The download directory could not be protected.' }
foreach ($name in @('siteops-bootstrap.ps1', 'siteops-bootstrap.ps1.attestation.jsonl')) {
& curl.exe --fail --silent --show-error --location --proto '=https' --proto-redir '=https' `
--tlsv1.2 --max-redirs 3 --max-time 120 `
--output (Join-Path $download $name) ('https://github.com/Azure/digital-ops-scale-kit/releases/download/v1.0.0b7/' + $name)
if ($LASTEXITCODE -ne 0) { throw 'A bootstrap asset could not be downloaded.' }
}
$lines = [Collections.Generic.List[string]]::new(); $bytes = 0
$preference = $ErrorActionPreference
try {
$ErrorActionPreference = 'Continue'
& gh.exe attestation verify $script --bundle $proof `
--repo $repository --cert-identity $signer --source-ref $sourceRef `
--source-digest $sha --signer-digest $sha `
--cert-oidc-issuer https://token.actions.githubusercontent.com `
--predicate-type https://slsa.dev/provenance/v1 --hostname github.com `
--digest-alg sha256 --format json 2>$null | ForEach-Object {
$bytes += [Text.Encoding]::UTF8.GetByteCount($_) + 1
if ($bytes -gt 8388608) { throw 'Verification evidence is too large.' }
$lines.Add($_)
}
$status = $LASTEXITCODE
} finally { $ErrorActionPreference = $preference }
if ($status -ne 0 -or $lines.Count -eq 0) { throw 'Script verification failed.' }
$observations = @((($lines -join "`n") | ConvertFrom-Json))
if ($observations.Count -lt 1 -or $observations.Count -gt 128) {
throw 'Script verification returned an unsupported result count.'
}
$expected = @{
subjectAlternativeName = $signer
issuer = 'https://token.actions.githubusercontent.com'
sourceRepositoryURI = "https://github.com/$repository"
sourceRepositoryDigest = $sha
sourceRepositoryRef = $sourceRef
buildSignerDigest = $sha
buildConfigURI = $builder
buildConfigDigest = $sha
runnerEnvironment = 'self-hosted'
}
foreach ($item in $observations) {
$verified = $item.verificationResult
$certificate = $verified.signature.certificate
if ($verified -isnot [pscustomobject] -or $certificate -isnot [pscustomobject] -or
$verified.mediaType -isnot [string] -or
$verified.mediaType -cne 'application/vnd.dev.sigstore.verificationresult+json;version=0.1') {
throw 'Unsupported verified script observation.'
}
foreach ($key in $expected.Keys) {
$value = $certificate.PSObject.Properties[$key].Value
if ($value -isnot [string] -or $value -cne $expected[$key]) {
throw 'The verified script certificate differs from the selected release.'
}
}
}
powershell.exe -NoProfile -ExecutionPolicy Bypass -File $script `
-Release $tag -SourceCommit $sha `
-Repository $repository -SourceRef $sourceRef -Caller 'release.yaml'
if ($LASTEXITCODE -ne 0) { throw 'Site Ops installation did not complete.' }
} finally {
foreach ($path in @($script, $proof)) {
if (Test-Path -LiteralPath $path) { Remove-Item -LiteralPath $path }
}
[IO.Directory]::Delete($download)
}
}Enroll the content source
After installing with either route, enroll this publisher's content source once. Run the same command again to renew the 30 day enrollment. Enrollment works without signing in to GitHub or Azure.
siteops source enroll officialProvenance, verification and maintenance
Expected publisher: Azure/digital-ops-scale-kit. Source commit: 19c8fefb1080f89eba31325449c77c4f00f93890. Source ref: refs/heads/main. Expected calling workflow: release.yaml. Expected provenance runner class: self-hosted. The runner class does not identify a particular pool. Use these values with the guide verification policy.
The bootstrap commands download the complete script into a fresh private directory and check its size and digest before execution. The digest binds the script to these reviewed instructions. It is not independent publisher authentication. The initial script trusts this release's HTTPS delivery. The script separately authenticates the engine ZIP before extracting its installer helper. For publisher provenance before any installer code runs, use the commands under Verify the script before it runs.
Source enrollment is a separate choice: add --enroll-source NAME or -EnrollSource NAME only for an approved source. For the official Azure/digital-ops-scale-kit publisher, the guided examples use official.
The PowerShell execution policy setting applies only to the child process. An organization policy may require an approved managed installation instead.
Runtime dependencies come from your configured package index as wheels when you use the wheel command. To name it explicitly, add --default-index <your approved index>. uv does not read pip configuration. To replace or repair an existing online installation, review the selection and rerun with --reinstall. Confirm the result with siteops --version and siteops --help.
The installation ZIP and standalone wheel each have a detached attestation proof containing signed provenance evidence. uv does not automatically verify GitHub attestations for the online command. For external verification before extraction and a native installation locked to hashes from stable private storage, follow the verified installation guide. The engine path downloads the ZIP and its detached proof, authenticates the ZIP before extraction, then invokes native uv only after independent payload admission. The guide also describes switching between online and verified installations.
Release assets: siteops-1.0.0b1+build.39340415211.1.g19c8fefb1080-py3-none-any.whl, siteops-1.0.0b1+build.39340415211.1.g19c8fefb1080-py3-none-any.whl.attestation.jsonl, siteops-install.zip, and siteops-install.zip.attestation.jsonl. Bootstrap scripts: siteops-bootstrap.ps1 and siteops-bootstrap.ps1.attestation.jsonl, siteops-bootstrap.sh and siteops-bootstrap.sh.attestation.jsonl. Use these assets instead of the generated source archives.
Existing local -w workspaces and configured-Site fleet selectors remain supported. siteops inputs and explicit typed answers are optional for manifests with a typed input contract. A project pin selects content, not operator Site configuration.
Workspace content
This release contains complete workspace packages. Each package has a detached attestation proof containing signed provenance evidence.
After you enroll the content source, deploy Azure IoT Operations to an existing cluster connected to Azure Arc directly from this release:
siteops deploy aio-install --source "official@v1.0.0b7" --input "cluster=<Arc-cluster-resource-ID>"For a repeatable fleet, follow the workspace pin guidance to run siteops project pin with --release for this release. Use an approved source, or supply the trust policy and trusted roots independently. The routing descriptor cannot select either.
- iot-operations.zip
- iot-operations.zip.attestation.jsonl
- siteops-workspaces.json
- siteops-engine.json
- siteops-engine.json.attestation.jsonl
Workspace qualification used the selected installed engine to check package compatibility, protected cache use, and guarded catalog loading.