TSE — The Solomon Engine
TSE Voice Interview Pipeline
A two-part voice interview processed through a self-healing pipeline. No always-on servers. The system runs only when an interview completes, recovers from failures automatically, and pages a human only for genuine dead-ends.
01
Main Pipeline
Admin action
User action
System (automatic)
Failure / recovery
Supabase — database + edge functions
ElevenLabs — voice interview agents
Railway — processing worker (on-demand job)
Anthropic Claude — AI extraction + generation
flowchart TD
subgraph ADMIN["ADMIN"]
A1["Create invite
POST /create-invite
name + email"]
A2["Email two links
to user"]
A1 --> A2
end
subgraph SB1["SUPABASE"]
direction TB
DB1[("vi_sessions
vi_invites
created")]
end
A1 -->|"creates session + invite"| DB1
A1 -->|"returns part_1_url + part_2_url"| A2
subgraph USER["USER"]
U1["Clicks Part 1 link"]
U2["Voice interview
Pain Points & Workflow
~6 min"]
U3["Clicks Part 2 link"]
U4["Voice interview
Work Style & Tools
~6 min"]
U1 --> U2 --> U3 --> U4
end
A2 -.->|"sends links"| U1
subgraph EL["ELEVENLABS"]
EL1["Agent 1
var_session_id baked in"]
EL2["Agent 2
var_session_id baked in"]
end
U2 -->|"talks to"| EL1
U4 -->|"talks to"| EL2
subgraph DISPATCH["SUPABASE EDGE FUNCTION"]
D1["Dispatcher
/dispatcher"]
D2{"Both halves
received?"}
D1 --> D2
end
EL1 -->|"post-call webhook
+ dynamic_variables"| D1
EL2 -->|"post-call webhook
+ dynamic_variables"| D1
subgraph SB2["SUPABASE DB"]
DB2[("vi_transcripts
filed by session_id")]
DB3[("vi_jobs
queued")]
end
D1 -->|"verify sig + file transcript"| DB2
D2 -->|"No — wait"| DB2
D2 -->|"Yes — enqueue"| DB3
subgraph WORKER["RAILWAY JOB"]
W1["Claim job"]
W2["Stage 1: Extract
Claude API
JSON extraction"]
W3{"Validate
extraction"}
W4["Stage 2: Generate
Claude API
markdown instructions"]
W5{"Validate
output"}
W6["Write deliverable"]
W1 --> W2 --> W3
W3 -->|"pass"| W4 --> W5
W5 -->|"pass"| W6
end
DB3 -->|"trigger via Railway API"| W1
subgraph SB3["SUPABASE DB"]
DB4[("vi_deliverables
review_status: pending")]
DB5[("vi_sessions
status: complete")]
end
W6 -->|"atomic write"| DB4
W6 -->|"mark complete"| DB5
subgraph REVIEW["ADMIN"]
R1["Review deliverable"]
R2{"Approve?"}
R3["Deploy instructions"]
R4["Request re-interview"]
R1 --> R2
R2 -->|"yes"| R3
R2 -->|"no"| R4
end
DB4 -.->|"admin reviews"| R1
subgraph FAIL["FAILURE + RECOVERY"]
F1["Job fails"]
F2["Increment retry_count"]
F3{"retry_count
< 5?"}
F4["Back to ready_to_process"]
F5["Mark FAILED
+ alert admin"]
end
W3 -->|"fail"| F1
W5 -->|"fail"| F1
F1 --> F2 --> F3
F3 -->|"yes"| F4
F3 -->|"no"| F5
subgraph SWEEPER["SUPABASE CRON EDGE FUNCTION"]
S1["Sweeper
every 5 min"]
S2["Re-enqueue stuck jobs"]
S3["Flag orphan sessions"]
S1 --> S2
S1 --> S3
end
F4 -.->|"sweeper picks up"| S2
S2 -->|"create new vi_job + trigger worker"| DB3
classDef adminNode fill:#ECE6FB,stroke:#7C3AED,color:#241A12,stroke-width:1.5px
classDef userNode fill:#EAF2F9,stroke:#2F6FA8,color:#241A12,stroke-width:1.5px
classDef systemNode fill:#E4F1EE,stroke:#0E7C6E,color:#241A12,stroke-width:1.5px
classDef dbNode fill:#E4F1EE,stroke:#0E7C6E,color:#241A12,stroke-width:1.5px
classDef failNode fill:#FBEBEA,stroke:#C23A30,color:#241A12,stroke-width:1.5px
classDef elNode fill:#FAF0DC,stroke:#A5650A,color:#241A12,stroke-width:1.5px
classDef railNode fill:#ECE6FB,stroke:#7C3AED,color:#241A12,stroke-width:1.5px
classDef decisionNode fill:#FAF0DC,stroke:#A5650A,color:#241A12,stroke-width:1.5px
class A1,A2,R1,R3,R4 adminNode
class U1,U2,U3,U4 userNode
class D1,S1,S2,S3 systemNode
class DB1,DB2,DB3,DB4,DB5 dbNode
class F1,F2,F4,F5 failNode
class EL1,EL2 elNode
class W1,W2,W4,W6 railNode
class D2,W3,W5,R2,F3 decisionNode
style ADMIN fill:transparent,stroke:#7C3AED,stroke-width:1.5px,stroke-dasharray:5 5,color:#7C3AED
style USER fill:transparent,stroke:#2F6FA8,stroke-width:1.5px,stroke-dasharray:5 5,color:#2F6FA8
style EL fill:transparent,stroke:#A5650A,stroke-width:1.5px,stroke-dasharray:5 5,color:#A5650A
style DISPATCH fill:transparent,stroke:#0E7C6E,stroke-width:1.5px,stroke-dasharray:5 5,color:#0E7C6E
style WORKER fill:transparent,stroke:#7C3AED,stroke-width:1.5px,stroke-dasharray:5 5,color:#7C3AED
style REVIEW fill:transparent,stroke:#7C3AED,stroke-width:1.5px,stroke-dasharray:5 5,color:#7C3AED
style FAIL fill:transparent,stroke:#C23A30,stroke-width:1.5px,stroke-dasharray:5 5,color:#C23A30
style SWEEPER fill:transparent,stroke:#0E7C6E,stroke-width:1.5px,stroke-dasharray:5 5,color:#0E7C6E
style SB1 fill:transparent,stroke:#0E7C6E,stroke-width:1px,stroke-dasharray:3 3,color:#0E7C6E
style SB2 fill:transparent,stroke:#0E7C6E,stroke-width:1px,stroke-dasharray:3 3,color:#0E7C6E
style SB3 fill:transparent,stroke:#0E7C6E,stroke-width:1px,stroke-dasharray:3 3,color:#0E7C6E
02
Session State Machine
Waiting
Active
Complete
Failed
flowchart LR
AH["awaiting_halves"]
RTP["ready_to_process"]
P["processing"]
C["complete"]
F["failed"]
AH -->|"both halves received"| RTP
RTP -->|"worker claims job"| P
P -->|"deliverable written"| C
P -->|"error + retries left"| RTP
P -->|"retry cap exhausted"| F
RTP -->|"retry cap exhausted"| F
classDef waiting fill:#EAF2F9,stroke:#2F6FA8,color:#241A12,stroke-width:1.5px
classDef active fill:#FAF0DC,stroke:#A5650A,color:#241A12,stroke-width:1.5px
classDef done fill:#E4F1EE,stroke:#0E7C6E,color:#241A12,stroke-width:1.5px
classDef dead fill:#FBEBEA,stroke:#C23A30,color:#241A12,stroke-width:1.5px
class AH waiting
class RTP,P active
class C done
class F dead
Self-healing design. Two recovery layers catch different failures: In-call retry (3 attempts, 2s/8s/30s backoff) handles transient API errors silently. Sweeper (cron, every 5 min) catches jobs that crashed mid-processing or were never picked up. Retry cap of
5 prevents infinite loops on unprocessable transcripts. Admin is alerted only on permanent failed status.