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.
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.
The router dispatches to different entry points based on input type, allowing the pipeline to skip irrelevant phases:
| Input Type | Entry Point | Skips |
|---|---|---|
| Zoom transcript | process_transcript (8 phases) | Nothing |
| Slack notes / email | normalize_input → spec_authoring | Transcript processing |
| Existing priority spec | visual_artifact directly | Transcript + spec |
| Client feedback | spec_authoring directly | Transcript + normalize |
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.
Four gates pause the pipeline for human approval. Each evaluates conditions, surfaces a summary, and waits for input via interrupt().
| Gate | Location | Evaluates | Resume Options |
|---|---|---|---|
| gate_1 | After process_transcript | 3+ action item owners, 2+ decisions | proceed, skip_to_visual, stop |
| gate_2 | After spec_authoring | CLIENT INPUT section, 3+ mermaid blocks | proceed, stop |
| brainstorm | Inside visual_artifact | 4 A/B/C/D design questions | answers dict |
| design_approval | Inside visual_artifact | Markdown design doc | approve, revise |
Tools are @tool-decorated functions bound to ChatAnthropic agents via bind_tools(). Each node selects the tools relevant to its domain.
| Category | Count | Tools | Used By |
|---|---|---|---|
| Filesystem | 6 | read_file, write_file, append_to_file, glob_files, move_file, file_exists | All agentic nodes |
| Vault | 6 | check_entity_exists, read_entity, write_entity, append_to_entity, list_entities, read_template | process_transcript, spec_authoring |
| Playwright QA | 5 | take_screenshots, evaluate_svg_diagrams, check_text_contrast, evaluate_cross_links, compute_qa_score | qa |
| FTP | 2 | ftp_upload, ftp_verify | deploy, manifest |
| Mermaid | 2 | batch_render_diagrams, render_single_diagram | visual_artifact |
| Notification | 2 | slack_notify, notify_pipeline_event | publish, manifest |
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 | Interface | Interrupt Handling | Use Case |
|---|---|---|---|
| CLI | python -m csa | stdin prompts | Development, manual runs |
| FastAPI | 6 REST endpoints | POST /resume | Webhook triggers, flywheel |
| Claude Bridge | Python function calls | .csa-interrupt.json | Claude Code integration |
| Method | Path | Purpose |
|---|---|---|
| POST | /run | Start new pipeline run |
| GET | /run/{thread_id}/status | Current step + interrupt payload |
| POST | /run/{thread_id}/resume | Resume with human input |
| POST | /webhook/form-response | submit.php callback (flywheel) |
| POST | /webhook/slack | Slack event auto-detect |
| GET | /health | Health check |
| Category | Files | Tests | Coverage |
|---|---|---|---|
| Node tests | 5 | ~25 | Individual node behavior, error handling |
| Prompt tests | 3 | ~18 | Phase generation, content quality |
| Tool tests | 6 | ~35 | Tool invocation with mocked external APIs |
| Integration tests | 3 | ~42 | Full pipeline paths, interrupt handling, output parity |
| Entrypoint tests | 2 | ~18 | CLI/API request handling, state persistence |
Playwright-based inspection at 3 viewports (1920×1080, 768×1024, 375×667). Production threshold: 90/100.
| Criterion | Weight | Tool |
|---|---|---|
| SVG rendering | 20 pts | evaluate_svg_diagrams |
| Text contrast | 20 pts | check_text_contrast |
| Cross-links | 15 pts | evaluate_cross_links |
| Responsive layout | 15 pts | take_screenshots |
| JS errors | 15 pts | Playwright console |
| Nav links | 10 pts | evaluate_cross_links |
| Warnings | 5 pts | Playwright console |
Three strategic decisions determine how the pipeline runs in production. Each is independent and has a recommended option.
Context: The pipeline supports CLI, FastAPI webhook, and Claude Code bridge. LangGraph Platform adds Docker deployment with Studio UI for visual debugging.
| Option | Description | Trade-off |
|---|---|---|
| A — Docker on VPS | Container alongside existing PM2 services | Full control, Studio UI, co-located |
| B — LangGraph Cloud | LangChain-hosted managed infrastructure | Zero-ops but vendor lock-in, recurring cost |
| C — Local-only | Trigger via Claude Code bridge as needed | Zero infra but no API access, no webhooks |
Context: Currently using SqliteSaver for single-machine persistence. PostgresSaver is a one-line code change but requires a running PostgreSQL instance.
| Option | Description | Trade-off |
|---|---|---|
| A — Stay on SQLite | No change until multi-user access needed | Zero infra, sufficient for single-operator |
| B — PostgresSaver now | Migrate immediately for future-proofing | Concurrent access but requires PG instance |
| C — Hybrid | MemorySaver for dev, SQLite for prod | Fast dev but two code paths |
Context: Three webhook integrations are built but not yet live. Enabling them determines how the pipeline gets triggered automatically.
| Option | Description | Trade-off |
|---|---|---|
| A — Form-response first | submit.php → webhook → new CSA run | Closes the flywheel loop |
| B — Slack webhook first | Auto-capture from channel discussions | Broadest trigger but needs noise filtering |
| C — All simultaneously | Enable all three at once | Complete automation but harder to debug |
| D — Manual-only | Keep current state | Zero risk but no automation |
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 Decision | Unlocks | Gate |
|---|---|---|
| Decision 1 (Deployment) | LangGraph Studio integration | Deployment model chosen |
| Decision 1 (Deployment) | Decision 3 (Webhooks) | Not local-only |
| Decision 2 (Checkpointer) | Multi-user concurrent runs | PostgresSaver if needed |
| Decision 3 (Webhooks) | Email trigger integration | Webhook infra active |
| First production run | Output parity validation | Live output to compare |
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.