# oh-my-codex (OMX) — Administrator & Developer Guide

> **Version:** 0.13.1 | **License:** MIT | **Repository:** [Yeachan-Heo/oh-my-codex](https://github.com/Yeachan-Heo/oh-my-codex)

---

## Table of Contents

1. [Architecture Overview](#1-architecture-overview)
2. [System Requirements](#2-system-requirements)
3. [Configuration Reference](#3-configuration-reference)
4. [Deployment & Scaling](#4-deployment--scaling)
5. [Operations](#5-operations)
6. [Performance](#6-performance)
7. [Security](#7-security)
8. [Developer Internals](#8-developer-internals)
9. [Integration Points](#9-integration-points)

---

## 1. Architecture Overview

oh-my-codex (OMX) is a multi-agent orchestration layer that sits on top of OpenAI Codex CLI. It transforms single-agent Codex sessions into coordinated multi-agent teams operating inside tmux sessions, with a Rust-backed native runtime for state management and an extensible hook and plugin system for deep Codex integration.

### 1.1 Component Inventory

```
oh-my-codex
├── TypeScript Layer (src/)
│   ├── cli/           — CLI entry + all subcommand handlers (28 files, ~490K chars)
│   ├── team/          — Multi-agent team orchestration (27 files, ~600K chars)
│   ├── notifications/ — Discord / Telegram / Slack (18 files, ~180K chars)
│   ├── mcp/           — 5 MCP servers (8 files, ~97K chars)
│   ├── hooks/         — Codex hook integration (8 files, ~95K chars)
│   │   ├── extensibility/ — Plugin system (9 files, ~27K chars)
│   │   └── code-simplifier/ — Code simplification hook
│   ├── hud/           — Heads-up display (9 files, ~52K chars)
│   ├── autoresearch/  — Experiment loops (2 files, ~53K chars)
│   ├── config/        — Config generators (4 files, ~52K chars)
│   ├── adapt/         — Adapter framework (6 files, ~47K chars)
│   ├── state/         — Mode state management (6 files, ~41K chars)
│   ├── openclaw/      — OpenClaw integration (4 files, ~35K chars)
│   ├── utils/         — Shared utilities (9 files, ~33K chars)
│   ├── agents/        — Agent definitions (2 files, ~21K chars)
│   ├── catalog/       — Skill/agent catalog (3 files, ~16K chars)
│   ├── pipeline/      — Pipeline orchestrator (3 files, ~15K chars)
│   ├── ralph/         — Verification loop (2 files, ~14K chars)
│   ├── session-history/ — Session history search (1 file, ~12K chars)
│   ├── runtime/       — Runtime bridge to Rust (1 file, ~10K chars)
│   ├── modes/         — Base mode lifecycle (1 file, ~9K chars)
│   ├── ralplan/       — RALPLAN mode runtime (1 file, ~9K chars)
│   ├── subagents/     — Subagent tracker (1 file, ~8K chars)
│   ├── planning/      — Planning artifacts (1 file, ~5K chars)
│   ├── verification/  — Verifier (1 file, ~3.5K chars)
│   └── visual/        — Visual verdict validation (2 files, ~3K chars)
│
├── Rust Layer (crates/)
│   ├── omx-explore-harness — Sandboxed exploration binary
│   ├── omx-mux             — tmux multiplexer abstractions
│   ├── omx-runtime-core    — Core runtime engine
│   ├── omx-runtime         — Runtime binary wrapper
│   └── omx-sparkshell      — Shell command runner with AI summary
│
├── prompts/   — 30+ agent prompt files
├── skills/    — 35+ skill definitions (SKILL.md)
├── missions/  — Experiment mission definitions
├── templates/ — AGENTS.md template, catalog-manifest.json
└── playground/ — Demo scripts
```

### 1.2 High-Level Architecture Diagram

```
┌─────────────────────────────────────────────────────────────────────┐
│                         User / CI / Script                          │
└────────────────────────────┬────────────────────────────────────────┘
                             │  omx <command>
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                       CLI Layer  (src/cli/)                         │
│   team | run | skill | plan | research | history | config | ...     │
└───────────┬─────────────────────────────────────────────────────────┘
            │
     ┌──────┴──────────────────────────────────┐
     │                                         │
     ▼                                         ▼
┌─────────────────┐                 ┌────────────────────────┐
│  Pipeline       │                 │  Direct Skill / Mode   │
│  (RALPLAN →     │                 │  Execution             │
│   Team Exec →   │                 └────────────────────────┘
│   Ralph Verify) │
└────────┬────────┘
         │
         ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   Team Orchestration  (src/team/)                   │
│                                                                     │
│  ┌──────────┐  ┌──────────────┐  ┌──────────┐  ┌───────────────┐  │
│  │  Leader  │  │  Workers     │  │  Mailbox │  │ Phase Control │  │
│  │  (tmux)  │◄─┤  (tmux panes)│  │  (MCP)  │  │  (lifecycle)  │  │
│  └──────────┘  └──────────────┘  └──────────┘  └───────────────┘  │
└───────────┬──────────────────────┬──────────────────────────────────┘
            │                      │
            ▼                      ▼
┌────────────────────┐  ┌──────────────────────────────────────────┐
│  Rust Runtime      │  │  MCP Servers (stdio processes)           │
│  (omx-runtime)     │  │  state | memory | code_intel | trace     │
│  omx-runtime-core  │  │  | wiki                                  │
│  omx-mux           │  └──────────────────────────────────────────┘
│  omx-sparkshell    │
│  omx-explore-      │
│  harness           │
└────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    Codex CLI  (external)                            │
│               hooks: SessionStart, PreToolUse, PostToolUse,         │
│                      UserPromptSubmit, Stop                         │
└─────────────────────────────────────────────────────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                Notifications  (src/notifications/)                  │
│          Discord webhook/bot | Telegram | Slack                     │
└─────────────────────────────────────────────────────────────────────┘
```

### 1.3 Technology Stack

| Layer | Technology | Version / Notes |
|---|---|---|
| CLI runtime | Node.js | >= 20 required |
| Language (TS) | TypeScript | Compiled to JS |
| Language (native) | Rust | Edition 2021 |
| Agent protocol | OpenAI Codex CLI | External dependency |
| Terminal multiplexer | tmux | Required for team mode |
| MCP protocol | Model Context Protocol | stdio transport |
| Distribution | cargo-dist | Cross-platform native binaries |
| Test runner | Node.js `--test` | Built-in test runner |
| Coverage | c8 | V8 coverage |
| Cargo tests | cargo test | Per-crate + compat tests |

### 1.4 Key Design Decisions

**File-based state machine.** All mode state lives in `.omx/state/` as JSON files. No database, no message broker. This makes state inspectable with any text tool and resilient to process crashes — the last-written file wins.

**Atomic tmux pane operations.** The Rust `omx-mux` crate wraps tmux pane I/O through capture, input injection, and delivery confirmation primitives. Injection is confirmed before the caller proceeds, preventing race conditions in multi-pane environments.

**Authority lease system.** `omx-runtime-core`'s `AuthorityLease` model ensures only one runtime process holds authority over a session at a time. Replays reconstruct state from a `DispatchLog` on restart, making the runtime crash-safe.

**Dual-model architecture.** SparkShell selects between a "spark" (lighter, faster) model and a "frontier" (more capable) model based on output line count. This caps cost for routine shell summaries while preserving quality for large outputs.

**POSIX-only explore harness.** `omx-explore-harness` runs only on POSIX systems. The sandboxed PATH allowlist ensures the Codex subprocess cannot access host tools outside the approved set.

---

## 2. System Requirements

### 2.1 Runtime Prerequisites

| Requirement | Minimum | Notes |
|---|---|---|
| Node.js | 20.0.0 | LTS or current; ESM support required |
| tmux | Any recent | Required for `team` mode; must be in PATH |
| OpenAI Codex CLI | Latest | Installed separately; `codex` must be in PATH |
| Git | 2.x+ | Used for worktree management and branch operations |
| Rust toolchain | 1.70+ (approx.) | Only needed for building from source |
| OS | Linux / macOS | POSIX required for `omx-explore-harness`; Windows supported for other features via `x86_64-pc-windows-msvc` binary |

### 2.2 Optional Prerequisites

| Dependency | Purpose | Required When |
|---|---|---|
| Discord bot token / webhook | Discord notifications | `OMX_DISCORD_*` configured |
| Telegram bot | Telegram notifications | `OMX_TELEGRAM_*` configured |
| Slack webhook | Slack notifications | `OMX_SLACK_WEBHOOK_URL` configured |
| OpenClaw server | External tool adapter | `OMX_OPENCLAW=true` |

### 2.3 Supported Platforms (cargo-dist targets)

| Target | Platform |
|---|---|
| `aarch64-apple-darwin` | macOS ARM (M-series) |
| `x86_64-apple-darwin` | macOS Intel |
| `aarch64-unknown-linux-gnu` | Linux ARM64 (glibc) |
| `aarch64-unknown-linux-musl` | Linux ARM64 (musl/static) |
| `x86_64-unknown-linux-gnu` | Linux x86_64 (glibc) |
| `x86_64-unknown-linux-musl` | Linux x86_64 (musl/static) |
| `x86_64-pc-windows-msvc` | Windows x86_64 |

> [!IMPORTANT]
> `omx-explore-harness` is **POSIX-only** and will not build or run on Windows. All other crates support the full target matrix above.

### 2.4 Network Requirements

- Outbound HTTPS to OpenAI API endpoints (via Codex CLI)
- Outbound HTTPS to Discord/Telegram/Slack APIs (if notifications enabled)
- No inbound port requirements — OMX is a CLI tool, not a server

---

## 3. Configuration Reference

### 3.1 Environment Variables — Complete Reference

All environment variables are sourced from `config_keys.tsv`. They are grouped by subsystem below.

#### 3.1.1 Team & Session Variables

| Variable | Purpose | Default |
|---|---|---|
| `OMX_TEAM_STATE_ROOT` | Override team state directory path | `.omx/state/` |
| `OMX_JOBS_DIR` | Jobs directory path | (derived from state root) |
| `OMX_TEAM_WORKER_CLI_MAP` | JSON mapping of worker names to CLI commands | — |
| `OMX_JOB_ID` | Current job identifier (injected by leader into worker env) | — |
| `OMX_TEAM_WORKER` | Current worker identifier (injected by leader) | — |
| `OMX_TEAM_WORKER_LAUNCH_ARGS` | Additional CLI arguments appended to worker launch command | — |
| `OMX_TEAM_MOUSE` | Enable mouse support in team tmux session | — |
| `OMX_TEAM_AUTO_ACCEPT_BYPASS` | Auto-accept bypass for worker prompts (dangerous — see §7) | — |
| `OMX_TEAM_SEND_STRATEGY` | Message delivery strategy for workers | — |
| `OMX_TEAM_AUTO_TRUST` | Auto-trust worker agents without confirmation | — |
| `OMX_TEAM_STRICT_SUBMIT` | Require strict submit validation before task acceptance | — |
| `OMX_RUNTIME_CLI_DISABLE_AUTO_START` | Disable automatic runtime CLI startup | — |
| `CODEX_HOME` | Codex home directory (read by both OMX and Codex) | `~/.codex` |
| `OMX_SESSION_ID` | Session identifier (checked first) | — |
| `CODEX_SESSION_ID` | Session identifier (checked second) | — |
| `SESSION_ID` | Session identifier (checked third) | — |
| `TMUX_PANE` | Current tmux pane ID (set by tmux) | — |
| `SHELL` | Default shell for command execution | System default |
| `WSL_DISTRO_NAME` | WSL distro name (used for WSL detection) | — |
| `WSL_INTEROP` | WSL interop socket path (used for WSL detection) | — |

#### 3.1.2 Notification Variables

| Variable | Purpose |
|---|---|
| `OMX_DISCORD_WEBHOOK_URL` | Discord incoming webhook URL |
| `OMX_DISCORD_NOTIFIER_BOT_TOKEN` | Discord bot token (for bot-based notifications) |
| `OMX_DISCORD_NOTIFIER_CHANNEL` | Discord channel ID (used with bot token) |
| `OMX_DISCORD_MENTION` | Discord mention string: `<@!USER_ID>` or `<@&ROLE_ID>` |
| `OMX_TELEGRAM_BOT_TOKEN` | Telegram bot token (primary key) |
| `OMX_TELEGRAM_NOTIFIER_BOT_TOKEN` | Telegram bot token (alternate key) |
| `OMX_TELEGRAM_CHAT_ID` | Telegram chat ID (primary key) |
| `OMX_TELEGRAM_NOTIFIER_CHAT_ID` | Telegram chat ID (alternate key) |
| `OMX_TELEGRAM_NOTIFIER_UID` | Telegram user ID (alternate key) |
| `OMX_SLACK_WEBHOOK_URL` | Slack incoming webhook URL |
| `OMX_SLACK_MENTION` | Slack mention: `<@USERID>`, `<!channel>`, `<!here>` |
| `OMX_NOTIFY_PROFILE` | Active notification profile name |
| `OMX_NOTIFY_VERBOSITY` | Notification verbosity level |
| `OMX_DISPATCH_COOLDOWN_SECONDS` | Minimum seconds between dispatched notifications |
| `OMX_IDLE_COOLDOWN_SECONDS` | Idle notification cooldown seconds |
| `OMX_HOOK_CONFIG` | Hook configuration path or JSON |
| `OMX_REPLY_ENABLED` | Enable reply listener (accepts commands via notification platform) |
| `OMX_REPLY_DISCORD_USER_IDS` | Comma-separated Discord user IDs allowed to send replies |
| `OMX_REPLY_POLL_INTERVAL_MS` | Polling interval (ms) for the reply listener |
| `OMX_REPLY_RATE_LIMIT` | Max replies per interval before throttling |
| `OMX_REPLY_INCLUDE_PREFIX` | Prefix required in reply messages |
| `OMX_NOTIFY_FALLBACK_MAX_LIFETIME_MS` | Max lifetime (ms) of the fallback notification watcher |

#### 3.1.3 OpenClaw Variables

| Variable | Purpose |
|---|---|
| `OMX_OPENCLAW` | Set to `true` to enable OpenClaw integration |
| `OMX_OPENCLAW_CONFIG` | Path to OpenClaw config file (overrides auto-discovery) |
| `OMX_OPENCLAW_COMMAND` | OpenClaw command gateway executable |
| `OMX_OPENCLAW_COMMAND_TIMEOUT_MS` | Timeout (ms) for command gateway calls |
| `OMX_OPENCLAW_DEBUG` | Enable OpenClaw debug logging |
| `OPENCLAW_REPLY_CHANNEL` | Reply routing: channel name |
| `OPENCLAW_REPLY_TARGET` | Reply routing: target identifier |
| `OPENCLAW_REPLY_THREAD` | Reply routing: thread identifier |

#### 3.1.4 SparkShell & Explore Variables

| Variable | Purpose |
|---|---|
| `OMX_SPARKSHELL_MODEL` | Override SparkShell model |
| `OMX_DEFAULT_SPARK_MODEL` | Default spark (lightweight) model |
| `OMX_SPARK_MODEL` | Spark model selection |
| `OMX_SPARKSHELL_FALLBACK_MODEL` | Fallback if primary model fails |
| `OMX_DEFAULT_FRONTIER_MODEL` | Default frontier (powerful) model |
| `OMX_SPARKSHELL_SUMMARY_TIMEOUT_MS` | Timeout (ms) for AI summary generation |
| `OMX_SPARKSHELL_LINES` | Line count threshold: outputs above this get frontier model |
| `ComSpec` | Windows command spec (used on Windows platforms) |

#### 3.1.5 MCP Server Variables

| Variable | Purpose |
|---|---|
| `OMX_MCP_SERVER_DISABLE_AUTO_START` | Disable all MCP server auto-start globally |
| `OMX_STATE_SERVER_DISABLE_AUTO_START` | Disable state MCP server only |
| `OMX_MEMORY_SERVER_DISABLE_AUTO_START` | Disable memory MCP server only |
| `OMX_CODE_INTEL_SERVER_DISABLE_AUTO_START` | Disable code_intel MCP server only |
| `OMX_TRACE_SERVER_DISABLE_AUTO_START` | Disable trace MCP server only |
| `OMX_WIKI_SERVER_DISABLE_AUTO_START` | Disable wiki MCP server only |
| `OMX_MCP_TRANSPORT_DEBUG` | Enable MCP transport debug logging to stderr |

#### 3.1.6 Runtime & Miscellaneous Variables

| Variable | Purpose |
|---|---|
| `OMX_AUTO_UPDATE` | Auto-update behavior on startup |
| `OMX_MOUSE` | Enable mouse support globally |
| `OMX_HOOK_DERIVED_SIGNALS` | Hook derived signals configuration |
| `OMX_RUNTIME_BRIDGE` | Override path to the runtime bridge binary |
| `OMX_RUNTIME_BINARY` | Override path to the runtime binary |
| `OMX_TMUX_PID_FALLBACK` | Fallback PID for tmux attachment |

### 3.2 Configuration Files

#### 3.2.1 `AGENTS.md` (per-project)

OMX reads and writes `AGENTS.md` at project root. This file defines agent roles, capabilities, and inter-agent communication protocols. A template lives at `templates/AGENTS.md`.

> [!WARNING]
> GitHub issue #1671 documents a bug where `omx update` may overwrite a project's existing `AGENTS.md`. Until fixed, back up `AGENTS.md` before running update commands.

#### 3.2.2 Catalog Manifest (`templates/catalog-manifest.json`)

Defines the registry of available skills and agents. The `src/catalog/` module reads this manifest and validates entries against a JSON schema. Keys include skill names, entry points, and metadata.

#### 3.2.3 Codex Hooks Config

Generated by `src/config/` (the hooks config generator). Produces a JSON/TOML config consumed by Codex CLI specifying which OMX hook handlers fire on which Codex events.

#### 3.2.4 OpenClaw Config

Path set via `OMX_OPENCLAW_CONFIG` or auto-discovered. Contains gateway type (HTTP or command), endpoint, timeout, and reply routing parameters.

### 3.3 State Directory Layout

```
.omx/
└── state/
    ├── mode/          — Active mode state files (JSON)
    ├── session/       — Per-session state files
    ├── jobs/          — Job definitions and status
    ├── ralph/         — Verification phase state
    ├── subagents/     — Subagent tracker state
    └── dispatch/      — Dispatch notification log
```

All state files are JSON. Write operations are atomic (write temp → rename).

### 3.4 Skill Definitions (`skills/`)

Each skill is defined by a `SKILL.md` file. The catalog loader reads these files and registers skills into the catalog. Skills define:

- Name and description
- Required inputs / parameters
- Execution entry point
- Agent role affinity

Skills are namespaced under `omx:` prefix (see known issue #1648 — built-in skills not yet fully namespaced; in-progress).

### 3.5 Agent Prompts (`prompts/`)

30+ agent prompt files define role-specific system prompts. Covered roles include (non-exhaustive):

- `analyst.md`, `architect.md`, `debugger.md`, `executor.md`
- `planner.md`, `verifier.md`, `reviewer.md`, `researcher.md`
- Domain-specific roles added as the catalog grows

Prompts are loaded by the agent bootstrap process and injected as system context.

---

## 4. Deployment & Scaling

### 4.1 Installation (End-User)

```bash
# Via npm (TypeScript layer)
npm install -g oh-my-codex

# Verify
omx --version
```

Native Rust binaries are bundled with the npm package via cargo-dist. They are extracted to a platform-appropriate location on first run if not already present.

### 4.2 Building from Source

#### TypeScript Layer

```bash
git clone https://github.com/Yeachan-Heo/oh-my-codex.git
cd oh-my-codex
npm install
npm run build
```

#### Rust Crates

```bash
# Build all crates
cargo build --release

# Build a specific crate
cargo build -p omx-runtime --release
cargo build -p omx-mux --release
cargo build -p omx-sparkshell --release
cargo build -p omx-explore-harness --release   # POSIX only
```

> [!NOTE]
> `omx-explore-harness` will fail to compile on Windows (`x86_64-pc-windows-msvc`). Exclude it from Windows builds: `cargo build --release --exclude omx-explore-harness`

#### Running Tests

```bash
# TypeScript tests
node --test

# With coverage
npx c8 node --test

# Rust tests (all crates)
cargo test

# TypeScript <-> Rust compat tests
cargo test -p omx-runtime   # includes compat suite
```

**Coverage thresholds (team critical paths):**

| Metric | Threshold |
|---|---|
| Lines | 78% |
| Functions | 90% |
| Branches | 70% |
| Statements | 78% |

### 4.3 Release Process (cargo-dist)

OMX uses [cargo-dist](https://github.com/axodotdev/cargo-dist) for cross-platform binary distribution. The dist configuration lives in `Cargo.toml` or `dist.toml`.

```bash
# Dry-run release plan
cargo dist plan

# Build release artifacts locally
cargo dist build

# Trigger CI release (tag-based)
git tag v0.13.1
git push origin v0.13.1
```

CI produces native binaries for all 7 targets and publishes them as GitHub Release assets. The npm package downloads the appropriate binary for the host platform on install.

### 4.4 Scaling the Team

OMX team mode scales by adjusting the number of worker panes. Workers are tmux panes, not OS processes in the traditional sense — each is a Codex CLI session managed by OMX.

**Scale up:** Leader spawns additional worker panes via `src/team/` scaling logic, assigns new worktrees via Git, and bootstraps new worker sessions.

**Scale down:** Leader sends graceful shutdown signal; workers finish current tasks, release worktrees, and exit. Leader kills panes.

**Worktree isolation:** Each worker operates in a dedicated Git worktree, providing filesystem isolation. Tasks are allocated with path-overlap scoring to minimize merge conflicts.

> [!TIP]
> For CPU-bound analysis tasks, scale up workers. For I/O-bound tasks (API calls, file reads), 3-5 workers is typically optimal. Watch tmux pane activity; idle panes waste Codex API quota.

### 4.5 Deployment Topology

OMX has no server component. Deployment means installing the package on any machine where users run Codex CLI. For CI/CD use:

```yaml
# Example GitHub Actions
- name: Install oh-my-codex
  run: npm install -g oh-my-codex

- name: Run OMX pipeline
  run: omx run --skill my-skill
  env:
    OMX_DISCORD_WEBHOOK_URL: ${{ secrets.OMX_DISCORD_WEBHOOK_URL }}
```

---

## 5. Operations

### 5.1 State Inspection

Because state is file-based, any standard UNIX tool works:

```bash
# View current mode
cat .omx/state/mode/*.json | jq .

# View job queue
ls -la .omx/state/jobs/

# View dispatch log
cat .omx/state/dispatch/*.json | jq .

# Watch for state changes
watch -n1 'cat .omx/state/mode/*.json | jq .'
```

### 5.2 MCP Server Management

MCP servers are stdio processes started automatically by OMX. Each has a parent watchdog that polls every 25ms; if the parent process disappears, the server exits within one watchdog cycle.

**Disable specific servers** (useful for debugging or resource constraints):

```bash
export OMX_STATE_SERVER_DISABLE_AUTO_START=1
export OMX_MEMORY_SERVER_DISABLE_AUTO_START=1
# ... etc
```

**Disable all servers:**

```bash
export OMX_MCP_SERVER_DISABLE_AUTO_START=1
```

**Debug MCP transport:**

```bash
export OMX_MCP_TRANSPORT_DEBUG=1
omx team start
# Transport frames logged to stderr
```

> [!CAUTION]
> GitHub issue #1665 documents that MCP duplicate sibling processes can accumulate if parent detection fails. Monitor process counts with `ps aux | grep omx-mcp` and kill stray processes if needed. The 5-second sibling detection window reduces but does not eliminate this risk.

### 5.3 Team Session Management

```bash
# Start a new team session
omx team start --workers 3

# Attach to existing session
omx team attach

# List active team sessions
tmux list-sessions | grep omx

# Kill a team session
omx team stop
# Or directly: tmux kill-session -t omx-SESSIONNAME
```

> [!WARNING]
> GitHub issue #1642 documents that detached leader cleanup may skip `tmux kill-session`, leaving orphan sessions. Run `tmux list-sessions` periodically and kill stale sessions manually: `tmux kill-session -t <session-name>`

### 5.4 Job Queue Operations

```bash
# List pending jobs
ls .omx/state/jobs/

# Inspect a job
cat .omx/state/jobs/<job-id>.json | jq .

# Cancel a stuck job (delete the file — terminal state on next poll)
rm .omx/state/jobs/<job-id>.json
```

### 5.5 Session History

```bash
# Search session history
omx history search "query string"

# Uses fuzzy matching — partial matches are ranked by relevance
omx history search "fix auth bug"
```

The session history module (`src/session-history/`) indexes past sessions and supports fuzzy-match retrieval. History files are stored per-session in `.omx/state/session/`.

### 5.6 HUD (Heads-Up Display)

The HUD renders live team state in the tmux leader pane:

- Authority status (who holds the lease)
- Worker pane assignments and current task
- Phase progress (planning → executing → verifying → complete)
- Pending notifications

HUD state is reconciled from `.omx/state/` on each render cycle. If the HUD freezes, inspect the state directory for inconsistencies.

> [!NOTE]
> GitHub issue #1635 documents the leader UI getting stuck on MCP startup. If the HUD does not render after ~10 seconds, check MCP server stderr for startup errors and restart with `omx team stop && omx team start`.

### 5.7 Monitoring Checklist

| Check | Command / Method |
|---|---|
| Active MCP servers | `ps aux \| grep omx-mcp` |
| Stale tmux sessions | `tmux list-sessions` |
| State directory sanity | `ls -la .omx/state/` |
| Ralph lock health | `cat .omx/state/ralph/*.json \| jq .phase` |
| Dispatch cooldown | `cat .omx/state/dispatch/*.json \| jq .lastSent` |
| Worker liveness | `tmux list-panes -t <session>` |

---

## 6. Performance

### 6.1 SparkShell Model Selection

`omx-sparkshell` implements a dual-model strategy for AI-assisted shell command summarization:

```
output_lines < OMX_SPARKSHELL_LINES  → use spark model (OMX_SPARK_MODEL)
output_lines >= OMX_SPARKSHELL_LINES → use frontier model (OMX_DEFAULT_FRONTIER_MODEL)
```

**Tuning recommendations:**

| Scenario | Recommended Setting |
|---|---|
| Mostly short outputs (build logs) | Lower `OMX_SPARKSHELL_LINES` (e.g., 50) |
| Mostly long outputs (test suites) | Raise `OMX_SPARKSHELL_LINES` (e.g., 500) |
| Cost-sensitive environment | Set `OMX_SPARKSHELL_MODEL` to a cheap model |
| Accuracy-critical environment | Set `OMX_DEFAULT_FRONTIER_MODEL` to best available |

SparkShell is language-aware: it constructs prompts adapted to the programming language of the output context, improving summary quality without extra tokens.

### 6.2 MCP Server Lifecycle

Each MCP server is started as a stdio child process. The 25ms parent watchdog adds negligible overhead but ensures servers die with the parent.

**Startup latency:** Allow ~2-5 seconds for all 5 MCP servers to initialize and register with the parent. The leader HUD will show "MCP starting" during this window.

**Memory footprint:** Each MCP server is a lightweight Node.js process. Typical RAM per server: 30-60 MB. Total for 5 servers: ~200 MB baseline.

### 6.3 Team Worker Allocation Scoring

Task allocation uses a multi-factor scoring algorithm:

1. **Role match** — Worker's assigned role vs. task's required role
2. **Domain hints** — Keywords in task description vs. worker specialization
3. **Path overlap** — Files in task scope vs. worker's current worktree
4. **Load balancing** — Prefer workers with fewer in-flight tasks

Workers with the highest combined score receive the task. This is computed in `src/team/` allocation logic at dispatch time.

### 6.4 Dispatch Cooldown

Notifications have two cooldown levels:

- `OMX_DISPATCH_COOLDOWN_SECONDS` — Global cooldown between any dispatched notifications
- `OMX_IDLE_COOLDOWN_SECONDS` — Cooldown specifically for idle-state notifications

Set these to avoid flooding notification channels during rapid task cycling.

### 6.5 Runtime Core Performance

`omx-runtime-core` uses an event-log architecture (`DispatchLog`) that enables O(1) appends and O(n) replay on restart. For long-lived sessions with thousands of events, consider periodic log rotation (no built-in mechanism; delete `.omx/state/dispatch/` to reset).

The `MailboxLog` similarly grows unbounded over a session. For sessions running >24 hours, monitor mailbox file sizes.

---

## 7. Security

> [!CAUTION]
> Several known security issues exist in v0.13.1. Review all items in this section before deploying OMX in shared or production environments.

### 7.1 Shell Injection Risks

**Issue #1640 — `buildWorkerStartupCommand` shell injection.**

Worker launch arguments (`OMX_TEAM_WORKER_LAUNCH_ARGS`) are interpolated into shell command strings. If this variable contains untrusted input, it can inject arbitrary shell commands.

**Mitigation:** Never set `OMX_TEAM_WORKER_LAUNCH_ARGS` from untrusted sources. Validate all values in CI pipelines before passing to OMX.

**Issue #1659 — `hud/state.ts` git injection via `remoteName`.**

The HUD reads the git remote name and uses it in git command construction without sanitization. A malicious `remoteName` (e.g., in `.git/config`) could inject arbitrary git flags.

**Mitigation:** Ensure `.git/config` is from a trusted source. Avoid running OMX against repositories with untrusted git configurations.

### 7.2 Path Traversal

**Issue #1649 — Path traversal via unvalidated identifiers.**

Skill names, job IDs, and other identifier fields used in file path construction are not validated for `../` sequences. A crafted identifier could traverse outside `.omx/state/`.

**Mitigation:** Until patched, enforce identifier validation at the call site (alphanumeric + hyphens only). Do not allow user-supplied identifiers to flow into OMX without sanitization.

### 7.3 Sensitive Data in Notifications

**Issue #1661 — Reply listener leaks sensitive data.**

The reply listener (`OMX_REPLY_ENABLED`) may include sensitive content (environment variables, file contents) in notification messages sent to Discord/Telegram/Slack.

**Mitigation:** Disable the reply listener unless required (`OMX_REPLY_ENABLED` unset or `false`). If enabled, restrict `OMX_REPLY_DISCORD_USER_IDS` to trusted operator IDs only. Use private channels for OMX notifications.

### 7.4 Auto-Accept Bypass

`OMX_TEAM_AUTO_ACCEPT_BYPASS` causes workers to skip confirmation prompts. This is intended for unattended CI runs but eliminates a human-in-the-loop safety check.

> [!WARNING]
> Do not set `OMX_TEAM_AUTO_ACCEPT_BYPASS=true` in environments where workers have write access to production systems or sensitive credentials.

### 7.5 Explore Harness Sandbox

`omx-explore-harness` restricts the Codex subprocess's PATH to an allowlist. The sandboxed binary runs on POSIX only and provides filesystem-level isolation for exploration tasks.

The allowlist is hardcoded in the harness source. Verify its contents match your security policy before deploying explore mode.

### 7.6 Dependency Vulnerabilities

**Issue #1660 — Transitive dependency vulnerabilities.**

Run `npm audit` and `cargo audit` periodically:

```bash
npm audit
npm audit fix    # for auto-fixable issues

cargo install cargo-audit
cargo audit
```

### 7.7 Signal Handling

**Issue #1657 — SIGTERM without PID verification.**

OMX sends SIGTERM to process groups without verifying PID before signal delivery. In unusual process tree configurations this could terminate unintended processes.

**Mitigation:** Run OMX in isolated process namespaces (e.g., Docker, systemd unit with `PrivateTmp=yes`) when operating near sensitive process groups.

### 7.8 Stale Lock Recovery

**Issue #1655 — `withTmuxExtendedKeysLeaseLock` has no stale-lock recovery.**

If a tmux extended keys lease is not released (e.g., process crash), subsequent operations that require this lock will hang indefinitely.

**Mitigation:** If OMX hangs on tmux operations, inspect `.omx/state/` for stale lock files and remove them manually.

### 7.9 Authority Lease Security Model

The `AuthorityLease` in `omx-runtime-core` is a cooperative lock — it relies on all participants honoring the lease protocol. There is no kernel-level enforcement. In adversarial multi-user environments, a rogue process could bypass the lease.

---

## 8. Developer Internals

### 8.1 Repository Structure

```
oh-my-codex/
├── src/                    TypeScript source
│   ├── cli/                CLI entry + subcommand handlers
│   ├── team/               Team orchestration
│   ├── notifications/      Notification subsystem
│   ├── mcp/                MCP servers
│   ├── hooks/              Codex hook handlers
│   │   ├── extensibility/  Plugin system
│   │   └── code-simplifier/
│   ├── hud/                Heads-up display
│   ├── autoresearch/       Experiment automation
│   ├── config/             Config generators
│   ├── adapt/              External tool adapters
│   ├── state/              Mode state management
│   ├── openclaw/           OpenClaw integration
│   ├── utils/              Shared utilities
│   ├── agents/             Agent definitions
│   ├── catalog/            Skill/agent catalog
│   ├── pipeline/           Pipeline orchestrator
│   ├── ralph/              Verification loop
│   ├── session-history/    Session history
│   ├── runtime/            Rust runtime bridge
│   ├── modes/              Mode base class
│   ├── ralplan/            RALPLAN mode
│   ├── subagents/          Subagent tracker
│   ├── planning/           Planning artifacts
│   ├── verification/       Verifier
│   └── visual/             Visual verdict validation
│
├── crates/                 Rust crates
│   ├── omx-explore-harness/
│   ├── omx-mux/
│   ├── omx-runtime-core/
│   ├── omx-runtime/
│   └── omx-sparkshell/
│
├── prompts/                Agent role prompts (30+)
├── skills/                 Skill definitions (35+ SKILL.md)
├── missions/               Experiment missions
├── templates/              AGENTS.md template, catalog manifest
├── playground/             Demo/benchmark scripts
├── package.json
├── tsconfig.json
└── Cargo.toml              Workspace manifest
```

### 8.2 TypeScript Module Reference

#### `src/cli/` — CLI Entry Point (28 files, ~490K chars)

The CLI uses a command-router pattern. `omx` dispatches to subcommand handlers based on `argv[2]`. Each subcommand file exports a `run(args)` function.

Key subcommands (inferred from architecture):
- `team` — Team orchestration (start, stop, attach, scale)
- `run` — Single-shot skill or pipeline execution
- `skill` — Skill management (list, run, validate)
- `plan` — RALPLAN planning mode
- `research` — Autoresearch experiment loop
- `history` — Session history search
- `config` — Config generation (hooks, TOML, MCP registry)
- `hud` — HUD control

CLI argument parsing is handled inline (no heavy framework dependency). Flag values map directly to the environment variables documented in §3.1.

#### `src/team/` — Team Orchestration (27 files, ~600K chars)

The largest TypeScript module. Key responsibilities:

**Allocation (`allocation.ts`)** — Scores worker-task assignments using role match, domain hints, path overlap, and load factors. Returns ranked worker list.

**Worktrees (`worktrees.ts`)** — Creates and destroys Git worktrees for worker isolation. Each worker gets its own branch checkout.

**tmux Sessions (`tmux-sessions.ts`)** — Creates the tmux session with leader pane + N worker panes. Handles pane layout, window naming, and mouse support.

**Worker Bootstrap (`worker-bootstrap.ts`)** — Injects environment variables, AGENTS.md context, and initial task into each worker pane via `omx-mux`.

**Scaling (`scaling.ts`)** — Adds or removes worker panes at runtime without tearing down the session.

**Phases (`phases.ts`)** — State machine for team lifecycle: `planning → executing → verifying → complete`. Phase transitions write to `.omx/state/mode/`.

**Delivery (`delivery.ts`)** — Tracks task delivery confirmation per worker. Uses `omx-mux` delivery confirmation to ensure injection was received.

**Runtime (`runtime.ts`)** — Bridge between TypeScript team logic and the Rust runtime binary.

**Mailbox** — Workers communicate via MCP-based mailbox. Messages are persisted to the dispatch log in `omx-runtime-core`.

#### `src/notifications/` — Notification System (18 files, ~180K chars)

**Platforms:**
- `discord-webhook.ts` — Sends via incoming webhook (simplest, no bot required)
- `discord-bot.ts` — Full Discord bot with channel targeting and mention support
- `telegram.ts` — Telegram Bot API
- `slack.ts` — Slack incoming webhook

**Profiles (`profiles.ts`)** — Named notification profiles (e.g., "ci", "quiet", "verbose") that bundle platform config, verbosity, and cooldown settings. Selected via `OMX_NOTIFY_PROFILE`.

**Cooldowns (`cooldowns.ts`)** — Enforces `OMX_DISPATCH_COOLDOWN_SECONDS` and `OMX_IDLE_COOLDOWN_SECONDS`. State persisted to `.omx/state/dispatch/`.

**Formatters** — Platform-specific message formatters. Discord uses markdown embeds; Telegram uses HTML; Slack uses Block Kit.

**Reply Listener** — Polls notification platform for incoming messages that match the reply prefix. Allowed senders restricted by `OMX_REPLY_DISCORD_USER_IDS`. See §7.3 for security considerations.

#### `src/mcp/` — MCP Servers (8 files, ~97K chars)

All 5 servers share a common bootstrap pattern:

```typescript
// Pseudo-code — actual implementation in src/mcp/
const server = new MCPServer({
  parentWatchdog: { intervalMs: 25 },
  siblingDetection: { timeoutMs: 5000 },
  disableEnvVar: 'OMX_<NAME>_SERVER_DISABLE_AUTO_START',
});
server.start();
```

**state server** — Exposes MCP tools to read/write `.omx/state/` JSON files. Used by all team components for shared state.

**memory server** — Persistent key-value memory across sessions. Backed by a JSON file in `.omx/state/`.

**code_intel server** — Code intelligence queries: symbol lookup, dependency graph, file search. Backed by tree-sitter or similar parser.

**trace server** — Execution tracing: records tool calls, timing, and results for replay and debugging.

**wiki server** — Project wiki with ingest (write), query (read), lint (validate), and storage with CJK support. Known issue: #1641 — `titleToSlug` strips non-ASCII characters, producing hash-based filenames for CJK titles instead of readable slugs.

#### `src/hooks/` — Codex Hook Integration (8 files, ~95K chars)

Hooks fire on Codex lifecycle events:

| Event | OMX Handler |
|---|---|
| `SessionStart` | Initialize MCP servers, load agent overlay, build codebase map |
| `PreToolUse` | Route explore requests, detect keywords, inject prompt guidance |
| `PostToolUse` | Update state, trigger notifications |
| `UserPromptSubmit` | Detect task size, adjust agent strategy |
| `Stop` | Cleanup, persist session state, send completion notification |

**Agents overlay (`agents-overlay.ts`)** — Injects agent role context into Codex's system prompt at session start.

**Codebase map (`codebase-map.ts`)** — Builds a structural map of the codebase (directories, key files) for hook context.

**Explore routing (`explore-routing.ts`)** — Decides whether to route a tool call through `omx-explore-harness` (sandboxed) or allow it to run normally.

**Keyword detection (`keyword-detection.ts`)** — Scans prompts for configured keywords and triggers associated actions or notifications.

**Task-size detection (`task-size-detection.ts`)** — Classifies incoming tasks as small/medium/large and adjusts parallelism and strategy accordingly.

#### `src/hooks/extensibility/` — Plugin System (9 files, ~27K chars)

Plugin architecture for extending the hook system without modifying core:

**Dispatcher (`dispatcher.ts`)** — Routes hook events to registered plugins in priority order.

**Events (`events.ts`)** — Typed event definitions for all hook lifecycle points.

**Loader (`loader.ts`)** — Discovers and loads plugin modules from configured directories.

**Plugin Runner (`plugin-runner.ts`)** — Executes plugin handlers with timeout and error isolation.

**SDK (`sdk.ts`)** — Public API for plugin authors. Exposes event subscription, state access, and notification dispatch.

To create a plugin: implement the SDK interface, export a `plugin` object, and place the module where the loader can discover it.

#### `src/hud/` — Heads-Up Display (9 files, ~52K chars)

**Authority (`authority.ts`)** — Reads `AuthorityLease` from the runtime to display who currently holds authority.

**Reconcile (`reconcile.ts`)** — Diffs current rendered state vs. live state and computes minimal update set.

**Render (`render.ts`)** — Builds the HUD layout: authority banner, worker grid, phase progress bar, notification queue.

**tmux integration (`tmux.ts`)** — Writes HUD output to the leader pane via `omx-mux` input injection.

**Colors (`colors.ts`)** — ANSI color constants and theme definitions.

HUD renders on a tick interval; the interval pauses when the leader pane is inactive.

#### `src/autoresearch/` — Automated Experiment Loops (2 files, ~53K chars)

**Mission contracts (`missions.ts`)** — Defines experiment missions as typed contracts: hypothesis, evaluation criteria, max iterations, success threshold.

**Sandbox parsing (`sandbox.ts`)** — Parses experiment output from sandboxed Codex runs and extracts structured results.

**Worktree management** — Each experiment run uses an isolated Git worktree to prevent cross-contamination.

**Evaluator scoring** — Scores experiment outcomes against mission criteria. Persists scores for trend analysis.

Available experiment missions (in `missions/`):
- `adaptive-sort` — Benchmark adaptive sorting algorithms
- `bayesopt` — Bayesian optimization experiments

#### `src/config/` — Config Generation (4 files, ~52K chars)

**Codex hooks config generator** — Produces the JSON/TOML config telling Codex which OMX hook handlers to call and when.

**TOML config generator** — Generates OMX's own TOML configuration file from environment variables and defaults.

**MCP registry** — Generates the MCP server registry config consumed by Codex at startup.

**Model defaults** — Defines default model selections for spark vs. frontier contexts.

#### `src/adapt/` — Adapter Framework (6 files, ~47K chars)

Abstracts external tool integrations (currently OpenClaw and Hermes):

**Contracts (`contracts.ts`)** — TypeScript interfaces for the adapter API: `probe()`, `status()`, `init()`, `envelope()`, `doctor()`.

**Probe** — Tests whether the external tool is available and responsive.

**Status** — Returns current tool status (healthy/degraded/unavailable).

**Init** — Initializes the tool integration (auth, config load).

**Envelope** — Wraps an outgoing message in the tool's required format.

**Doctor** — Runs diagnostics and returns actionable remediation steps.

#### `src/state/` — Mode State Management (6 files, ~41K chars)

**Operations (`operations.ts`)** — CRUD operations for state files: read, write, delete, list. All writes are atomic (temp file + rename).

**Paths (`paths.ts`)** — Canonical path resolver for all state locations. Single source of truth for `.omx/state/` structure.

**Skill-active (`skill-active.ts`)** — Tracks which skill is currently executing; prevents conflicting concurrent executions.

**Workflow transitions (`transitions.ts`)** — Validates state machine transitions. Illegal transitions (e.g., jumping from `planning` to `complete` without `executing`) are rejected.

**File-based locking** — Lock files in `.omx/state/` prevent concurrent writes. See §7.8 for stale-lock risk.

#### `src/pipeline/` — Pipeline Orchestrator (3 files, ~15K chars)

Three-stage pipeline:

```
RALPLAN → Team Execution → Ralph Verification
```

**Stage 1 — RALPLAN.** Planner agent produces a structured plan: tasks, assignments, acceptance criteria.

**Stage 2 — Team Execution.** Leader dispatches tasks to workers per plan. Workers execute in parallel worktrees.

**Stage 3 — Ralph Verification.** Ralph agent verifies outputs against acceptance criteria. Loops with fix attempts if criteria not met.

The pipeline writes stage outputs to `.omx/state/` for cross-stage continuity.

#### `src/ralph/` — Verification Loop (2 files, ~14K chars)

Ralph is the verification agent. Its phase contract:

```
starting → executing → verifying → fixing → complete
                                          ↘ failed
                                          ↘ cancelled
```

Ralph reads the acceptance criteria from the RALPLAN output, inspects worker outputs, and issues a `PASS` or `FAIL` verdict with structured feedback.

On `FAIL`, Ralph enters `fixing` phase: it synthesizes a remediation prompt and hands back to the execution layer for one more attempt. The cycle repeats up to a configured maximum.

> [!NOTE]
> GitHub issue #1653 documents `withRalphSteerLock` entering infinite retry if the lock is never acquired. Until fixed, set a maximum wall-clock timeout externally (e.g., `timeout 300 omx run ...`).

#### `src/openclaw/` — OpenClaw Integration (4 files, ~35K chars)

OpenClaw is an external automation gateway. OMX supports two gateway types:

**HTTP gateway** — POSTs structured requests to an HTTP endpoint. Configured via `OMX_OPENCLAW_COMMAND_TIMEOUT_MS`.

**Command gateway** — Executes a local command (`OMX_OPENCLAW_COMMAND`) with the request as stdin. Used for local OpenClaw installations.

**Hook event mapping (`event-mapping.ts`)** — Maps Codex hook events to OpenClaw event types.

**Dispatcher (`dispatcher.ts`)** — Routes events to the configured gateway; handles timeouts and retry.

#### `src/utils/` — Shared Utilities (9 files, ~33K chars)

| File | Purpose |
|---|---|
| `agents-md.ts` | Parse and manipulate AGENTS.md files |
| `model-tables.ts` | Model name to capability/cost tables |
| `git-layout.ts` | Git worktree and branch helpers |
| `paths.ts` | Cross-platform path resolution |
| `platform-commands.ts` | OS-specific command wrappers (Windows vs. POSIX) |
| `repo-deps.ts` | Repository dependency graph analysis |
| `safe-json.ts` | JSON parse/stringify with error containment |
| `sleep.ts` | Promise-based sleep with cancellation |
| `index.ts` | Re-exports |

### 8.3 Rust Crate Reference

#### `omx-runtime-core` — Core Runtime Engine

The foundational crate. All higher-level runtime logic depends on it.

**`AuthorityLease`** — Cooperative lock granting one process authority over a session. Backed by a lease file in `.omx/state/`. Lease is time-limited; holder must renew periodically.

**`RuntimeEngine`** — Main event loop. Accepts events, dispatches to handlers, writes to `DispatchLog`.

**`DispatchLog`** — Append-only event log. Enables crash recovery by replaying events on restart. Entries are newline-delimited JSON.

**`MailboxLog`** — Per-worker message inbox. Each worker has a dedicated log file. Leader writes; worker reads and acknowledges.

**`ReplayState`** — Reconstructs in-memory state from `DispatchLog` on startup.

**`RateLimiter`** — Token-bucket rate limiter used for notification dispatch throttling.

```
omx-runtime-core/
├── src/
│   ├── authority.rs      AuthorityLease
│   ├── dispatch_log.rs   DispatchLog
│   ├── engine.rs         RuntimeEngine
│   ├── mailbox.rs        MailboxLog
│   ├── rate_limit.rs     RateLimiter
│   ├── replay.rs         ReplayState
│   └── lib.rs
└── Cargo.toml
```

#### `omx-mux` — tmux Multiplexer Abstractions

**`TmuxAdapter`** — Primary interface. Wraps the `tmux` binary with typed methods:
- `capture_pane(pane_id)` returns `String` — Captures current pane content
- `send_keys(pane_id, keys)` — Injects keystrokes
- `confirm_delivery(pane_id, sentinel)` returns `bool` — Waits for sentinel string to appear in pane output

**`InputEnvelope`** — Typed wrapper for an input injection operation, including pane target, content, and delivery confirmation parameters.

**`CommandOutput`** — Structured output from tmux command execution: exit code, stdout, stderr.

Operation types: capture, send, confirm, resize, split, kill.

```
omx-mux/
├── src/
│   ├── adapter.rs        TmuxAdapter
│   ├── envelope.rs       InputEnvelope
│   ├── output.rs         CommandOutput
│   ├── operations.rs     Operation enum
│   └── lib.rs
└── Cargo.toml
```

#### `omx-runtime` — Runtime Binary Wrapper

Thin binary crate that wraps `omx-runtime-core` and `omx-mux` into a standalone executable. Started as a child process by `src/runtime/` (the TypeScript bridge). Communicates with the parent via stdin/stdout JSON protocol.

```
omx-runtime/
├── src/
│   └── main.rs
└── Cargo.toml    (depends on omx-mux, omx-runtime-core)
```

#### `omx-sparkshell` — Shell Command Execution with AI Summary

Standalone binary. Called by OMX hooks to run a shell command and produce an AI-generated summary of the output.

**Language-aware prompt construction** — Detects the language context from file extensions or explicit hint; selects appropriate prompt template (e.g., Rust compilation errors vs. Python test output).

**Line-count thresholding** — Checks output line count against `OMX_SPARKSHELL_LINES`. Selects spark vs. frontier model accordingly.

**Summary timeout** — Enforced by `OMX_SPARKSHELL_SUMMARY_TIMEOUT_MS`. If the AI call times out, raw output is returned unchanged.

```
omx-sparkshell/
├── src/
│   ├── main.rs
│   ├── prompt.rs     Language-aware prompt builder
│   ├── model.rs      Model selection logic
│   └── summarize.rs  AI call + timeout handling
└── Cargo.toml
```

#### `omx-explore-harness` — Sandboxed Exploration Binary

POSIX-only. Wraps Codex CLI with a restricted PATH allowlist, preventing the subprocess from accessing host tools not in the approved list.

The harness:
1. Parses the allowlist (hardcoded in source)
2. Constructs a sanitized `PATH` containing only allowed tool directories
3. `exec`s Codex with the sanitized environment

No network sandboxing is performed — only PATH restriction.

```
omx-explore-harness/
├── src/
│   ├── main.rs
│   └── allowlist.rs  PATH allowlist definition
└── Cargo.toml
```

### 8.4 Pipeline Architecture Deep Dive

```
User: omx run --skill my-analysis
         │
         ▼
┌─────────────────────────────────────────────────────────────┐
│  Stage 1: RALPLAN                                           │
│  src/ralplan/ + src/planning/                               │
│                                                             │
│  Planner agent reads task description + codebase map        │
│  Produces structured plan JSON:                             │
│    { tasks: [...], assignments: [...], criteria: [...] }    │
│  Written to .omx/state/mode/ralplan.json                    │
└────────────────────────────┬────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────┐
│  Stage 2: Team Execution                                    │
│  src/team/ + omx-runtime + omx-mux                         │
│                                                             │
│  Leader creates tmux session                                │
│  Leader spawns N worker panes                               │
│  Workers bootstrap with roles + task assignments            │
│  Workers execute in isolated Git worktrees                  │
│  Mailbox system routes inter-worker messages                │
│  Phase controller tracks progress                           │
│  Results written to .omx/state/jobs/<job-id>.json           │
└────────────────────────────┬────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────┐
│  Stage 3: Ralph Verification                                │
│  src/ralph/                                                 │
│                                                             │
│  Ralph reads criteria from RALPLAN output                   │
│  Inspects worker outputs                                    │
│  Issues PASS / FAIL verdict                                 │
│  On FAIL: synthesize fix prompt, back to Stage 2            │
│  On PASS: write final result, notify                        │
└─────────────────────────────────────────────────────────────┘
```

### 8.5 Code Patterns & Conventions

**State writes are always atomic.** Pattern throughout `src/state/`:

```typescript
// Write temp, then rename (never corrupt on crash)
await fs.writeFile(tmpPath, JSON.stringify(state), 'utf8');
await fs.rename(tmpPath, finalPath);
```

**Safe JSON everywhere.** `src/utils/safe-json.ts` wraps `JSON.parse` to return `null` on error rather than throwing, preventing cascade failures from corrupt state files.

**Environment variable resolution with fallback chain.** Session ID example:

```typescript
const sessionId =
  process.env.OMX_SESSION_ID ??
  process.env.CODEX_SESSION_ID ??
  process.env.SESSION_ID;
```

**Platform command abstraction.** `src/utils/platform-commands.ts` provides `getPlatformCommand(name)` that returns the OS-appropriate command string. Used for shell invocations and tool discovery.

**Rust `AuthorityLease` pattern** — Cooperative, not kernel-enforced. All runtime components must respect the lease and not modify shared state while another holder is active.

### 8.6 Testing Strategy

#### TypeScript Tests

```bash
# Run all tests
node --test

# Run with coverage
npx c8 node --test

# Run specific file
node --test src/team/allocation.test.ts
```

Tests use Node.js built-in `assert` module. Mocking is done with manual stubs (no heavy framework).

Coverage thresholds enforced via c8 config:

```json
{
  "lines": 78,
  "functions": 90,
  "branches": 70,
  "statements": 78
}
```

#### Rust Tests

```bash
# All crates
cargo test

# Specific crate
cargo test -p omx-runtime-core
cargo test -p omx-mux

# With output
cargo test -- --nocapture
```

#### TypeScript / Rust Compat Tests

```bash
cargo test -p omx-runtime   # includes compat suite
```

Compat tests verify that the TypeScript bridge and the Rust runtime binary communicate correctly. They serialize test messages from TypeScript, pass through the binary, and assert round-trip fidelity.

### 8.7 Contributing

**Branching:** Single `main` branch development. Feature branches for non-trivial changes.

**Commit style:** Conventional commits preferred (`feat:`, `fix:`, `chore:`, `docs:`).

**Before submitting:**

```bash
# TypeScript
npm run build
node --test
npx c8 node --test   # verify coverage thresholds

# Rust
cargo fmt --check
cargo clippy -- -D warnings
cargo test
```

**New skills:** Create `skills/my-skill/SKILL.md`, register in `templates/catalog-manifest.json`, add prompt in `prompts/`.

**New MCP server:** Follow the bootstrap pattern in `src/mcp/`; add disable env var `OMX_<NAME>_SERVER_DISABLE_AUTO_START`; add parent watchdog and sibling detection.

**New notification platform:** Implement the notifier interface (probe, send, format methods), add env vars to `config_keys.tsv`, add formatter.

---

## 9. Integration Points

### 9.1 MCP Server Integration

OMX exposes its internal state via 5 MCP servers on the stdio transport. External tools (including Codex agents) can connect as MCP clients.

**Server discovery:** Codex is configured via the generated MCP registry (see `src/config/`) to connect to all 5 servers on session start.

**State server tools:**
- `read_state(path)` — Read a state file by relative path under `.omx/state/`
- `write_state(path, content)` — Atomic write to a state file
- `list_state(prefix)` — List state files matching prefix

**Memory server tools:**
- `remember(key, value)` — Store a key-value pair
- `recall(key)` — Retrieve by key
- `forget(key)` — Delete a key

**Wiki server tools:**
- `ingest(title, content)` — Write a wiki page
- `query(query)` — Full-text search
- `lint(title)` — Validate page structure

> [!NOTE]
> CJK wiki titles produce hash-based filenames due to issue #1641. Until patched, use ASCII slug titles for pages that must have human-readable filenames.

### 9.2 OpenClaw Integration

OpenClaw is an external automation gateway. OMX supports two connection modes:

```bash
# HTTP gateway
export OMX_OPENCLAW=true
export OMX_OPENCLAW_COMMAND_TIMEOUT_MS=5000
# OpenClaw server must be running at configured endpoint

# Command gateway
export OMX_OPENCLAW=true
export OMX_OPENCLAW_COMMAND=/usr/local/bin/openclaw-cli
```

The adapter framework (`src/adapt/`) provides the `doctor` command to diagnose connectivity:

```bash
omx adapt doctor openclaw
```

### 9.3 Notification Platform Integration

#### Discord (Webhook — simplest)

```bash
export OMX_DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
export OMX_DISCORD_MENTION="<@!123456789>"   # optional user ping
omx team start
```

#### Discord (Bot — full features)

```bash
export OMX_DISCORD_NOTIFIER_BOT_TOKEN="Bot ..."
export OMX_DISCORD_NOTIFIER_CHANNEL="987654321"
export OMX_DISCORD_MENTION="<@&112233445>"   # role ping
```

#### Telegram

```bash
export OMX_TELEGRAM_BOT_TOKEN="123456:ABC..."
export OMX_TELEGRAM_CHAT_ID="-100123456789"
```

#### Slack

```bash
export OMX_SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export OMX_SLACK_MENTION="<!channel>"
```

#### Reply Listener

```bash
export OMX_REPLY_ENABLED=true
export OMX_REPLY_DISCORD_USER_IDS="111222333,444555666"
export OMX_REPLY_POLL_INTERVAL_MS=5000
export OMX_REPLY_RATE_LIMIT=10
```

> [!CAUTION]
> The reply listener has a known sensitive data leak (issue #1661). Enable only in private channels with trusted users.

### 9.4 Hook System Extension

To add a custom hook handler via the plugin system:

```typescript
// my-plugin.ts
import { OMXPlugin, HookEvent } from 'oh-my-codex/sdk';

export const plugin: OMXPlugin = {
  name: 'my-plugin',
  version: '1.0.0',
  hooks: {
    [HookEvent.PreToolUse]: async (ctx) => {
      // Inspect or modify ctx.toolCall
      return ctx;
    },
    [HookEvent.Stop]: async (ctx) => {
      // Cleanup
    },
  },
};
```

Place the plugin where the loader discovers it (configured via `OMX_HOOK_CONFIG`).

### 9.5 Codex CLI Integration

OMX requires Codex CLI to be installed and configured. It integrates via:

1. **Config generation** — `omx config` writes the Codex hooks config pointing to OMX handlers
2. **Process spawning** — Leader spawns `codex` processes in worker panes via tmux
3. **Hook firing** — Codex calls OMX hook handlers via configured endpoints on lifecycle events
4. **Explore harness** — `omx-explore-harness` wraps `codex` for sandboxed exploration

To initialize OMX for a project:

```bash
cd /path/to/project
omx config init          # generate AGENTS.md, hooks config, MCP registry
omx team start --workers 3
```

### 9.6 Adapt Framework — Adding New Adapters

Implement the adapter contract in `src/adapt/`:

```typescript
// src/adapt/my-tool/index.ts
import { AdapterContract } from '../contracts';

export const myToolAdapter: AdapterContract = {
  probe: async () => { /* check availability */ },
  status: async () => { /* return health */ },
  init: async (config) => { /* initialize */ },
  envelope: (message) => { /* format message */ },
  doctor: async () => { /* run diagnostics */ },
};
```

Register in the adapter registry and add environment variables to `config_keys.tsv`.

### 9.7 Known Issues Summary Table

| Issue | Area | Severity | Workaround |
|---|---|---|---|
| #1643 | macOS TTY (omx exits immediately) | High | Run in foreground; avoid backgrounding Codex |
| #1671 | `omx update` overwrites AGENTS.md | High | Backup AGENTS.md before updating |
| #1635 | Leader HUD stuck on MCP startup | Medium | Stop + restart team |
| #1665 | MCP duplicate sibling accumulation | Medium | Kill stray `omx-mcp` processes |
| #1657 | SIGTERM without PID verification | Medium | Run in isolated process namespace |
| #1677 | Stream error / connection recovery | Medium | Restart affected worker pane |
| #1661 | Reply listener leaks sensitive data | High | Disable `OMX_REPLY_ENABLED` |
| #1660 | Transitive dep vulnerabilities | Medium | `npm audit fix` + `cargo audit` |
| #1653 | withRalphSteerLock infinite retry | Medium | External timeout on omx invocations |
| #1654 | stateDirToProjectRoot hardcoded depth | Low | Keep `.omx/` at repo root |
| #1656 | Leader git polling blocks event loop | Low | Reduce polling frequency (no config yet) |
| #1655 | withTmuxExtendedKeysLeaseLock no stale recovery | Medium | Delete stale lock files manually |
| #1642 | Detached leader skips tmux kill-session | Low | Kill orphan sessions manually |
| #1641 | wiki titleToSlug strips non-ASCII | Low | Use ASCII slug titles for CJK pages |
| #1648 | Built-in skills not namespaced with omx: | Low | No impact until namespacing enforced |
| #1640 | buildWorkerStartupCommand shell injection | High | Never pass untrusted LAUNCH_ARGS |
| #1649 | Path traversal via identifiers | High | Validate all identifiers before passing |
| #1659 | hud/state.ts git injection via remoteName | Medium | Ensure trusted .git/config only |

---

_Generated May 2026 from Yeachan-Heo/oh-my-codex at 09d2126. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
