Skip to content

Commit f5bc09a

Browse files
authored
Merge pull request #23 from cipher813/feat/split-evaluator-step-function
Split Evaluator from Backtester into independent Step Function step
2 parents bc2c94a + 2f3d4c8 commit f5bc09a

1 file changed

Lines changed: 110 additions & 1 deletion

File tree

infrastructure/step_function.json

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@
476476
{
477477
"Variable": "$.backtester_poll.Status",
478478
"StringEquals": "Success",
479-
"Next": "SaturdayHealthCheck"
479+
"Next": "Evaluator"
480480
},
481481
{
482482
"Variable": "$.backtester_poll.Status",
@@ -498,6 +498,115 @@
498498
"Next": "WaitForBacktester"
499499
},
500500

501+
"Evaluator": {
502+
"Type": "Task",
503+
"Comment": "Signal quality, attribution, grading, config optimization. Runs on always-on EC2 (not spot) — reads simulation artifacts from S3. Split from Backtester step on 2026-04-12 so eval can run at a different cadence.",
504+
"Resource": "arn:aws:states:::aws-sdk:ssm:sendCommand",
505+
"Parameters": {
506+
"DocumentName": "AWS-RunShellScript",
507+
"InstanceIds.$": "$.ec2_instance_id",
508+
"Parameters": {
509+
"commands": [
510+
"set -eo pipefail",
511+
"export HOME=/home/ec2-user",
512+
"sudo -u ec2-user git -C /home/ec2-user/alpha-engine-backtester pull --ff-only origin main",
513+
"cd /home/ec2-user/alpha-engine-backtester",
514+
"set -a && source /home/ec2-user/.alpha-engine.env && set +a",
515+
"source .venv/bin/activate",
516+
"python evaluate.py --mode all --upload --log-level INFO 2>&1 | tee /var/log/evaluator.log"
517+
],
518+
"executionTimeout": ["1800"]
519+
},
520+
"TimeoutSeconds": 1800
521+
},
522+
"TimeoutSeconds": 1860,
523+
"Retry": [
524+
{
525+
"ErrorEquals": ["States.TaskFailed"],
526+
"MaxAttempts": 1,
527+
"IntervalSeconds": 30,
528+
"BackoffRate": 1.0
529+
}
530+
],
531+
"Catch": [
532+
{
533+
"ErrorEquals": ["States.ALL"],
534+
"Next": "HandleFailure",
535+
"ResultPath": "$.error"
536+
}
537+
],
538+
"ResultPath": "$.evaluator_result",
539+
"Next": "WaitForEvaluator"
540+
},
541+
542+
"WaitForEvaluator": {
543+
"Type": "Task",
544+
"Comment": "Poll SSM command until evaluator complete",
545+
"Resource": "arn:aws:states:::aws-sdk:ssm:getCommandInvocation",
546+
"Parameters": {
547+
"CommandId.$": "$.evaluator_result.Command.CommandId",
548+
"InstanceId.$": "$.ec2_instance_id[0]"
549+
},
550+
"Retry": [
551+
{
552+
"ErrorEquals": ["Ssm.InvocationDoesNotExistException"],
553+
"MaxAttempts": 10,
554+
"IntervalSeconds": 10,
555+
"BackoffRate": 1.5
556+
}
557+
],
558+
"Catch": [
559+
{
560+
"ErrorEquals": ["States.ALL"],
561+
"Next": "HandleFailure",
562+
"ResultPath": "$.error"
563+
}
564+
],
565+
"ResultPath": "$.evaluator_poll",
566+
"Next": "CheckEvaluatorStatus"
567+
},
568+
569+
"CheckEvaluatorStatus": {
570+
"Type": "Choice",
571+
"Choices": [
572+
{
573+
"Variable": "$.evaluator_poll.Status",
574+
"StringEquals": "Success",
575+
"Next": "SaturdayHealthCheck"
576+
},
577+
{
578+
"Variable": "$.evaluator_poll.Status",
579+
"StringEquals": "InProgress",
580+
"Next": "EvaluatorWait"
581+
},
582+
{
583+
"Variable": "$.evaluator_poll.Status",
584+
"StringEquals": "Pending",
585+
"Next": "EvaluatorWait"
586+
}
587+
],
588+
"Default": "ExtractEvaluatorError"
589+
},
590+
591+
"EvaluatorWait": {
592+
"Type": "Wait",
593+
"Seconds": 15,
594+
"Next": "WaitForEvaluator"
595+
},
596+
597+
"ExtractEvaluatorError": {
598+
"Type": "Pass",
599+
"Comment": "Normalize Evaluator SSM non-Success poll into $.error.",
600+
"Result": {},
601+
"ResultPath": "$.error",
602+
"Parameters": {
603+
"phase": "Evaluator",
604+
"source": "CheckEvaluatorStatus.Default",
605+
"poll.$": "$.evaluator_poll"
606+
},
607+
"Next": "HandleFailure"
608+
},
609+
501610
"SaturdayHealthCheck": {
502611
"Type": "Task",
503612
"Comment": "Check data freshness after full pipeline — non-blocking (alerts on failure but does not halt)",

0 commit comments

Comments
 (0)