# Repeatable local acceptance checks. No application deployment or device flashing. $ErrorActionPreference = 'Stop' $taskRoot = Split-Path -Parent $PSScriptRoot $taskPreviousLocation = Get-Location $taskPreviousPlaywright = $env:PLAYWRIGHT_REQUIRE_FROM $taskPreviousDatabase = $env:TEST_DATABASE_URL $taskPreviousRedis = $env:TEST_REDIS_ADDR $taskReport = Join-Path $taskRoot ('.design-evidence/call-memory-acceptance/' + (Get-Date -Format 'yyyyMMdd-HHmmss-fff')) $taskSteps = [System.Collections.Generic.List[object]]::new() $taskStarted = (Get-Date).ToString('o') $taskFailure = $null $taskPassedCount = 0 $taskUnverified = @() function Invoke-AcceptanceCheck { param([string]$Name, [string]$Command, [string[]]$Arguments) Write-Host "[$Name] Running..." $taskLog = Join-Path $taskReport "$Name.log" $taskStepStart = Get-Date # Native stderr (e.g. build warnings) is logged; exit status decides success. $taskOldPreference = $ErrorActionPreference try { $ErrorActionPreference = 'Continue' & $Command @Arguments *> $taskLog $taskCode = $LASTEXITCODE } finally { $ErrorActionPreference = $taskOldPreference } $taskSteps.Add([ordered]@{ name = $Name; exit_code = $taskCode; log = $taskLog seconds = [math]::Round(((Get-Date) - $taskStepStart).TotalSeconds, 2) }) if ($taskCode -ne 0) { Get-Content -LiteralPath $taskLog -Tail 35 throw "$Name failed; see $taskLog" } Write-Host "[$Name] PASS" } try { Set-Location -LiteralPath $taskRoot New-Item -ItemType Directory -Force -Path $taskReport | Out-Null foreach ($taskTool in @('git', 'docker', 'go', 'node', 'npm.cmd', 'powershell.exe')) { Get-Command $taskTool -ErrorAction Stop | Out-Null } if (-not (Test-Path 'web/node_modules/vite')) { throw 'Web dependencies missing. Run npm ci --prefix web first.' } if (-not $env:PLAYWRIGHT_REQUIRE_FROM) { $taskBundledPlaywright = Join-Path $env:USERPROFILE '.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright/package.json' if (Test-Path -LiteralPath $taskBundledPlaywright) { $env:PLAYWRIGHT_REQUIRE_FROM = $taskBundledPlaywright } } # Record hashes for tracked and untracked source files, including local changes. git rev-parse HEAD | Set-Content (Join-Path $taskReport 'base-commit.txt') git -c core.quotepath=false status --short | Set-Content -Encoding UTF8 (Join-Path $taskReport 'worktree-status.txt') $taskSourceHashes = @(foreach ($taskRelative in (git -c core.quotepath=false ls-files --cached --others --exclude-standard)) { if (Test-Path -LiteralPath $taskRelative -PathType Leaf) { [ordered]@{ path = $taskRelative; sha256 = (Get-FileHash -LiteralPath $taskRelative -Algorithm SHA256).Hash } } }) ConvertTo-Json -Depth 4 -InputObject $taskSourceHashes | Set-Content -Encoding UTF8 (Join-Path $taskReport 'source-sha256.json') # Ignore any inherited test DB setting; integration tests create their own databases. $env:TEST_DATABASE_URL = $null $env:TEST_REDIS_ADDR = $null Invoke-AcceptanceCheck 'dependencies' 'docker' @('compose', 'up', '-d', 'postgres', 'redis') Invoke-AcceptanceCheck 'go-tests' 'go' @('test', '-count=1', './...') Invoke-AcceptanceCheck 'go-vet' 'go' @('vet', './...') $taskIntegration = Join-Path $taskRoot 'scripts/test-onboarding-integration.ps1' # A child shell gives thrown integration errors an unambiguous nonzero exit code. $taskQuotedScript = $taskIntegration.Replace("'", "''") $taskQuotedOutput = (Join-Path $taskReport 'database').Replace("'", "''") $taskIntegrationCommand = "& '$taskQuotedScript' -VerboseTests -OutputDirectory '$taskQuotedOutput' -Packages billing,callmemory,onboarding,saas,extraction,retrieval,memorytool,privacy,orchestration,vikingmemory" Invoke-AcceptanceCheck 'database-integration' 'powershell.exe' @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', $taskIntegrationCommand) $taskDbLogs = Get-ChildItem -LiteralPath (Join-Path $taskReport 'database') -Filter 'integration-*.log' $taskPassed = @($taskDbLogs | Select-String -Pattern '^--- PASS:') $taskSkipped = @($taskDbLogs | Select-String -Pattern '^\s*--- SKIP:') $taskPassedCount = $taskPassed.Count $taskUnverified = @($taskSkipped | ForEach-Object { $_.Line }) $taskPassed | ForEach-Object { $_.Line } | Set-Content -Encoding UTF8 (Join-Path $taskReport 'database-passed-tests.txt') $taskSkipped | ForEach-Object { $_.Line } | Set-Content -Encoding UTF8 (Join-Path $taskReport 'database-skipped-tests.txt') # This existing optional test needs a separately configured real content model. # Keep it explicitly unverified; all database-required tests must actually run. $taskUnexpectedSkips = @($taskSkipped | Where-Object { $_.Line -notmatch '^--- SKIP: TestLocalModelContentValueDecisions \(' }) if ($taskDbLogs.Count -ne 10 -or $taskPassed.Count -eq 0 -or $taskUnexpectedSkips.Count -gt 0) { throw 'Database verification incomplete: a package is missing or a required test was skipped. Inspect database logs.' } foreach ($taskSkippedTest in $taskUnverified) { Write-Host "UNVERIFIED: $taskSkippedTest" } Invoke-AcceptanceCheck 'web-build' 'npm.cmd' @('run', 'build', '--prefix', 'web') Invoke-AcceptanceCheck 'browser-component' 'node' @('test/e2e/memory-workspace.mjs') Copy-Item -LiteralPath (Join-Path $taskRoot '.design-evidence/call-memory') -Destination (Join-Path $taskReport 'browser') -Recurse Invoke-AcceptanceCheck 'firmware-node-tests' 'node' @('--test', 'firmware/echoear-platform-agent/tests/setup-portal.test.cjs', 'firmware/echoear-platform-agent/tests/private-sdk-logs.test.cjs') } catch { $taskFailure = $_.Exception.Message Write-Host "FAILED: $taskFailure" } finally { if (Test-Path -LiteralPath $taskReport) { [ordered]@{ status = $(if ($taskFailure) { 'FAILED' } else { 'PASSED_LOCAL_CHECKS' }) started_at = $taskStarted; finished_at = (Get-Date).ToString('o') error = $taskFailure; steps = @($taskSteps.ToArray()) integration_package_test_passes = $taskPassedCount unverified_tests = $taskUnverified boundary = 'Real isolated PostgreSQL tests; browser uses synthetic APIs. Not hardware/provider/end-to-end acceptance. Firmware compile is not run by this script.' } | ConvertTo-Json -Depth 6 | Set-Content -Encoding UTF8 (Join-Path $taskReport 'summary.json') Write-Host "Evidence: $taskReport" } $env:PLAYWRIGHT_REQUIRE_FROM = $taskPreviousPlaywright $env:TEST_DATABASE_URL = $taskPreviousDatabase $env:TEST_REDIS_ADDR = $taskPreviousRedis Set-Location -LiteralPath $taskPreviousLocation } if ($taskFailure) { exit 1 } Write-Host 'PASSED_LOCAL_CHECKS (not full hardware/provider acceptance)'