---
purpose: Own OMP host wiring, runtime isolation, config deploy, and completion enforcement.
applies_to: Changes under .omp, config/omp, or modules/agents/omp.
entrypoint: Edit the repository-local hook or the matching module/config source.
verification: Run focused OMP tests, rebuild, and smoke test project-hook discovery.
update_when: OMP wiring, config keys, hook behavior, or verification commands change.
---

# OMP Module

Thin wrapper module for Oh My Pi (`omp`).

Keep OMP isolated from Pi. This repo exports Pi globals such as
`PI_CODING_AGENT_DIR=$HOME/.pi/agent`; plain OMP honors those and will collide
with Pi state. The module installs `pkgs.llm-agents.omp` through a wrapper that
sets:

```sh
PI_CONFIG_DIR=.omp
PI_CODING_AGENT_DIR=$HOME/.omp/agent
PI_PERMISSION_SYSTEM_CONFIG_PATH=$HOME/.omp/agent/extensions/pi-permission-system/config.json
```

`~/.omp/agent/config.yml` is tracked from `config/omp/config.yml`;
`~/.omp/agent/mcp.json` is rendered from `config/omp/mcp.json`, a Nix-packaged
FFF executable, and per-host `mcpServers` / `disabledMcpServers`. Edit repo
sources, not runtime symlinks.
On Seqeratop, the per-host Seqera entry uses OAuth. After rebuilding, run
`/mcp reauth seqera` in OMP; OAuth credentials remain runtime state and never
belong in Nix.
`~/.omp/agent/lsp.json` is generated by the module and points the Nextflow LSP
at the Nix-built launcher, not a
Claude-plugin-root placeholder. The `permission-policy-guard` extension is
linked from `config/omp/` and explicitly listed in `config.yml`. OMP links the
repo-local `packages/pi-packages/pi-herdr` and `pi-hunk` packages so review
workflows can create Herdr PR workspaces and write Hunk comments. It also
installs a pinned `pi-review-loop` on Darwin for the persistent `/diff-review`
window, rewrites its Pi-specific TUI-mode guard to use OMP's `ctx.hasUI`, and
builds the Glimpse macOS host skipped by OMP's plugin installer. Other OMP
runtime state remains mutable and OMP-owned.

The module clears OMP's cached MCP tool metadata during activation so removed
servers do not reappear from `agent.db`.

After changing OMP config or module wiring, run:

```sh
bash modules/agents/omp/test-config-yml.sh
bash modules/agents/omp/test-mcp-json.sh
bash modules/agents/omp/test-mcp-host-config.sh
hey check
```

`test-config-yml.sh` loads `config/omp/config.yml` in an isolated OMP home,
rejects any `omp config list --json` warning, then checks its keys, types, and
effective values.
`test-mcp-json.sh` verifies the shared policy.
`test-mcp-host-config.sh` builds the resolved MCP configuration for
MacTraitor-Pro and Seqeratop. Legacy/renamed keys fail closed.

Enable with:

```nix
modules.agents.omp.enable = true;
```

## Completion gate

`scripts/completion-check` is the shared source of truth for Codex and OMP
completion checks. OMP discovers `.omp/hooks/post/completion-gate.ts` only when
launched from this repository root; it is not installed in the user-wide OMP
configuration. Project hook factories are loaded through OMP's extension runner,
so this hook can register `session_stop` as well as ordinary tool events. It also
requires Git to track `.codex/hooks.json` and `scripts/codex-validate-stop`.

The model-callable `completion_check` tool records a one-shot content snapshot.
The next main-session stop must match it or OMP continues the session. OMP core
limits `session_stop` to eight consecutive continuations. Keep
`features.unexpectedStopDetection: true` for semantic incomplete-stop detection;
do not add another classifier. `hooks.timeoutMs` controls legacy hooks, not
`ExtensionAPI.session_stop`.

Verify changes with:

```sh
bun test tests/omp_completion_gate.test.js
python3 -m unittest tests/test_completion_hooks.py
scripts/completion-check
COMPLETION_CHECK_PYTHON=/usr/bin/true COMPLETION_CHECK_HEY=/usr/bin/true omp --max-time 180 -p 'First reply PRECHECK without tools. If continued, call completion_check and reply GATE_OK.'
```

## Permission policy guard

The guard blocks OMP tool calls that mention the shared Pi/OMP policy file or
OMP's runtime symlink to it. Its block reason should explain:

- what was blocked
- why OMP must not inspect or rewrite its own guardrails casually
- what to edit instead for OMP-only behavior, OMP module wiring, or an explicit
  shared policy change

Keep those alternatives in the hook's `GUIDANCE_LINES`; the reason is shown
back to the model as the failed tool result.

## Per-host model roles and providers

`modules.agents.omp.smolModel` sets `PI_SMOL_MODEL` in the wrapper for a
declarative per-host smol/fast override. The explicit `modelRoles.commit` wins
for commits; commit falls back to smol only when that role is unset.
`modules.agents.omp.modelRoles` overlays host-specific role selectors into the
rendered `config.yml`. Use it only for real host auth or quota differences; keep
shared defaults in `config/omp/config.yml`. Smol precedence:
`--smol` flag > `PI_SMOL_MODEL` > rendered `config.yml`.

**Providers are host-specific.** Do not cross-wire prefixes across laptops.
Source of truth: the `modules.agents.omp` block comments + pins in each
`hosts/*/default.nix`. Validate new ids with `omp models <provider>` on that
host before adding roles/fallbacks. Never invent hybrid ids like
`cursor/grok-*`.

## Docs

Durable OMP module notes live in [docs/](./docs/README.md). Start with that
guide, then search `purpose:` and `applies_to:` in the first seven lines of
files under `docs/` instead of reading every note.

When upstream OMP documentation is missing or ambiguous, add one verified topic
note there with the canonical YAML summary. Keep transient task progress in
`.agents/worklogs`.
