# projnanda/nandatown architecture

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

- Interactive diagram: https://gitdiagram.com/projnanda/nandatown
- Repository: https://github.com/projnanda/nandatown

## Overview

NandaTown is a local-first agent test harness with three execution modes: seeded Lab simulations, HTTP-based Track runs, and tests against an existing A2A endpoint in Path mode. The CLI and terminal UI initiate runs; each mode records observations that are evaluated into portable evidence bundles for reporting, verification, replay, and visualization. The README documents these product capabilities; source excerpts and the SOURCE INDEX support the main orchestration and evidence links, while some subsystem details remain unsampled.

Main entry points: [`src/nandatown/cli.py`](https://github.com/projnanda/nandatown/blob/main/src/nandatown/cli.py) (CLI), [`src/nandatown/runner.py`](https://github.com/projnanda/nandatown/blob/main/src/nandatown/runner.py) (Track runner), [`src/nandatown/sim/runner.py`](https://github.com/projnanda/nandatown/blob/main/src/nandatown/sim/runner.py) (Lab runner), [`src/nandatown/path_runner.py`](https://github.com/projnanda/nandatown/blob/main/src/nandatown/path_runner.py) (Path runner)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_front["Front doors"]
  node_cli["CLI<br/>[cli.py]"]
  node_tui["Terminal UI<br/>[tui.py]"]
end

subgraph group_modes["Run modes"]
  node_track["Track runner<br/>[runner.py]"]
  node_coordinator["HTTP coordinator<br/>[coordinator.py]"]
  node_db[("Track database<br/>[db.py]")]
  node_client["Participant client<br/>[client.py]"]
  node_participants["Participants"]
  node_lab["Lab runner<br/>[runner.py]"]
  node_scenario["Scenario spec<br/>[scenario.py]"]
  node_path["Path runner<br/>[path_runner.py]"]
  node_pathprofile["Path profiles<br/>[path_profiles.py]"]
  node_profile["Track profiles<br/>[profiles.py]"]
  node_campaign["Campaigns<br/>[campaign.py]"]
  node_compare["Layer comparison<br/>[compare.py]"]
end

subgraph group_protocol["Protocol and participants"]
  node_engine["Simulation engine<br/>[engine.py]"]
  node_layers["Protocol layers"]
  node_a2a["A2A adapter<br/>[a2a_adapter.py]"]
  node_transport["A2A transport<br/>[a2a_transport.py]"]
  node_identity["Portable identity"]
end

subgraph group_evidence["Evidence and analysis"]
  node_records["Run records<br/>[records.py]"]
  node_evaluator["Stage evaluator<br/>[evaluator.py]"]
  node_validators["Lab validators<br/>[validators.py]"]
  node_bundle["Evidence bundle<br/>[bundle.py]"]
  node_report["Report<br/>[report.py]"]
  node_replay["Replay<br/>[replay.py]"]
  node_visualizer["Visualizer<br/>[visualizer.py]"]
end

node_user(("Engineer"))

node_user -->|"invokes"| node_cli
node_user -->|"opens"| node_tui
node_cli -->|"starts runs"| node_track
node_cli -->|"starts runs"| node_lab
node_cli -->|"starts tests"| node_path
node_cli -->|"runs campaigns"| node_campaign
node_cli -->|"compares layers"| node_compare
node_track -->|"starts subprocess"| node_coordinator
node_coordinator -->|"reads and writes"| node_db
node_participants -->|"uses"| node_client
node_client -->|"sends HTTP"| node_coordinator
node_track -->|"loads profile"| node_profile
node_track -->|"spawns"| node_participants
node_track -->|"uses grants"| node_identity
node_lab -->|"runs scenario"| node_scenario
node_lab -->|"executes simulation"| node_engine
node_engine -->|"resolves plugins"| node_layers
node_path -->|"loads profile"| node_pathprofile
node_path -->|"tests endpoint"| node_a2a
node_path -->|"uses transport"| node_transport
node_track -->|"writes bundle"| node_bundle
node_lab -->|"writes bundle"| node_bundle
node_path -->|"writes bundle"| node_bundle
node_bundle -->|"assembles records"| node_records
node_track -->|"evaluates events"| node_evaluator
node_path -->|"evaluates events"| node_evaluator
node_lab -->|"checks properties"| node_validators
node_bundle -->|"replays evaluation"| node_evaluator
node_cli -->|"renders report"| node_report
node_cli -->|"replays bundle"| node_replay
node_cli -->|"visualizes bundle"| node_visualizer
node_campaign -->|"runs scenarios"| node_lab
node_compare -->|"compares runs"| node_lab

click node_cli "https://github.com/projnanda/nandatown/blob/main/src/nandatown/cli.py"
click node_tui "https://github.com/projnanda/nandatown/blob/main/src/nandatown/tui.py"
click node_track "https://github.com/projnanda/nandatown/blob/main/src/nandatown/runner.py"
click node_coordinator "https://github.com/projnanda/nandatown/blob/main/src/nandatown/coordinator.py"
click node_db "https://github.com/projnanda/nandatown/blob/main/src/nandatown/db.py"
click node_client "https://github.com/projnanda/nandatown/blob/main/src/nandatown/client.py"
click node_participants "https://github.com/projnanda/nandatown/tree/main/src/nandatown/participants"
click node_lab "https://github.com/projnanda/nandatown/blob/main/src/nandatown/sim/runner.py"
click node_scenario "https://github.com/projnanda/nandatown/blob/main/src/nandatown/sim/scenario.py"
click node_engine "https://github.com/projnanda/nandatown/blob/main/src/nandatown/sim/engine.py"
click node_layers "https://github.com/projnanda/nandatown/tree/main/src/nandatown/layers"
click node_path "https://github.com/projnanda/nandatown/blob/main/src/nandatown/path_runner.py"
click node_pathprofile "https://github.com/projnanda/nandatown/blob/main/src/nandatown/path_profiles.py"
click node_a2a "https://github.com/projnanda/nandatown/blob/main/src/nandatown/a2a_adapter.py"
click node_transport "https://github.com/projnanda/nandatown/blob/main/src/nandatown/a2a_transport.py"
click node_profile "https://github.com/projnanda/nandatown/blob/main/src/nandatown/profiles.py"
click node_identity "https://github.com/projnanda/nandatown/blob/main/src/nandatown/identity_portable.py"
click node_records "https://github.com/projnanda/nandatown/blob/main/src/nandatown/records.py"
click node_evaluator "https://github.com/projnanda/nandatown/blob/main/src/nandatown/evaluator.py"
click node_validators "https://github.com/projnanda/nandatown/blob/main/src/nandatown/sim/validators.py"
click node_bundle "https://github.com/projnanda/nandatown/blob/main/src/nandatown/bundle.py"
click node_report "https://github.com/projnanda/nandatown/blob/main/src/nandatown/report.py"
click node_replay "https://github.com/projnanda/nandatown/blob/main/src/nandatown/replay.py"
click node_visualizer "https://github.com/projnanda/nandatown/blob/main/src/nandatown/visualizer.py"
click node_campaign "https://github.com/projnanda/nandatown/blob/main/src/nandatown/campaign.py"
click node_compare "https://github.com/projnanda/nandatown/blob/main/src/nandatown/compare.py"

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_tui toneBlue
class node_track,node_coordinator,node_db,node_client,node_participants,node_lab,node_scenario,node_path,node_pathprofile,node_profile,node_campaign,node_compare toneAmber
class node_engine,node_layers,node_a2a,node_transport,node_identity toneMint
class node_records,node_evaluator,node_validators,node_bundle,node_report,node_replay,node_visualizer toneRose
class node_user toneIndigo
```

## Components

### Front doors

- [CLI](https://github.com/projnanda/nandatown/blob/main/src/nandatown/cli.py): `src/nandatown/cli.py`
- [Terminal UI](https://github.com/projnanda/nandatown/blob/main/src/nandatown/tui.py): `src/nandatown/tui.py`

### Run modes

- [Track runner](https://github.com/projnanda/nandatown/blob/main/src/nandatown/runner.py): `src/nandatown/runner.py`
- [HTTP coordinator](https://github.com/projnanda/nandatown/blob/main/src/nandatown/coordinator.py): `src/nandatown/coordinator.py`
- [Track database](https://github.com/projnanda/nandatown/blob/main/src/nandatown/db.py): `src/nandatown/db.py`
- [Participant client](https://github.com/projnanda/nandatown/blob/main/src/nandatown/client.py): `src/nandatown/client.py`
- [Participants](https://github.com/projnanda/nandatown/tree/main/src/nandatown/participants): `src/nandatown/participants`
- [Lab runner](https://github.com/projnanda/nandatown/blob/main/src/nandatown/sim/runner.py): `src/nandatown/sim/runner.py`
- [Scenario spec](https://github.com/projnanda/nandatown/blob/main/src/nandatown/sim/scenario.py): `src/nandatown/sim/scenario.py`
- [Path runner](https://github.com/projnanda/nandatown/blob/main/src/nandatown/path_runner.py): `src/nandatown/path_runner.py`
- [Path profiles](https://github.com/projnanda/nandatown/blob/main/src/nandatown/path_profiles.py): `src/nandatown/path_profiles.py`
- [Track profiles](https://github.com/projnanda/nandatown/blob/main/src/nandatown/profiles.py): `src/nandatown/profiles.py`
- [Campaigns](https://github.com/projnanda/nandatown/blob/main/src/nandatown/campaign.py): `src/nandatown/campaign.py`
- [Layer comparison](https://github.com/projnanda/nandatown/blob/main/src/nandatown/compare.py): `src/nandatown/compare.py`

### Protocol and participants

- [Simulation engine](https://github.com/projnanda/nandatown/blob/main/src/nandatown/sim/engine.py): `src/nandatown/sim/engine.py`
- [Protocol layers](https://github.com/projnanda/nandatown/tree/main/src/nandatown/layers): `src/nandatown/layers`
- [A2A adapter](https://github.com/projnanda/nandatown/blob/main/src/nandatown/a2a_adapter.py): `src/nandatown/a2a_adapter.py`
- [A2A transport](https://github.com/projnanda/nandatown/blob/main/src/nandatown/a2a_transport.py): `src/nandatown/a2a_transport.py`
- [Portable identity](https://github.com/projnanda/nandatown/blob/main/src/nandatown/identity_portable.py): `src/nandatown/identity_portable.py`

### Evidence and analysis

- [Run records](https://github.com/projnanda/nandatown/blob/main/src/nandatown/records.py): `src/nandatown/records.py`
- [Stage evaluator](https://github.com/projnanda/nandatown/blob/main/src/nandatown/evaluator.py): `src/nandatown/evaluator.py`
- [Lab validators](https://github.com/projnanda/nandatown/blob/main/src/nandatown/sim/validators.py): `src/nandatown/sim/validators.py`
- [Evidence bundle](https://github.com/projnanda/nandatown/blob/main/src/nandatown/bundle.py): `src/nandatown/bundle.py`
- [Report](https://github.com/projnanda/nandatown/blob/main/src/nandatown/report.py): `src/nandatown/report.py`
- [Replay](https://github.com/projnanda/nandatown/blob/main/src/nandatown/replay.py): `src/nandatown/replay.py`
- [Visualizer](https://github.com/projnanda/nandatown/blob/main/src/nandatown/visualizer.py): `src/nandatown/visualizer.py`

### Other components

- **Engineer**

## Connections

- Engineer → CLI: invokes (evidence: `README.md`)
- Engineer → Terminal UI: opens (evidence: `README.md`)
- CLI → Track runner: starts runs (evidence: `src/nandatown/cli.py`)
- CLI → Lab runner: starts runs (evidence: `src/nandatown/cli.py`)
- CLI → Path runner: starts tests (evidence: `src/nandatown/cli.py`)
- CLI → Campaigns: runs campaigns (evidence: `src/nandatown/cli.py`)
- CLI → Layer comparison: compares layers (evidence: `src/nandatown/cli.py`)
- Track runner → HTTP coordinator: starts subprocess (evidence: `src/nandatown/runner.py`)
- HTTP coordinator → Track database: reads and writes (evidence: `src/nandatown/coordinator.py`)
- Participants → Participant client: uses (evidence: `src/nandatown/participants/base.py`)
- Participant client → HTTP coordinator: sends HTTP (evidence: `README.md`)
- Track runner → Track profiles: loads profile (evidence: `src/nandatown/runner.py`)
- Track runner → Participants: spawns (evidence: `src/nandatown/runner.py`)
- Track runner → Portable identity: uses grants (evidence: `src/nandatown/runner.py`)
- Lab runner → Scenario spec: runs scenario (evidence: `src/nandatown/campaign.py`)
- Lab runner → Simulation engine: executes simulation (evidence: `README.md`)
- Simulation engine → Protocol layers: resolves plugins (evidence: `src/nandatown/sim/engine.py`)
- Path runner → Path profiles: loads profile (evidence: `src/nandatown/path_runner.py`)
- Path runner → A2A adapter: tests endpoint (evidence: `src/nandatown/path_runner.py`)
- Path runner → A2A transport: uses transport (evidence: `src/nandatown/path_runner.py`)
- Track runner → Evidence bundle: writes bundle (evidence: `src/nandatown/runner.py`)
- Lab runner → Evidence bundle: writes bundle (evidence: `README.md`)
- Path runner → Evidence bundle: writes bundle (evidence: `src/nandatown/path_runner.py`)
- Evidence bundle → Run records: assembles records (evidence: `src/nandatown/bundle.py`)
- Track runner → Stage evaluator: evaluates events (evidence: `src/nandatown/runner.py`)
- Path runner → Stage evaluator: evaluates events (evidence: `src/nandatown/path_runner.py`)
- Lab runner → Lab validators: checks properties (evidence: `README.md`)
- Evidence bundle → Stage evaluator: replays evaluation (evidence: `src/nandatown/bundle.py`)
- CLI → Report: renders report (evidence: `src/nandatown/cli.py`)
- CLI → Replay: replays bundle (evidence: `README.md`)
- CLI → Visualizer: visualizes bundle (evidence: `README.md`)
- Campaigns → Lab runner: runs scenarios (evidence: `src/nandatown/campaign.py`)
- Layer comparison → Lab runner: compares runs (evidence: `src/nandatown/compare.py`)
