Skip to content

Commit 7c2f840

Browse files
SociableSteveclaude
andcommitted
Add docs/ directory and AGENTS.md for future devs and agents
Move DESIGN.md and DEPLOY.md under docs/ (history preserved via git mv) and add: - docs/README.md — documentation index - docs/architecture.md — how the system works: package graph, the turn lifecycle, live-state/scaling, the DM agent loop + tool layer, providers, data model, character/spell system, and a file-by-file code map - AGENTS.md (root) — operational guide for coding agents: the engine-is-truth invariant, commands, build-engine-first rule, conventions, where things live, git/deploy conventions, and known gotchas Fix all cross-references: relative links in the moved docs, README links, the source comments that cite docs/DESIGN.md, and the workflow/infra comments. Comment-only source edits; 80 engine + 42 server tests still pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent e05f845 commit 7c2f840

12 files changed

Lines changed: 343 additions & 12 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Deploy to Cloud Run
33
# Builds the single-container app (SPA + API + WebSocket) and deploys it to
44
# Cloud Run, wired to Cloud SQL (Postgres+pgvector), Memorystore (Redis, via a
55
# Serverless VPC connector), and a GCS bucket for generated images.
6-
# One-time GCP/GitHub setup is in DEPLOY.md.
6+
# One-time GCP/GitHub setup is in docs/DEPLOY.md.
77

88
on:
99
push:

AGENTS.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# AGENTS.md
2+
3+
Guidance for coding agents working in this repository. Humans: see
4+
[`README.md`](README.md) to run it and [`docs/`](docs/) for the full design.
5+
6+
## What this is
7+
8+
An AI-driven, web-based D&D experience: an LLM Dungeon Master narrates, a
9+
deterministic rules engine adjudicates, multiple players share a real-time
10+
session, and art is generated on demand. Monorepo of npm workspaces
11+
(`packages/engine`, `protocol`, `server`, `web`).
12+
13+
**Read [`docs/architecture.md`](docs/architecture.md) first** — it's the code map
14+
and the turn-flow walkthrough. The deeper rationale is in
15+
[`docs/DESIGN.md`](docs/DESIGN.md) (cited from source comments as `docs/DESIGN.md §N`).
16+
17+
## The invariant you must not break
18+
19+
> **The engine is the source of truth; the LLM only narrates.**
20+
21+
The LLM proposes actions through the tool layer (`server/src/gameEngine.ts`); the
22+
engine (`packages/engine`) validates, rolls dice (seeded), and applies results. The
23+
model never sets HP, decides hits, or invents numbers. If a change would let the LLM
24+
mutate state directly, it's wrong — route it through a tool that calls the engine.
25+
26+
## Setup & commands
27+
28+
Node 20+ (CI uses 22). From the repo root:
29+
30+
```bash
31+
npm install
32+
npm run build --workspace @ai-dm/engine # MUST build engine first — others consume its dist/
33+
npm run typecheck # all workspaces
34+
npm test # engine unit tests + server integration tests
35+
```
36+
37+
Run locally:
38+
39+
```bash
40+
npm run dev:server # http + ws on :8787 (scripted DM, JSON store — no cloud needed)
41+
npm run dev:web # Vite on :5173, proxies /api and /ws to the server
42+
```
43+
44+
A single package: append `--workspace @ai-dm/<name>` to `typecheck`/`test`/`build`.
45+
46+
## Before you say "done"
47+
48+
Always, from the root: **`npm run build --workspace @ai-dm/engine && npm run typecheck && npm test`**.
49+
If you touched a package's behavior, add or update its tests. Report failures with the
50+
actual output — don't claim green you haven't seen. Tests are colocated as `*.test.ts`
51+
(engine: pure unit tests; server: `backend.test.ts` + focused loop/memory/dm tests).
52+
53+
## Code conventions
54+
55+
- **Strict TypeScript** (`tsconfig.base.json`): `strict`, `noUncheckedIndexedAccess`,
56+
`noImplicitOverride`, `verbatimModuleSyntax`.
57+
- **ESM / NodeNext:** relative imports use a **`.js` extension** even from `.ts`
58+
files (e.g. `import { x } from "./store.js"`). Type-only imports use `import type`.
59+
- **Seeded randomness only.** Never call global `Math.random()` in the engine or game
60+
logic — use the session's `RNG`, so turns replay identically and snapshots are exact.
61+
- **Wire types live in `@ai-dm/protocol`.** Don't redefine DTOs/messages in the web;
62+
import them. Changing a shape? Update protocol, then both sides.
63+
- **Match the surrounding style** (comment density, naming, idiom). Files carry a
64+
short top-of-file comment explaining their role and citing `docs/DESIGN.md §N` where
65+
relevant — keep that habit.
66+
- **Client never sees enemy stat blocks.** `CreatureView.sheet` is for PCs only.
67+
68+
## Where things live
69+
70+
| You want to change… | Look in |
71+
|----------------------|---------|
72+
| Rules / dice / combat math | `packages/engine/src/*` |
73+
| What the DM can *do* (tools) | `server/src/gameEngine.ts` |
74+
| DM prompt / context / scripted fallback | `server/src/dm.ts`, `geminiDm.ts` |
75+
| The turn loop / WebSocket | `server/src/index.ts` |
76+
| Session shape, snapshots, `toView` | `server/src/session.ts` |
77+
| Persistence | `server/src/store.ts`, `postgres.ts` |
78+
| Scaling (broadcast/lock/presence) | `server/src/realtime.ts`, `runtime.ts` |
79+
| Character building / spells / inventory / XP | `server/src/srd.ts`, `srdContent.ts` |
80+
| REST endpoints | `server/src/routes.ts` |
81+
| Wire types | `packages/protocol/src/index.ts` |
82+
| UI screens / play table | `packages/web/src/screens/*`, `components.tsx` |
83+
84+
## Git & deployment
85+
86+
- This repo deploys on **push to `main`** via GitHub Actions → Cloud Run. Don't push
87+
or commit unless the user asks; branch off `main` if they do.
88+
- Commit messages end with the trailer:
89+
`Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>`
90+
- After a deploy, **verify the run's conclusion** (`gh run view <id> --json conclusion`),
91+
not just that the command exited — `gh run watch` can report success for a run that
92+
already failed.
93+
- Deployment setup and topology: [`docs/DEPLOY.md`](docs/DEPLOY.md); infra is Terraform
94+
in [`infra/`](infra/).
95+
96+
## Gotchas learned the hard way
97+
98+
- **Build the engine before typecheck/test**, or you'll hit `Cannot find module
99+
'@ai-dm/engine'`.
100+
- **Backtick characters inside SQL string templates** in `postgres.ts` break the JS
101+
template literal — avoid them in comments there.
102+
- **`ensureCharacterFields` runs on read** and must stay idempotent (returns `true`
103+
only when it actually changed something). New backfills go there.
104+
- Cloud Run reserves `/healthz` at the frontend — the health endpoint is `/api/health`.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
An AI-driven, web-based D&D experience where an LLM acts as the Dungeon Master for
44
one or more players, with images and maps generated on demand.
55

6-
See [`DESIGN.md`](DESIGN.md) for the full system design and the decisions behind it.
6+
See [`DESIGN.md`](docs/DESIGN.md) for the full system design and the decisions behind it.
77

88
## Architecture at a glance
99

@@ -41,7 +41,7 @@ packages/
4141
- **Play** — real-time DM narration, dice, combat with initiative and a tactical
4242
map, on-demand images, and a campaign memory that keeps continuity over long play.
4343

44-
See [`DEPLOY.md`](DEPLOY.md) for deploying to Cloud Run via GitHub Actions.
44+
See [`DEPLOY.md`](docs/DEPLOY.md) for deploying to Cloud Run via GitHub Actions.
4545

4646
The **engine is authoritative**: the DM (LLM) proposes actions through a tool
4747
layer; the engine validates, rolls dice, and applies results. The LLM never edits

DEPLOY.md renamed to docs/DEPLOY.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ the WebSocket connection (same-origin — no proxy/CORS in prod), wired to:
88
- **Cloud Storage** — a bucket mounted for generated images.
99
- **Vertex AI** (Gemini + Imagen) — via the service's own identity (ADC), no key files.
1010

11-
The GCP infrastructure is **Terraform** ([`infra/`](infra/)); the app is built and
12-
deployed by **GitHub Actions** ([`.github/workflows/deploy.yml`](.github/workflows/deploy.yml))
11+
The GCP infrastructure is **Terraform** ([`infra/`](../infra/)); the app is built and
12+
deployed by **GitHub Actions** ([`.github/workflows/deploy.yml`](../.github/workflows/deploy.yml))
1313
using **Workload Identity Federation** (no service-account keys).
1414

1515
> **Scaling.** Live session state lives in Redis (shared) with a per-session lock,
@@ -20,7 +20,7 @@ using **Workload Identity Federation** (no service-account keys).
2020

2121
Everything in GCP — Cloud SQL, Memorystore + VPC connector, the image bucket,
2222
Artifact Registry, both service accounts + IAM, and Workload Identity Federation —
23-
is declared in [`infra/`](infra/). One-time:
23+
is declared in [`infra/`](../infra/). One-time:
2424

2525
```bash
2626
cd infra
@@ -29,7 +29,7 @@ gcloud auth application-default login # your account (Owner/Editor)
2929
terraform init && terraform apply
3030
```
3131

32-
See [`infra/README.md`](infra/README.md) for details (billing + a `default` VPC are
32+
See [`infra/README.md`](../infra/README.md) for details (billing + a `default` VPC are
3333
prerequisites).
3434

3535
## 2. Set GitHub secrets from the Terraform outputs
File renamed without changes.

docs/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Documentation
2+
3+
System documentation for the AI Dungeon Master. Start here.
4+
5+
| Doc | What it covers |
6+
|-----|----------------|
7+
| [architecture.md](architecture.md) | **How the system works** — packages, the turn lifecycle, data flow, the engine/LLM split, and a file-by-file code map. Read this first to orient. |
8+
| [DESIGN.md](DESIGN.md) | The full **system design** and the decisions behind it: product decisions (locked), the engine-is-truth principle, the DM agent loop, the memory/context model, retrieval, multiplayer, images, persistence, and deployment topology. The "why". |
9+
| [DEPLOY.md](DEPLOY.md) | **Deploying to Cloud Run** via Terraform + GitHub Actions (Workload Identity Federation, Cloud SQL, Memorystore, GCS). |
10+
| [../infra/README.md](../infra/README.md) | The **Terraform** stack (what it provisions, how to apply, state, cost). |
11+
| [../README.md](../README.md) | Project overview + how to **run it locally** (the repo entry point). |
12+
| [../AGENTS.md](../AGENTS.md) | Conventions and workflow for **coding agents** working in this repo. |
13+
14+
## Quick orientation
15+
16+
- **`architecture.md`** is the practical "where does X live and how does a turn flow" map.
17+
- **`DESIGN.md`** is the deeper rationale; engine/server source comments cite it by
18+
section (e.g. `docs/DESIGN.md §5` for the memory model).
19+
- The **engine is authoritative**: the LLM proposes actions through a tool layer; the
20+
engine validates, rolls dice, and applies results. The LLM only narrates. This single
21+
invariant explains most of the architecture — keep it in mind everywhere.

0 commit comments

Comments
 (0)