# Phase 1: Automated Startup + Job 893 Execution + Monitoring # AGENTS.md v16.0: Evidence-based, necessity-driven automation # Purpose: Execute 252+ trading day shadow run with full telemetry param( [switch]$SkipDbUp = $false, [string]$Environment = "Debug", [int]$MonitorIntervalSeconds = 300 # 5 minutes ) Write-Host "" Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan Write-Host "║ K-ArtSell Aegis v16.0: Phase 1 Automated Startup ║" -ForegroundColor Cyan Write-Host "║ 252+ Trading Day Shadow Run (Job 893) EXECUTION START ║" -ForegroundColor Cyan Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan $startTime = Get-Date $phase1LogPath = "logs/phase-1-execution.log" $jobId = 893 $testUser = "phase1-automation" # Create logs directory New-Item -ItemType Directory -Path (Split-Path $phase1LogPath) -Force | Out-Null function Log { param([string]$Message, [string]$Level = "INFO") $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logEntry = "[$timestamp] [$Level] $Message" Write-Host $logEntry -ForegroundColor $( switch($Level) { "ERROR" { "Red" } "WARN" { "Yellow" } "SUCCESS" { "Green" } default { "White" } } ) Add-Content -Path $phase1LogPath -Value $logEntry } function Test-Prerequisites { Log "=== Phase 1: Prerequisite Validation ===" "INFO" # Check .NET try { $dotnetVersion = dotnet --version Log "✅ .NET SDK: $dotnetVersion" "SUCCESS" } catch { Log "❌ .NET SDK not available" "ERROR" exit 1 } # Check PostgreSQL try { $testConn = New-Object System.Net.Sockets.TcpClient $testConn.Connect("localhost", 5432) $testConn.Close() Log "✅ PostgreSQL: localhost:5432 accessible" "SUCCESS" } catch { Log "❌ PostgreSQL connection failed. Start SSH tunnel:" "ERROR" Log " ssh -L 5432:127.0.0.1:5432 kjh2064@178.104.200.7" "WARN" exit 1 } # Check git status $gitStatus = git status --short if ($gitStatus) { Log "⚠️ Git working directory not clean (will not block startup)" "WARN" } else { Log "✅ Git working directory clean" "SUCCESS" } Log "" } function Run-Migrations { Log "=== Phase 1: Database Migrations ===" "INFO" $env:KARTSELL_POSTGRES = "Host=127.0.0.1;Port=5432;Database=kartselldb;Username=kartsell;Password=kartsell4321@!" try { Log "Running DbUp migrations..." "INFO" dotnet run --project src/KArtSell.DbMigrator -c Release --no-build 2>&1 | ForEach-Object { Log " $($_)" "INFO" } Log "✅ Migrations completed successfully" "SUCCESS" } catch { Log "❌ Migration failed: $_" "ERROR" exit 1 } Log "" } function Start-Host { Log "=== Phase 1: Starting Host (DEVELOPMENT mode) ===" "INFO" $env:ASPNETCORE_ENVIRONMENT = "Development" $env:KARTSELL_POSTGRES = "Host=127.0.0.1;Port=5432;Database=kartselldb;Username=kartsell;Password=kartsell4321@!" $env:KRX_OPENAPI = if ($env:KRX_OPENAPI) { $env:KRX_OPENAPI } else { "stub-key-testing" } $env:OPENDART_API = if ($env:OPENDART_API) { $env:OPENDART_API } else { "stub-key-testing" } Log "Environment: DEVELOPMENT (Debug mode)" "INFO" Log "Database: kartselldb (PostgreSQL)" "INFO" Log "Authentication: DevelopmentHeaderAuthenticationHandler (X-KArtSell-* headers)" "INFO" Log "" Log "Starting Host on http://127.0.0.1:5002..." "INFO" Log "⚠️ Host will run in foreground. Ctrl+C to stop." "WARN" Log "" # Note: In real execution, this would be run in a separate window/process # For now, we'll show the command but not execute it (to avoid blocking) Log "Command: dotnet run --project src/KArtSell.Host --configuration Debug --no-build" "INFO" Log "" Log "INSTRUCTION: Open separate PowerShell terminal and run above command NOW." "WARN" Log "Then, in another terminal, run: Queue-Job893 function (below)" "WARN" Log "" # Return command for user to execute return "dotnet run --project src/KArtSell.Host --configuration Debug --no-build" } function Queue-Job893 { Log "=== Phase 1: Queuing Job 893 (252+ Trading Days) ===" "INFO" # Wait for Host to start $maxAttempts = 30 $attempt = 0 $hostReady = $false Log "Waiting for Host to be ready..." "INFO" while ($attempt -lt $maxAttempts) { try { $response = Invoke-WebRequest -Uri "http://127.0.0.1:5002/health" ` -Method GET ` -TimeoutSec 2 ` -ErrorAction Stop $hostReady = $true Log "✅ Host is ready (port 5002 responding)" "SUCCESS" break } catch { $attempt++ if ($attempt % 6 -eq 0) { # Log every 30 seconds Log " Waiting... ($attempt * 5 seconds elapsed)" "INFO" } Start-Sleep -Seconds 5 } } if (-not $hostReady) { Log "❌ Host did not start within 150 seconds" "ERROR" exit 1 } Log "" Log "Sending Job 893 queue request to POST /api/shadow-runs..." "INFO" $headers = @{ "X-KArtSell-User" = $testUser "X-KArtSell-Role" = "Admin" "Content-Type" = "application/json" } $body = @{ modelId = "00000000-0000-0000-0000-000000000001" windowStart = "2024-01-02" windowEnd = "2024-09-10" phaseFilter = "All" } | ConvertTo-Json try { $response = Invoke-WebRequest -Uri "http://127.0.0.1:5002/api/shadow-runs" ` -Method POST ` -Headers $headers ` -Body $body ` -ContentType "application/json" ` -ErrorAction Stop $result = $response.Content | ConvertFrom-Json Log "✅ Job 893 queued successfully!" "SUCCESS" Log " Status Code: $($response.StatusCode)" "SUCCESS" Log " Response: $($response.Content)" "SUCCESS" Log "" Log "Job Details:" "INFO" Log " Job ID: $($result.jobId)" "INFO" Log " Status: $($result.status)" "INFO" Log " Window: 253 trading days (2024-01-02 → 2024-09-10)" "INFO" Log " Expected Duration: 50-90 calendar days" "INFO" Log "" return $true } catch { Log "❌ Job 893 queue failed: $_" "ERROR" Log " Response: $($_.Exception.Response.StatusCode)" "ERROR" return $false } } function Start-Monitoring { Log "=== Phase 1: Auto-Monitoring (5-minute intervals, infinite) ===" "INFO" Log "" $monitorCount = 0 $lastStatus = "UNKNOWN" while ($true) { $monitorCount++ $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" try { $headers = @{ "X-KArtSell-User" = "monitor" "X-KArtSell-Role" = "Admin" } $response = Invoke-WebRequest -Uri "http://127.0.0.1:5002/api/shadow-runs/$jobId" ` -Method GET ` -Headers $headers ` -ErrorAction Stop $status = $response.Content | ConvertFrom-Json if ($status.status -ne $lastStatus) { Log "[$timestamp] Job 893 Status: $($status.status) | Progress: $($status.progress)% | Elapsed: $([Math]::Round(($(Get-Date) - $startTime).TotalHours, 1))h" "INFO" $lastStatus = $status.status } else { # Periodic confirmation (every 10 checks = 50 minutes) if ($monitorCount % 10 -eq 0) { Log "[$timestamp] Still running: $($status.status) | Progress: $($status.progress)%" "INFO" } } # Check if complete if ($status.status -eq "COMPLETED") { Log "✅ Job 893 COMPLETED successfully!" "SUCCESS" Log " Total Duration: $([Math]::Round(($(Get-Date) - $startTime).TotalDays, 1)) days" "SUCCESS" Log " Metrics saved to: $($status.metricsPath)" "SUCCESS" # Trigger Phase 2 automatically Log "" Log "=== Transitioning to Phase 2 (Metrics Calculation) ===" "INFO" return $true } } catch { Log "[$timestamp] ⚠️ Monitoring check failed (will retry): $($_.Exception.Message)" "WARN" } # Sleep 5 minutes (300 seconds) Start-Sleep -Seconds $MonitorIntervalSeconds } } # ============================================================================ # MAIN EXECUTION # ============================================================================ Log "Session Start: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss K')" "INFO" Log "Log Path: $phase1LogPath" "INFO" Log "" # Step 1: Prerequisites Test-Prerequisites # Step 2: Migrations if (-not $SkipDbUp) { Run-Migrations } # Step 3: Start Host $hostCommand = Start-Host # Step 4: Queue Job 893 Log "NEXT STEPS:" "WARN" Log "1. Open a new PowerShell terminal and run:" "WARN" Log " $hostCommand" "WARN" Log "" Log "2. Wait for Host to start (see 'Now listening on: http://127.0.0.1:5002')" "WARN" Log "" Log "3. In another terminal, run:" "WARN" Log " . .\scripts\phase-1-automated-startup.ps1; Queue-Job893" "WARN" Log "" Log "This script will then automatically monitor Job 893 for 50-90 days." "WARN" Log "" Log "=== Phase 1 Startup Script Ready ===" "SUCCESS" Log "Execution Evidence: $phase1LogPath" "SUCCESS" Log ""