CLAUDE.md · git:20260712.591b850 · 2026-07-12 · sha256 e4c53a8e4c463169

CLAUDE.md git:20260712.591b850A

Immutable. This exact content is served forever at /api/v1/blob/e4c53a8e4c463169.

# CLAUDE.md — working on oh-my-design with Claude Code

This file governs how Claude Code contributes to this repository. `AGENTS.md` covers the
Codex / GPT-5.6 path; both share the repository conventions at the bottom.

## Division of labour: frontier plans, Sonnet builds

The design of this repo is that **a frontier model plans and a cheaper model executes**,
because planning quality dominates outcome while most implementation is mechanical once the
plan is precise.

- **Plan with Opus.** Interrogating the request, choosing the approach, writing the spec,
  and reviewing the result stay with Opus. It decides *what* changes and *why*, and it holds
  the whole-repo context.
- **Build with Sonnet 5.** Each planned unit of work is dispatched to a Sonnet 5 executor
  with a self-contained spec: the files to touch, the rule to follow, the definition of
  done. Sonnet 5 writes the code, the tests, and runs the gates.
- **Opus does not hand-write the implementation.** It writes the spec, spawns the executor,
  then verifies the result (tests pass, the change matches the spec, no scope drift).
  Verification is Opus's job precisely because it did not write the code.

Practically, in Claude Code: set the session model to Opus for the planning and
orchestration turn, dispatch implementation to `oh-my-claudecode:executor` (Sonnet 5) with a
written spec, and review its report against the spec before committing.

A spec dispatched to Sonnet should carry: the exact files that are source-of-truth vs
generated, the narrowness discipline for any new linter rule (positive AND negative tests),
the baseline test count, and the definition of done (`npm test` clean, `tsc` clean,
`npm run build` succeeds).

### Role → model

| Role | Model | Why |
|---|---|---|
| **Orchestration · architecture · high-risk review (planner/critic)** | **Opus** | Holds whole-repo context, decides what changes and why, reviews the diff it did not write. |
| **Precise code-edit executor** | **Sonnet 5** | The builder — writes the code, the tests, and runs the gates from a written spec. |
| **Low-cost lane** | **Haiku 4.5** | Cheaper lane for lower-risk mechanical work when quality permits. |

**The pipeline's own agents already embody this.** `adapters/tool-map.json` resolves each
agent's abstract tier to a concrete model: `@high` → `claude-opus-4-8`, `@medium` →
`claude-sonnet-5`. So `omd-framer` (interrogates the brief), `omd-scout` (measures
references), and `omd-eye` (critiques in a fresh context) run on Opus, while `omd-hand`
(builds the committed structure) runs on Sonnet 5 — planning and review on the frontier
model, building on the builder. On the Codex host the same tiers resolve to the GPT-5.6
generation (see `AGENTS.md`).

## Repository conventions

- **Source of truth is `src/`.** `src/agents/*.agent.yaml` and `src/skills/omd-*/SKILL.md`
  are the prompt originals. Root `agents/`, `skills/`, and `dist/` are generated by
  `npm run build` — never edit them directly.
- **Edited directly:** `core/`, `bin/`, `adapters/`, `test/`, `evals/`, `scripts/`,
  `README.md`, `README.ko.md`, `.github/`, and the theory/recipe packs under `core/`.
- **`.omd/` is the design record**, committed with the repo. `.omc/` is local session state
  and is gitignored.
- **New linter rules stay narrow.** Every pattern gets a positive AND a negative test; a
  tell that cannot be made safe goes to the prompt layer with the reason recorded in-file.
  Rules warn, never error — a deliberate choice can overrule one with a written reason.
- **Commits use conventional prefixes** (`feat:`, `fix:`, `docs:`, `chore:`). Do not add
  Claude/AI attribution footers to commit messages.
- **Branch → PR → squash-merge.** Every change lands on a feature branch and merges through
  a PR; `main` is protected (one approval; the admin, 3x-haust, may bypass).
- **Merge continuously, release on request only.** Feature branches merge to `main` as
  they finish — do not cut a version for every feature. A release happens **only when the
  user explicitly asks** for one ("버전 올려라" / "release it"). Work accumulates on `main`
  between releases.
- **Releasing (when asked):** bump all three manifests with `scripts/bump.ts`, merge the
  bump to `main`, and the release workflow tags and publishes structured notes
  automatically.
- **Definition of done for any change:** `npm test` 0 fail, `npx tsc --noEmit` clean,
  `npm run build` succeeds.