# tthandi/parabank-agentic-workflow architecture

> Architecture diagram of the GitHub repository tthandi/parabank-agentic-workflow, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-11). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/tthandi/parabank-agentic-workflow
- Repository: https://github.com/tthandi/parabank-agentic-workflow

## Overview

CUA automates ParaBank workflows by letting an LLM discover a browser procedure, recording that procedure as a typed, versioned capability, then replaying it deterministically without an LLM. The principal path is user request → CLI/discovery → live browser actions → recorded capability; later callers invoke cataloged capabilities through replay and receive structured outcomes. Safety checks, redaction, logging, and human handoff support both discovery and replay. The README documents catalog invocation, approval, and replay statistics; source evidence for some of those links is limited to module references, so the graph omits uncertain call details.

Main entry points: [`src/cua/replay/executor.py`](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/replay/executor.py) (Replay executor), [`src/cua/agent/loop.py`](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/agent/loop.py) (Discovery loop), [`src/cua/cli.py`](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/cli.py) (CLI entrypoints), [`src/cua/artifact/store.py`](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/artifact/store.py) (Artifact store)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_discovery["Discovery and surface"]
  node_cli["CLI entrypoints<br/>[cli.py]"]
  node_agent_loop["Discovery loop<br/>[loop.py]"]
  node_llm["LLM decider<br/>[llm.py]"]
  node_browser["Browser surface<br/>[browser.py]"]
end

subgraph group_capabilities["Capability lifecycle"]
  node_recorder["Artifact recorder<br/>[recorder.py]"]
  node_transcript["Run transcript<br/>[transcript.py]"]
  node_schema["Capability schema<br/>[schema.py]"]
  node_store[("Artifact store<br/>[store.py]")]
  node_artifacts[("Versioned capabilities")]
end

subgraph group_execution["Replay and catalog"]
  node_catalog["Tool catalog<br/>[registry.py]"]
  node_replay["Replay executor<br/>[executor.py]"]
  node_locator["Locator fallback<br/>[locator.py]"]
  node_outcomes["Replay outcomes<br/>[outcomes.py]"]
  node_stats["Replay stats and approval<br/>[stats.py]"]
end

subgraph group_guardrails["Safety and oversight"]
  node_allowlist["Allowlist checks<br/>[allowlist.py]"]
  node_policy["Risk policy<br/>[policy.py]"]
  node_redact["Sensitive-data redaction<br/>[redact.py]"]
  node_handoff["Human handoff<br/>[handoff.py]"]
  node_intervention["Intervention request<br/>[intervention.py]"]
  node_operator_mock["Operator interface<br/>[operator_mock.py]"]
end

subgraph group_observability["Run evidence"]
  node_logger["Structured run logger<br/>[logger.py]"]
  node_evidence[("Run evidence")]
end

node_user(("Operator or agent"))
node_para_bank["ParaBank app"]

node_user -->|"starts run"| node_cli
node_cli -->|"starts discovery"| node_agent_loop
node_agent_loop -->|"requests decisions"| node_llm
node_agent_loop -->|"observes and acts"| node_browser
node_llm -.->|"uses observations"| node_browser
node_browser -->|"drives UI"| node_para_bank
node_agent_loop -->|"records steps"| node_transcript
node_recorder -->|"distills"| node_transcript
node_recorder -->|"builds capability"| node_schema
node_cli -->|"records capability"| node_recorder
node_store -->|"loads and validates"| node_schema
node_store -->|"reads and writes"| node_artifacts
node_cli -->|"loads capability"| node_store
node_cli -->|"lists and invokes"| node_catalog
node_catalog -->|"loads saved tools"| node_store
node_user -->|"selects capability"| node_catalog
node_cli -->|"starts replay"| node_replay
node_replay -->|"executes steps"| node_browser
node_replay -->|"resolves targets"| node_locator
node_replay -->|"classifies result"| node_outcomes
node_cli -->|"records replay stats"| node_stats
node_stats -->|"updates capability"| node_store
node_replay -->|"checks actions"| node_allowlist
node_agent_loop -->|"checks actions"| node_allowlist
node_replay -->|"checks risk"| node_policy
node_agent_loop -->|"scrubs sensitive data"| node_redact
node_replay -->|"scrubs run data"| node_redact
node_agent_loop -->|"cedes control"| node_handoff
node_replay -->|"cedes control"| node_handoff
node_handoff -->|"transfers control"| node_browser
node_agent_loop -->|"raises request"| node_intervention
node_replay -->|"raises request"| node_intervention
node_operator_mock -->|"handles requests"| node_intervention
node_agent_loop -->|"logs run"| node_logger
node_replay -->|"logs run"| node_logger
node_logger -->|"scrubs log data"| node_redact
node_logger -->|"writes run logs"| node_evidence
node_intervention -->|"persists request"| node_evidence

click node_cli "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/cli.py"
click node_agent_loop "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/agent/loop.py"
click node_llm "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/agent/llm.py"
click node_browser "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/surface/browser.py"
click node_recorder "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/artifact/recorder.py"
click node_transcript "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/artifact/transcript.py"
click node_schema "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/artifact/schema.py"
click node_store "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/artifact/store.py"
click node_artifacts "https://github.com/tthandi/parabank-agentic-workflow/tree/main/capabilities"
click node_catalog "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/catalog/registry.py"
click node_replay "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/replay/executor.py"
click node_locator "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/replay/locator.py"
click node_outcomes "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/replay/outcomes.py"
click node_stats "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/catalog/stats.py"
click node_allowlist "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/safety/allowlist.py"
click node_policy "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/safety/policy.py"
click node_redact "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/safety/redact.py"
click node_handoff "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/escalation/handoff.py"
click node_intervention "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/escalation/intervention.py"
click node_operator_mock "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/escalation/operator_mock.py"
click node_logger "https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/obslog/logger.py"
click node_evidence "https://github.com/tthandi/parabank-agentic-workflow/tree/main/evidence"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cli,node_agent_loop,node_llm,node_browser toneBlue
class node_recorder,node_transcript,node_schema,node_store,node_artifacts toneAmber
class node_catalog,node_replay,node_locator,node_outcomes,node_stats toneMint
class node_allowlist,node_policy,node_redact,node_handoff,node_intervention,node_operator_mock toneRose
class node_logger,node_evidence,node_user,node_para_bank toneIndigo
```

## Components

### Discovery and surface

- [CLI entrypoints](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/cli.py): `src/cua/cli.py`
- [Discovery loop](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/agent/loop.py): `src/cua/agent/loop.py`
- [LLM decider](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/agent/llm.py): `src/cua/agent/llm.py`
- [Browser surface](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/surface/browser.py): `src/cua/surface/browser.py`

### Capability lifecycle

- [Artifact recorder](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/artifact/recorder.py): `src/cua/artifact/recorder.py`
- [Run transcript](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/artifact/transcript.py): `src/cua/artifact/transcript.py`
- [Capability schema](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/artifact/schema.py): `src/cua/artifact/schema.py`
- [Artifact store](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/artifact/store.py): `src/cua/artifact/store.py`
- [Versioned capabilities](https://github.com/tthandi/parabank-agentic-workflow/tree/main/capabilities): `capabilities`

### Replay and catalog

- [Tool catalog](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/catalog/registry.py): `src/cua/catalog/registry.py`
- [Replay executor](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/replay/executor.py): `src/cua/replay/executor.py`
- [Locator fallback](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/replay/locator.py): `src/cua/replay/locator.py`
- [Replay outcomes](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/replay/outcomes.py): `src/cua/replay/outcomes.py`
- [Replay stats and approval](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/catalog/stats.py): `src/cua/catalog/stats.py`

### Safety and oversight

- [Allowlist checks](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/safety/allowlist.py): `src/cua/safety/allowlist.py`
- [Risk policy](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/safety/policy.py): `src/cua/safety/policy.py`
- [Sensitive-data redaction](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/safety/redact.py): `src/cua/safety/redact.py`
- [Human handoff](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/escalation/handoff.py): `src/cua/escalation/handoff.py`
- [Intervention request](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/escalation/intervention.py): `src/cua/escalation/intervention.py`
- [Operator interface](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/escalation/operator_mock.py): `src/cua/escalation/operator_mock.py`

### Run evidence

- [Structured run logger](https://github.com/tthandi/parabank-agentic-workflow/blob/main/src/cua/obslog/logger.py): `src/cua/obslog/logger.py`
- [Run evidence](https://github.com/tthandi/parabank-agentic-workflow/tree/main/evidence): `evidence`

### Other components

- **Operator or agent**
- **ParaBank app**

## Connections

- Operator or agent → CLI entrypoints: starts run (evidence: `README.md`)
- CLI entrypoints → Discovery loop: starts discovery (evidence: `src/cua/cli.py`)
- Discovery loop → LLM decider: requests decisions (evidence: `src/cua/agent/loop.py`)
- Discovery loop → Browser surface: observes and acts (evidence: `src/cua/agent/loop.py`)
- LLM decider → Browser surface: uses observations
- Browser surface → ParaBank app: drives UI (evidence: `README.md`)
- Discovery loop → Run transcript: records steps (evidence: `src/cua/agent/loop.py`)
- Artifact recorder → Run transcript: distills (evidence: `src/cua/artifact/recorder.py`)
- Artifact recorder → Capability schema: builds capability (evidence: `src/cua/artifact/recorder.py`)
- CLI entrypoints → Artifact recorder: records capability (evidence: `src/cua/cli.py`)
- Artifact store → Capability schema: loads and validates (evidence: `src/cua/artifact/store.py`)
- Artifact store → Versioned capabilities: reads and writes (evidence: `src/cua/artifact/store.py`)
- CLI entrypoints → Artifact store: loads capability (evidence: `src/cua/cli.py`)
- CLI entrypoints → Tool catalog: lists and invokes (evidence: `src/cua/cli.py`)
- Tool catalog → Artifact store: loads saved tools (evidence: `src/cua/catalog/registry.py`)
- Operator or agent → Tool catalog: selects capability (evidence: `README.md`)
- CLI entrypoints → Replay executor: starts replay (evidence: `src/cua/cli.py`)
- Replay executor → Browser surface: executes steps (evidence: `src/cua/replay/executor.py`)
- Replay executor → Locator fallback: resolves targets (evidence: `src/cua/replay/executor.py`)
- Replay executor → Replay outcomes: classifies result (evidence: `src/cua/replay/executor.py`)
- CLI entrypoints → Replay stats and approval: records replay stats (evidence: `src/cua/cli.py`)
- Replay stats and approval → Artifact store: updates capability (evidence: `src/cua/catalog/stats.py`)
- Replay executor → Allowlist checks: checks actions (evidence: `src/cua/replay/executor.py`)
- Discovery loop → Allowlist checks: checks actions (evidence: `src/cua/agent/loop.py`)
- Replay executor → Risk policy: checks risk (evidence: `src/cua/replay/executor.py`)
- Discovery loop → Sensitive-data redaction: scrubs sensitive data (evidence: `src/cua/agent/loop.py`)
- Replay executor → Sensitive-data redaction: scrubs run data (evidence: `src/cua/replay/executor.py`)
- Discovery loop → Human handoff: cedes control (evidence: `src/cua/agent/loop.py`)
- Replay executor → Human handoff: cedes control (evidence: `src/cua/replay/executor.py`)
- Human handoff → Browser surface: transfers control (evidence: `src/cua/escalation/handoff.py`)
- Discovery loop → Intervention request: raises request (evidence: `src/cua/agent/loop.py`)
- Replay executor → Intervention request: raises request (evidence: `src/cua/replay/executor.py`)
- Operator interface → Intervention request: handles requests (evidence: `src/cua/escalation/operator_mock.py`)
- Discovery loop → Structured run logger: logs run (evidence: `src/cua/agent/loop.py`)
- Replay executor → Structured run logger: logs run (evidence: `src/cua/replay/executor.py`)
- Structured run logger → Sensitive-data redaction: scrubs log data (evidence: `src/cua/obslog/logger.py`)
- Structured run logger → Run evidence: writes run logs (evidence: `README.md`)
- Intervention request → Run evidence: persists request (evidence: `src/cua/escalation/intervention.py`)
