name: Runtime conformance
on:
workflow_dispatch:
inputs:
prism_benchmarks:
description: Run the ported Prism benchmark workloads on Windows ARM64
type: boolean
default: false
prism_gradients:
description: Include optional gradient mode; pinned upstream has unsupported backward operations
type: boolean
default: false
permissions:
contents: read
actions: read
env:
# Checkout timestamps change on every runner. Reuse compiled Rust only when
# Cargo verifies the source contents, while every check and test still runs.
CARGO_UNSTABLE_CHECKSUM_FRESHNESS: 'true'
CARGO_BUILD_FINGERPRINT: content
# Execution can use finer partitions than the unchanged 16-part planning
# proof. Keep this in sync with the prism-backend-run matrix below.
PRISM_BACKEND_EXECUTION_COUNT: '32'
concurrency:
# Full source/reference qualification is an explicit release/diagnostic request.
# Routine pushes use runtime-regression.yml and never satisfy this full gate.
group: runtime-conformance-${{ github.ref }}-${{ github.run_id }}
cancel-in-progress: false
jobs:
changes:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-24.04-arm
timeout-minutes: 5
outputs:
plan: ${{ steps.impact.outputs.plan }}
conformance: ${{ steps.impact.outputs.conformance }}
codec: ${{ steps.impact.outputs.codec }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 0
- name: Verify affected-crate selection and aggregate-gate contracts
shell: bash
run: python3 -B -m unittest discover -s .github/ci -p 'test_*.py'
- name: Select affected runtime conformance groups
id: impact
shell: bash
env:
BEFORE: ${{ github.event.before }}
GITHUB_TOKEN: ${{ github.token }}
run: python3 .github/ci/impact.py --before "$BEFORE" --after "$GITHUB_SHA" --workflow runtime-conformance.yml
prism-upstream:
name: prism-upstream / ${{ matrix.partition }}
if: github.ref == 'refs/heads/main' && needs.changes.outputs.conformance == 'true'
needs: [changes, prism-backend-tools]
runs-on: windows-11-arm
timeout-minutes: 330
strategy:
fail-fast: false
matrix:
partition: [0, 1, 3]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Build local conformance policy for ordinary source partitions
uses: ./.github/actions/conformance-policy
- name: Reuse the pinned upstream archive
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/SwiftBonsai-PrismUpstreamDownloads
key: prism-upstream-download-v1-${{ runner.os }}-${{ hashFiles('tools/prism/source.lock.json') }}
- name: Download revision-bound common production tools
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: prism-backend-tools
path: ${{ runner.temp }}/prism-backend-tools
- name: Reuse hash-locked tokenizer and LoRA download inputs
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/SwiftBonsai-PrismFixtureDownloads
key: prism-fixtures-v1-source-${{ matrix.partition }}-${{ hashFiles('tests/upstream_prism/tokenizer-reference-assets.json', 'tests/upstream_prism/tokenizer-repository-assets.json', 'tests/upstream_prism/lora-assets.json') }}
- name: Run safe Rust conformance on upstream and Rust
shell: pwsh
working-directory: ${{ runner.temp }}
env:
SOURCE_PARTITION: ${{ matrix.partition }}
# DSpark's unchanged native session passes in isolation; avoid
# overlapping it with the other heavy partition-three adapters.
PRISM_CASE_PARALLEL: ${{ matrix.partition == 3 && '1' || '4' }}
run: |
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
$evidence = Join-Path $env:RUNNER_TEMP ('SwiftBonsai-PrismUpstream-' + [guid]::NewGuid().ToString('N'))
"PRISM_UPSTREAM_EVIDENCE=$evidence" >> $env:GITHUB_ENV
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.Common.psm1')
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.PrismSource.psm1')
$inference = Resolve-PrismSource
$lock = Get-Content -LiteralPath (Join-Path $inference 'tools/prism/source.lock.json') -Raw | ConvertFrom-Json
$downloads = Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismUpstreamDownloads'
[void][IO.Directory]::CreateDirectory($downloads)
$archive = Join-Path $downloads ("prism-$($lock.ArchiveSha256).zip")
$null = Receive-LockedArtifact -Uri $lock.ArchiveUrl -Path $archive -Bytes $lock.ArchiveBytes -Sha256 $lock.ArchiveSha256 -TimeoutSeconds 600
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismUpstream.ps1') -SourceArchive $archive -EvidenceDirectory $evidence -TargetDirectory (Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismUpstreamRust') -CommonToolsBundleDirectory (Join-Path $env:RUNNER_TEMP 'prism-backend-tools') -AssetCacheDirectory (Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismFixtureDownloads') -Generator 'Visual Studio 18 2026' -NativePlatform ARM64 -Toolchain nightly-2026-11-09-aarch64-pc-windows-msvc -Parallel 4 -CaseParallel ([int]$env:PRISM_CASE_PARALLEL) -DeferBackend -SourcePartition ([int]$env:SOURCE_PARTITION) | ConvertTo-Json -Depth 12
- name: Publish ordinary source results for the complete gate
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: prism-ordinary-results-${{ matrix.partition }}
path: |
${{ env.PRISM_UPSTREAM_EVIDENCE }}/cpp-results.json
${{ env.PRISM_UPSTREAM_EVIDENCE }}/rust-results.json
${{ env.PRISM_UPSTREAM_EVIDENCE }}/receipt.json
if-no-files-found: error
- name: Run explicitly requested safe Rust benchmark workloads
if: matrix.partition == 3 && github.event_name == 'workflow_dispatch' && inputs.prism_benchmarks
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.Native.psm1')
$receipt = Get-Content -LiteralPath (Join-Path $env:PRISM_UPSTREAM_EVIDENCE 'receipt.json') -Raw | ConvertFrom-Json
$bridge = @($receipt.NativeBuilds | Where-Object { $_.Family -ceq 'common' })
if ($receipt.Status -cnotin @('complete','awaiting-backend') -or $bridge.Count -ne 1) { throw 'Benchmark requires the settled reference build.' }
foreach ($benchmark in @('peg-deserialize', 'sampling', 'chat-peg')) {
foreach ($target in @('cpp', 'rust')) {
$output = Join-Path $env:PRISM_UPSTREAM_EVIDENCE "$benchmark-$target-benchmark.json"
$arguments = @('--target', $target, '--benchmark', $benchmark, '--output', $output)
if ($target -eq 'cpp') { $arguments += @('--common-bridge', $bridge[0].Executable, '--evidence-directory', (Join-Path $env:PRISM_UPSTREAM_EVIDENCE "$benchmark-benchmark-bridge")) }
$result = Invoke-BonsaiNativeProcess -Executable $receipt.HarnessExecutable -ArgumentList $arguments -WorkingDirectory $env:PRISM_UPSTREAM_EVIDENCE -TimeoutSeconds 300 -LogPath (Join-Path $env:PRISM_UPSTREAM_EVIDENCE "$benchmark-$target-benchmark.log")
if ($result.ExitCode -ne 0) { throw "Benchmark infrastructure failed for $target." }
$report = Get-Content -LiteralPath $output -Raw | ConvertFrom-Json
if ($report.Measure -cne 'benchmark-workloads' -or $report.Cases.Count -ne 1 -or ($target -eq 'cpp' -and $report.Cases[0].Status -cne 'measured')) { throw 'Benchmark workload report is incomplete.' }
($report | ConvertTo-Json -Depth 8) >> $env:GITHUB_STEP_SUMMARY
}
}
- name: Summarize imported Prism coverage
if: always() && env.PRISM_UPSTREAM_EVIDENCE != ''
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
$report = Join-Path $env:PRISM_UPSTREAM_EVIDENCE 'report.json'
if (Test-Path -LiteralPath $report) {
$result = Get-Content -LiteralPath $report -Raw | ConvertFrom-Json
'### Pinned Prism conformance baseline' >> $env:GITHUB_STEP_SUMMARY
'Coverage unit: upstream test source files. Unsupported files count against the green fraction; this is not an assertion-level pass rate.' >> $env:GITHUB_STEP_SUMMARY
($result.Summary | ConvertTo-Json -Depth 8) >> $env:GITHUB_STEP_SUMMARY
'' >> $env:GITHUB_STEP_SUMMARY
'| Source | Rust | C++ control | Detail |' >> $env:GITHUB_STEP_SUMMARY
'| --- | --- | --- | --- |' >> $env:GITHUB_STEP_SUMMARY
foreach ($case in $result.Cases) {
$detail = ([string]$case.Detail).Replace('|', '/').Replace("`n", ' ').Replace("`r", ' ')
"| $($case.Id) | $($case.Status) | $($case.ReferenceStatus) | $detail |" >> $env:GITHUB_STEP_SUMMARY
}
} else {
'Prism import did not produce a complete report; inspect retained build/command logs.' >> $env:GITHUB_STEP_SUMMARY
}
- name: Pack every Prism outcome and build diagnostic
if: always() && env.PRISM_UPSTREAM_EVIDENCE != ''
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
$archive = Join-Path $env:RUNNER_TEMP 'prism-upstream-${{ matrix.partition }}-${{ github.sha }}-${{ github.run_id }}.zip'
& (Join-Path $env:GITHUB_WORKSPACE 'scripts/Compress-PrismEvidence.ps1') -EvidenceDirectory $env:PRISM_UPSTREAM_EVIDENCE -ArchivePath $archive -EvidenceKind Ordinary | ConvertTo-Json
"PRISM_UPSTREAM_ARCHIVE=$archive" >> $env:GITHUB_ENV
- name: Retain every Prism outcome and build diagnostic
if: always() && env.PRISM_UPSTREAM_ARCHIVE != ''
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
path: ${{ env.PRISM_UPSTREAM_ARCHIVE }}
if-no-files-found: error
# Stream one precompressed file instead of a JS ZIP entry per request.
archive: false
prism-upstream-grammar:
name: prism-upstream / ${{ matrix.partition }}
if: github.ref == 'refs/heads/main' && needs.changes.outputs.conformance == 'true'
needs: changes
runs-on: windows-11-arm
timeout-minutes: 330
strategy:
fail-fast: false
matrix:
partition: [2]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Build local conformance policy for source regressions
uses: ./.github/actions/conformance-policy
- name: Verify the native acceptance host and identify the Rust cache
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
if (-not $IsWindows -or [Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -ne [Runtime.InteropServices.Architecture]::Arm64) { throw 'Prism acceptance requires native Windows ARM64.' }
$identity = rustc +nightly-2026-11-09-aarch64-pc-windows-msvc -vV
if ($identity -notcontains 'host: aarch64-pc-windows-msvc') { throw 'Expected native Windows ARM64 Rust.' }
$identity
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio/Installer/vswhere.exe'
if (-not [IO.File]::Exists($vswhere)) { throw 'Visual Studio Installer discovery is required for the ClangCL toolset.' }
$visualStudio = (& $vswhere -latest -products '*' -version '[18.0,19.0)' -requires Microsoft.VisualStudio.Component.VC.Llvm.Clang -property installationPath | Out-String).Trim()
if (-not $visualStudio -or -not [IO.Directory]::Exists($visualStudio)) { throw 'Visual Studio 2026 with the LLVM Clang component is required for ARM64 ggml.' }
"Native C++ acceptance uses Visual Studio 2026 ClangCL ARM64: $visualStudio"
"PRISM_UPSTREAM_CACHE_HOST=$env:ImageOS-$env:ImageVersion-$([Environment]::OSVersion.Version)" >> $env:GITHUB_ENV
$visualStudioVersion = (& $vswhere -latest -products '*' -version '[18.0,19.0)' -requires Microsoft.VisualStudio.Component.VC.Llvm.Clang -property installationVersion | Out-String).Trim()
$msvcVersion = (Get-Content -LiteralPath (Join-Path $visualStudio 'VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt') -Raw).Trim()
$llvmCompilers = @(Get-ChildItem -LiteralPath (Join-Path $visualStudio 'VC/Tools/Llvm') -Recurse -File -Filter clang-cl.exe)
if (-not $llvmCompilers.Count) { throw 'The pinned Visual Studio LLVM compiler is missing.' }
$llvmIdentity = @($llvmCompilers | Sort-Object FullName | ForEach-Object { "$($_.FullName):$((Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash)" }) -join ';'
$cmakeVersion = cmake --version | Out-String
$nativeIdentity = "$env:ImageOS-$env:ImageVersion-$([Environment]::OSVersion.Version)-$visualStudioVersion-$msvcVersion-$llvmIdentity-$cmakeVersion"
$nativeDigest = [Convert]::ToHexStringLower([Security.Cryptography.SHA256]::HashData([Text.Encoding]::UTF8.GetBytes($nativeIdentity)))
"PRISM_UPSTREAM_NATIVE_HOST=$nativeDigest" >> $env:GITHUB_ENV
# Tests and evidence are always fresh. Verified source and native bridge
# outputs can survive checkout timestamps in a stable external directory.
- name: Reuse the pinned upstream archive
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/SwiftBonsai-PrismUpstreamDownloads
key: prism-upstream-download-v1-${{ runner.os }}-${{ hashFiles('tools/prism/source.lock.json') }}
- name: Reuse shared-assertion Rust dependencies and build artifacts
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
${{ runner.temp }}/SwiftBonsai-PrismUpstreamRust
key: prism-upstream-rust-v3-${{ runner.os }}-${{ runner.arch }}-${{ env.PRISM_UPSTREAM_CACHE_HOST }}-nightly-2026-11-09-${{ hashFiles('Cargo.toml', 'Cargo.lock', 'tools/prism/source.lock.json') }}-${{ hashFiles('src/**', 'tests/upstream_prism/**', 'tests/fixtures/**', 'tools/ternary/**', 'tools/gguf/**', 'tools/prism/src/**', 'tools/prism/build.rs', 'tools/prism/Cargo.toml', 'rust-toolchain.toml', '.cargo/**') }}-content-v2
restore-keys: |
prism-upstream-rust-v3-${{ runner.os }}-${{ runner.arch }}-${{ env.PRISM_UPSTREAM_CACHE_HOST }}-nightly-2026-11-09-
- name: Reuse exact pinned upstream native builds
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/SwiftBonsai-PrismUpstreamNative
# Orchestration changes can reuse the same native source/compiler tree.
# Never restore across source pins, adapter code or compiler identities;
# source verification and CMake still run before every correctness test.
key: prism-upstream-native-v2-${{ runner.os }}-${{ runner.arch }}-${{ env.PRISM_UPSTREAM_NATIVE_HOST }}-vs18-clangcl-arm64-${{ hashFiles('tools/prism/source.lock.json') }}-source-${{ matrix.partition }}-${{ hashFiles('tools/prism/upstream/**/CMakeLists.txt', 'tools/prism/upstream/**/*.cmake', 'tools/prism/upstream/**/*.c', 'tools/prism/upstream/**/*.cpp', 'tools/prism/upstream/**/*.h', 'tools/prism/upstream/**/*.hpp', 'tools/prism/upstream/**/*.inc', 'tools/prism/upstream/**/*.rs', 'tools/prism/upstream/patches/**', 'tools/prism/upstream/reference-patches.lock.json', 'tools/prism/upstream/llguidance.lock.json', 'tests/Test-PrismUpstream.ps1', 'scripts/Bonsai.PrismNativeCache.psm1', 'scripts/Bonsai.PrismGrammar.psm1', 'scripts/Bonsai.PrismReferencePatch.psm1') }}
- name: Run safe Rust conformance on upstream and Rust
shell: pwsh
working-directory: ${{ runner.temp }}
env:
SOURCE_PARTITION: ${{ matrix.partition }}
run: |
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
$evidence = Join-Path $env:RUNNER_TEMP ('SwiftBonsai-PrismUpstream-' + [guid]::NewGuid().ToString('N'))
"PRISM_UPSTREAM_EVIDENCE=$evidence" >> $env:GITHUB_ENV
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.Common.psm1')
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.PrismSource.psm1')
$inference = Resolve-PrismSource
$lock = Get-Content -LiteralPath (Join-Path $inference 'tools/prism/source.lock.json') -Raw | ConvertFrom-Json
$downloads = Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismUpstreamDownloads'
[void][IO.Directory]::CreateDirectory($downloads)
$archive = Join-Path $downloads ("prism-$($lock.ArchiveSha256).zip")
$null = Receive-LockedArtifact -Uri $lock.ArchiveUrl -Path $archive -Bytes $lock.ArchiveBytes -Sha256 $lock.ArchiveSha256 -TimeoutSeconds 600
cargo +nightly-2026-11-09-aarch64-pc-windows-msvc fetch --locked --manifest-path (Join-Path $inference 'Cargo.toml')
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismEvidence.ps1') -Case Ordinary
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismEvidence.ps1') -Case Backend
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismNativeCache.ps1')
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismFixtureCache.ps1')
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismSourcePartition.ps1')
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismSourceResults.ps1')
foreach ($case in @('Scheduling', 'Identity', 'ProcessFailure')) {
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismRunner.ps1') -Case $case
}
foreach ($case in @('Scheduling', 'ProcessFailure')) {
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismTaskRunner.ps1') -Case $case
}
foreach ($case in @('Catalog', 'Ratchet', 'Evidence')) {
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismBaseline.ps1') -Case $case
}
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismUpstream.ps1') -SourceArchive $archive -EvidenceDirectory $evidence -TargetDirectory (Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismUpstreamRust') -NativeBuildDirectory (Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismUpstreamNative') -Generator 'Visual Studio 18 2026' -NativePlatform ARM64 -Toolchain nightly-2026-11-09-aarch64-pc-windows-msvc -Parallel 4 -CaseParallel 2 -DeferBackend -SourcePartition ([int]$env:SOURCE_PARTITION) | ConvertTo-Json -Depth 12
- name: Publish ordinary source results for the complete gate
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: prism-ordinary-results-${{ matrix.partition }}
path: |
${{ env.PRISM_UPSTREAM_EVIDENCE }}/cpp-results.json
${{ env.PRISM_UPSTREAM_EVIDENCE }}/rust-results.json
${{ env.PRISM_UPSTREAM_EVIDENCE }}/receipt.json
if-no-files-found: error
- name: Summarize imported Prism coverage
if: always() && env.PRISM_UPSTREAM_EVIDENCE != ''
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
$report = Join-Path $env:PRISM_UPSTREAM_EVIDENCE 'report.json'
if (Test-Path -LiteralPath $report) {
$result = Get-Content -LiteralPath $report -Raw | ConvertFrom-Json
'### Pinned Prism conformance baseline' >> $env:GITHUB_STEP_SUMMARY
'Coverage unit: upstream test source files. Unsupported files count against the green fraction; this is not an assertion-level pass rate.' >> $env:GITHUB_STEP_SUMMARY
($result.Summary | ConvertTo-Json -Depth 8) >> $env:GITHUB_STEP_SUMMARY
'' >> $env:GITHUB_STEP_SUMMARY
'| Source | Rust | C++ control | Detail |' >> $env:GITHUB_STEP_SUMMARY
'| --- | --- | --- | --- |' >> $env:GITHUB_STEP_SUMMARY
foreach ($case in $result.Cases) {
$detail = ([string]$case.Detail).Replace('|', '/').Replace("`n", ' ').Replace("`r", ' ')
"| $($case.Id) | $($case.Status) | $($case.ReferenceStatus) | $detail |" >> $env:GITHUB_STEP_SUMMARY
}
} else {
'Prism import did not produce a complete report; inspect retained build/command logs.' >> $env:GITHUB_STEP_SUMMARY
}
- name: Pack every Prism outcome and build diagnostic
if: always() && env.PRISM_UPSTREAM_EVIDENCE != ''
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
$archive = Join-Path $env:RUNNER_TEMP 'prism-upstream-${{ matrix.partition }}-${{ github.sha }}-${{ github.run_id }}.zip'
& (Join-Path $env:GITHUB_WORKSPACE 'scripts/Compress-PrismEvidence.ps1') -EvidenceDirectory $env:PRISM_UPSTREAM_EVIDENCE -ArchivePath $archive -EvidenceKind Ordinary | ConvertTo-Json
"PRISM_UPSTREAM_ARCHIVE=$archive" >> $env:GITHUB_ENV
- name: Retain every Prism outcome and build diagnostic
if: always() && env.PRISM_UPSTREAM_ARCHIVE != ''
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
path: ${{ env.PRISM_UPSTREAM_ARCHIVE }}
if-no-files-found: error
# Stream one precompressed file instead of a JS ZIP entry per request.
archive: false
# Backend planning needs compiled production tools, not ordinary-source
# verdicts. Prepare the checked bundle independently so all backend partitions
# can overlap the exhaustive tokenizer, grammar and model workloads.
prism-backend-tools:
if: github.ref == 'refs/heads/main' && needs.changes.outputs.conformance == 'true'
needs: changes
runs-on: windows-11-arm
timeout-minutes: 35
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Reuse the pinned native Windows ARM64 Rust compiler
uses: ./.github/actions/rust-toolchain
with:
toolchain: nightly-2026-11-09-aarch64-pc-windows-msvc
- name: Identify the backend build host
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
if (-not $IsWindows -or [Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -ne [Runtime.InteropServices.Architecture]::Arm64) { throw 'Prism acceptance requires native Windows ARM64.' }
$identity = rustc +nightly-2026-11-09-aarch64-pc-windows-msvc -vV
if ($identity -notcontains 'host: aarch64-pc-windows-msvc') { throw 'Expected native Windows ARM64 Rust.' }
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio/Installer/vswhere.exe'
if (-not [IO.File]::Exists($vswhere)) { throw 'Visual Studio Installer discovery is required for the ClangCL toolset.' }
$visualStudio = (& $vswhere -latest -products '*' -version '[18.0,19.0)' -requires Microsoft.VisualStudio.Component.VC.Llvm.Clang -property installationPath | Out-String).Trim()
if (-not $visualStudio -or -not [IO.Directory]::Exists($visualStudio)) { throw 'Visual Studio 2026 with the LLVM Clang component is required for ARM64 ggml.' }
"Native C++ acceptance uses Visual Studio 2026 ClangCL ARM64: $visualStudio"
"PRISM_UPSTREAM_CACHE_HOST=$env:ImageOS-$env:ImageVersion-$([Environment]::OSVersion.Version)" >> $env:GITHUB_ENV
$visualStudioVersion = (& $vswhere -latest -products '*' -version '[18.0,19.0)' -requires Microsoft.VisualStudio.Component.VC.Llvm.Clang -property installationVersion | Out-String).Trim()
$msvcVersion = (Get-Content -LiteralPath (Join-Path $visualStudio 'VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt') -Raw).Trim()
$llvmCompilers = @(Get-ChildItem -LiteralPath (Join-Path $visualStudio 'VC/Tools/Llvm') -Recurse -File -Filter clang-cl.exe)
if (-not $llvmCompilers.Count) { throw 'The pinned Visual Studio LLVM compiler is missing.' }
$llvmIdentity = @($llvmCompilers | Sort-Object FullName | ForEach-Object { "$($_.FullName):$((Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash)" }) -join ';'
$cmakeVersion = cmake --version | Out-String
$nativeIdentity = "$env:ImageOS-$env:ImageVersion-$([Environment]::OSVersion.Version)-$visualStudioVersion-$msvcVersion-$llvmIdentity-$cmakeVersion"
$nativeDigest = [Convert]::ToHexStringLower([Security.Cryptography.SHA256]::HashData([Text.Encoding]::UTF8.GetBytes($nativeIdentity)))
"PRISM_UPSTREAM_NATIVE_HOST=$nativeDigest" >> $env:GITHUB_ENV
- name: Reuse the pinned upstream archive
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/SwiftBonsai-PrismUpstreamDownloads
key: prism-upstream-download-v1-${{ runner.os }}-${{ hashFiles('tools/prism/source.lock.json') }}
- name: Reuse shared-assertion Rust dependencies and build artifacts
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
${{ runner.temp }}/SwiftBonsai-PrismUpstreamRust
key: prism-backend-tools-rust-v1-${{ runner.os }}-${{ runner.arch }}-${{ env.PRISM_UPSTREAM_CACHE_HOST }}-nightly-2026-11-09-${{ hashFiles('Cargo.toml', 'Cargo.lock', 'tools/prism/source.lock.json') }}-${{ hashFiles('src/**', 'tests/upstream_prism/**', 'tests/fixtures/**', 'tools/ternary/**', 'tools/gguf/**', 'tools/prism/src/**', 'tools/prism/build.rs', 'tools/prism/Cargo.toml', 'rust-toolchain.toml', '.cargo/**') }}-content-v2
restore-keys: |
prism-backend-tools-rust-v1-${{ runner.os }}-${{ runner.arch }}-${{ env.PRISM_UPSTREAM_CACHE_HOST }}-nightly-2026-11-09-
prism-upstream-rust-v3-${{ runner.os }}-${{ runner.arch }}-${{ env.PRISM_UPSTREAM_CACHE_HOST }}-nightly-2026-11-09-
- name: Reuse exact pinned upstream native builds
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/SwiftBonsai-PrismUpstreamNative
# Orchestration changes can reuse the same native source/compiler tree.
# Never restore across source pins, adapter code or compiler identities;
# source verification and CMake still run before every correctness test.
key: prism-upstream-native-v2-${{ runner.os }}-${{ runner.arch }}-${{ env.PRISM_UPSTREAM_NATIVE_HOST }}-vs18-clangcl-arm64-${{ hashFiles('tools/prism/source.lock.json') }}-backend-tools-${{ hashFiles('tools/prism/upstream/**/CMakeLists.txt', 'tools/prism/upstream/**/*.cmake', 'tools/prism/upstream/**/*.c', 'tools/prism/upstream/**/*.cpp', 'tools/prism/upstream/**/*.h', 'tools/prism/upstream/**/*.hpp', 'tools/prism/upstream/**/*.inc', 'tools/prism/upstream/**/*.rs', 'tools/prism/upstream/patches/**', 'tools/prism/upstream/reference-patches.lock.json', 'tools/prism/upstream/llguidance.lock.json', 'tests/Test-PrismUpstream.ps1', 'scripts/Bonsai.PrismNativeCache.psm1', 'scripts/Bonsai.PrismGrammar.psm1', 'scripts/Bonsai.PrismReferencePatch.psm1') }}
- name: Prepare revision-bound native backend tools without running source workloads
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
$evidence = Join-Path $env:RUNNER_TEMP ('SwiftBonsai-PrismBackendTools-' + [guid]::NewGuid().ToString('N'))
"PRISM_BACKEND_TOOLS_EVIDENCE=$evidence" >> $env:GITHUB_ENV
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.Common.psm1')
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.PrismSource.psm1')
$inference = Resolve-PrismSource
$lock = Get-Content -LiteralPath (Join-Path $inference 'tools/prism/source.lock.json') -Raw | ConvertFrom-Json
$downloads = Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismUpstreamDownloads'
[void][IO.Directory]::CreateDirectory($downloads)
$archive = Join-Path $downloads ("prism-$($lock.ArchiveSha256).zip")
$null = Receive-LockedArtifact -Uri $lock.ArchiveUrl -Path $archive -Bytes $lock.ArchiveBytes -Sha256 $lock.ArchiveSha256 -TimeoutSeconds 600
cargo +nightly-2026-11-09-aarch64-pc-windows-msvc fetch --locked --manifest-path (Join-Path $inference 'Cargo.toml')
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismBackendBundle.ps1') -SourceArchive $archive
$prepared = & (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismUpstream.ps1') -Case BackendOps -PrepareBackendToolsOnly -SourceArchive $archive -EvidenceDirectory $evidence -TargetDirectory (Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismUpstreamRust') -NativeBuildDirectory (Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismUpstreamNative') -Generator 'Visual Studio 18 2026' -NativePlatform ARM64 -Toolchain nightly-2026-11-09-aarch64-pc-windows-msvc -Parallel 4 -CaseParallel 1
if ($prepared.Status -cne 'backend-tools-ready' -or $prepared.ProjectRevision -cne $env:GITHUB_SHA -or $prepared.FullSourceGate -isnot [bool] -or $prepared.FullSourceGate -ne $false) { throw 'Backend preparation did not produce the expected revision-bound tool handoff.' }
$prepared | ConvertTo-Json -Depth 12
- name: Require native transport equivalence and geometry isolation
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.PrismSource.psm1')
$inference = Resolve-PrismSource
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.PrismBackendBundle.psm1')
$bundle = Import-BonsaiPrismBackendBundle -Directory (Join-Path $env:PRISM_BACKEND_TOOLS_EVIDENCE 'backend-tools') -Repository $inference
$env:BONSAI_BACKEND_TRANSPORT_BRIDGE = $bundle.CommonBridgePath
$env:BONSAI_BACKEND_TRANSPORT_EVIDENCE = Join-Path $env:PRISM_BACKEND_TOOLS_EVIDENCE 'transport-checks'
[void][IO.Directory]::CreateDirectory($env:BONSAI_BACKEND_TRANSPORT_EVIDENCE)
$checks = @(
'backend_ops::transport::pipe::tests::native_file_and_pipe_observations_match_and_geometry_state_is_fresh',
'llguidance::tests::native_candidate_templates_match_original_file_imports'
)
foreach ($check in $checks) {
$log = Join-Path $env:PRISM_BACKEND_TOOLS_EVIDENCE (($check -replace '::', '-') + '.log')
cargo +nightly-2026-11-09-aarch64-pc-windows-msvc test --manifest-path (Join-Path $inference 'Cargo.toml') --package prism-inference --example upstream_prism --target-dir (Join-Path $env:RUNNER_TEMP 'SwiftBonsai-PrismUpstreamRust') --locked --offline --release $check -- --ignored --exact 2>&1 | Tee-Object -FilePath $log
if (-not (Select-String -LiteralPath $log -SimpleMatch 'test result: ok. 1 passed; 0 failed;')) { throw "Required native equivalence check did not run exactly once: $check" }
}
- name: Publish revision-bound native backend shard tools
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: prism-backend-tools
path: ${{ env.PRISM_BACKEND_TOOLS_EVIDENCE }}/backend-tools
if-no-files-found: error
- name: Retain backend tool preparation evidence
if: always() && env.PRISM_BACKEND_TOOLS_EVIDENCE != ''
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: prism-backend-tools-evidence-${{ github.sha }}-${{ github.run_id }}
path: |
${{ env.PRISM_BACKEND_TOOLS_EVIDENCE }}/receipt.json
${{ env.PRISM_BACKEND_TOOLS_EVIDENCE }}/*.log
${{ env.PRISM_BACKEND_TOOLS_EVIDENCE }}/native-*/**
${{ env.PRISM_BACKEND_TOOLS_EVIDENCE }}/transport-checks
if-no-files-found: error
prism-backend-plan:
if: github.ref == 'refs/heads/main' && needs.changes.outputs.conformance == 'true'
needs: [changes, prism-backend-tools]
runs-on: windows-11-arm
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
partition: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: prism-backend-tools
path: ${{ runner.temp }}/prism-backend-tools
- name: Plan every assigned source geometry on both targets
shell: pwsh
working-directory: ${{ runner.temp }}
env:
PARTITION: ${{ matrix.partition }}
RUN_BENCHMARKS: ${{ github.event_name == 'workflow_dispatch' && inputs.prism_benchmarks }}
RUN_GRADIENTS: ${{ github.event_name == 'workflow_dispatch' && inputs.prism_gradients }}
run: |
$evidence = Join-Path $env:RUNNER_TEMP ('prism-backend-plan-' + $env:PARTITION)
"BACKEND_STAGE=$evidence" >> $env:GITHUB_ENV
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismBackend.ps1') -Phase Plan -BundleDirectory (Join-Path $env:RUNNER_TEMP 'prism-backend-tools') -EvidenceDirectory $evidence -Index ([int]$env:PARTITION) -Benchmarks:($env:RUN_BENCHMARKS -ceq 'true') -Gradients:($env:RUN_GRADIENTS -ceq 'true') | Out-Null
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always() && env.BACKEND_STAGE != ''
with:
name: prism-backend-plan-${{ matrix.partition }}
# Fan-in consumes this complete stage envelope, not its verbose evidence.
path: ${{ env.BACKEND_STAGE }}/record.json
if-no-files-found: error
compression-level: 1
- name: Pack backend plan diagnostics
if: always() && env.BACKEND_STAGE != ''
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
$archive = Join-Path $env:RUNNER_TEMP 'prism-backend-evidence-plan-${{ matrix.partition }}.zip'
& (Join-Path $env:GITHUB_WORKSPACE 'scripts/Compress-PrismEvidence.ps1') -EvidenceDirectory $env:BACKEND_STAGE -ArchivePath $archive -EvidenceKind Backend | ConvertTo-Json
"BACKEND_EVIDENCE_ARCHIVE=$archive" >> $env:GITHUB_ENV
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always() && env.BACKEND_EVIDENCE_ARCHIVE != ''
with:
path: ${{ env.BACKEND_EVIDENCE_ARCHIVE }}
if-no-files-found: error
archive: false
prism-backend-join-plan:
if: always() && !cancelled() && github.ref == 'refs/heads/main' && needs.prism-backend-plan.result == 'success' && needs.changes.outputs.conformance == 'true'
needs: [changes, prism-backend-plan]
runs-on: windows-11-arm
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: prism-backend-tools
path: ${{ runner.temp }}/prism-backend-tools
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
pattern: prism-backend-plan-*
path: ${{ runner.temp }}/prism-backend-plans
- name: Prove complete plans and source-order random offsets
shell: pwsh
working-directory: ${{ runner.temp }}
env:
RUN_BENCHMARKS: ${{ github.event_name == 'workflow_dispatch' && inputs.prism_benchmarks }}
RUN_GRADIENTS: ${{ github.event_name == 'workflow_dispatch' && inputs.prism_gradients }}
run: |
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismBackend.ps1') -Phase JoinPlan -BundleDirectory (Join-Path $env:RUNNER_TEMP 'prism-backend-tools') -EvidenceDirectory (Join-Path $env:RUNNER_TEMP 'prism-backend-complete-plans') -InputDirectory (Join-Path $env:RUNNER_TEMP 'prism-backend-plans') -Benchmarks:($env:RUN_BENCHMARKS -ceq 'true') -Gradients:($env:RUN_GRADIENTS -ceq 'true') | Out-Null
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always()
with:
name: prism-backend-complete-plans
path: ${{ runner.temp }}/prism-backend-complete-plans
if-no-files-found: error
compression-level: 1
prism-backend-run:
if: always() && !cancelled() && github.ref == 'refs/heads/main' && needs.prism-backend-join-plan.result == 'success' && needs.changes.outputs.conformance == 'true'
needs: [changes, prism-backend-join-plan]
runs-on: windows-11-arm
timeout-minutes: 330
strategy:
fail-fast: false
matrix:
# Longest observed shards start first under the shared runner limit.
# Membership, source order, RNG offsets and the 32-shard proof stay exact.
# Baseline: Runtime conformance run 40243150077 (Windows ARM64).
partition: [18, 17, 20, 30, 15, 11, 19, 16, 9, 10, 8, 28, 12, 23, 25, 4, 27, 21, 14, 22, 3, 13, 26, 0, 24, 7, 29, 31, 5, 6, 1, 2]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: prism-backend-tools
path: ${{ runner.temp }}/prism-backend-tools
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: prism-backend-complete-plans
path: ${{ runner.temp }}/prism-backend-complete-plans
- name: Execute every assigned workload with its proven plan
shell: pwsh
working-directory: ${{ runner.temp }}
env:
PARTITION: ${{ matrix.partition }}
RUN_BENCHMARKS: ${{ github.event_name == 'workflow_dispatch' && inputs.prism_benchmarks }}
RUN_GRADIENTS: ${{ github.event_name == 'workflow_dispatch' && inputs.prism_gradients }}
run: |
$evidence = Join-Path $env:RUNNER_TEMP ('prism-backend-run-' + $env:PARTITION)
"BACKEND_STAGE=$evidence" >> $env:GITHUB_ENV
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismBackend.ps1') -Phase Run -BundleDirectory (Join-Path $env:RUNNER_TEMP 'prism-backend-tools') -EvidenceDirectory $evidence -PlanPath (Join-Path $env:RUNNER_TEMP 'prism-backend-complete-plans/plans.json') -Index ([int]$env:PARTITION) -ExecutionCount ([int]$env:PRISM_BACKEND_EXECUTION_COUNT) -Benchmarks:($env:RUN_BENCHMARKS -ceq 'true') -Gradients:($env:RUN_GRADIENTS -ceq 'true') | Out-Null
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always() && env.BACKEND_STAGE != ''
with:
name: prism-backend-run-${{ matrix.partition }}
# Keep numerical evidence separate from the final gate's compact input.
path: ${{ env.BACKEND_STAGE }}/record.json
if-no-files-found: error
compression-level: 1
- name: Pack backend run diagnostics
if: always() && env.BACKEND_STAGE != ''
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
$archive = Join-Path $env:RUNNER_TEMP 'prism-backend-evidence-run-${{ matrix.partition }}.zip'
& (Join-Path $env:GITHUB_WORKSPACE 'scripts/Compress-PrismEvidence.ps1') -EvidenceDirectory $env:BACKEND_STAGE -ArchivePath $archive -EvidenceKind Backend | ConvertTo-Json
"BACKEND_EVIDENCE_ARCHIVE=$archive" >> $env:GITHUB_ENV
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always() && env.BACKEND_EVIDENCE_ARCHIVE != ''
with:
path: ${{ env.BACKEND_EVIDENCE_ARCHIVE }}
if-no-files-found: error
archive: false
prism-upstream-gate:
if: github.ref == 'refs/heads/main' && needs.changes.outputs.conformance == 'true'
needs: [changes, prism-upstream, prism-upstream-grammar, prism-backend-run]
runs-on: windows-11-arm
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Reuse maintenance tools for ordinary source result fan-in
uses: ./.github/actions/conformance-policy
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: prism-backend-tools
path: ${{ runner.temp }}/prism-backend-tools
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: prism-backend-complete-plans
path: ${{ runner.temp }}/prism-backend-complete-plans
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
pattern: prism-ordinary-results-*
path: ${{ runner.temp }}/prism-ordinary-results
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
pattern: prism-backend-run-*
path: ${{ runner.temp }}/prism-backend-runs
- name: Require every source and every backend correctness geometry
shell: pwsh
working-directory: ${{ runner.temp }}
env:
RUN_BENCHMARKS: ${{ github.event_name == 'workflow_dispatch' && inputs.prism_benchmarks }}
RUN_GRADIENTS: ${{ github.event_name == 'workflow_dispatch' && inputs.prism_gradients }}
run: |
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismBackend.ps1') -Phase Gate -BundleDirectory (Join-Path $env:RUNNER_TEMP 'prism-backend-tools') -EvidenceDirectory (Join-Path $env:RUNNER_TEMP 'prism-upstream-gate') -InputDirectory (Join-Path $env:RUNNER_TEMP 'prism-backend-runs') -PlanPath (Join-Path $env:RUNNER_TEMP 'prism-backend-complete-plans/plans.json') -ExecutionCount ([int]$env:PRISM_BACKEND_EXECUTION_COUNT) -OrdinaryEvidenceDirectory (Join-Path $env:RUNNER_TEMP 'prism-ordinary-results') -PartitionedOrdinary -Benchmarks:($env:RUN_BENCHMARKS -ceq 'true') -Gradients:($env:RUN_GRADIENTS -ceq 'true') | ConvertTo-Json -Depth 12
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always()
with:
name: prism-complete-source-gate
path: ${{ runner.temp }}/prism-upstream-gate
if-no-files-found: error
compression-level: 1
codec-native:
if: github.ref == 'refs/heads/main' && needs.changes.outputs.codec == 'true'
needs: changes
runs-on: windows-11-arm
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: ./.github/actions/rust-toolchain
with:
toolchain: nightly-2026-11-09-aarch64-pc-windows-msvc
- name: Reuse the immutable released runtime archive
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/Prism-CodecDownloads
key: prism-codec-download-v1-${{ runner.os }}-${{ hashFiles('tools/codec-probe/native.lock.json') }}
- name: Reuse native codec probe compiler artifacts
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
${{ runner.temp }}/Prism-CodecTarget
key: prism-codec-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('Cargo.toml', 'Cargo.lock', 'tools/codec-probe/**', 'tools/ternary/**', 'rust-toolchain.toml') }}-content-v1
restore-keys: |
prism-codec-v1-${{ runner.os }}-${{ runner.arch }}-
- name: Check the probe and consume every preserved synthetic native codec input
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
if (-not $IsWindows -or [Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -ne 'Arm64') { throw 'Native codec acceptance requires Windows ARM64.' }
$checks = Join-Path $env:RUNNER_TEMP ('Prism-CodecChecks-' + [guid]::NewGuid().ToString('N'))
"PRISM_CODEC_EVIDENCE=$checks" >> $env:GITHUB_ENV
[void][IO.Directory]::CreateDirectory($checks)
$target = Join-Path $env:RUNNER_TEMP 'Prism-CodecTarget'
$manifest = Join-Path $env:GITHUB_WORKSPACE 'Cargo.toml'
Start-Transcript -LiteralPath (Join-Path $checks 'codec-workflow.log') | Out-Null
try {
cargo +nightly-2026-11-09-aarch64-pc-windows-msvc fetch --manifest-path $manifest --locked
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-Rust.ps1') -Package bonsai-codec-probe -Phase build -TargetDirectory $target -EvidenceDirectory (Join-Path $checks 'rust') -Offline | ConvertTo-Json -Depth 8
Import-Module (Join-Path $env:GITHUB_WORKSPACE 'scripts/Bonsai.Common.psm1')
$lock = Get-Content -LiteralPath (Join-Path $env:GITHUB_WORKSPACE 'tools/codec-probe/native.lock.json') -Raw | ConvertFrom-Json
$downloads = Join-Path $env:RUNNER_TEMP 'Prism-CodecDownloads'
[void][IO.Directory]::CreateDirectory($downloads)
$archive = Join-Path $downloads $lock.Runtime.asset.filename
$null = Receive-LockedArtifact -Uri $lock.Runtime.asset.url -Path $archive -Bytes $lock.Runtime.asset.bytes -Sha256 $lock.Runtime.asset.sha256 -TimeoutSeconds 600
& (Join-Path $env:GITHUB_WORKSPACE 'tests/Test-PrismCodec.ps1') -RuntimeArchive $archive -ProbeToolPath (Join-Path $target 'release/bonsai-codec-probe.exe') -EvidenceDirectory (Join-Path $checks 'native')
} finally { Stop-Transcript | Out-Null }
- name: Retain codec corpus, ABI, package and process receipts
if: always() && env.PRISM_CODEC_EVIDENCE != ''
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: prism-native-codec-${{ github.sha }}-${{ github.run_id }}
path: |
${{ env.PRISM_CODEC_EVIDENCE }}/*.log
${{ env.PRISM_CODEC_EVIDENCE }}/rust
${{ env.PRISM_CODEC_EVIDENCE }}/native/*.json
${{ env.PRISM_CODEC_EVIDENCE }}/native/*.log
${{ env.PRISM_CODEC_EVIDENCE }}/native/*.stdout
${{ env.PRISM_CODEC_EVIDENCE }}/native/*.stderr
if-no-files-found: error
runtime-conformance:
if: always() && github.ref == 'refs/heads/main'
needs: [changes, prism-upstream, prism-upstream-grammar, prism-backend-tools, prism-backend-plan, prism-backend-join-plan, prism-backend-run, prism-upstream-gate, codec-native]
runs-on: ubuntu-24.04-arm
timeout-minutes: 2
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Require every selected validation group
shell: bash
env:
CI_NEEDS: ${{ toJSON(needs) }}
run: python3 .github/ci/gate.py --workflow runtime-conformance