Rewrite CLAUDE.md — document three-shell model and workflow
This commit is contained in:
276
CLAUDE.md
276
CLAUDE.md
@@ -1,46 +1,160 @@
|
||||
# CLAUDE.md — OTIVM Project
|
||||
|
||||
This file is read automatically by Claude Code at the start of every session.
|
||||
Read it completely before doing anything else.
|
||||
Read it completely before doing anything else. It describes not just the project
|
||||
but exactly how the development process works — including how Claude chat, Claude
|
||||
Code, and the human work together. A new assistant who skips this file will
|
||||
immediately make mistakes that waste the session.
|
||||
|
||||
---
|
||||
|
||||
## What OTIVM Is
|
||||
|
||||
A browser-based Roman merchant idle game. One screen, one resource loop.
|
||||
The narrative unfolds through trade goods and journal entries.
|
||||
It is a standalone light-hearted project — not part of CIVICVS or TESSERA infrastructure.
|
||||
A browser-based Roman merchant idle game. The narrative unfolds through trade
|
||||
goods and journal entries. It is a standalone light-hearted project under TheRON,
|
||||
but it is built on the same H3/TESSERA substrate as the CIVICVS Mesolithic
|
||||
Simulator. Every architectural decision is permanent and load-bearing for future
|
||||
releases up to OTIVM-X.
|
||||
|
||||
**Live URL:** https://otium.civicus.us
|
||||
**Repo:** https://gitea.barternetwork.us/TheRON/OTIVM (branch: main)
|
||||
**Roadmap:** docs/roadmap.md — read it to understand where this is going
|
||||
|
||||
---
|
||||
|
||||
## The Three-Shell Model — Read This First
|
||||
|
||||
Development always uses three terminal shells simultaneously. Each shell has one
|
||||
fixed role and must never be used for another role's work.
|
||||
|
||||
### Shell 1 — Claude Code shell (otivm user)
|
||||
- Started by typing `work` at the otivm prompt
|
||||
- `work` is an alias for: `cd ~/OTIVM && claude`
|
||||
- This shell runs Claude Code continuously for the entire session
|
||||
- Claude Code reads CLAUDE.md on startup, checks git status, checks pm2 list
|
||||
- All file writes, git commits, and git pushes happen here and nowhere else
|
||||
- Do not use this shell for npm commands, pm2 restarts, or manual file edits
|
||||
|
||||
### Shell 2 — otivm shell (otivm user)
|
||||
- A second terminal logged in as otivm, in ~/OTIVM
|
||||
- Used for: npm install, npm run build, pm2 restart, curl tests, git pull
|
||||
- The Proxmox console drops the otivm user directly into ~/OTIVM with venv active
|
||||
- Treat every Proxmox console visit as a fresh terminal — no scroll-back history
|
||||
|
||||
### Shell 3 — root shell (root user)
|
||||
- Used only for: vzdump backups, pct commands, chown fixes, systemctl for PM2
|
||||
- Never run pm2 as root — PM2 belongs to the otivm user
|
||||
- Never modify /opt/civicvs or /opt/civmap from this shell
|
||||
|
||||
---
|
||||
|
||||
## How Claude Chat and Claude Code Divide Responsibilities
|
||||
|
||||
These are two different Claude instances with different roles.
|
||||
Confusing them is the most common source of wasted sessions.
|
||||
|
||||
### Claude chat (claude.ai in the browser)
|
||||
- Reads the repo via Gitea MCP (read-only access to gitea.barternetwork.us)
|
||||
- Discusses architecture, makes decisions, designs files
|
||||
- Produces one file at a time as a downloadable attachment
|
||||
- Each file has a Claude Code instruction header at the top, followed by the
|
||||
file content that Claude Code writes to disk
|
||||
- Claude chat does NOT write to disk, does NOT commit, does NOT push
|
||||
|
||||
### Claude Code (running in Shell 1 on the container)
|
||||
- Receives one file at a time — the human downloads it from Claude chat and pastes it
|
||||
- Reads the instruction header at the top of the file
|
||||
- Writes the content below the instructions to the path specified in the header
|
||||
- Commits and pushes to Gitea
|
||||
- Does NOT design, does NOT make architectural decisions
|
||||
- Does NOT modify content — writes exactly what is given
|
||||
- Confirms what it did in one sentence — does not reprint file contents
|
||||
|
||||
### The human
|
||||
- Downloads the file from Claude chat
|
||||
- Pastes it into Claude Code (Shell 1)
|
||||
- Runs build and test commands in Shell 2 (otivm shell)
|
||||
- Runs backup commands in Shell 3 (root shell)
|
||||
- Confirms results before the next step begins
|
||||
|
||||
---
|
||||
|
||||
## The Exact Workflow — Step by Step
|
||||
|
||||
Every change to the codebase follows this sequence without exception:
|
||||
|
||||
1. Claude chat discusses the change and produces one downloadable file
|
||||
2. The file header contains the Claude Code instruction (path, commit message)
|
||||
3. The file body contains the exact content to write to disk
|
||||
4. Human downloads the file from Claude chat
|
||||
5. Human pastes the file into Claude Code (Shell 1)
|
||||
6. Claude Code reads the instruction header, writes the content to the specified path
|
||||
7. Claude Code commits and pushes to main
|
||||
8. Human runs `npm run build` in the otivm shell (Shell 2)
|
||||
9. Human runs `pm2 restart otivm` in Shell 2
|
||||
10. Human confirms the result in the browser at https://otium.civicus.us
|
||||
11. Human reports the result back to Claude chat
|
||||
12. Claude chat proceeds to the next step
|
||||
|
||||
**One file. One step. One confirmation. Never batch.**
|
||||
|
||||
---
|
||||
|
||||
## What Claude Code Must Never Do
|
||||
|
||||
- Never modify file contents — write exactly what is given
|
||||
- Never reformat code — indentation, spacing, structure are intentional
|
||||
- Never add imports, exports, or dependencies not in the instruction
|
||||
- Never run npm install without explicit instruction
|
||||
- Never run pm2 as root
|
||||
- Never commit without explicit instruction to commit
|
||||
- Never push to any branch other than main
|
||||
- Never reprint long file contents back into chat — confirm with one sentence
|
||||
|
||||
---
|
||||
|
||||
## What Claude Chat Must Never Do
|
||||
|
||||
- Never print file contents or code blocks in the chat window
|
||||
- All files and instructions are produced as downloadable attachments only
|
||||
- Printing code in chat wastes context window and shortens the session
|
||||
- Never make assumptions about what is on disk — always read from Gitea MCP first
|
||||
|
||||
---
|
||||
|
||||
## Deployment Facts — Do Not Guess These
|
||||
|
||||
These facts were learned during initial deployment. They are not in any tutorial.
|
||||
|
||||
- PM2 ecosystem file must be named `.cjs` not `.js` — Vite sets `"type": "module"`
|
||||
in package.json which breaks CommonJS `module.exports`
|
||||
- PM2 ecosystem file uses absolute path `/usr/bin/node` for the script field
|
||||
- Always run `pm2 start ecosystem.config.cjs` from `~/OTIVM`, not from `~`
|
||||
- PM2 startup is configured via systemd unit `pm2-otivm.service` — do not run
|
||||
`pm2 startup` again
|
||||
- `pm2 save` must be run after any change to the process list
|
||||
- Nginx for `otium.civicus.us` lives on wg-pk (198.58.111.109), not on this
|
||||
container — do not look for a vhost here
|
||||
- The app is proxied from wg-pk to this container at `10.110.0.18:3000`
|
||||
- The Proxmox console loses scroll history on every container switch — treat
|
||||
every shell session as fresh
|
||||
|
||||
---
|
||||
|
||||
## Stack
|
||||
|
||||
- React 19 + Vite frontend
|
||||
- Node.js v22
|
||||
- React 19 + Vite 8 frontend
|
||||
- Fastify backend (server/index.js) — serves dist/ and save API on port 3000
|
||||
- Node.js v22 at /usr/bin/node
|
||||
- PM2 under otivm user (never root)
|
||||
- Python venv at /home/otivm/venv (never run Python outside venv)
|
||||
- No database — JSON flat files for any local state
|
||||
|
||||
---
|
||||
|
||||
## Ground Rules — Do Not Violate
|
||||
|
||||
- **Never run PM2 as root** — always as otivm user
|
||||
- **Never run Python outside the venv** — /home/otivm/venv always
|
||||
- **Never commit secrets** — no tokens, no keys, no passwords in any file
|
||||
- **Never push to main without testing** — test locally on port 3000 first
|
||||
- **One screen, one loop** — do not add complexity without explicit instruction
|
||||
- **No database** — JSON flat files only, consistent with TheRON design principles
|
||||
- No database — JSON flat files in data/saves/ for player state
|
||||
|
||||
---
|
||||
|
||||
## Container Facts
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
|-------------|---------------------|
|
||||
| Hostname | otivm-dev |
|
||||
| LAN IP | 10.0.0.23 |
|
||||
| WireGuard | 10.110.0.18 |
|
||||
@@ -51,16 +165,28 @@ It is a standalone light-hearted project — not part of CIVICVS or TESSERA infr
|
||||
| Python venv | /home/otivm/venv |
|
||||
| PM2 home | /home/otivm/.pm2 |
|
||||
| Repo path | /home/otivm/OTIVM |
|
||||
| Node path | /usr/bin/node |
|
||||
|
||||
---
|
||||
|
||||
## PM2 Commands
|
||||
## Ground Rules — Do Not Violate
|
||||
|
||||
- **Never run PM2 as root** — always as otivm user
|
||||
- **Never run Python outside the venv** — /home/otivm/venv always
|
||||
- **Never commit secrets** — no tokens, no keys, no passwords in any file
|
||||
- **Never push to main without building** — npm run build must pass first
|
||||
- **No database** — JSON flat files only
|
||||
- **H3 IDs on every location** — never a coordinate pair or string name alone
|
||||
- **One change confirmed before the next** — no batching steps
|
||||
|
||||
---
|
||||
|
||||
## PM2 Commands (always as otivm user)
|
||||
|
||||
```bash
|
||||
# Always as otivm user
|
||||
pm2 start ecosystem.config.js
|
||||
pm2 restart otivm
|
||||
pm2 logs otivm
|
||||
pm2 list
|
||||
pm2 logs otivm --lines 30 --nostream
|
||||
pm2 save
|
||||
```
|
||||
|
||||
@@ -69,80 +195,62 @@ pm2 save
|
||||
## Git Workflow
|
||||
|
||||
```bash
|
||||
git pull origin main
|
||||
git add <files>
|
||||
git commit -m "imperative mood, under 72 chars"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
Commit messages: imperative mood, present tense, under 72 characters.
|
||||
Example: `Add trade route unlock mechanic` not `Added trade routes`.
|
||||
Example: `Add Mediterranean SVG map to Map screen` not `Added map`.
|
||||
|
||||
---
|
||||
|
||||
## Session Start Checklist (Claude Code)
|
||||
|
||||
1. Read this file completely ✓
|
||||
2. Run `git log --oneline -5` — know what was last committed
|
||||
3. Run `git status` — confirm working tree is clean
|
||||
4. Run `pm2 list` — confirm otivm is online
|
||||
5. Wait for instruction from the human — do not act until instructed
|
||||
|
||||
---
|
||||
|
||||
## TheRON Infrastructure Context
|
||||
|
||||
- **wg-pk** (198.58.111.109) — Linode hub, Nginx proxy, WireGuard hub
|
||||
- **srv-a** (10.0.0.11) — dev Proxmox host, runs this container
|
||||
- **mcp.civicus.us** — gitea-mcp server, gives Claude chat read access to this repo
|
||||
- **srv-a** (10.0.0.11) — dev Proxmox host, runs LXC 1105 (this container)
|
||||
- **mcp.civicus.us** — gitea-mcp server, gives Claude chat read-only access
|
||||
- **Gitea** — https://gitea.barternetwork.us (owner: TheRON)
|
||||
|
||||
---
|
||||
|
||||
## Design Notes
|
||||
|
||||
The game carries quiet atmospheric references to Mesolithic cultures
|
||||
(Maglemosian, Ertebølle, Sauveterrian, Azilian) through trade goods,
|
||||
place names, and merchant journal entries. These are never labelled
|
||||
academically — they are atmosphere only. The amber road, the northern
|
||||
forests, the flint from the Pyrenean foothills.
|
||||
|
||||
The Roman merchant's journey: Ostia → Capua → Brundisium → Carthago → Alexandria.
|
||||
Five chapters. Five trade routes. Five journal entries.
|
||||
|
||||
---
|
||||
|
||||
## Session Start Checklist
|
||||
|
||||
1. Read this file ✓
|
||||
2. Check `git status` and `git log --oneline -5`
|
||||
3. Check `pm2 list` (as otivm user)
|
||||
4. Proceed with the task
|
||||
- **TESSERA** — H3-based physical world model, same grid OTIVM uses for waypoints
|
||||
|
||||
---
|
||||
|
||||
## Aliases
|
||||
|
||||
| Location | Alias | Effect |
|
||||
|----------|-------|--------|
|
||||
|---------------------------|------------|------------------------|
|
||||
| root@otivm-dev ~/.bashrc | webmin-on | systemctl start webmin |
|
||||
| root@otivm-dev ~/.bashrc | webmin-off | systemctl stop webmin |
|
||||
| otivm@otivm-dev ~/.bashrc | work | cd ~/OTIVM && claude |
|
||||
|
||||
---
|
||||
|
||||
*CLAUDE.md — OTIVM — TheRON*
|
||||
## Design Notes
|
||||
|
||||
The game carries quiet atmospheric references to Mesolithic cultures
|
||||
(Maglemosian, Ertebølle, Sauveterrian, Azilian) through trade goods, place names,
|
||||
and merchant journal entries. These are never labelled academically — they are
|
||||
atmosphere only. The amber road, the northern forests, the flint from the
|
||||
Pyrenean foothills.
|
||||
|
||||
The Roman merchant's journey: Ostia → Capua → Brundisium → Carthago → Alexandria.
|
||||
Five chapters. Five trade routes. Releases OTIVM-I through OTIVM-X build on this
|
||||
foundation — see docs/roadmap.md.
|
||||
|
||||
---
|
||||
|
||||
## Session workflow — paste-and-commit
|
||||
|
||||
Each development step follows this exact sequence:
|
||||
|
||||
1. The design discussion happens in Claude chat (not here)
|
||||
2. Claude chat produces one file or one change at a time
|
||||
3. That content is pasted into this Claude Code session as a prompt
|
||||
4. Claude Code writes the file to disk exactly as given, then commits and pushes
|
||||
5. The human confirms it works before the next step begins
|
||||
|
||||
**When a file is pasted into this prompt**, the instruction will say:
|
||||
|
||||
> Write this to `<path>` exactly as given, then commit with message `<message>` and push to main.
|
||||
|
||||
Do not modify the content. Do not reformat. Do not add imports or change structure. Write it exactly as given.
|
||||
|
||||
**When a shell command result is pasted**, it is for context only — no action unless explicitly instructed.
|
||||
|
||||
## Current development state — updated 2026-04-25
|
||||
## Current Development State — updated 2026-04-25
|
||||
|
||||
### OTIVM-I — complete
|
||||
- Fastify backend serving dist/ and save API on port 3000
|
||||
@@ -158,17 +266,31 @@ Do not modify the content. Do not reformat. Do not add imports or change structu
|
||||
- Game.jsx renamed to src/screens/Ledger.jsx
|
||||
- App.jsx manages screen state — ledger and map
|
||||
- Both screens stay mounted — no state lost on switch
|
||||
- Map screen shows placeholder — ready for OTIVM-II work
|
||||
|
||||
### OTIVM-II — next
|
||||
- src/screens/Map.jsx to be created
|
||||
- Mediterranean rendered using H3 geometry
|
||||
- Five waypoints plotted using confirmed H3 res-5 IDs
|
||||
- Route lines drawn between waypoints
|
||||
- No interactivity required in first Map commit — visual only
|
||||
### OTIVM-II — complete
|
||||
- src/screens/Map.jsx created and committed
|
||||
- Mediterranean SVG map, equirectangular projection, bounding box 5°E–38°E / 28°N–48°N
|
||||
- Five waypoints plotted at hardcoded H3 res-5 cell centres
|
||||
- Route lines between waypoints — gold when unlocked, muted dashed when locked
|
||||
- Current chapter waypoint highlighted in gold, reached waypoints in green
|
||||
- Land outline is a rough placeholder polygon — replaced in a later release
|
||||
- App.jsx updated to import and render Map component
|
||||
- Map screen CSS added to App.css
|
||||
- **Build and PM2 restart still required on container** — code is committed but
|
||||
dist/ has not been rebuilt yet
|
||||
|
||||
### Architecture decisions locked
|
||||
- H3 IDs on all waypoints — permanent, TESSERA-compatible
|
||||
- constants.js / gameState.js / api.js separation — permanent
|
||||
- Virtual screens via display:none — state preserved in browser
|
||||
- Save on meaningful events only — not on every tick
|
||||
- H3 cell centre coordinates hardcoded in Map.jsx — h3-js is server-side only
|
||||
- Mediterranean map replaced in a later release (Azgaar bridge planned OTIVM-VII)
|
||||
|
||||
### OTIVM-III — not yet defined
|
||||
- To be discussed in Claude chat before any code is written
|
||||
|
||||
---
|
||||
|
||||
*CLAUDE.md — OTIVM — TheRON*
|
||||
*Claude Code implements. Claude chat designs. The human decides.*
|
||||
|
||||
Reference in New Issue
Block a user