State Machines
State machines wired together via EventBridge. ASL JSON definitions in modules/idp/state-machines/; Terraform deploys them via aws_sfn_state_machine. Per-SM diagrams in ./diagrams/.
Pipeline
S3 Object Created (Financial_Evidence_Digital/YYYY/MM)
↓ EventBridge Object Created rule (prefix + year/month filter in SM)
classification.asl.json Claude on Bedrock → type + confidence + page breakdown
↓ DocumentProcessing-Classified (EventBridge rule filters on classification + numeric matchers)
extraction.asl.json Bedrock Data Automation, custom blueprint, splitter enabled
↓ DocumentProcessing-Extracted
context-gathering.asl.json applicant profile from DynamoDB
↓ DocumentProcessing-ContextGathered
claude-analysis.asl.json Bedrock managed prompt + forced tool use, persist to DDB
↓ DocumentProcessing-Completed
State machines
1. classification.asl.json
📊 Diagram
Classifies PDFs via Claude on Amazon Bedrock. Reports the dominant document type + numeric confidence + page breakdown as a DocumentProcessing-Classified event; downstream routing is handled at the EventBridge bus.
- Trigger: EventBridge
Object Createdrule on the sabredav S3 bucket, filtered to theFinancial_Evidence_Digital/key prefix. A JSONata$now()check inside the SM further narrows to the current year/month — no re-deploy needed on rollover. - Lambda:
classify-document—GetObject→ base64 → BedrockInvokeModel(Claude Haiku, forcedsubmit_classificationtool). PDF bytes never enter Step Functions state; only the small verdict is returned. - S3 tagging: reads existing tags and appends a
Classificationtag, preservingApplicationNumber,LicenceNumber, etc. - Emits:
DocumentProcessing-Classifiedwith{ classification, classificationConfidence, totalPages, classifiedPages, dominantTypePages, pageBreakdown, documentSizeBytes, modelId }. - Failure mode:
DocumentTooLargeForInlineClassification, Bedrock errors, or unsupported content-type →DocumentProcessing-ClassificationFailed. - Timeout: 15 minutes.
2. extraction.asl.json
📊 Diagram
Invokes Bedrock Data Automation against the Terraform-managed BDA project (custom bank-statement blueprint).
- Trigger:
DocumentProcessing-Classifiedmatching all of:classificationin[BANK_STATEMENT, TRANSACTION_REPORT]ANDclassificationConfidence >= 0.75ANDtotalPages <= 100ANDdocumentSizeBytes <= 209715200. - BDA project config: splitter enabled (multi-doc PDFs return per-segment output, only segments matching the blueprint get
custom_output); image/video/audio modalities disabled; document granularityDOCUMENTonly; bounding boxes off; markdown-only text format. - Custom blueprint: signed balance numbers (overdraft markers detected by BDA, not by Claude). Schema in
modules/idp/config/bank-statement-blueprint.json. - Polling: invoked async via
InvokeDataAutomationAsync, status polled viaGetDataAutomationStatus. - Emits:
DocumentProcessing-ExtractedwithbedrockInvocationArn,bedrockInvocationId,extractedDataS3Bucket,extractedDataS3KeyPrefix. - On skip (document type not eligible):
DocumentProcessing-ExtractionSkipped. - On failure:
DocumentProcessing-ExtractionFailed. - Timeout: 30 minutes.
Common ASL patterns
Retry with exponential backoff
{
"Retry": [
{
"ErrorEquals": ["ThrottlingException"],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2
}
]
}
Catch + route to failure
{
"Catch": [
{
"ErrorEquals": ["States.ALL"],
"ResultPath": "$.error",
"Next": "EmitFailureEvent"
}
]
}
Emit a typed event
{
"Type": "Task",
"Resource": "arn:aws:states:::events:putEvents",
"Parameters": {
"Entries": [
{
"Detail": { "bucket.$": "$.bucket", "key.$": "$.key" },
"DetailType": "DocumentProcessing-Completed",
"Source": "custom.documentProcessing"
}
]
}
}
JSONata (Pass state)
Used in classification.asl.json for the dominant-type calculation. Note JSONata's $sort takes a boolean comparator (true means $a should come after $b), not numeric like JavaScript.
$sort($breakdown, function($a, $b){ $a.pageCount < $b.pageCount })
Modifying a step
Edit the ASL JSON in modules/idp/state-machines/, then run terraform apply. Terraform re-deploys the state machine definition automatically — no other changes needed for ASL edits.
Validating
Online: ASL Validator or the AWS Step Functions Workflow Studio.
CLI:
aws stepfunctions validate-state-machine-definition \
--definition file://classification.asl.json