CSA LangGraph Pipeline Architecture

Date: 2026-03-01 From: Jonathan (Architect) To: Jay Gatlit, Skip Blankley
Implementation complete — 6 phases, 138 tests passing, 2 validated runs

Executive Summary

The CSA (Call > Specification > Artifact) pipeline has been reimplemented as a LangGraph agent system. It transforms consultative call transcripts, meeting notes, and Slack threads into two published HTML artifacts — an internal briefing and a client-facing input form — with a response capture API and an export manifest.

The new implementation replaces the previous 3-skill Claude Code chain with a typed, checkpointed, multi-entrypoint agent graph that supports resumable runs, API triggers, parallel QA+deploy, and programmatic state inspection.

Graph Nodes
12
With 4 interrupt gates
State Fields
40
CSAState TypedDict
Tools
21
Across 6 categories
Prompt Phases
23
3 domains
Production LOC
~3,500
Python 3.12
Test LOC
~2,000
138 tests, 20 files
Entrypoints
3
CLI, API, Bridge
Validated Runs
2
92/100 & 95/100 QA

Pipeline Graph — 12-Node StateGraph

The pipeline is a LangGraph StateGraph with conditional routing by input type, 4 human-approval interrupt gates, and parallel fan-out for deploy + QA via the Send API.

Pipeline Graph Topology

Input Flexibility

The router dispatches to different entry points based on input type, allowing the pipeline to skip irrelevant phases:

Input TypeEntry PointSkips
Zoom transcriptprocess_transcript (8 phases)Nothing
Slack notes / emailnormalize_input → spec_authoringTranscript processing
Existing priority specvisual_artifact directlyTranscript + spec
Client feedbackspec_authoring directlyTranscript + normalize
Input Routing Paths

State Management & Interrupt Gates

CSAState — 40-Field TypedDict

All nodes share a single typed state dictionary. Three fields use accumulator reducers (operator.add) that grow across nodes rather than overwrite: pipeline_steps_used, errors, and vault_entities. The LLM conversation is tracked via add_messages.

State Accumulation Across Nodes

Interrupt Gate Pattern

Four gates pause the pipeline for human approval. Each evaluates conditions, surfaces a summary, and waits for input via interrupt().

GateLocationEvaluatesResume Options
gate_1After process_transcript3+ action item owners, 2+ decisionsproceed, skip_to_visual, stop
gate_2After spec_authoringCLIENT INPUT section, 3+ mermaid blocksproceed, stop
brainstormInside visual_artifact4 A/B/C/D design questionsanswers dict
design_approvalInside visual_artifactMarkdown design docapprove, revise
Interrupt Gate Flow

Tool Ecosystem — 21 LangChain Tools

Tools are @tool-decorated functions bound to ChatAnthropic agents via bind_tools(). Each node selects the tools relevant to its domain.

Tool Distribution by Category
CategoryCountToolsUsed By
Filesystem6read_file, write_file, append_to_file, glob_files, move_file, file_existsAll agentic nodes
Vault6check_entity_exists, read_entity, write_entity, append_to_entity, list_entities, read_templateprocess_transcript, spec_authoring
Playwright QA5take_screenshots, evaluate_svg_diagrams, check_text_contrast, evaluate_cross_links, compute_qa_scoreqa
FTP2ftp_upload, ftp_verifydeploy, manifest
Mermaid2batch_render_diagrams, render_single_diagramvisual_artifact
Notification2slack_notify, notify_pipeline_eventpublish, manifest

Three Entrypoints

The pipeline can be triggered from CLI, webhook API, or programmatically from Claude Code. All entrypoints produce identical outputs and share the same checkpoint persistence.

Entrypoint Architecture
EntrypointInterfaceInterrupt HandlingUse Case
CLIpython -m csastdin promptsDevelopment, manual runs
FastAPI6 REST endpointsPOST /resumeWebhook triggers, flywheel
Claude BridgePython function calls.csa-interrupt.jsonClaude Code integration

FastAPI Webhook Endpoints

MethodPathPurpose
POST/runStart new pipeline run
GET/run/{thread_id}/statusCurrent step + interrupt payload
POST/run/{thread_id}/resumeResume with human input
POST/webhook/form-responsesubmit.php callback (flywheel)
POST/webhook/slackSlack event auto-detect
GET/healthHealth check

Testing & Quality

Test Suite — 138 Tests

Test Distribution
CategoryFilesTestsCoverage
Node tests5~25Individual node behavior, error handling
Prompt tests3~18Phase generation, content quality
Tool tests6~35Tool invocation with mocked external APIs
Integration tests3~42Full pipeline paths, interrupt handling, output parity
Entrypoint tests2~18CLI/API request handling, state persistence

Visual QA Scoring — 10 Criteria

Playwright-based inspection at 3 viewports (1920×1080, 768×1024, 375×667). Production threshold: 90/100.

CriterionWeightTool
SVG rendering20 ptsevaluate_svg_diagrams
Text contrast20 ptscheck_text_contrast
Cross-links15 ptsevaluate_cross_links
Responsive layout15 ptstake_screenshots
JS errors15 ptsPlaywright console
Nav links10 ptsevaluate_cross_links
Warnings5 ptsPlaywright console

Validated Runs

Estate Planner (POC)
92/100
Full chain • Zoom transcript • /estate-planner/
CSA Self-Doc (Meta)
95/100
Partial chain • Slack notes • /csa/

Three Decisions Needed

Three strategic decisions determine how the pipeline runs in production. Each is independent and has a recommended option.

1. LangGraph Platform Deployment Strategy
✓ Recommended: Docker on VPS

Context: The pipeline supports CLI, FastAPI webhook, and Claude Code bridge. LangGraph Platform adds Docker deployment with Studio UI for visual debugging.

OptionDescriptionTrade-off
A — Docker on VPSContainer alongside existing PM2 servicesFull control, Studio UI, co-located
B — LangGraph CloudLangChain-hosted managed infrastructureZero-ops but vendor lock-in, recurring cost
C — Local-onlyTrigger via Claude Code bridge as neededZero infra but no API access, no webhooks
2. Checkpointer Migration Path
✓ Recommended: Stay on SQLite

Context: Currently using SqliteSaver for single-machine persistence. PostgresSaver is a one-line code change but requires a running PostgreSQL instance.

OptionDescriptionTrade-off
A — Stay on SQLiteNo change until multi-user access neededZero infra, sufficient for single-operator
B — PostgresSaver nowMigrate immediately for future-proofingConcurrent access but requires PG instance
C — HybridMemorySaver for dev, SQLite for prodFast dev but two code paths
3. Webhook Integration Priority
✓ Recommended: Form-response callback first

Context: Three webhook integrations are built but not yet live. Enabling them determines how the pipeline gets triggered automatically.

OptionDescriptionTrade-off
A — Form-response firstsubmit.php → webhook → new CSA runCloses the flywheel loop
B — Slack webhook firstAuto-capture from channel discussionsBroadest trigger but needs noise filtering
C — All simultaneouslyEnable all three at onceComplete automation but harder to debug
D — Manual-onlyKeep current stateZero risk but no automation
Flywheel Loop (Decision 3, Option A)

Dependency Chain & Future

Resolving the three decisions unlocks four deferred capabilities. The deployment decision is the primary gate — it determines whether webhook triggers and Studio debugging are available.

Current DecisionUnlocksGate
Decision 1 (Deployment)LangGraph Studio integrationDeployment model chosen
Decision 1 (Deployment)Decision 3 (Webhooks)Not local-only
Decision 2 (Checkpointer)Multi-user concurrent runsPostgresSaver if needed
Decision 3 (Webhooks)Email trigger integrationWebhook infra active
First production runOutput parity validationLive output to compare

Phase Transition Checklist

Bridge strategy: The current 3-skill Claude Code chain remains available as a fallback. Both systems produce equivalent outputs. The LangGraph pipeline becomes the default once the first production run validates parity.