Luna, M1 round 1 of 4 (plan in Standalone/ASSEMBLER_M1_REPORT.md): - Versioned fixed-scale world manifest (the shipped plan format) and the Core block contract: point evaluation, interval-or-unknown, influence bound, detail envelope, channels. - Interval audit: 256 boxes / 6,912 samples, 0 missed, 0 unknown; a deliberately false bound is detected (negative control). - Native Heightfield2D with biome input: 4,096-point hash fae2721c052aec5c identical at W1/W8/W16; point queries 2.059 ms vs 62.115 ms legacy -- but NOT a match yet (mean density error 274 voxels, 2,261 sign mismatches vs the legacy surface). 45 mesh-free Core queries match direct evaluation exactly. Existing cave world unchanged (walkability, 64/64 tiles). - Open: collision readiness, a valid full-view timing (viewer captures were occluded/empty; top-down height maps are the only usable pair). Also carries the design doc's owner decisions (fixed water; player edits unrestricted, route law for automatic changes only) and three plugin files + BuildHost scripts that earlier round commits had missed (also fixed on unreal/core-integration as 2574b56). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
113 lines
5.2 KiB
PowerShell
113 lines
5.2 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[string]$ExecutableName = 'VoxelForgeUnrealSurfaceNative.exe',
|
|
[ValidateRange(1, 16)][int]$Workers = 8,
|
|
[ValidateRange(30, 900)][int]$TimeoutSeconds = 120
|
|
)
|
|
|
|
# Rejoue les probes de strates sauvegardées et fait échouer l'audit si un passage redevient solide.
|
|
# Replays the saved strate probes and fails the audit if any passage becomes solid again.
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$PluginRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..\..'))
|
|
$StandaloneRoot = Join-Path $PluginRoot 'Standalone'
|
|
$ExecutablePath = Join-Path $StandaloneRoot ('bin\' + $ExecutableName)
|
|
$ProbeRoot = Join-Path $StandaloneRoot 'Research\OwnerShapeWorld\core_strate_coverage\probes'
|
|
$LogRoot = Join-Path $ProbeRoot ('round5_walkability_w' + $Workers)
|
|
|
|
if ([IO.Path]::GetFileName($ExecutableName) -ne $ExecutableName -or
|
|
[IO.Path]::GetExtension($ExecutableName) -ne '.exe') {
|
|
throw 'ExecutableName must be an executable filename.'
|
|
}
|
|
if (-not (Test-Path -LiteralPath $ExecutablePath -PathType Leaf)) {
|
|
throw "Viewer not found: $ExecutablePath"
|
|
}
|
|
if (-not (Test-Path -LiteralPath $ProbeRoot -PathType Container)) {
|
|
throw "Passage probe directory not found: $ProbeRoot"
|
|
}
|
|
[IO.Directory]::CreateDirectory($LogRoot) | Out-Null
|
|
|
|
$HostProcess = Get-Process -Id $PID
|
|
$HostProcess.PriorityClass = [Diagnostics.ProcessPriorityClass]::Normal
|
|
$HostProcess.ProcessorAffinity = [IntPtr]0xFFFF
|
|
|
|
$Probes = @(Get-ChildItem -LiteralPath $ProbeRoot -Filter '*.json' -File | Sort-Object Name)
|
|
if ($Probes.Count -ne 15) {
|
|
throw "Expected all 15 saved strate probes, found $($Probes.Count)."
|
|
}
|
|
|
|
$Passed = 0
|
|
foreach ($Probe in $Probes) {
|
|
$Stem = [IO.Path]::GetFileNameWithoutExtension($Probe.Name)
|
|
$StdoutPath = Join-Path $LogRoot ($Stem + '.stdout.log')
|
|
$StderrPath = Join-Path $LogRoot ($Stem + '.stderr.log')
|
|
# Start-Process flattens this array into one command-line string on Windows.
|
|
# Quote the JSON path because the workspace's parent directory contains a space.
|
|
$Arguments = @(('"' + $Probe.FullName + '"'), '--walkability-audit', "--workers=$Workers")
|
|
$Succeeded = $false
|
|
|
|
for ($Attempt = 1; $Attempt -le 2 -and -not $Succeeded; ++$Attempt) {
|
|
if ($Attempt -eq 2) {
|
|
Write-Warning "$Stem exited with 0xC0000142; retrying once after 60 seconds."
|
|
Start-Sleep -Seconds 60
|
|
}
|
|
Remove-Item -LiteralPath $StdoutPath, $StderrPath -Force -ErrorAction SilentlyContinue
|
|
$Process = Start-Process -FilePath $ExecutablePath -ArgumentList $Arguments `
|
|
-WorkingDirectory $StandaloneRoot -WindowStyle Hidden -PassThru `
|
|
-RedirectStandardOutput $StdoutPath -RedirectStandardError $StderrPath
|
|
$StartedUtc = [datetime]::UtcNow
|
|
$PeakPrivateBytes = [int64]0
|
|
try {
|
|
while (-not $Process.HasExited) {
|
|
Start-Sleep -Milliseconds 100
|
|
$Process.Refresh()
|
|
if ($Process.HasExited) { break }
|
|
$Process.PriorityClass = [Diagnostics.ProcessPriorityClass]::Normal
|
|
$Process.ProcessorAffinity = [IntPtr]0xFFFF
|
|
$PeakPrivateBytes = [Math]::Max($PeakPrivateBytes, [int64]$Process.PrivateMemorySize64)
|
|
if (([datetime]::UtcNow - $StartedUtc).TotalSeconds -gt $TimeoutSeconds) {
|
|
$Process.Kill()
|
|
$Process.WaitForExit()
|
|
throw "$Stem exceeded the $TimeoutSeconds-second per-probe time limit."
|
|
}
|
|
if ($PeakPrivateBytes -ge 8GB) {
|
|
$Process.Kill()
|
|
$Process.WaitForExit()
|
|
throw "$Stem exceeded the 8 GiB private-memory limit."
|
|
}
|
|
}
|
|
$Process.WaitForExit()
|
|
$Process.Refresh()
|
|
$ExitCode = [int]$Process.ExitCode
|
|
} finally {
|
|
if (-not $Process.HasExited) {
|
|
$Process.Kill()
|
|
$Process.WaitForExit()
|
|
}
|
|
}
|
|
|
|
if ($ExitCode -eq -1073741502 -and $Attempt -eq 1) { continue }
|
|
if ($ExitCode -eq -1073741502) {
|
|
throw "$Stem repeated 0xC0000142 after its single retry."
|
|
}
|
|
$LogText = Get-Content -LiteralPath $StdoutPath -Raw
|
|
$Walkability = [regex]::Match($LogText, '(?m)^\[Walkability\] PASS (\d+)/(\d+)')
|
|
if ($LogText -match '(?m)^\[Walkability\] FAIL ' -or -not $Walkability.Success) {
|
|
throw "$Stem failed the walkability regression gate; see $StdoutPath (exit $ExitCode)."
|
|
}
|
|
if ([int64]$Walkability.Groups[1].Value -ne [int64]$Walkability.Groups[2].Value -or
|
|
[int64]$Walkability.Groups[2].Value -le 0) {
|
|
throw "$Stem reported an incomplete or empty walkability sample set: $($Walkability.Value)."
|
|
}
|
|
if ($ExitCode -ne 0) {
|
|
throw "$Stem passed route samples but the shape audit exited $ExitCode; see $StdoutPath."
|
|
}
|
|
$Succeeded = $true
|
|
++$Passed
|
|
Write-Output "PASS probe=$Stem workers=$Workers samples=$($Walkability.Groups[1].Value)/$($Walkability.Groups[2].Value) peak_private_gb=$([math]::Round($PeakPrivateBytes / 1GB, 2))"
|
|
}
|
|
}
|
|
|
|
Write-Output "PASS saved_strate_probes=$Passed/$($Probes.Count) workers=$Workers"
|