# sortedcord/ada architecture

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

- Interactive diagram: https://gitdiagram.com/sortedcord/ada
- Repository: https://github.com/sortedcord/ada

## Overview

Ada is a self-hosted, single-player narrative simulation. A player submits an action through the web client; the API accepts a turn and queues durable work, and the worker runs resumable intent, perception, NPC cognition, resolution, narration, and memory/card stages. Validated canonical state is persisted in PostgreSQL, while the client reads run and journal views. Separate authoring paths manage versioned scenarios and story cards, and an MCP bridge exposes scenario tools. The README documents these capabilities; sampled excerpts show only parts of their wiring, so uncertain calls are omitted.

Main entry points: [`apps/worker/src/turn-worker.ts`](https://github.com/sortedcord/ada/blob/main/apps/worker/src/turn-worker.ts) (Turn worker), [`packages/db/src/schema.ts`](https://github.com/sortedcord/ada/blob/main/packages/db/src/schema.ts) (Canonical database), [`apps/api/src/app.ts`](https://github.com/sortedcord/ada/blob/main/apps/api/src/app.ts) (REST and SSE API), [`apps/api/src/scenario-service.ts`](https://github.com/sortedcord/ada/blob/main/apps/api/src/scenario-service.ts) (Scenario service)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Player client"]
  node_web["Web app<br/>[main.tsx]"]
end

subgraph group_services["Application services"]
  node_api["REST and SSE API<br/>[app.ts]"]
  node_runservice["Run service<br/>[run-service.ts]"]
  node_mcp["Scenario MCP server<br/>[server.ts]"]
end

subgraph group_runtime["Turn runtime"]
  node_worker["Turn worker<br/>[turn-worker.ts]"]
  node_engine["Turn engine<br/>[orchestrator.ts]"]
  node_npccontext["NPC context"]
  node_ai["AI gateway<br/>[index.ts]"]
  node_prompts["Prompt builders<br/>[builders.ts]"]
end

subgraph group_world["World data"]
  node_domain["Domain policies<br/>[policies.ts]"]
  node_contracts["API contracts<br/>[api.ts]"]
  node_dbservices["Run and scenario services<br/>[run-services.ts]"]
  node_dbcontext["NPC context repository<br/>[npc-context.ts]"]
  node_db[("Canonical database<br/>[schema.ts]")]
end

subgraph group_authoring["Authoring and context"]
  node_scenarioservice["Scenario service"]
  node_architect["Narrative architect<br/>[index.ts]"]
  node_retrieval["Context retrieval<br/>[sql-service.ts]"]
  node_scenario_tools["Scenario tools<br/>[index.ts]"]
  node_retrieval_index["Retrieval indexing<br/>[indexer.ts]"]
end

node_player(("Player"))
node_queue["Turn queue"]
node_postgres[("PostgreSQL")]

node_player -->|"submits actions"| node_web
node_web -->|"requests views and turns"| node_api
node_api -->|"validates API data"| node_contracts
node_api -->|"delegates run operations"| node_runservice
node_api -->|"delegates scenario edits"| node_scenarioservice
node_runservice -->|"enqueues turns"| node_queue
node_queue -->|"delivers jobs"| node_worker
node_worker -->|"orchestrates stages"| node_engine
node_worker -->|"requests generation"| node_ai
node_worker -->|"builds role prompts"| node_prompts
node_worker -->|"advances story guidance"| node_architect
node_worker -->|"persists turn state"| node_dbservices
node_engine -->|"applies policies"| node_domain
node_engine -->|"builds NPC context"| node_npccontext
node_npccontext -->|"loads scoped context"| node_dbcontext
node_npccontext -->|"checks query scope"| node_domain
node_dbservices -->|"reads and writes"| node_db
node_dbcontext -->|"reads context records"| node_db
node_retrieval -->|"searches and audits"| node_db
node_retrieval_index -->|"indexes context"| node_db
node_db -->|"stores canonical state"| node_postgres
node_scenarioservice -->|"validates operations"| node_scenario_tools
node_scenarioservice -->|"critiques card changes"| node_architect
node_scenarioservice -->|"versions scenario data"| node_db
node_mcp -->|"calls scenario API"| node_api

click node_web "https://github.com/sortedcord/ada/blob/main/apps/web/src/main.tsx"
click node_api "https://github.com/sortedcord/ada/blob/main/apps/api/src/app.ts"
click node_runservice "https://github.com/sortedcord/ada/blob/main/apps/api/src/run-service.ts"
click node_scenarioservice "https://github.com/sortedcord/ada/blob/main/apps/api/src/scenario-service.ts"
click node_worker "https://github.com/sortedcord/ada/blob/main/apps/worker/src/turn-worker.ts"
click node_engine "https://github.com/sortedcord/ada/blob/main/packages/engine/src/orchestrator.ts"
click node_npccontext "https://github.com/sortedcord/ada/blob/main/packages/engine/src/npc-context-service.ts"
click node_ai "https://github.com/sortedcord/ada/blob/main/packages/ai/src/index.ts"
click node_prompts "https://github.com/sortedcord/ada/blob/main/packages/prompts/src/builders.ts"
click node_architect "https://github.com/sortedcord/ada/blob/main/packages/architect/src/index.ts"
click node_retrieval "https://github.com/sortedcord/ada/blob/main/packages/retrieval/src/sql-service.ts"
click node_domain "https://github.com/sortedcord/ada/blob/main/packages/domain/src/policies.ts"
click node_contracts "https://github.com/sortedcord/ada/blob/main/packages/contracts/src/api.ts"
click node_dbservices "https://github.com/sortedcord/ada/blob/main/packages/db/src/run-services.ts"
click node_dbcontext "https://github.com/sortedcord/ada/blob/main/packages/db/src/npc-context.ts"
click node_db "https://github.com/sortedcord/ada/blob/main/packages/db/src/schema.ts"
click node_mcp "https://github.com/sortedcord/ada/blob/main/apps/scenario-mcp/src/server.ts"
click node_scenario_tools "https://github.com/sortedcord/ada/blob/main/packages/scenario-tools/src/index.ts"
click node_retrieval_index "https://github.com/sortedcord/ada/blob/main/packages/retrieval/src/indexer.ts"

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_web toneBlue
class node_api,node_runservice,node_mcp,node_postgres toneAmber
class node_worker,node_engine,node_npccontext,node_ai,node_prompts toneMint
class node_domain,node_contracts,node_dbservices,node_dbcontext,node_db,node_queue toneRose
class node_scenarioservice,node_architect,node_retrieval,node_scenario_tools,node_retrieval_index,node_player toneIndigo
```

## Components

### Player client

- [Web app](https://github.com/sortedcord/ada/blob/main/apps/web/src/main.tsx): `apps/web/src/main.tsx`

### Application services

- [REST and SSE API](https://github.com/sortedcord/ada/blob/main/apps/api/src/app.ts): `apps/api/src/app.ts`
- [Run service](https://github.com/sortedcord/ada/blob/main/apps/api/src/run-service.ts): `apps/api/src/run-service.ts`
- [Scenario MCP server](https://github.com/sortedcord/ada/blob/main/apps/scenario-mcp/src/server.ts): `apps/scenario-mcp/src/server.ts`

### Turn runtime

- [Turn worker](https://github.com/sortedcord/ada/blob/main/apps/worker/src/turn-worker.ts): `apps/worker/src/turn-worker.ts`
- [Turn engine](https://github.com/sortedcord/ada/blob/main/packages/engine/src/orchestrator.ts): `packages/engine/src/orchestrator.ts`
- [NPC context](https://github.com/sortedcord/ada/blob/main/packages/engine/src/npc-context-service.ts): `packages/engine/src/npc-context-service.ts`
- [AI gateway](https://github.com/sortedcord/ada/blob/main/packages/ai/src/index.ts): `packages/ai/src/index.ts`
- [Prompt builders](https://github.com/sortedcord/ada/blob/main/packages/prompts/src/builders.ts): `packages/prompts/src/builders.ts`

### World data

- [Domain policies](https://github.com/sortedcord/ada/blob/main/packages/domain/src/policies.ts): `packages/domain/src/policies.ts`
- [API contracts](https://github.com/sortedcord/ada/blob/main/packages/contracts/src/api.ts): `packages/contracts/src/api.ts`
- [Run and scenario services](https://github.com/sortedcord/ada/blob/main/packages/db/src/run-services.ts): `packages/db/src/run-services.ts`
- [NPC context repository](https://github.com/sortedcord/ada/blob/main/packages/db/src/npc-context.ts): `packages/db/src/npc-context.ts`
- [Canonical database](https://github.com/sortedcord/ada/blob/main/packages/db/src/schema.ts): `packages/db/src/schema.ts`

### Authoring and context

- [Scenario service](https://github.com/sortedcord/ada/blob/main/apps/api/src/scenario-service.ts): `apps/api/src/scenario-service.ts`
- [Narrative architect](https://github.com/sortedcord/ada/blob/main/packages/architect/src/index.ts): `packages/architect/src/index.ts`
- [Context retrieval](https://github.com/sortedcord/ada/blob/main/packages/retrieval/src/sql-service.ts): `packages/retrieval/src/sql-service.ts`
- [Scenario tools](https://github.com/sortedcord/ada/blob/main/packages/scenario-tools/src/index.ts): `packages/scenario-tools/src/index.ts`
- [Retrieval indexing](https://github.com/sortedcord/ada/blob/main/packages/retrieval/src/indexer.ts): `packages/retrieval/src/indexer.ts`

### Other components

- **Player**
- **Turn queue**
- **PostgreSQL**

## Connections

- Player → Web app: submits actions
- Web app → REST and SSE API: requests views and turns
- REST and SSE API → API contracts: validates API data
- REST and SSE API → Run service: delegates run operations
- REST and SSE API → Scenario service: delegates scenario edits
- Run service → Turn queue: enqueues turns
- Turn queue → Turn worker: delivers jobs
- Turn worker → Turn engine: orchestrates stages
- Turn worker → AI gateway: requests generation
- Turn worker → Prompt builders: builds role prompts
- Turn worker → Narrative architect: advances story guidance
- Turn worker → Run and scenario services: persists turn state
- Turn engine → Domain policies: applies policies
- Turn engine → NPC context: builds NPC context
- NPC context → NPC context repository: loads scoped context
- NPC context → Domain policies: checks query scope
- Run and scenario services → Canonical database: reads and writes
- NPC context repository → Canonical database: reads context records
- Context retrieval → Canonical database: searches and audits
- Retrieval indexing → Canonical database: indexes context
- Canonical database → PostgreSQL: stores canonical state
- Scenario service → Scenario tools: validates operations
- Scenario service → Narrative architect: critiques card changes
- Scenario service → Canonical database: versions scenario data
- Scenario MCP server → REST and SSE API: calls scenario API
