Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
7c5279b
Add production-backed compiled activation contract family
coneilen Nov 2, 2026
a6fab30
Initialize activation fixture diagnostics under nullable checks
coneilen Nov 2, 2026
dfea333
Add compiled validation host with fail-closed coverage ledger
coneilen Nov 2, 2026
eae3d1e
Normalize compiled host sources and isolate owned SDK caches
coneilen Nov 2, 2026
85658af
Integrate frozen Cards production dependencies by verified three-way …
coneilen Nov 2, 2026
163bf51
Migrate complete UI native helpers and case-level input contracts
coneilen Nov 2, 2026
4481af5
Add held-job child supervision and compiled ownership cases
coneilen Nov 2, 2026
4ceadef
Add protected suite adapters and compiled fixture ABI
coneilen Nov 2, 2026
ef6b73d
Exercise shared owned cleanup authority with negative controls
coneilen Nov 2, 2026
9228042
Normalize shared cleanup coordinator to LF
coneilen Nov 2, 2026
896bdbf
Add supervised PowerShell UI contracts and bounded source assertion o…
coneilen Nov 2, 2026
185e524
Preserve ownership PowerShell semantics in protected focused adapters
coneilen Nov 2, 2026
0f1a551
Share compiled production bindings across UIA packaging and validation
coneilen Nov 2, 2026
b02bba9
Preserve functional UI cases and verify consumed production source li…
coneilen Nov 2, 2026
28a772c
Latch live descendant retention before owned cleanup
coneilen Nov 2, 2026
f313395
Complete production-backed UI derived contracts and full case corresp…
coneilen Nov 2, 2026
dabe363
Preserve hidden target standard handles and retain unknown gate autho…
coneilen Nov 2, 2026
1083da5
Preserve original pipe bytes before strict protocol decoding
coneilen Nov 2, 2026
d09b349
Expose owned focus control primitive without duplicating focus policy
coneilen Nov 2, 2026
0d4adb0
Derive composite coverage from current invocation and verify compiled…
coneilen Nov 2, 2026
a86714e
Support same-invocation suite composition without double-counting der…
coneilen Nov 2, 2026
ca86b23
Implement six compiled host root contract families
coneilen Nov 2, 2026
e71e886
Preserve residual packaging task wiring in compiled validation
coneilen Nov 2, 2026
7eb1d63
Add production-backed mixed UI policy and geometry contracts
coneilen Nov 2, 2026
04f5009
Emit byte-stable UTF-8 mixed UI case protocol
coneilen Nov 2, 2026
1e07958
Exercise actual mixed native edit Rename and metadata policies with i…
coneilen Nov 2, 2026
1881f68
Bind measured mixed UI results to canonical root coverage group
coneilen Nov 2, 2026
d982f84
Map every original mixed validation contract to measured focused cases
coneilen Nov 2, 2026
6b663f2
Cut Windows validation CI over to the full compiled runner
coneilen Nov 2, 2026
fd0c35a
Scope private SDK runtime roots for the compiled validation caller
coneilen Nov 2, 2026
55bdfdd
Bootstrap the exact compiled validation SDK in an owned tool root
coneilen Nov 2, 2026
c5be4f5
Prepare owned Pester 5 before canonical compiled validation
coneilen Nov 2, 2026
a36ac1d
Load compatible UIA runtime dependencies and expose recovery fixture …
coneilen Nov 2, 2026
a3ead8a
Load UIA runtime dependencies at the verified production assembly bou…
coneilen Nov 2, 2026
29becee
Require normal full proof and cover final host prerequisites
coneilen Nov 2, 2026
f9b21f2
Allow measured full compiled validation runtime in CI
coneilen Nov 2, 2026
43cc05e
Document the canonical compiled validation entry
coneilen Nov 2, 2026
4c5d367
Compare Delete Select wrappers consistently across checkout line endings
coneilen Nov 2, 2026
ae92163
Retain hidden compiled validation evidence in scoped CI uploads
coneilen Nov 2, 2026
c3237b9
Wait for original held roots after owned job termination
coneilen Nov 3, 2026
8553112
Preserve native validation failure and lifecycle semantics
coneilen Nov 3, 2026
cfbe45a
Restore the visible canvas after Delete selection
coneilen Nov 3, 2026
374c22c
Require owned Delete canvas restoration and successful stress-job rel…
coneilen Nov 3, 2026
0bf9e39
Use exact control root authority while preserving immediate-parent hi…
coneilen Nov 3, 2026
5a7a3bd
Limit the explicit control click fixture to one activation attempt
coneilen Nov 3, 2026
90479b3
Publish compiled assembly at the real Windows validation boundary
coneilen Nov 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 93 additions & 6 deletions .github/workflows/windows-hardening.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
env:
HARDENING_REQUIRED: ${{ github.event_name != 'pull_request' || needs.changes.result != 'success' || needs.changes.outputs.windows == 'true' }}
runs-on: ${{ (github.event_name != 'pull_request' || needs.changes.result != 'success' || needs.changes.outputs.windows == 'true') && matrix.os || 'ubuntu-latest' }}
timeout-minutes: 15
timeout-minutes: 40
steps:
- name: No Windows-relevant changes
if: env.HARDENING_REQUIRED != 'true'
Expand All @@ -69,13 +69,100 @@ jobs:
if: env.HARDENING_REQUIRED == 'true'
shell: pwsh
run: ./Tools/windows/validate.ps1 -Task hardening
- name: Verify runner contract
# Pull requests run this source contract in the windows-spikes aggregate
# once with pinned Swift. Keep one fallback for this workflow's independent
# scheduled and manual runs.
# Pull requests run the complete compiled host once in windows-spikes.
# Independent scheduled/manual runs retain one Windows 2022 fallback.
- name: Install pinned Swift for runner fallback
if: env.HARDENING_REQUIRED == 'true' && github.event_name != 'pull_request' && matrix.os == 'windows-2022'
uses: compnerd/gha-setup-swift@397094e75494a93fa8d81db0268dbc8f5d6cf7c6 # v0.4.1
timeout-minutes: 10
with:
swift-version: swift-6.3.3-release
swift-build: 6.3.3-RELEASE
cache: true
- name: Install pinned compiled validation SDK
if: env.HARDENING_REQUIRED == 'true' && github.event_name != 'pull_request' && matrix.os == 'windows-2022'
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
timeout-minutes: 10
with:
dotnet-version: 10.0.403
- name: Build compiled validation runner
if: env.HARDENING_REQUIRED == 'true' && github.event_name != 'pull_request' && matrix.os == 'windows-2022'
shell: pwsh
working-directory: Tools/windows/ValidationRunner
timeout-minutes: 10
run: |
$ErrorActionPreference = 'Stop'
$version = dotnet --version
if ($LASTEXITCODE -ne 0 -or $version -cne '10.0.403') {
throw 'Compiled validation requires SDK 10.0.403 selected by global.json.'
}
dotnet build -c Release
if ($LASTEXITCODE -ne 0) { throw "Compiled validation build failed: exit=$LASTEXITCODE" }
- name: Prepare owned Pester 5 prerequisite
if: env.HARDENING_REQUIRED == 'true' && github.event_name != 'pull_request' && matrix.os == 'windows-2022'
shell: pwsh
timeout-minutes: 5
run: |
$ErrorActionPreference = 'Stop'
$pester5 = @(Get-Module -Name Pester | Where-Object { $_.Version.Major -eq 5 })
if ($pester5.Count -eq 0) {
$pester5 = @(Get-Module -ListAvailable -Name Pester | Where-Object { $_.Version.Major -eq 5 })
}
if ($pester5.Count -eq 0) {
$moduleRoot = Join-Path $PWD '.ci-modules'
$null = New-Item -ItemType Directory -Force -Path $moduleRoot
Save-Module -Name Pester -RequiredVersion 5.7.1 -Path $moduleRoot -ErrorAction Stop
$env:PSModulePath = $moduleRoot + [IO.Path]::PathSeparator + $env:PSModulePath
[IO.File]::AppendAllText($env:GITHUB_ENV, "PSModulePath=$env:PSModulePath`n", [Text.UTF8Encoding]::new($false))
}
. .\Tools\windows\Import-PinnedPester.ps1
$loaded = @(Get-Module -Name Pester | Where-Object { $_.Version.Major -eq 5 })
if ($loaded.Count -ne 1) { throw 'Compiled validation requires exactly one loaded Pester 5 module.' }
- name: Verify complete compiled validation runner contract
if: env.HARDENING_REQUIRED == 'true' && github.event_name != 'pull_request' && matrix.os == 'windows-2022'
shell: pwsh
run: ./Tools/windows/Invoke-ValidationRunnerContract.ps1
# Normal full run measured 16m14s; allow 25m execution headroom.
timeout-minutes: 25
run: |
$ErrorActionPreference = 'Stop'
if (Test-Path -LiteralPath .ci-validation-runner\coverage.json) {
throw 'Compiled validation requires a fresh coverage report; prior evidence was retained.'
}
$output = [Collections.Generic.List[string]]::new()
$exitCode = $null
& {
.\Tools\windows\ValidationRunner\bin\Release\net10.0-windows\ValidationRunner.exe --repository-root $PWD --artifact-root .ci-validation-runner
$script:exitCode = $LASTEXITCODE
} 2>&1 | ForEach-Object {
$line = "$_"
$output.Add($line)
Write-Host $line
}
if ($exitCode -ne 0) { throw "Compiled validation failed: exit=$exitCode" }
$report = Get-Content -LiteralPath .ci-validation-runner\coverage.json -Raw | ConvertFrom-Json
if ($report.runner -cne 'CompiledValidationRunner' -or
$report.complete -isnot [bool] -or -not $report.complete -or
-not ($report.requiredCount -is [int] -or $report.requiredCount -is [long]) -or
-not ($report.passedCount -is [int] -or $report.passedCount -is [long]) -or
$report.requiredCount -le 0 -or $report.passedCount -ne $report.requiredCount -or
@($report.units).Count -ne $report.requiredCount -or @($report.errors).Count -ne 0) {
throw 'Compiled validation did not report complete positive full coverage.'
}
$passMarkers = @($output | Where-Object { $_ -ceq 'CompiledValidationRunner: PASS' }).Count
$executedMarkers = @($output | Where-Object { $_ -ceq 'VALIDATION_RUNNER_EXECUTED=1' }).Count
if ($passMarkers -ne 1 -or $executedMarkers -ne 1) {
throw 'Compiled validation must report exactly one full PASS and one positive execution marker.'
}
- name: Retain compiled validation fallback evidence
if: ${{ always() && env.HARDENING_REQUIRED == 'true' && github.event_name != 'pull_request' && matrix.os == 'windows-2022' }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
timeout-minutes: 5
with:
name: compiled-validation-hardening-${{ matrix.os }}-${{ github.run_attempt }}
path: .ci-validation-runner
include-hidden-files: true
if-no-files-found: warn
retention-days: 7
- name: Resolve capture contract failure diagnostics root
id: capture_temp
if: failure()
Expand Down
94 changes: 87 additions & 7 deletions .github/workflows/windows-port-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ env:
# on every Windows-relevant pull request: windows-shell and packaging run in
# windows-shell.yml (required check `windows-shell`), and hardening runs in
# windows-hardening.yml (required `Deterministic hardening (...)` checks). The
# remaining tasks and the source-only runner contract are split across three
# remaining tasks and the compiled runner contract are split across three
# parallel parts behind the required
# `windows-spikes` aggregate job.
jobs:
Expand Down Expand Up @@ -59,16 +59,16 @@ jobs:
shell: pwsh
run: ./Tools/windows/validate.ps1 -Task privacy

# ValidationRunner.Tests.ps1 is source-only but deliberately uses the real
# pinned Swift formatter for its negative control. Run it once on Windows
# The compiled contract host uses the real pinned Swift formatter for its
# negative control. Run the full host once on Windows
# 2022 in parallel instead of repeating it inside spikes-swift and both
# deterministic hardening legs. Windows 2025 remains covered by hardening.
validation-runner:
name: Validation runner contract
needs: changes
if: ${{ !cancelled() && (github.event_name != 'pull_request' || needs.changes.result != 'success' || needs.changes.outputs.windows == 'true') }}
runs-on: windows-2022
timeout-minutes: 20
timeout-minutes: 40
steps:
- name: Check out repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
Expand All @@ -82,10 +82,90 @@ jobs:
swift-build: 6.3.3-RELEASE
cache: true

- name: Verify validation runner contract
- name: Install pinned compiled validation SDK
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
timeout-minutes: 10
with:
dotnet-version: 10.0.403

- name: Build compiled validation runner
shell: pwsh
timeout-minutes: 15
run: ./Tools/windows/Invoke-ValidationRunnerContract.ps1
working-directory: Tools/windows/ValidationRunner
timeout-minutes: 10
run: |
$ErrorActionPreference = 'Stop'
$version = dotnet --version
if ($LASTEXITCODE -ne 0 -or $version -cne '10.0.403') {
throw 'Compiled validation requires SDK 10.0.403 selected by global.json.'
}
dotnet build -c Release
if ($LASTEXITCODE -ne 0) { throw "Compiled validation build failed: exit=$LASTEXITCODE" }

- name: Prepare owned Pester 5 prerequisite
shell: pwsh
timeout-minutes: 5
run: |
$ErrorActionPreference = 'Stop'
$pester5 = @(Get-Module -Name Pester | Where-Object { $_.Version.Major -eq 5 })
if ($pester5.Count -eq 0) {
$pester5 = @(Get-Module -ListAvailable -Name Pester | Where-Object { $_.Version.Major -eq 5 })
}
if ($pester5.Count -eq 0) {
$moduleRoot = Join-Path $PWD '.ci-modules'
$null = New-Item -ItemType Directory -Force -Path $moduleRoot
Save-Module -Name Pester -RequiredVersion 5.7.1 -Path $moduleRoot -ErrorAction Stop
$env:PSModulePath = $moduleRoot + [IO.Path]::PathSeparator + $env:PSModulePath
[IO.File]::AppendAllText($env:GITHUB_ENV, "PSModulePath=$env:PSModulePath`n", [Text.UTF8Encoding]::new($false))
}
. .\Tools\windows\Import-PinnedPester.ps1
$loaded = @(Get-Module -Name Pester | Where-Object { $_.Version.Major -eq 5 })
if ($loaded.Count -ne 1) { throw 'Compiled validation requires exactly one loaded Pester 5 module.' }

- name: Verify complete compiled validation runner contract
shell: pwsh
# Normal full run measured 16m14s; allow 25m execution headroom.
timeout-minutes: 25
run: |
$ErrorActionPreference = 'Stop'
if (Test-Path -LiteralPath .ci-validation-runner\coverage.json) {
throw 'Compiled validation requires a fresh coverage report; prior evidence was retained.'
}
$output = [Collections.Generic.List[string]]::new()
$exitCode = $null
& {
.\Tools\windows\ValidationRunner\bin\Release\net10.0-windows\ValidationRunner.exe --repository-root $PWD --artifact-root .ci-validation-runner
$script:exitCode = $LASTEXITCODE
} 2>&1 | ForEach-Object {
$line = "$_"
$output.Add($line)
Write-Host $line
}
if ($exitCode -ne 0) { throw "Compiled validation failed: exit=$exitCode" }
$report = Get-Content -LiteralPath .ci-validation-runner\coverage.json -Raw | ConvertFrom-Json
if ($report.runner -cne 'CompiledValidationRunner' -or
$report.complete -isnot [bool] -or -not $report.complete -or
-not ($report.requiredCount -is [int] -or $report.requiredCount -is [long]) -or
-not ($report.passedCount -is [int] -or $report.passedCount -is [long]) -or
$report.requiredCount -le 0 -or $report.passedCount -ne $report.requiredCount -or
@($report.units).Count -ne $report.requiredCount -or @($report.errors).Count -ne 0) {
throw 'Compiled validation did not report complete positive full coverage.'
}
$passMarkers = @($output | Where-Object { $_ -ceq 'CompiledValidationRunner: PASS' }).Count
$executedMarkers = @($output | Where-Object { $_ -ceq 'VALIDATION_RUNNER_EXECUTED=1' }).Count
if ($passMarkers -ne 1 -or $executedMarkers -ne 1) {
throw 'Compiled validation must report exactly one full PASS and one positive execution marker.'
}

- name: Retain compiled validation evidence
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
timeout-minutes: 5
with:
name: compiled-validation-runner-${{ github.run_attempt }}
path: .ci-validation-runner
include-hidden-files: true
if-no-files-found: warn
retention-days: 7

- name: Resolve capture contract failure diagnostics root
id: capture_temp
Expand Down
60 changes: 60 additions & 0 deletions Tools/windows/Build-CompiledValidationRunner.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
[CmdletBinding()]
param(
[ValidateSet("Debug", "Release")][string] $Configuration = "Release"
)

$ErrorActionPreference = "Stop"
. (Join-Path $PSScriptRoot "DotNetSdk.ps1")
$repositoryRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot "..\.."))
$projectRoot = Join-Path $PSScriptRoot "ValidationRunner"
$local = Join-Path $projectRoot ".local"
$names = @("DOTNET_CLI_HOME", "NUGET_PACKAGES", "TEMP", "TMP", "DOTNET_CLI_TELEMETRY_OPTOUT",
"DOTNET_GENERATE_ASPNET_CERTIFICATE", "DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "DOTNET_ROOT",
"DOTNET_MULTILEVEL_LOOKUP", "DOTNET_ROLL_FORWARD", "DOTNET_NOLOGO")
$before = @{}
$environment = [Environment]::GetEnvironmentVariables("Process")
foreach ($name in $names) {
$before[$name] = @{ present = $environment.Contains($name); value = $environment[$name] }
}
try {
$env:DOTNET_CLI_HOME = Join-Path $local "dotnet"
$env:NUGET_PACKAGES = Join-Path $local "nuget"
$env:TEMP = Join-Path $local "temp"
$env:TMP = $env:TEMP
$env:DOTNET_CLI_TELEMETRY_OPTOUT = "1"
$env:DOTNET_GENERATE_ASPNET_CERTIFICATE = "false"
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = "1"
$env:DOTNET_NOLOGO = "1"
[void][IO.Directory]::CreateDirectory($env:TEMP)
# A loaded bootstrap environment supplies GRAPHCODE_DOTNET10403. The resolver
# also admits an installed exact SDK, but never downloads during a build.
$dotnet = Resolve-GraphCodeDotNetSdk -RepositoryRoot $repositoryRoot `
-ToolRoot (Join-Path $repositoryRoot ".graphcode-tools")
$expectedVersion = Get-GraphCodeDotNetPin $repositoryRoot
$env:DOTNET_ROOT = [IO.Path]::GetDirectoryName($dotnet)
$env:DOTNET_MULTILEVEL_LOOKUP = "0"
$env:DOTNET_ROLL_FORWARD = "LatestPatch"
Push-Location $projectRoot
try {
$version = & $dotnet --version
if ($LASTEXITCODE -ne 0 -or $version -cne $expectedVersion) {
throw "Compiled validation requires the pinned .NET SDK $expectedVersion; rerun Tools\windows\bootstrap.ps1"
}
& $dotnet build ValidationRunner.csproj --configuration $Configuration --nologo --verbosity quiet |
ForEach-Object { Write-Host $_ }
if ($LASTEXITCODE -ne 0) { throw "Compiled validation build failed: exit=$LASTEXITCODE" }
} finally { Pop-Location }
$assembly = Join-Path $projectRoot "bin\$Configuration\net10.0-windows\ValidationRunner.dll"
if (-not (Test-Path -LiteralPath $assembly -PathType Leaf)) { throw "Compiled validation build produced no assembly" }
Write-Output $assembly
} finally {
foreach ($name in $names) {
if ($before[$name].present) {
[Environment]::SetEnvironmentVariable($name, $before[$name].value, "Process")
} else {
if ([Environment]::GetEnvironmentVariables("Process").Contains($name)) {
Remove-Item -LiteralPath "Env:\$name" -ErrorAction Stop
}
}
}
}
Loading
Loading