Oh My Harness
Native Claude Code and Codex harness with a spec-driven autonomous loop, safety guards, model routing, and multi-agent orchestration.
Installation
# Claude Code
claude plugin marketplace add Hoya324/oh-my-harness
claude plugin install oh-my-harness@oh-my-harness
# Codex marketplace source
codex plugin marketplace add Hoya324/oh-my-harness
# Local project install
oh-my-harness init --runtime claude
oh-my-harness init --runtime codex
oh-my-harness init --runtime both
For the Codex CLI, start Codex, enter /plugins, choose the configured marketplace, install oh-my-harness, and start a new session. See the official Codex plugin guide.
In Codex desktop, open Plugins, choose the configured marketplace under Personal, install it, and open a new chat.
After installation, review OMH hooks in /hooks. Codex keeps its native trust boundary. Use omh-status for tier, loop, verification, usage, and memory state.
Marketplace installation bundles hooks, skills, and MCP only. To add Codex quick/standard/architect profiles and durable
AGENTS.mdguidance, invoke/harness-setupand approve those writes, or runoh-my-harness init --runtime codex|both.
Updating
claude plugin update oh-my-harness@oh-my-harness
/harness-setup
oh-my-harness update --runtime codex
Updates preserve
harness.config.jsonand user-owned skills. Codex update refreshes managed hooks, skills, roles, guidance, and memory runtime; Claude plugin update follows its plugin setup flow.
Claude plugin mode loads memory through .mcp.json and exposes MCP tools. Local Codex init provisions .claude/.omh/runtime/bin/omh-memory.sh and .claude/.omh/runtime/lib/memory.mjs, and manages [mcp_servers.omh-memory]. User-scoped init uses ~/.claude/.omh/runtime/. Both use ~/.omh/memory/graph.jsonl.
MCP changes to the plugin root and runs bin/omh-memory.sh, which invokes npx --yes --prefer-offline @modelcontextprotocol/server-memory@2026.7.4. A first uncached launch needs npm registry/network access; release verification on macOS warms the current machine cache. Native Windows hooks use commandWindows, while the MCP launcher requires Bash.
Quick Start
Bundled hooks, skills, and MCP are available after installation; provision Codex profiles and durable guidance explicitly. In your first session:
- Convention detected — OMH scans your project and outputs:
[omh:convention-detect] Project: node | test: vitest | lint: eslint - Guards active — Ambiguity guidance, dangerous-command denial, and test enforcement are all ON by default.
- Model routing ready — Claude automatically delegates to haiku/sonnet/opus based on task complexity.
Run /init-project to scaffold project-specific skills (code review, test writing, lint fixing) for your detected stack.
Configuration
All settings live in .claude/.omh/harness.config.json.
Default Config
{
"version": 1,
"features": {
"conventionSetup": true,
"testEnforcement": true,
"contextOptimization": true,
"autoPlanMode": true,
"ambiguityDetection": true,
"dangerousGuard": true,
"contextSnapshot": true,
"commitConvention": true,
"scopeGuard": false,
"usageTracking": true,
"autoGitignore": true,
"skillScaffolding": true,
"autonomousLoop": true
},
"testEnforcement": { "minCases": 2, "promptOnMissing": true },
"modelRouting": { "quick": "haiku", "standard": "sonnet", "complex": "opus" },
"autoPlan": { "threshold": 3 },
"ambiguityDetection": { "threshold": 2, "language": "auto" },
"commitConvention": { "style": "auto" },
"scopeGuard": { "allowedPaths": [] },
"multiAgent": { "maxAgents": 4, "useWorktree": true, "tmuxSession": "omh-agents" },
"conventions": { "autoDetect": true, "overrides": {} }
}
Modify Settings
/set-harness # Show all current settings
/set-harness features.scopeGuard true # Enable scope guard
/set-harness testEnforcement.minCases 3 # Require 3+ test cases
/set-harness modelRouting.standard opus # Use opus for implementation
/set-harness commitConvention.style gitmoji # Switch to gitmoji
Autonomous Loop
The headline feature of 0.3.0. Define a goal once in a machine-checkable spec, then OMH loops — implementing, self-verifying, and cross-verifying — until every acceptance criterion is objectively met or a guardrail fires. This is a deliberate identity shift: from "warnings instead of walls" to autonomy with real walls. The harness owns when to continue and when to stop; the model never decides termination from its own self-assessment.
# 1. Author a machine-checkable spec (refuses vague specs)
/omh-spec "Add rate limiting to the public API"
# 2. Run the loop (classifies a tier, gates on the spec, then iterates)
/omh-loop SPEC.md
# 3. Abort any time
/omh-loop stop
The Stop hook
hooks/loop-guard.mjsis the loop engine and safety enforcer. It forces continuation by printing a top-level{"decision":"block","reason":...}and exiting 0, and allows the session to stop when the spec is met or a guardrail fires. The pure corelib/loop.mjsis unit-tested in isolation.
Spec Authoring (SPEC.md)
/omh-spec authors a SPEC.md with EARS acceptance criteria — WHEN <trigger> THE SYSTEM SHALL <response> — each mapped to a verify command. The loop may stop only when every criterion's command exits 0. /omh-spec refuses to start a loop while any [NEEDS CLARIFICATION] markers remain, falling back to the Ambiguity Guard.
Tiers & Verify Ladder
Effort is tiered. The loop starts on the cheapest tier and escalates only on observed signals (verify failure, large diff, repeated failure signature). A cross-tier cap of 30 total iterations applies regardless of tier.
| Tier | Budget | Cross-Verify |
|---|---|---|
quick | ≤ 3 iterations / 5 min | None |
standard | ≤ 8 iterations / 15 min | At done |
deep | ≤ 20 iterations / 45 min | Every 5 + at done |
Each iteration runs a cheap-first verify ladder that fails fast and feeds the actual failing output back as the next iteration's instruction:
quickCheck (lint / typecheck) → verify (tests / build) → self-review → cross-verify
The cheapest rung runs first with its own subprocess timeout. On the first non-zero exit the loop blocks with the real failing output piped into the next instruction — it never spends a model judge on structurally broken code.
Cross-Verification
Cross-verification uses a different model than the generator (opus via model routing) to kill self-enhancement bias. It scores each SPEC acceptance criterion PASS/FAIL with evidence, verifies independently against repo state (runs the tests, greps the diff — not the agent's self-report), and runs a revert-and-rerun mutation check so vacuous tests can't satisfy the gate. The verdict is typed PASS | FAIL | INCONCLUSIVE; INCONCLUSIVE fails safe to stop-and-report. Results emit as [omh:cross-verify] with a rubric table.
Guardrails
Termination is a layered checklist owned by the hook — autonomy never becomes runaway:
- Self-trigger guard —
stop_hook_activeis checked first, preventing the hook's own respond→block→respond infinite loop - Isolation — concurrent-session / worktree safety via
sessionIdmatching - Kill switch —
.claude/.omh/STOPor/omh-loop stophalts immediately - Budgets — per-tier and cross-tier iteration caps plus an independent wall-clock timeout
- No-progress / plateau — an empty or cosmetic commit diff over the plateau window stops the loop
- Oscillation — a repeated failure signature or A-B-A-B pattern stops and escalates ("architectural, not iterative")
- Fail-open state — atomic state writes; corruption deletes state and exits cleanly, never trapping the user
Loop Config
The loop is enabled by features.autonomousLoop (default ON, inert until /omh-loop writes an active state) plus a loop block. State lives in .claude/.omh/loop-state.json; the human-readable plan and log is PROGRESS.md.
"features": { "autonomousLoop": true },
"loop": {
"classify": "auto", // auto | quick | standard | deep
"defaultTier": "quick", // start cheap, escalate on signals
"requireSpec": true,
"specPath": "SPEC.md",
"logFile": "PROGRESS.md",
"learningsFile": ".claude/.omh/loop-learnings.md",
"requireCommit": true,
"oneTaskPerIteration": true,
"maxDiffFilesPerIteration": 20,
"maxTotalIterations": 30,
"stopOnNoProgress": true,
"verifyInHook": true,
"rungTimeoutSec": { "quickCheck": 30, "verify": 180 },
"crossVerify": true,
"crossVerifyModel": "architect", // different model than generator
"maxDeepVerifiesPerTask": 3,
"reflectionWindow": 3,
"tiers": {
"quick": { "maxIterations": 3, "maxWallClockMinutes": 5, "crossVerify": false },
"standard": { "maxIterations": 8, "maxWallClockMinutes": 15, "crossVerify": true },
"deep": { "maxIterations": 20, "maxWallClockMinutes": 45, "crossVerify": true, "crossVerifyEvery": 5 }
}
}
Techniques drawn on: the Ralph Wiggum loop, Reflexion, Self-Refine, Chain-of-Verification (CoVe), LLM-as-judge, FrugalGPT cascade, Agreement-Based Cascading, EARS notation, and Spec-Driven Development.
Architecture
OMH is built in four layers. Pure, unit-tested decisions are separated from native adapters that apply each event's safety policy.
| Layer | Role |
|---|---|
① Hooks (hooks/) | 11 shared scripts (9 guards/observers + 2 gates) and 2 Codex bridge modules |
② Pure Core (lib/) | All decision logic as pure functions (no fs / git / time) — fully unit-tested |
③ Skills (claude/skills/ + codex/skills/) | 13 Claude Code skills and 14 Codex skills |
④ Agents (agents/) | Routed roles — Claude uses haiku/sonnet/opus; Codex uses profile preferences |
Hooks
OMH hooks into the native Claude Code or Codex lifecycle. Ordered event chains share the same decision core; Codex uses two bridge modules.
Official Codex sibling handlers are concurrent. OMH registers one orchestrator per event and runs shared handlers sequentially for deterministic safety ordering.
Critical PreToolUse guards fail closed when safety cannot be verified; advisory hooks warn or continue and fail open.
| Hook File | Event | What it does |
|---|---|---|
session-start.mjs | SessionStart | Convention detection, skill hints |
pre-prompt.mjs | UserPromptSubmit | Ambiguity guard, auto-plan mode |
dangerous-guard.mjs | PreToolUse | Denies destructive operations or malformed hook input |
plan-gate.mjs | PreToolUse | Plan gate — requires a plan before edits |
commit-convention.mjs | PostToolUse | Reminds commit format |
scope-guard.mjs | Codex: PreToolUse Claude: PostToolUse | Codex denies before execution; Claude reports after execution |
usage-tracker.mjs | PostToolUse | Records tool usage |
pre-compact.mjs | PreCompact | Saves context snapshot |
loop-guard.mjs | Stop | Autonomous loop engine + safety enforcer |
verify-gate.mjs | Stop | Risk-gated verify gate for plain sessions |
post-task.mjs | Stop | Test enforcement reminder |
For Tier-3 work, Claude gates Edit/Write-class tools and clears with ExitPlanMode. Codex maps apply_patch to an edit and clears only for a non-empty update_plan whose entries each have a nonblank step and an allowed status; other payloads do not clear it. The denial cap remains a non-wedging fallback.
Feature Tags — [omh:*]
Every OMH action is prefixed with a tag so you always know which feature fired:
[omh:convention-detect] → Detected project conventions
[omh:ambiguity-guard] → Asking for clarification
[omh:auto-plan] → Detected 3+ tasks
[omh:dangerous-guard] → Denial of destructive or malformed request
[omh:model-routing → sonnet] → Delegating to sonnet
[omh:test-enforcement] → Reminding to verify tests
[omh:commit-convention] → Showing commit format
[omh:scope-guard] → Codex denial / Claude report outside paths
[omh:context-snapshot] → Saving state before compaction
Skills
OMH provides 13 Claude Code skills and 14 Codex skills (including omh-status):
| Command | Availability | Description |
|---|---|---|
/omh-spec [goal] | Claude + Codex | Author a machine-checkable SPEC.md with EARS acceptance criteria |
/omh-loop [SPEC.md] | stop | Claude + Codex | Run the autonomous loop until the spec is met; stop aborts |
/omh-verify | Claude + Codex | Run independent multi-model verification rounds and persist high-confidence findings |
omh-status | Codex only | Show Codex harness tier, loop, verification, usage, and memory state |
/harness-setup | Claude + Codex | Initialize oh-my-harness with interactive onboarding |
/set-harness [path] [value] | Claude + Codex | View or modify harness settings |
/init-project | Claude + Codex | Detect conventions and scaffold project skills |
/agent-spawn [N] [task] | Claude + Codex | Spawn N selected-runtime agents in tmux |
/agent-status | Claude + Codex | Check status of running agents |
/agent-apply [id|all] | Claude + Codex | Preview diffs and merge agent worktree changes |
/agent-stop [id|all] | Claude + Codex | Stop agents and cleanup worktrees |
/team-spawn [template|N] [task] | Claude + Codex | Create native team with teammates |
/team-status | Claude + Codex | Check team and task progress |
/team-stop | Claude + Codex | Shutdown team and cleanup |
Agents
OMH provides 3 built-in agent types for cost-efficient subagent delegation:
| Role | Claude identifier / model | Codex profile preference | Use For |
|---|---|---|---|
quick | harness:quick · Haiku | quick · preferred gpt-5.6-luna / low reasoning | File lookups, simple questions, exploration |
standard | harness:standard · Sonnet | standard · preferred gpt-5.6-terra / medium reasoning | Implementation, bug fixes, debugging |
architect | harness:architect · Opus | architect · preferred gpt-5.6-sol / xhigh reasoning | Architecture, complex analysis, security review |
Codex profile model and reasoning values are preferences from the bundled profiles, not availability guarantees.
Model Routing
OMH routes subagent work through the native Claude Code agent definitions or Codex quick/standard/architect roles. Runtime model settings are preferences, not availability guarantees.
Announce with: [omh:model-routing → <model>]
# Customize model assignments
/set-harness modelRouting.quick haiku
/set-harness modelRouting.standard sonnet
/set-harness modelRouting.complex opus
Features Overview
Features group into three layers — automatic guards that fire on every session, autonomous execution you invoke explicitly, and the cross-cutting routing & observability layer.
A · Automatic guards & routing (always on)
| Feature | Hook | Default |
|---|---|---|
| Convention Auto-Detect | SessionStart | ON |
| Weight Routing (Tier 1/2/3) | UserPromptSubmit | ON |
| Ambiguity Guard | UserPromptSubmit | ON |
| Auto-Plan Mode | UserPromptSubmit | ON |
| Dangerous Guard | PreToolUse | ON |
| Plan Gate | PreToolUse | ON |
| Commit Convention | PostToolUse | ON |
| Scope Guard | Codex: PreToolUse Claude: PostToolUse | OFF |
| Usage Tracking | PostToolUse | ON |
| Test Enforcement | Stop | ON |
| Verify Gate | Stop | ON |
| Context Snapshot | PreCompact | ON |
| Living State (STATE.md) | SessionStart / PreCompact | ON |
B · Autonomous execution (you invoke it)
| Feature | Trigger | Default |
|---|---|---|
| Autonomous Loop | Stop / /omh-loop | ON |
| Spec Authoring | /omh-spec | ON |
| N-Round Verify | /omh-verify | — |
| Native Team | /team-spawn | ON |
| Multi-Agent | /agent-spawn | — |
| Long-Term Memory | omh-memory MCP | ON |
C · Routing, scaffolding & observability
| Feature | Trigger | Default |
|---|---|---|
| Model Routing | CLAUDE.md | ON |
| Skill Scaffolding | /init-project | ON |
| Auto .gitignore | CLI init | ON |
| Status HUD | status line | ON |
Safety Guards
Ambiguity Guard
Detects vague requests using a scoring system (threshold: 2):
| Signal | Score | Example |
|---|---|---|
| Vague references | +1 | "fix this", "change that" |
| Scope-less verbs | +1 | "refactor" (no target) |
| Open-ended choices | +1 | "or something", "whatever" |
| Very short message | +1 | < 15 chars |
Dangerous Guard
Denies potentially destructive operations before execution:
| Pattern | Warning |
|---|---|
rm -rf | File deletion |
git push --force | Force push |
git reset --hard | Hard reset |
DROP TABLE | Database destruction |
chmod 777 | Unsafe permissions |
curl | sh | Remote execution |
.env files | Environment secrets |
id_rsa, .pem, .key | Private keys |
Hard PreToolUse guard — denies detected unsafe operations or malformed hook input until the request is made safe.
Scope Guard
When enabled, Codex denies out-of-scope edits and recognized filesystem mutations with no auditable path before execution; Claude retains post-tool reporting.
{
"features": { "scopeGuard": true },
"scopeGuard": { "allowedPaths": ["src/auth", "src/utils"] }
}
OFF by default. Enable when you want to restrict Claude's write scope.
Convention Auto-Detect
Scans project root on session start and injects detected conventions as context. Results are cached for 1 hour.
| Project File | Language | Detected Tools |
|---|---|---|
package.json | Node.js | jest / vitest / mocha, eslint / biome, prettier |
pyproject.toml | Python | pytest, ruff / flake8, black, mypy |
go.mod | Go | go test, golangci-lint |
Cargo.toml | Rust | cargo test, clippy, rustfmt |
build.gradle | Java | junit, gradle |
pom.xml | Java | junit, maven |
Test Enforcement
After code changes (Edit / Write / NotebookEdit), injects a reminder at session stop:
- Verify test files exist for changed code
- Each test file has at least N cases (configurable, default: 2)
- Tests must cover happy path, edge case, and error case at minimum
HUD Status Line
OMH replaces Claude Code's default status line with a real-time dashboard:
[OMH] | 5h:14%(3h51m) | wk:7%(6d5h) | session:29m | ctx:39% | 🔧53 | agents:2 | opus-4-6
| Segment | Meaning |
|---|---|
5h:14%(3h51m) | 5-hour rate limit usage, resets in 3h 51m |
wk:7%(6d5h) | Weekly rate limit usage, resets in 6d 5h |
session:29m | Current session duration |
ctx:39% | Context window usage (green → yellow → red) |
🔧53 | Total tool calls this session |
agents:2 | Running subagents |
opus-4-6 | Active model |
Skill Scaffolding
Run /init-project to auto-generate project-specific skills based on your detected stack.
Generated Skills
| Skill | What it does |
|---|---|
code-review | Language-specific review checklist |
test-write | Test writing conventions for detected framework |
lint-fix | Lint check and auto-fix workflow |
Supported Languages
| Language | Test | Linter |
|---|---|---|
| Node.js | vitest / jest / mocha | eslint / biome |
| Python | pytest | ruff / flake8 |
| Go | go test | golangci-lint |
| Rust | cargo test | clippy |
| Java | junit | — |
| Kotlin | kotest / junit5 | ktlint / detekt |
Skills are user-owned. Customize freely — OMH never overwrites existing skills.
Multi-Agent System
Spawn parallel workers in isolated tmux/worktree lanes. The Claude edition launches Claude; the Codex edition honors multiAgent.runtime (codex or claude).
Agent Commands
| Command | Description |
|---|---|
/agent-spawn [N] [task] | Spawn N agents (default: 2) with worktrees in tmux panes |
/agent-status | Check status of all agents (commits, changed files) |
/agent-apply [id|all] | Preview and merge agent changes to main |
/agent-stop [id|all] | Stop agents, warn about unmerged work, cleanup |
Worktree Mode
| useWorktree: true (default) | useWorktree: false | |
|---|---|---|
| Isolation | Each agent on its own branch | All agents in project root |
| Conflicts | Impossible during parallel work | Possible — use with care |
| /agent-apply | Required to merge changes | Not applicable |
| Best for | Any parallel code changes | Read-only tasks, analysis |
Safety Policies
- Always ask first — never spawn without explicit user confirmation
- Never auto-merge —
/agent-applyalways shows a diff and waits for approval - Never silently discard —
/agent-stopwith unmerged commits requires explicit choice - Max agents — capped by
multiAgent.maxAgents(default: 4)
Prerequisites
- tmux —
brew install tmux(macOS) /apt install tmux(Linux) - git — for worktree isolation
- Selected runtime CLI —
claudeorcodexmust be available in PATH
Native Team System
Use native collaboration without tmux or worktrees: Claude Code uses TeamCreate/TaskCreate/Agent operations; Codex uses spawn_agent/list_agents/send_message/interrupt_agent.
Team Commands
| Command | Description |
|---|---|
/team-spawn [template|N] [task] | Create a team with teammates from a template or custom count |
/team-status | Check teammate status and task progress |
/team-stop | Shutdown teammates, warn about incomplete tasks, cleanup |
Templates
| Template | Members | Use For |
|---|---|---|
fullstack | frontend (standard) + backend (standard) + tester (standard) | Full-stack feature development |
review | reviewer (architect) + tester (standard) | Code review and testing |
research | researcher (quick) + implementer (standard) + architect (architect) | Research-driven development |
Claude maps these shared agent types to haiku/sonnet/opus. Codex treats them as available-profile preferences and does not guarantee a particular model.
Multi-Agent vs Native Team
| Multi-Agent (/agent-spawn) | Native Team (/team-spawn) | |
|---|---|---|
| Infrastructure | tmux + git worktrees | Native Claude Code or Codex collaboration operations |
| Prerequisites | tmux, git, selected runtime CLI | None (built-in) |
| Isolation | Git branches per agent | Runtime-native subagent isolation |
| Communication | Observe tmux panes | Claude messaging or Codex send_message |
| Best for | Parallel code changes needing isolation | Coordinated team workflows |
Team Safety Policies
- Always ask first — never create a team without explicit user confirmation
- Never silently discard —
/team-stopwith incomplete tasks requires explicit choice - Max teammates — capped by
nativeTeam.maxTeammates(default: 4) - One team at a time — must stop existing team before creating a new one
Settings Reference
| Path | Type | Default | Description |
|---|---|---|---|
features.conventionSetup | bool | true | Auto-detect project conventions |
features.testEnforcement | bool | true | Remind about tests after changes |
features.autoPlanMode | bool | true | Suggest plan mode for multi-task |
features.ambiguityDetection | bool | true | Force clarification for vague requests |
features.dangerousGuard | bool | true | Deny destructive operations or malformed hook input |
features.scopeGuard | bool | false | Restrict file modification scope |
features.usageTracking | bool | true | Track tool usage |
testEnforcement.minCases | number | 2 | Minimum test cases per file |
modelRouting.quick | string | haiku | Model for exploration |
modelRouting.standard | string | sonnet | Model for implementation |
modelRouting.complex | string | opus | Model for architecture |
autoPlan.threshold | number | 3 | Tasks to trigger auto-plan |
multiAgent.maxAgents | number | 4 | Max parallel agents |
multiAgent.useWorktree | bool | true | Use git worktrees for isolation |
features.nativeTeam | bool | true | Enable native team skills |
nativeTeam.maxTeammates | number | 4 | Max teammates per team |
nativeTeam.defaultTeamName | string | omh-team | Default team name |
features.autonomousLoop | bool | true | Enable the spec-driven autonomous loop |
loop.defaultTier | string | quick | Starting tier (escalates on signals) |
loop.maxTotalIterations | number | 30 | Cross-tier iteration cap |
loop.crossVerifyModel | string | architect | Different model for cross-verification |
CLI Commands
oh-my-harness init --runtime claude|codex|both
oh-my-harness init --runtime codex --scope user
oh-my-harness update --runtime claude|codex|both
oh-my-harness status
oh-my-harness reset --runtime claude
oh-my-harness reset --runtime codex
oh-my-harness reset --runtime both
Use --scope user to provision user-scoped Codex configuration and memory runtime. A bare reset retains the Claude-only default.
omh-status reads project state first, then the user-global fallback. Explicit --scope project and --scope user keep Claude lifecycles isolated. A malformed managed config, settings file, or guidance block fails preflight before mutation.
OMC Compatibility
Oh My Harness coexists cleanly with Oh My ClaudeCode:
| Concern | OMH | OMC |
|---|---|---|
| CLAUDE.md markers | <!-- HARNESS:START/END --> | <!-- OMC:START/END --> |
| Hook namespace | .omh/hooks/ | OMC plugin hooks |
| Agent prefix | harness: | oh-my-claudecode: |
| Kill switch | DISABLE_HARNESS=1 | DISABLE_OMC=1 |
Both plugins can be installed simultaneously without conflicts.
Disable / Uninstall
# Temporarily disable
DISABLE_HARNESS=1 claude
# Plugin mode — uninstall
claude plugin uninstall oh-my-harness
# Local CLI — Claude only (bare reset default)
oh-my-harness reset --runtime claude
# Local CLI — Codex only
oh-my-harness reset --runtime codex
# Local CLI — full dual-runtime removal
oh-my-harness reset --runtime both
npm uninstall -g oh-my-harness
User-owned project skills and the separate memory graph at ~/.omh/memory/graph.jsonl are preserved.
Requirements
- Node.js >= 18
- Claude Code and/or Codex CLI/desktop
- tmux — for multi-agent only
- git — for worktree isolation