✅ Validation Results: - PPO training: 24.2s (1 epoch, 950 samples, dim=225) - Feature extraction: 105μs/bar (9.5x faster than target) - Model checkpoint: 293KB (147KB actor + 146KB critic) - GPU memory: 145MB used (96.4% headroom) - Zero dimension mismatches 📊 Success Criteria (5/5): ✅ Feature dimension = 225 (Wave C 201 + Wave D 24) ✅ Model state_dim = 225 ✅ Training completed without errors ✅ Checkpoint saved successfully ✅ No dimension mismatch errors 📁 Training Data Ready: - ES.FUT: 2.9MB, 180 days - NQ.FUT: 4.4MB, 180 days - 6E.FUT: 2.8MB, 180 days - ZN.FUT: 65KB, 90 days (clean) 🚀 Next: Full production model retraining (4 models, ~10min GPU time) 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
7.8 KiB
7.8 KiB
Incident Response Runbook
Last Updated: 2025-10-22 Scope: All production incidents On-Call Rotation: 24/7 coverage required
Severity Levels
| Level | Definition | Response Time | Examples |
|---|---|---|---|
| P0 | Critical - System down | 5 min | Complete trading halt, data loss, security breach |
| P1 | High - Severe degradation | 15 min | API failures >10%, high latency P99 >1s, DB unavailable |
| P2 | Medium - Partial degradation | 1 hour | Single service degraded, non-critical feature broken |
| P3 | Low - Minor issue | 4 hours | Performance degradation <5%, non-urgent bugs |
| P4 | Info - No impact | Next business day | Documentation updates, cosmetic issues |
P0: Critical Incident Response
1. Initial Response (0-5 minutes)
# Step 1: Acknowledge incident
curl -X POST https://api.pagerduty.com/incidents/${INCIDENT_ID}/acknowledge \
-H "Authorization: Token token=${PD_TOKEN}"
# Step 2: Declare incident in Slack
curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \
-H 'Content-Type: application/json' \
-d '{"text":"🚨 P0 INCIDENT: Trading system down. War room: #incident-2025-10-22"}'
# Step 3: Create war room channel
# Manually create #incident-YYYY-MM-DD in Slack
# Step 4: Assess system health
kubectl get pods -n foxhunt --no-headers | awk '{if ($3 != "Running") print $0}'
2. Triage (5-10 minutes)
# Check service health
for svc in api-gateway trading-service backtesting-service ml-training-service trading-agent; do
echo "=== $svc ==="
kubectl logs -n foxhunt -l app.kubernetes.io/component=$svc --tail=50 | grep -i error
done
# Check infrastructure
kubectl top nodes
kubectl top pods -n foxhunt --sort-by=memory | head -20
# Check database
kubectl exec -n foxhunt foxhunt-postgresql-0 -- \
psql -U foxhunt -d foxhunt -c "SELECT count(*) FROM pg_stat_activity WHERE state='active';"
# Check metrics
curl -s http://prometheus:9090/api/v1/query?query=up{job=\"trading-service\"} | jq '.data.result'
3. Mitigation (10-30 minutes)
Service Restart:
# Restart unhealthy service
kubectl rollout restart deployment/foxhunt-trading-service -n foxhunt
# OR immediate pod deletion (faster but riskier)
kubectl delete pods -n foxhunt -l app.kubernetes.io/component=trading-service
Rollback:
# Quick rollback to previous version
kubectl rollout undo deployment/foxhunt-trading-service -n foxhunt
# Verify rollback
kubectl rollout status deployment/foxhunt-trading-service -n foxhunt
Circuit Breaker:
# Enable maintenance mode
kubectl create configmap foxhunt-maintenance -n foxhunt \
--from-literal=enabled=true \
--from-literal=message="Emergency maintenance. Trading suspended."
4. Recovery Verification (30-45 minutes)
# Health checks
for port in 8080 8081 8082 8095 8083; do
curl -sf http://localhost:$port/health && echo "Port $port: OK" || echo "Port $port: FAILED"
done
# End-to-end test
tli auth login --username admin --password ${ADMIN_PASSWORD}
tli trade order submit --symbol ES.FUT --action BUY --quantity 1 --order-type MARKET --paper-trade
# Verify in database
kubectl exec -n foxhunt foxhunt-postgresql-0 -- \
psql -U foxhunt -d foxhunt -c "SELECT * FROM orders ORDER BY created_at DESC LIMIT 1;"
5. Post-Incident (45-60 minutes)
# Notify resolution
curl -X POST https://api.pagerduty.com/incidents/${INCIDENT_ID}/resolve \
-H "Authorization: Token token=${PD_TOKEN}"
curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \
-H 'Content-Type: application/json' \
-d '{"text":"✅ P0 RESOLVED: Trading system operational. Duration: 45 minutes."}'
# Schedule postmortem within 24 hours
# Use template: /home/jgrusewski/Work/foxhunt/docs/templates/incident-report.md
P1: High Severity Response
Response Procedure (15 minutes)
# 1. Assess scope
kubectl get pods -n foxhunt -o wide
kubectl logs -n foxhunt -l app.kubernetes.io/component=api-gateway --tail=100 | grep ERROR
# 2. Check metrics
curl -s "http://prometheus:9090/api/v1/query?query=rate(grpc_requests_total{code!~\"2..\"}[5m])" | jq '.data.result'
# 3. Scale if needed
kubectl scale deployment/foxhunt-api-gateway -n foxhunt --replicas=10
# 4. Monitor recovery
watch kubectl get hpa -n foxhunt
Common Incident Scenarios
Scenario 1: Database Connection Pool Exhausted
Symptoms:
ERROR: FATAL: remaining connection slots are reserved for non-replication superuser connections
Resolution:
# Check active connections
kubectl exec -n foxhunt foxhunt-postgresql-0 -- \
psql -U foxhunt -d foxhunt -c "SELECT count(*), state FROM pg_stat_activity GROUP BY state;"
# Terminate idle connections
kubectl exec -n foxhunt foxhunt-postgresql-0 -- \
psql -U foxhunt -d foxhunt -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state='idle' AND state_change < now() - interval '5 minutes';"
# Increase max_connections (requires restart)
kubectl exec -n foxhunt foxhunt-postgresql-0 -- \
psql -U foxhunt -d foxhunt -c "ALTER SYSTEM SET max_connections = 200;"
kubectl delete pod foxhunt-postgresql-0 -n foxhunt
Scenario 2: Redis Memory Full
Symptoms:
ERROR: OOM command not allowed when used memory > 'maxmemory'
Resolution:
# Check memory usage
kubectl exec -n foxhunt foxhunt-redis-master-0 -- redis-cli INFO memory | grep used_memory_human
# Evict keys (if eviction policy allows)
kubectl exec -n foxhunt foxhunt-redis-master-0 -- redis-cli FLUSHDB
# OR increase memory limit
kubectl patch statefulset foxhunt-redis-master -n foxhunt \
-p '{"spec":{"template":{"spec":{"containers":[{"name":"redis","resources":{"limits":{"memory":"2Gi"}}}]}}}}'
Scenario 3: GPU Out of Memory
Symptoms:
ERROR: CUDA error: out of memory
Resolution:
# Check GPU memory
kubectl exec -n foxhunt foxhunt-ml-training-service-xxxxx -- nvidia-smi
# Kill GPU process
kubectl exec -n foxhunt foxhunt-ml-training-service-xxxxx -- nvidia-smi --gpu-reset
# Restart service
kubectl delete pod foxhunt-ml-training-service-xxxxx -n foxhunt
Incident Communication Template
Initial Report (within 5 minutes)
🚨 P0 INCIDENT: [Brief Description]
STATUS: Investigating
IMPACT: [Users affected, services down]
STARTED: 2025-10-22 10:00 UTC
INCIDENT COMMANDER: @john.doe
WAR ROOM: #incident-2025-10-22
Current actions:
- Checking service health
- Reviewing logs
- Escalating to engineering team
Update (every 15 minutes)
UPDATE 10:15 UTC:
ROOT CAUSE: Database connection pool exhausted
MITIGATION: Terminated idle connections, increased pool size
RECOVERY: Services restarting, ETA 5 minutes
Next update: 10:30 UTC
Resolution
✅ INCIDENT RESOLVED
DURATION: 45 minutes (10:00-10:45 UTC)
ROOT CAUSE: Database connection pool exhausted due to connection leak
RESOLUTION: Terminated idle connections, increased max_connections from 100 to 200
IMPACT: 150 users unable to submit orders for 45 minutes
FOLLOW-UP:
- [ ] Postmortem scheduled for 2025-10-23 10:00 UTC
- [ ] Fix connection leak in Trading Service v0.1.7
- [ ] Add monitoring alert for connection pool usage >80%
Escalation Matrix
| Role | Primary | Secondary | Phone |
|---|---|---|---|
| Incident Commander | John Doe | Jane Smith | +1-555-0100 |
| Engineering Lead | Alice Brown | Bob Wilson | +1-555-0101 |
| Database Admin | Charlie Davis | Diana Evans | +1-555-0102 |
| DevOps Lead | Eve Foster | Frank Green | +1-555-0103 |
| Security Lead | Grace Harris | Henry Irving | +1-555-0104 |
Escalation Path:
- On-call engineer (responds within 5 min)
- Engineering Lead (escalate after 15 min)
- CTO (escalate for P0 after 30 min or P1 after 2 hours)
End of Incident Response Runbook