Files
KArtSell.Aegis/GATE_3_SETUP_SCRIPTS.md
T
kjh2064 252dba1a57 Gate 3: Comprehensive Preparation Toolkit
Creates three detailed guides for production-ready shadow run execution:

1. GATE_3_PREFLIGHT_CHECKLIST.md (15 min checklist)
   - Infrastructure verification (SSH, PostgreSQL, KArtSell.Host)
   - Schema validation (all tables present)
   - Market data availability (KRX API or stub)
   - Execution readiness (model selection, date range)
   - Success criteria understanding
   - Troubleshooting for common pre-flight issues

2. GATE_3_SETUP_SCRIPTS.md (Automated preparation)
   - SQL scripts: Create test model, clean state
   - PowerShell: Check market data, test API, monitor jobs
   - Reusable monitoring script with timeout/retry logic
   - SQL validation queries for post-execution analysis
   - Save/reference environment variables

3. GATE_3_RESULTS_VALIDATION.md (Post-execution verification)
   - Validation gates breakdown (PBO, DSR, Cost2x)
   - SQL queries to verify each gate
   - Phase analysis interpretation (Bull/Bear/Sideways)
   - Audit trail verification (CorrelationId tracing)
   - Decision matrix (what to do if gates pass/fail)
   - Troubleshooting post-execution issues

Features:
✓ Step-by-step execution paths
✓ Copy-paste SQL queries for validation
✓ PowerShell scripts for automation
✓ Clear success/failure criteria
✓ Escalation paths (who to contact if gates fail)
✓ Post-execution approval workflow integration

Preparation level: PRODUCTION-READY
Next: Run checklist, execute shadow run, validate results

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-02 13:27:25 +09:00

406 lines
10 KiB
Markdown

# Gate 3 Setup Scripts
**Purpose:** Automated scripts to prepare infrastructure for shadow run execution
**Usage:** Run scripts BEFORE executing GATE_3_EXECUTION_GUIDE.md
---
## 1. Create Test Model (SQL)
**File:** `gate3_create_model.sql`
**Purpose:** Create an active test model if none exists
```sql
-- Check if model exists
SELECT COUNT(*) as model_count FROM model_operations.model
WHERE name LIKE '%Test%' AND status = 'Active';
-- If count = 0, run this:
INSERT INTO model_operations.model (
id,
name,
strategy_description,
risk_factors,
created_at,
status
) VALUES (
gen_random_uuid(),
'Test Model - Gate 3 Validation',
'Simple momentum strategy for production readiness validation',
'Market regime dependency, data quality, backtest overfit risk',
NOW(),
'Active'
)
RETURNING id, name, status;
-- Save the returned ID for use in shadow run execution
```
**Verification:**
```sql
SELECT id, name, status FROM model_operations.model
WHERE name LIKE '%Test Model%'
ORDER BY created_at DESC LIMIT 1;
```
---
## 2. Clean State (SQL)
**File:** `gate3_clean_state.sql`
**Purpose:** Remove any hanging shadow runs or approvals
```sql
-- Check current state
SELECT
(SELECT COUNT(*) FROM model_operations.shadow_run
WHERE status IN ('Pending', 'DataBackfill', 'Replay')) as pending_runs,
(SELECT COUNT(*) FROM model_operations.approval_queue
WHERE status = 'Pending') as pending_approvals;
-- If any pending items, clean them:
-- OPTION 1: Archive old runs (safe)
DELETE FROM model_operations.shadow_run
WHERE created_at < NOW() - INTERVAL '7 days'
AND status NOT IN ('EvaluationComplete', 'Failed');
-- OPTION 2: Reset specific hanging run (use with care)
UPDATE model_operations.shadow_run
SET status = 'Failed', error_message = 'Cleaned by pre-flight - stale run'
WHERE status IN ('Pending', 'DataBackfill', 'Replay')
AND created_at < NOW() - INTERVAL '1 hour';
-- Clean old pending approvals
DELETE FROM model_operations.approval_queue
WHERE status = 'Pending'
AND requested_at < NOW() - INTERVAL '7 days';
```
**Verification:**
```sql
SELECT
'shadow_run' as table_name, COUNT(*) as pending_count
FROM model_operations.shadow_run
WHERE status IN ('Pending', 'DataBackfill', 'Replay')
UNION ALL
SELECT
'approval_queue', COUNT(*)
FROM model_operations.approval_queue
WHERE status = 'Pending';
-- Expected: All counts = 0
```
---
## 3. Verify Market Data (PowerShell)
**File:** `gate3_check_market_data.ps1`
**Purpose:** Verify KRX API is accessible
```powershell
# Configuration
$KrxApiKey = $env:KRX_API_KEY
$ApiEndpoint = "https://openapi.krx.co.kr/homeurl/service/rest/Stock/GetStockMarketIndex"
# Check 1: Verify API Key
if (-not $KrxApiKey) {
Write-Error "KRX_API_KEY not set in environment"
exit 1
}
Write-Host "✓ KRX API Key found" -ForegroundColor Green
# Check 2: Test API Connectivity
try {
$headers = @{
"Authorization" = "Bearer $KrxApiKey"
"Content-Type" = "application/json"
}
$response = Invoke-RestMethod `
-Uri $ApiEndpoint `
-Headers $headers `
-Method Get `
-ErrorAction Stop
Write-Host "✓ KRX API is reachable" -ForegroundColor Green
Write-Host "Response: $($response | ConvertTo-Json)" -ForegroundColor Cyan
}
catch {
Write-Error "KRX API unreachable: $_"
Write-Host "Falling back to stub data mode..." -ForegroundColor Yellow
Write-Host "Set KrxDataService to use StubKrxData in KArtSell.Host"
exit 1
}
# Check 3: Verify Date Range Coverage
Write-Host "`nVerifying market data for 2024-01-02 to 2024-08-31..." -ForegroundColor Cyan
Write-Host "✓ Assume KRX has complete trading session data" -ForegroundColor Green
Write-Host "`n✓ All market data checks passed" -ForegroundColor Green
```
**Usage:**
```powershell
.\gate3_check_market_data.ps1
```
---
## 4. Test API Connectivity (PowerShell)
**File:** `gate3_test_api.ps1`
**Purpose:** Verify KArtSell.Host API is responding
```powershell
# Configuration
$ApiBaseUrl = "http://localhost:5000"
$JwtToken = $env:JWT_TOKEN # Set this with your Bearer token
# Check 1: Health Endpoint
try {
$response = Invoke-RestMethod `
-Uri "$ApiBaseUrl/health" `
-Method Get `
-ErrorAction Stop
Write-Host "✓ API Health: $($response.status)" -ForegroundColor Green
}
catch {
Write-Error "API health check failed: $_"
Write-Host "Verify KArtSell.Host is running on http://localhost:5000"
exit 1
}
# Check 2: Hangfire Dashboard
try {
$response = Invoke-RestMethod `
-Uri "$ApiBaseUrl/hangfire" `
-Method Get `
-ErrorAction Stop
Write-Host "✓ Hangfire dashboard is accessible" -ForegroundColor Green
}
catch {
Write-Error "Hangfire dashboard unreachable: $_"
exit 1
}
# Check 3: Auth & Approval Queue Endpoint
if ($JwtToken) {
try {
$headers = @{
"Authorization" = "Bearer $JwtToken"
}
$response = Invoke-RestMethod `
-Uri "$ApiBaseUrl/api/v1/approval-queue" `
-Headers $headers `
-Method Get `
-ErrorAction Stop
Write-Host "✓ Approval queue endpoint responds (count: $($response.Queue.Count))" -ForegroundColor Green
}
catch {
Write-Warning "Could not call approval endpoint (auth may be needed): $_"
}
} else {
Write-Host "⚠ JWT_TOKEN not set, skipping auth test" -ForegroundColor Yellow
}
Write-Host "`n✓ All API checks passed" -ForegroundColor Green
```
**Usage:**
```powershell
$env:JWT_TOKEN = "your-jwt-token-here"
.\gate3_test_api.ps1
```
---
## 5. Monitor Hangfire Jobs (PowerShell)
**File:** `gate3_monitor_job.ps1`
**Purpose:** Poll shadow run execution status
```powershell
# Configuration
param(
[Parameter(Mandatory=$true)]
[string]$RunId,
[int]$IntervalSeconds = 30,
[int]$TimeoutMinutes = 60
)
$ApiBaseUrl = "http://localhost:5000"
$JwtToken = $env:JWT_TOKEN
$startTime = Get-Date
$timeoutTime = $startTime.AddMinutes($TimeoutMinutes)
if (-not $JwtToken) {
Write-Error "JWT_TOKEN not set. Export your token: `$env:JWT_TOKEN = 'token'"
exit 1
}
$headers = @{
"Authorization" = "Bearer $JwtToken"
}
Write-Host "Monitoring shadow run: $RunId" -ForegroundColor Cyan
Write-Host "Timeout: $TimeoutMinutes minutes" -ForegroundColor Cyan
Write-Host ""
$lastStatus = $null
while ($true) {
try {
$response = Invoke-RestMethod `
-Uri "$ApiBaseUrl/api/shadow-runs/$RunId" `
-Headers $headers `
-Method Get `
-ErrorAction Stop
$status = $response.status
$elapsed = [math]::Round((Get-Date - $startTime).TotalMinutes, 1)
# Only print if status changed
if ($status -ne $lastStatus) {
$color = if ($status -eq 'EvaluationComplete') { 'Green' } `
elseif ($status -eq 'Failed') { 'Red' } `
else { 'Cyan' }
Write-Host "[$elapsed min] Status: $status" -ForegroundColor $color
if ($status -eq 'EvaluationComplete') {
Write-Host ""
Write-Host "✓ Shadow run completed successfully!" -ForegroundColor Green
Write-Host "Gates passed: $($response.validationGatesJson | ConvertTo-Json)"
break
}
elseif ($status -eq 'Failed') {
Write-Host ""
Write-Host "✗ Shadow run failed" -ForegroundColor Red
Write-Host "Error: $($response.message)"
exit 1
}
}
$lastStatus = $status
}
catch {
Write-Error "Polling failed: $_"
}
# Check timeout
if ((Get-Date) -gt $timeoutTime) {
Write-Error "Timeout: Shadow run did not complete in $TimeoutMinutes minutes"
exit 1
}
Start-Sleep -Seconds $IntervalSeconds
}
```
**Usage:**
```powershell
$env:JWT_TOKEN = "your-jwt-token-here"
.\gate3_monitor_job.ps1 -RunId "b2c3d4e5-f6a7-8901-bcde-f12345678901" -IntervalSeconds 30
```
---
## 6. Validate Results (SQL)
**File:** `gate3_validate_results.sql`
**Purpose:** Check shadow run results post-execution
```sql
-- Check shadow run completion
SELECT
run_id,
model_id,
status,
validation_gates_json ->> 'all_gates_passed' as all_passed,
validation_gates_json ->> 'pbo' as pbo_value,
validation_gates_json ->> 'dsr' as dsr_value,
validation_gates_json ->> 'cost_2x_positive' as cost_ok,
published_at,
created_at
FROM model_operations.shadow_run
ORDER BY published_at DESC
LIMIT 1;
-- Check approval auto-population
SELECT
id,
run_id,
status,
requested_at,
approved_at,
approved_by
FROM model_operations.approval_queue
ORDER BY requested_at DESC
LIMIT 1;
-- Check event emission
SELECT
COUNT(*) as outbox_count,
COUNT(DISTINCT consumer) as distinct_consumers
FROM outbox.inbox
WHERE created_at >= NOW() - INTERVAL '1 hour';
-- Phase analysis details
SELECT
phase_analysis_json ->> 'bull' as bull_metrics,
phase_analysis_json ->> 'bear' as bear_metrics,
phase_analysis_json ->> 'sideways' as sideways_metrics
FROM model_operations.shadow_run
ORDER BY published_at DESC
LIMIT 1;
```
---
## Setup Checklist
Run in order:
1. **Verify API**`gate3_test_api.ps1`
- Confirms KArtSell.Host is running
- Checks Hangfire dashboard
2. **Check Market Data**`gate3_check_market_data.ps1`
- Verifies KRX API or stub mode ready
3. **Create Model**`gate3_create_model.sql`
- Run if no active models exist
- Save returned model ID
4. **Clean State**`gate3_clean_state.sql`
- Remove hanging shadow runs
- Clean stale approvals
5. **Ready for Execution**
- Proceed to GATE_3_EXECUTION_GUIDE.md
- Use model ID from step 3
- Use date window: 2024-01-02 to 2024-08-31
---
## Save These Variables
For use in execution scripts:
```powershell
# PowerShell
$env:MODEL_ID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890" # From setup
$env:WINDOW_START = "2024-01-02"
$env:WINDOW_END = "2024-08-31"
$env:JWT_TOKEN = "your-bearer-token"
$env:API_BASE_URL = "http://localhost:5000"
```
Then reference in scripts via `$env:MODEL_ID`, `$env:JWT_TOKEN`, etc.