1,250 words
Shared working card for Codex, Claude Code, and Cursor. Read this first; the agent handbook covers the workflow, and human documentation describes the system.
Start here
- Read working.md, STYLE.md, and the unscoped branching, writing, and browser rules.
- Inspect the current branch,
git status, andgit worktree list. Preserve other agents' work. Follow an explicit user-selected base; otherwise useorigin/mainwhen cutting a branch at the first commit. Never commit tomain. - Read the relevant ADR and the full rule linked below.
Run
pnpm checkbefore changing code; report a pre-existing failure. - Find the test covering the behavior. Write a missing regression test first and prove it fails with the defect present. Prefer properties for mathematics.
- Use Node 26 and pnpm 12. See development.
In a fresh worktree, run
pnpm install --frozen-lockfile --prefer-offline. - Ask headlessly first:
pnpm sim, focused Vitest, oropenSessionin.scratch/. Browser work goes throughnode scripts/drive.mjsand thedriveskill.
One infrastructure, native adapters
.claude/ holds the shared rule extracts, skill bodies, agent briefs, and hook
implementations. Keep Claude Code working when changing them. CLAUDE.md is
Claude-specific orientation; .cursor/ contains Cursor's
adapters. Codex setup explains its native configuration.
- Codex reads this file automatically. It reads relevant
.claude/rules/*.mdexplicitly; Claude's path loading is not a Codex feature. .agents/skills/links to.claude/skills/. Edit the shared target, never a copied skill. Resolve its relative links from the target's directory..codex/agents/loads the shared Claude briefs with Codex-specific tool, memory, and worktree instructions. Do not translate.claudeinto.Codex.ship,parallel,invariant-auditor, anddocs-curatorare opt-in. Do not launch the review commands on the user's behalf. A configured agent is available, not authorization to spend on an audit.- Codex subagents share the checkout unless assigned an actual worktree. For authorized parallel work, create isolated worktrees, assign absolute paths and file ownership, and verify each there. Do not disturb another agent's worktree or mutate the tree during a read-only audit.
- Format files changed through shell commands explicitly. Hooks are a safety net; they do not replace verification or carry permissions between hosts.
The rules that actually matter
These imperatives are canonical. The full rules
retain their constraints, exceptions, measured failures, and technical links.
When a rule changes, update both accounts and the matching .claude/rules/
extract; keep its .cursor/rules/ glob in step. Read the linked details for
any rule governing the files being changed.
- Never put an absolute position in a
Vec3. Details. - Never use
Math.random(),Date.now(), orperformance.now()in canonical code. Details. - Never call
console.timeStamp,performance.markorperformance.measureoutsideengine/browserTiming.ts, Details. - Never make generation depend on order. Details.
- Never hold an algorithm version because the draw order is intact. Details.
- Never put canonical state in a React component, Details.
- Never write a presentation switch directly. Details.
- Never construct a
Workeroutsideapps/game/src/engine/browserWorker.ts. Details. - Never assemble a session by hand. Details.
- Never pass a bare
Vec3to anything that samples terrain. Details. - Never read a field value off something chosen by rank. Details.
- Never write entity state around the world's verbs. Details.
- Never assert that something is landed. Details.
- Never let a coasting entity keep its epoch through a move it did not make. Details.
- Never persist anything regenerable. Details.
- Never make the star catalog ambient. Details.
- Never store what the catalog can derive. Details.
- Never filter a survey to serve a search box. Details.
- Never sort a system's planets by orbit and call it order. Details.
- Never import a hosting vendor's SDK below the adapter layer. Details.
- Never let React Compiler memoize a component that reads mutable state. Details.
- Never put the
<Canvas>inside a route, Details. - Never hold the current mode in React state. Details.
- Never read the raw pathname when a dialog could be open over a mode. Details.
- Never apply
flatteningto a body that has afigure. Details. - Never leave a field out of a record because nothing has measured it. Details.
- Never read a body's figure as "unknown". Details.
- Never place a compressed body about the render origin. Details.
- Never scale metric geometry by
placement.scale. Details. - Never size or position chrome against the viewport. Details.
- Never add a second producer of the camera. Details.
- Never add a second producer of the lens. Details.
- Never add a second window-level key listener. Details.
- Never call
localStorageoutsidestate/preferences.ts. Details. - Never write a key name in a label. Details.
- Never turn the head at a constant radians-per-pixel. Details.
- Never let the planetarium write canonical state. Details.
- Never ask where something is at
clock.timein order to put it in a frame. Details. - Never give a mode its chrome without
pointer-events-auto. Details. - Never give
AnimatePresencemode="wait"over the overlay routes, Details. - Never guard a "run once" effect with a ref. Details.
- Never move a workspace panel by splicing an array at a call site. Details.
- Never derive a stored value from a captured snapshot. Details.
- Never put two components in one file. Details.
- Never hand-roll a control the registry already has. Details.
- Never add a markdown file under
docs/without listing it inscripts/docs/wings.mjs. Details. - Never write a plan under
docs/. Details. - Never let a cinematic effect fire off a script. Details.
- Never fly a scripted camera through the prop it is staging. Details.
- Never treat a beat past a shot's last frame as dead. Details.
- Never write a label in the case you want to see it in. Details.
- Never subtract two planetary radii from each other in a shader, and never take a screen-space derivative of a planetary position. Details.
- Never read the drawn ground where the canonical one belongs, or the reverse. Details.
- Never give two attribute names one
BufferAttributeobject. Details. - Never call
geometry.dispose()on anything holding the shared index. Details. - Never leave a stand-in
DataTextureat its nearest default. Details. - Never build two texture nodes over one stand-in object. Details.
- Never take a fine lattice coordinate from an absolute float32 direction, and never take a lattice decision in a float. Details.
- Never add a shading term to the ground without adding it to the sphere. Details.
- Never import from
threeinapps/game. Details. - Never hand-write a compile-ahead. Details.
- Never edit a file
pnpm brandwrites. Details. - Never change what the site says about itself in only one place. Details.
- Never load a third-party tag from the document head. Details.
- Never let a readout change the frame or stop it. Details.
Finish the work
Correctness, layer boundaries, determinism, passing tests, and pnpm check
are the definition of done. Use the checks the change warrants; prose-only
work needs formatting and documentation-link validation, not a renderer.
Update ADRs for architectural decisions and use context-log for findings
worth carrying forward. Commit each coherent, reversible step before lengthy
verification or the next large phase; then verify it and commit any fixes.
Do not collect a whole refactor into an uncommitted batch while waiting for the
full gate. Use a conventional subject and an extended body explaining why.
Pushing and opening a PR use
ship when requested. State what changed, what was verified, and limitations.
Cloud environments
Cursor's environment is .cursor/environment.json; it pins Node 26 and pnpm
12 and installs dependencies during the build. Inspect the Game and Worker
terminal before starting another dev server. pnpm dev serves ports 5173 and 8787. Claude cloud setup is in CLAUDE.md; other fresh hosts use
scripts/cloud-setup.sh as their environment setup script.
The app and tests need no Docker, database, or production credentials. Missing reference audio and analytics settings must still produce a successful silent, non-measuring build. Never add production credentials to silence those notices.