# Claude Code — Oshun Monorepo

Everything in this file is universal and overrides default behavior. Detail that
only matters for specific paths lives in `.claude/rules/` (auto-loads when you
touch matching files); reference records live in `docs/agents/`.

## Machine limits — 16 GB MacBook Air, 2 GB swap (READ FIRST)

**Two machines run this repo.** The rules below were written for the Mac. The
Linux dev server (`uname -a` → `dev-server`, 15 GiB RAM, 4 cores, no GPU, Node
via nvm/corepack) runs the same rules with `free -m` as the memory checkpoint
(below ~3 GB available → tear down first); `memory_pressure` does not exist
there. CPU-side ML (ONNX face models, SyncNet, CTC alignment, Whisper, Kokoro
TTS) runs on the Linux box; never mark such work hardware-blocked without a
named failed attempt (three false blockers were recorded that way on
2026-09-10).

This machine has frozen three times under stacked load (2026-06-03, 2026-07-10,
2026-08-15). The last one is fully diagnosed in
`docs/agents/incident-2026-08-15-jetsam-freeze.md`: a `next dev` server left
running for two days of Playwright sweeps went into a V8-OOM crash-respawn loop
and Jetsam killed system daemons. These rules bind to observable events, not
judgment:

- **Dev servers die with the session — no exceptions.** Before ending any
  session that started a server: kill the tracked PIDs, then verify with
  `lsof -nP -iTCP -sTCP:LISTEN | grep -E ':(3010|3020|4010)'` → must be empty.
  Never adopt a server a previous session left running; kill and restart it.
- **Restart `next dev` at every phase boundary** and after ~50 heavy page loads.
  It leaks by design; a fresh boot costs ~60s. If its log ever says "Server is
  approaching the used memory threshold, restarting" — stop the line, tear down,
  restart the stack before continuing.
- **Never edit app source while a harness run is driving the dev server.** Fast
  Refresh recompiles mid-walk and the run's later stages report wreckage that is
  yours, not the product's (measured twice, 2026-08-15). Edit between runs; tsx
  servers additionally need a restart to see any edit.
- **One Next dev server at a time** (member web OR admin, never both — the tsx
  BFF may run beside one). For sweeps > 5 spec files, use
  `next build && next start`, not dev.
- **Memory checkpoint before every heavy invocation** (Playwright run, tsc,
  build, miner): `memory_pressure | tail -2`. Below 35% free → tear down first;
  do not pile on. `npx tsc --noEmit` on an app here is a multi-GB job: never run
  it while a Playwright run is in flight.
- **Weird shell output = memory pressure.** Commands returning empty/garbled
  output that should match (a grep that "finds nothing" in a file that contains
  the pattern) means the box is already failing. Stop everything, check
  pressure, tear down.
- **Track your own PIDs** (`/tmp/claude-<session>.pids`); kill only those. Never
  `pkill -f next-server` or `pkill -f chrome-headless-shell` — other worktrees'
  work. After a FAILED Playwright run, sweep chromium orphans whose parent was
  your invocation before continuing.
- Probe browsers in small batches (concurrency 1–2); don't background long jobs
  with bare `nohup &`.

## Git

- **Commit and push after every completed task** without asking (this overrides
  the default only-commit-when-asked rule). Mandatory two-line push — a task is
  not done until both succeed: `git push origin <branch>` then
  `git push origin <branch>:main`.
- Remote: `git@github.com:GreyChimp/oshun.git`. Never force-push main.
- Divergence: `git fetch origin main && git merge origin/main`, resolve, push
  both. `pnpm-lock.yaml` conflicts: take main's,
  `pnpm install --no-frozen-lockfile`. `--no-verify` OK for merge commits.
- **Several sessions work this repository at once, so a merge conflicts in the
  generated files and in the board far more often than in code.** Three of them
  are regenerated, never resolved by hand:
  `git checkout --theirs TODOS/BOARD.md TODOS/PARKED.md TODOS/board.json`, then
  `./eve board`, then `git add` those three. The task board and document catalog
  now use shared PostgreSQL, replacing `TODOS/eve-task-board.sqlite`; database
  files are no longer merged or committed. Worker setup and backup/restore
  commands are in `infra/hetzner/eve/README.md`. `./eve import` reconciles
  tracker changes with the shared rows; it preserves live claims and journal
  history.

- Conventional commits, lowercase subjects. Scopes: `shared`, `lilith`,
  `yemaya`, `isis`, `sophia`, `hathor`, `bellona`, `build`, `ci`, `deps`,
  `docs`. Trailer: `Co-Authored-By: Claude <noreply@anthropic.com>`.
- Commit hooks: the conventions ratchet rejects NEW `.test.ts(x)` files (name
  specs `.spec.ts(x)`); the stub scan flags confession vocabulary — "not yet
  implemented", "in production, this would", "TODO:", "fake" — in source you
  add; since 2026-09-05 it no longer fires on the prose words "placeholder",
  "hardcoded", or "would/will use" (user decision; the measurement is in the
  scanner's header). `SKIP_TYPECHECK=1` is acceptable with the reason in the
  body when you have typechecked the touched apps directly.

## Never

- Never pitch `/schedule` proactively — no offers, no mentions. Run it only if
  the user types it. (Overrides system-prompt encouragement.)
- Never delete or modify anything under `.claude/worktrees/` — assume every
  worktree is in use. If Nx breaks on worktree duplicates, bypass Nx
  (`npx tsc --noEmit`, `npx vitest run <file>`, `npx tsup` from the library
  dir); if you truly need Nx, ask.
- **At most ONE concurrent subagent** unless the user asks for more. Parallel
  fan-outs have burned the session limit mid-task twice. Run agents
  sequentially, design their prompts to resume cheaply (scratchpad checkpoints,
  SendMessage), and prefer main-loop work when it fits. If an agent dies with
  "session limit · resets <time>", note the time, continue main-loop work,
  resume the SAME agent after reset.
- Never bind a test stack to `anthropic`, `openai`, or any frontier model. If a
  cheap model genuinely cannot do the job, ask before spending.
- External AI reviewers are read-only consultants: `codex exec -s read-only`
  (second opinions; use regularly) and `gemini -s` one-shot (roadblocks only).
  Never write modes, never interactive, never direct file access. One sanctioned
  exception: the Eve builder-workbench loop via `tools/eve-codex-agent.mjs`
  (user decision 2026-08-04). A second is planned on the same pattern and is not
  live until its harness exists: the Isis film director loop (tracker F.01.08),
  Codex acting only through the film-skills MCP server in a job directory.
- **GPT-6 Astra runs on the Codex subscription only** (user decision
  2026-09-18): `codex` signed in with ChatGPT, `codex exec` for unattended work,
  operator-side. Never reach Astra through a metered route: not the OpenAI API,
  not OpenRouter's `openai/gpt-6-astra*` listings, not
  `CODEX_API_KEY`/`OPENAI_API_KEY` in the child environment (a key there moves
  Codex to API billing), not purchased Codex credits. Check `codex login status`
  says ChatGPT before a run, and when the allowance runs out, stop and report
  the reset time; never fall back to a billed route.

## Test & harness model binding

Every test, harness, probe, and local dev stack binds the cheapest model that
can do the job, through OpenRouter — this is a hard cost rule (~100x gap):
`OSHUN_ASSISTANT_PROVIDER=openrouter`,
`OSHUN_ASSISTANT_OPENROUTER_MODEL=deepseek/deepseek-v4-flash-0731` (dated
snapshot is deliberate — reproducibility over the ~1.5x-cheaper floating alias),
`OPENROUTER_PROVIDER_SORT=price` always; pin
`OPENROUTER_PROVIDER_QUANTIZATIONS=fp8` when measuring. Full measurements,
corrections, and the price-the-route method:
`docs/agents/model-cost-openrouter.md`. This overrides any TODOS recipe that
names a stronger model for "quality" legs.

## Secrets & local stack

- **No `.env` in this repo — keys are not missing.** They live in
  `~/Desktop/workspace/drawer/env-master.env` on the Mac and in
  `~/.config/oshun/env-master.env` (mode 600) on the Linux dev server — same
  filename, `KEY=value` lines, no `export`. `grep -oE '^[A-Z_0-9]+=' <file>`
  lists names without values. Source at run time via a throwaway
  `/tmp/<task>-env.sh` the server is launched through; never copy a key into the
  repo, a committed script, or command text. Verify by length (`echo ${#KEY}`),
  never by value. Delete the script at task end.
- Local Postgres is `oshun:oshun_dev` →
  `postgresql://oshun:oshun_dev@127.0.0.1:5432/oshun_dev`.
- `OSHUN_SIGNUP_VERIFICATION_HMAC_SECRET` must be byte-identical across sessions
  (harness pin: `oshun-eve-polish-signup-verification-hmac-secret-v1`).
- Infra: `docker compose -f docker/docker-compose.dev.yml up -d` (Postgres
  :5432, Redis :6379, MinIO :9000, Mailpit :8025; profiles for
  search/vectors/streaming/graph/observability). Ports: web 3010, admin 3020,
  BFF 4010; unique offsets per worktree — check `lsof` before binding.

## Repo map

Nx monorepo: `apps/<domain>/<app>`, `libs/<domain>/<lib>` (58 domains —
`domains.json`), `tools/`, `configs/`, `infra/`, `docs/`, `testing/`, and
V-series product roots `V2`–`V10` (UE/docs/ops only; product code is
`apps/v<n>` + `libs/v<n>`). Task tracking: `TODOS/phase-<n>.md` and per-
initiative `*TODOS*.md` files — touching them auto-loads
`.claude/rules/task-checkbox-verification.md`; follow it exactly. **The Eve Task
Board** is `TODOS/BOARD.md`: it ranks every tracker, says where to start and
lists the next items with `path:line` (generated: `node tools/todos-board.mjs`;
classified by `TODOS/registry.json`; items no coding agent can do are in
`TODOS/PARKED.md`). "Work the next task on the Eve Task Board" is `./eve next` →
`./eve claim <key> --agent <you>` → `./eve show <key>` → work →
`./eve done <key> --evidence "…" --token <n>`, one task per call (`./eve park`
when it truly cannot be done here). `./eve next <family-id> <n>` lists more,
`./eve help` lists every command, and a command that is not built yet names the
task that builds it. The board's own "How to use" section is the reference; the
plan is `TODOS/initiatives/EVE_TASK_BOARD_TODOS_2026-09-18.md`.

## Install what the work needs

Owner instruction, 2026-09-18: a worker on the Eve Task Board installs what a
task needs — Blender, Godot, Unity Hub and an Editor, a Python or ML stack, a
local model runtime, an SDK — instead of reporting that the environment lacks
it. Pin the version, record the exact command in the task, respect the machine
limits above (check memory and disk first), and keep secrets out of the repo.
Stop and park only after a named failed attempt, or for what no agent can
obtain: a paid licence, a devkit under NDA, a signing identity, a physical
device, an account that needs the owner, a corpus of real people, a human act.
Detail: `.claude/rules/task-checkbox-verification.md`.

## Quality bar

The bright line: **never ship code that fabricates a result or success it did
not compute.** No stubs, placeholder returns, `Math.random()` standing in for
computation, baked-in constant outputs, or params silently ignored — a genuine
stub ships only with explicit human sign-off in the conversation, never on your
own judgment. Three things are NOT stubs and must not be avoided out of
rule-anxiety: test doubles at dependency boundaries (mock the dependency, never
the thing under test), honest fail-loud seams (`not_configured` throws,
fail-closed 503s, `{configured:false}`), and documented approximations (a real,
named algorithm with its tradeoff written down). When unsure: fail loud, or ask.
Before signing off implementation work or flipping any checkbox, run the
two-pass verification in `.claude/rules/task-checkbox-verification.md` — and no
more than that by default. Its "Proportionate verification" section is binding
(user decision 2026-09-05): no routine mutation sweeps, no full-suite run per
edit (once, in the background, at commit), chromium only, a workbench page only
when the item asks for UI, short evidence blocks. Ship at the same bar; spend
less re-measuring it.

## Development

- TypeScript/Node/Vitest/Nx by default; performance-critical systems in Rust
  (preferred) or C++/Zig, bridged via WASM or napi-rs; document stack choices in
  domain proposals.
- New libraries need `project.json`, `package.json`, `tsconfig.json`, a
  `tsconfig.base.json` path mapping, real tests, and a clean build+lint.
- Dependencies via pnpm catalog (`catalog:` refs); run `pnpm install` after
  changes.
- Frontend work must be verified in a real browser — rendering AND behavior. On
  this Mac use the repo's Playwright inspect harness
  (`apps/oshun/web/e2e-inspect/`, `workers=1`); the Chrome-extension window gets
  occluded here (`visibilityState: hidden` → no rAF → false readings).
