G0~G8 성과·동맹 측정 OS 작업 일괄 고정
8월 7일까지 워킹트리에만 남아 있던 미커밋 작업을 커밋한다. 여러 사본 폴더(worktree·clone)에 흩어져 있던 중간 스냅샷을 정리하기 전에 원본을 git 이력으로 고정하는 것이 목적이다. - contracts/routes/services: measurement, outcome_trajectory, rupture_repair, deliberate_practice, calibration_transfer, supervision_research, multimodal_alliance, continuous_improvement 계열 신규 모듈과 테스트 - infra/db/init: 07~16 마이그레이션(측정 기반~calibration transfer 실행) - apps/web: 세션 리뷰 카드·관리 화면·E2E 스펙 추가 - docs/ops: G0~G8 라이브 통합·배포·롤백 증거 문서와 evidence JSON/PNG - scripts: smoke·ledger·릴리스 에이전트·NAS 프리뷰 운영 스크립트 engine.public 로그 .bak과 apps/web/test-results 산출물은 커밋에서 제외했다.
This commit is contained in:
parent
93dd8f82d7
commit
16e791e044
390 changed files with 243188 additions and 499 deletions
|
|
@ -64,6 +64,45 @@ function Wait-JsonHealth {
|
|||
throw "Timed out waiting for healthy response from $Uri"
|
||||
}
|
||||
|
||||
function Test-EngineReady {
|
||||
param(
|
||||
[int]$Port,
|
||||
[int]$TimeoutSec = 45
|
||||
)
|
||||
|
||||
$headers = $null
|
||||
if ($env:ENGINE_GATEWAY_SHARED_SECRET) {
|
||||
$headers = @{ "X-Vignette-Engine-Token" = $env:ENGINE_GATEWAY_SHARED_SECRET }
|
||||
}
|
||||
try {
|
||||
if ($headers) {
|
||||
$response = Invoke-RestMethod -Uri "http://127.0.0.1:$Port/ready" -TimeoutSec $TimeoutSec -Headers $headers
|
||||
} else {
|
||||
$response = Invoke-RestMethod -Uri "http://127.0.0.1:$Port/ready" -TimeoutSec $TimeoutSec
|
||||
}
|
||||
return [bool]($response.ok -eq $true)
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Wait-EngineReady {
|
||||
param(
|
||||
[int]$Port,
|
||||
[int]$TimeoutSec = 90
|
||||
)
|
||||
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
do {
|
||||
if (Test-EngineReady -Port $Port) {
|
||||
return $true
|
||||
}
|
||||
Start-Sleep -Seconds 3
|
||||
} while ((Get-Date) -lt $deadline)
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
function Wait-HttpStatus {
|
||||
param(
|
||||
[string]$Uri,
|
||||
|
|
@ -91,8 +130,11 @@ function Stop-UvicornByPort {
|
|||
[int]$Port
|
||||
)
|
||||
|
||||
# Name 조건이 없으면 같은 문자열을 인자로 들고 있는 셸/래퍼 프로세스까지 매칭해
|
||||
# 호출자 자신을 죽일 수 있다. 대상은 항상 python 프로세스다.
|
||||
Get-CimInstance Win32_Process |
|
||||
Where-Object {
|
||||
$_.Name -like "python*" -and
|
||||
$_.CommandLine -and
|
||||
$_.CommandLine -like "*uvicorn $AppImport*" -and
|
||||
$_.CommandLine -like "*--port $Port*"
|
||||
|
|
@ -167,14 +209,30 @@ if (!(Test-Path $WebDir)) {
|
|||
throw "Web directory not found at $WebDir"
|
||||
}
|
||||
|
||||
# 재기동 판정은 /health(프로세스 liveness)가 아니라 /ready(실제 claude -p 생성)로 한다.
|
||||
# 프로세스는 살아 있는데 그 프로세스의 claude 세션만 죽은 상태는 /health를 통과하므로,
|
||||
# /health 기준으로는 복구가 필요한 순간에 오히려 재기동을 건너뛴다(2026-08-07 사고).
|
||||
$engineHealth = Get-JsonHealth -Uri "http://127.0.0.1:$EnginePort/health"
|
||||
$engineReady = $false
|
||||
if ($null -ne $engineHealth -and $engineHealth.ok) {
|
||||
$engineReady = Test-EngineReady -Port $EnginePort
|
||||
}
|
||||
if ($SkipEngineRestart) {
|
||||
if ($null -eq $engineHealth -or -not $engineHealth.ok) {
|
||||
throw "Engine gateway is not healthy on http://127.0.0.1:$EnginePort/health"
|
||||
if (-not $engineReady) {
|
||||
throw "Engine gateway is not ready on http://127.0.0.1:$EnginePort/ready"
|
||||
}
|
||||
} elseif ($null -eq $engineHealth -or -not $engineHealth.ok) {
|
||||
} elseif (-not $engineReady) {
|
||||
Stop-UvicornByPort -AppImport "engine_gateway.gateway:app" -Port $EnginePort
|
||||
|
||||
# Start-Process는 리다이렉트 대상 로그를 덮어쓴다. 직전 사고 로그를 보존해야
|
||||
# 재기동 후에도 원인을 추적할 수 있다.
|
||||
$rotateStamp = Get-Date -Format "yyyyMMdd-HHmmss"
|
||||
foreach ($logFile in @($EngineOutLog, $EngineErrLog)) {
|
||||
if (Test-Path $logFile) {
|
||||
Move-Item -LiteralPath $logFile -Destination "$logFile.$rotateStamp.bak" -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
Start-Process -WindowStyle Hidden -FilePath $Python `
|
||||
-ArgumentList @("-m", "uvicorn", "engine_gateway.gateway:app", "--host", "127.0.0.1", "--port", "$EnginePort") `
|
||||
-WorkingDirectory $ApiDir `
|
||||
|
|
@ -182,15 +240,11 @@ if ($SkipEngineRestart) {
|
|||
-RedirectStandardError $EngineErrLog `
|
||||
-PassThru | Out-Null
|
||||
|
||||
try {
|
||||
$engineHealth = Wait-JsonHealth `
|
||||
-Uri "http://127.0.0.1:$EnginePort/health" `
|
||||
-IsHealthy { param($health) $health.ok -eq $true } `
|
||||
-TimeoutSec 30
|
||||
} catch {
|
||||
$engineReady = Wait-EngineReady -Port $EnginePort -TimeoutSec 90
|
||||
if (-not $engineReady) {
|
||||
Write-Warning "Engine gateway is still degraded; continuing admin/auth recovery"
|
||||
$engineHealth = Get-JsonHealth -Uri "http://127.0.0.1:$EnginePort/health"
|
||||
}
|
||||
$engineHealth = Get-JsonHealth -Uri "http://127.0.0.1:$EnginePort/health"
|
||||
}
|
||||
|
||||
$env:ENVIRONMENT = "prod"
|
||||
|
|
@ -303,8 +357,8 @@ if (!$SkipCloudflaredRestart) {
|
|||
}
|
||||
}
|
||||
|
||||
if ($null -ne $engineHealth -and $engineHealth.ok) {
|
||||
Write-Output "Engine gateway healthy on http://127.0.0.1:$EnginePort"
|
||||
if ($engineReady) {
|
||||
Write-Output "Engine gateway ready (real generation proven) on http://127.0.0.1:$EnginePort"
|
||||
} else {
|
||||
Write-Warning "Engine gateway degraded; admin/auth control plane remains available"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue