---
title: "Setting up OMP in one evening: model roles, global skills, an advisor, and memory"
canonical: https://maxtokens.ai/posts/oh-my-pi-setup/
date: 2026-07-17
tags: [agents, terminal]
description: "Log audit, model roles, global skills, an advisor with WATCHDOG.md, and session memory — a working OMP configuration in one evening."
---
I moved to [Oh My Pi](https://github.com/can1357/oh-my-pi) as my primary coding harness. By then, I already had a lived-in Claude Code setup: plugins, skills across a dozen projects, and MCP servers in `~/.claude.json`. OMP can pick all of that up on its own. But discovering a configuration does not mean working with it correctly. Here is what surfaced during the audit and how I put together a setup I no longer have to keep reconfiguring.

## Audit first, configure second

The first thing worth doing after install is not tweaking settings but reading logs: `~/.omp/logs/omp.<date>.log`. One `grep -E` for `"level":"(error|warn)"` gave me a list of problems I would otherwise have discovered a week later at the worst possible moment:

- three MCP servers (railway, sequential-thinking, mobile) died on startup with "Transport closed". The cause had nothing to do with OMP: a corrupted npx cache (`ENOTEMPTY` in `~/.npm/_npx/...`). Deleting the cache directory brought every npx-based server back;
- OAuth servers from plugins (Linear, Notion, Figma, Slack) were silently failing with 401 — they need `/mcp reauth <name>`, and the ones you don't use are better muted via `disabledServers` so they stop polluting logs;
- one slash command failed to parse: OMP's strict YAML parser tripped over an unquoted `argument-hint: [...]` in frontmatter. Claude Code forgave it; OMP does not.

OMP is compatible with foreign configs but stricter about them. Everything that silently broke shows up in the logs within a minute.

## Model roles: expensive for planning, cheap for background

OMP does not take a single model: there are roles, each with its own workload profile. My layout in `~/.omp/agent/config.yml` is only a first pass; everyone should choose and tune the models and roles to fit their own workflow:

```yaml
modelRoles:
  # thinking: planning and "think hard" — opus at maximum
  plan: anthropic/claude-opus-4-8:max
  slow: anthropic/claude-opus-4-8:max
  # working: the main session — opus:high; save max for the thinking roles
  default: anthropic/claude-opus-4-8:high
  vision: anthropic/claude-sonnet-5:high      # screenshots and images
  designer: anthropic/claude-sonnet-5:high    # UI work
  task: openai-codex/gpt-5.6-sol:high      # executor subagents
  # every turn: the advisor stays on fable — opus here would burn more than the work itself
  advisor: anthropic/claude-fable-5:max    # the watchdog, more below
  # background: fires dozens of times per session — the cheapest
  smol: openai-codex/gpt-5.6-luna:low      # small subtasks
  commit: openai-codex/gpt-5.6-luna:low    # commit messages
  tiny: openai-codex/gpt-5.6-luna:min      # session titles
```

The suffix after the colon sets the reasoning level. The parser recognizes unambiguous abbreviations, so `:min` is equivalent to `:minimal`. The audit showed that even my session titles were being generated by an Opus-class model at `xhigh`—an unjustifiably expensive setting for a short background task. After that, I assigned models according to each role’s workload: the frequent, straightforward `tiny`, `commit`, and `smol` roles went to the cheapest model at the minimum reasoning level, while `plan` and `slow`, where depth really matters, stayed at the maximum.

You can verify a model id exists against the provider cache: `~/.omp/agent/models.db` (sqlite, table `model_cache`).

## Two Claude subscriptions: manual switching

I have two Claude subscriptions — a personal one and a team one. OMP runs inside Orca, and I choose the account manually from its status bar. When one subscription is almost at its limit, I switch to the other. If both are spent, all that’s left is to wait for the reset.

Paired with Orca, this is especially convenient: the remaining five-hour and weekly limits are visible in the status bar under the terminal, so you know exactly when to switch to the second subscription.

## Skills: one global source instead of per-project copies

Over six months, 190 skill directories accumulated across ten repositories. Many were duplicates; design and workflow skills came in different versions, and some had broken frontmatter.

The fix is a global install into `~/.omp/agent/skills/`. OMP's precedence order:

```
<project>/.omp/skills  >  ~/.omp/agent/skills  >  .claude/skills (project and plugins)
```

When OMP finds multiple skills with the same name, it picks the version from the highest-priority source. This means a global skill in `.omp` overrides project copies with the same name in `.claude`, so only the global skill needs updating.

Two details matter during the migration:

1. **Skills from plugins are the exception.** Don't move them into `~/.omp/agent/skills/`: the global copy takes precedence, and OMP stops using the version from the plugin. The plugin keeps updating, but the old global copy remains in use. For me, this applies to `superpowers` and `swiftui-pro`.
2. **Versions.** Skills with `metadata.version` have upstreams on GitHub. My `impeccable` copies were four minor versions behind (3.5.0 vs 3.9.1); ui-ux-pro-max was nearly a major behind. The check is quick: local SKILL.md frontmatter against the raw file in the repository.

The openspec skills are a special case: the CLI generates them. I updated the CLI from 1.4.1 to 1.6.0 and regenerated — as a bonus, 1.6.0 ships a native OMP target: `openspec init --tools oh-my-pi` writes skills straight into `.omp/skills`.

Result: 38 skills global, 5.6 MB, every frontmatter valid, one source of truth.

## The advisor: a second agent that reads every turn

The most underrated OMP feature. Two lines to enable:

```yaml
advisor:
  enabled: true
# plus modelRoles.advisor
```

The advisor is a full second agent. After each turn by the primary agent, it reads the new part of the transcript, reasoning included, and checks the code itself with read-only tools when needed. Advice comes at three levels: `nit` appears as a quiet note, while `concern` and `blocker` can interrupt the primary agent mid-turn. To prevent repeated interruptions, each one starts a three-turn cooldown during which new advice appears as ordinary notes.

<img src="/posts/oh-my-pi-setup/advisor-concern.png" alt="A concern card from the advisor (in Russian): an interruption with a diagnosis of why scrolling fails mid-stream and a suggested workaround" width="760" height="117" loading="lazy" decoding="async" />

The key to making it useful is `WATCHDOG.md`: instructions only the advisor sees. A global one lives in `~/.omp/agent/`, a per-project one in the repo root; they stack. What goes in there is not generic wishes but the project's specific traps: "migrations auto-apply on every deploy", "tenant isolation is app-level, no RLS — flag any unscoped query", "push to main is production".

When one reviewer is not enough, there is `WATCHDOG.yml` — a roster: several advisors, each with its own model, its own tools, and its own specialization. So far one is enough for me.

The advisor reviews the work as it unfolds, not a completed diff. It doesn't replace conventional code review: its job is to catch a wrong direction by turn two, before the agent spends an hour on it. The cost is additional token use, especially at maximum reasoning. `/advisor status` shows the exact spend.

<img src="/posts/oh-my-pi-setup/advisor-status.png" alt="An /advisor status card: advisor model, 6% of a 1M context, 1.4M tokens spent, $2.75 for the session" width="760" height="393" loading="lazy" decoding="async" />

## Session memory

Another layer that ships disabled:

```yaml
memory:
  backend: local
```

A background pipeline re-reads the project's settled sessions at startup — idle for at least 12 hours and no older than 30 days. The `default` role extracts decisions and pitfalls, while the cheaper `smol` combines the results into `MEMORY.md` and a compact summary. That summary enters the system prompt of every new session for the project. Before writing anything to disk, the pipeline removes secrets.

The practical effect: a new session doesn't start from zero — it starts knowing "deploys in this project happen only on the owner's request, tests run like this, last time we tripped over that". You can see what memory has actually learned: `/memory view`, or a plain `read` of `memory://root`.

## AGENTS.md for every project: parallel scouts

The final layer is project context. I have 13 active repositories; hand-writing 13 context files is drudgery. Instead: one read-only scout per project, all in parallel, with a strict response contract — identity, stack, commands, existing agent files, conventions, risks for the watchdog. Thirteen minutes, thirteen briefs, and the files get assembled from those by hand.

The resulting scheme per project:

- `AGENTS.md` — the canonical context: what the project is, commands, architecture, conventions. OMP reads it natively;
- `WATCHDOG.md` — risks for the advisor;
- the old `CLAUDE.md` is not deleted but replaced with a one-liner `@AGENTS.md` — Claude Code keeps working through the import, and the context isn't loaded twice.

Hard prohibitions such as "don't push without asking" belong in `RULES.md`, not `AGENTS.md`. OMP loads them as sticky rules and brings them back near the current turn, so they don't disappear into a long session.

The audit had another useful side effect: alongside the project context, it surfaced stale start commands, conflicting instructions, and other gaps between the documentation and the actual repositories.

## Useful features and non-obvious behavior

Useful features:

- `omp stats` — token and dollar spend by project and session, subagents and the advisor included. Sobering.
- `/advisor dump` — the advisor's transcript to the clipboard: you see what it read and why it grumbled.
- `omp config get <key>` — the merged value of a setting across all layers at once; kills the "which config won" guessing game.
- `memory://root` and `skill://<name>` open with a plain `read` — the harness's internals are inspectable from inside the harness.

Non-obvious behavior:

- settings arrays replace, they don't merge: a project-level `disabledProviders` silently overrides the global one wholesale;
- `google` and `gemini` are different ids in one namespace: the first kills the model backend, the second the Gemini CLI discovery files;
- an empty `.omp/` folder is skipped during context walk-up — the search moves to the parent, and the project lives with an ancestor's AGENTS.md;
- `hide: true` on a skill removes it from the system prompt but doesn't disable it — it stays reachable by name.

## Checklist

Globally, once:

1. `grep -E '"level":"(error|warn)"' ~/.omp/logs/omp.*.log` — and fix what it finds
2. Model roles: cheap on tiny/commit/smol, expensive on plan/advisor
3. Skills in `~/.omp/agent/skills`, no duplicates with plugins, versions checked against upstream
4. `advisor.enabled: true` plus a global `WATCHDOG.md`
5. `memory.backend: local`
6. A second Claude subscription, if you have one: OMP runs inside Orca, and I choose the account manually from its status bar

Per project, ten minutes each:

1. `AGENTS.md` (you can just ask the agent: "study the project and write AGENTS.md")
2. `WATCHDOG.md` with the project's concrete traps
3. `CLAUDE.md` → `@AGENTS.md` if one existed
4. `openspec init --tools oh-my-pi` if features go through specs

Configuration is read at process start, so restart after the edits. From then on it just works.