Skip to content
On this page

    Oh My Pi (omp): The Maximalist Harness That Puts the IDE in the Loop

    When Can Bölük forked Mario Zechner's minimalist Pi to create omp, he made a radical bet: harness defects are the real ceiling for AI coding. Here is the architecture behind that bet.

    24 min read

    In July, I wrote about Pi Agent’s minimalist philosophy and how its 4-tool harness (<1,000 token prompt) became the connective glue between heavier tools. A week later, I examined omp’s subagent coordination.

    For two years, developers focused on model weights. When an agent failed to edit a file, missed an export, or hallucinated a fix, users blamed the model and waited for the next generation.

    In my analysis of harness engineering, I argued the opposite: agents fail in production because the environment around the model breaks.

    Oh My Pi (omp), built by Can Bölük, proves this point.

    Can forked Mario Zechner’s Pi (pi-mono) in late 2025. Pi championed minimalism: four core tools (read, write, edit, bash), zero permission prompts, and an auditable shell where you build extensions for extra capabilities.

    omp took the opposite path. It turned the harness into an IDE engine built in Rust and Bun. omp embeds ripgrep, AST parsing, hash-anchored editing, Language Server Protocol (LSP), Debug Adapter Protocol (DAP), structured memory, and typed worker pools into the execution process.

    On identical model weights, changing the harness lifted benchmark pass rates by 15 percentage points across 16 models. One model saw a 10x jump in task completion.

    Oh My Pi In-Process IDE Engine Architecture Architecture diagram showing Host Model connecting to the Maximalist Harness and compiled Rust Native Core driving in-process intelligence and execution engines. 01 · HOST Agent Model Claude / Grok / DeepSeek 02 · HARNESS Maximalist Harness (omp) Rich tool schemas & protocols NATIVE Rust Native Core (Bun CLI) In-Process FFI · In-Memory Ripgrep · AST & Worktrees IN-PROCESS IDE SUBSYSTEMS CODE INTELLIGENCE & SAFETY Hashline Engine Content-hash anchored edits LSP Client vtsls · gopls · pyright · ruff DAP Debugger dlv · debugpy · lldb-dap EXECUTION & STATE Worker Pools Isolated Git worktrees + Hub bus Mnemopi SQLite Memory Graph relations + vector recall Snapcompact Engine Visual PNG context compression File System & Codebase Repository Direct in-process atomic disk writes

    The Fork: Minimalism vs Maximalism

    The architectural divergence between Pi and omp comes down to scope.

    Pi Agent Minimalist Subprocess Architecture Pipeline diagram showing Pi Agent's minimal 4-tool execution flow delegating operations to external Unix shell subprocesses. 01 · MODEL Agent Model (Prompt & Code Generation) 02 · CORE LOOP Minimal Core Loop (<1,000 Token Prompt) 03 · TOOL SURFACE 4 Core Tools (read · write · edit · bash) 04 · OS SUBPROCESS FORK Shell Subprocesses (rg · find · sed · git) Separate OS processes spawned per tool call Local File System Unformatted stdout returned over shell pipes ⚠ High startup latency and escaping drift on large multi-package repositories
    Pi relies on subtraction: 1. Keep the core loop small. 2. Delegate file and search operations to Unix tools via `bash`. 3. Keep the base prompt under 1,000 tokens to preserve context for user code. 4. Let developers write opt-in TypeScript extensions for specialized tasks.

    omp rejects reliance on shell scripts and textual diffs. Shell commands introduce process startup latency, string escaping bugs on Windows, and zero semantic awareness of code syntax.

    DimensionPi (pi-mono)omp (oh-my-pi)
    PhilosophyMinimalist harness, extension-firstMaximalist harness, baseline-first
    Core RuntimeTypeScript / Node shellBun CLI + Rust native core
    Tool Surface4 core tools (read, write, edit, bash)31+ in-process tools
    File EditingLine replacement and text diffsHashline (content-hash anchored)
    Language IntelligenceOptional user extensionsBuilt-in LSP client (TypeScript, Go, Python)
    DebuggingPrint statements via bashBuilt-in DAP client (dlv, debugpy, lldb)
    SubagentsSpawn separate Pi instances via bashWorker pools, typed yields, worktree isolation
    MemoryEphemeral or flat text filesMnemopi (SQLite + vector/graph) + Hindsight
    Prompt Size<1,000 tokens~4,000-8,000 tokens (rich tool schemas)

    Pi gives users full terminal auditability and low token overhead. omp gives the model execution reliability across multi-file codebases.

    The Rust Core: Removing Subprocess Overhead

    Coding agents spend significant time in fork/exec loops. When an agent searches a codebase, lists files, and edits three locations, it spawns multiple separate processes: ripgrep, find, git, and patch scripts.

    External process execution creates three bottlenecks:

    1. Latency: Starting hundreds of subprocesses across a multi-turn task adds seconds of wall-clock delay.
    2. Platform drift: Shell syntax that works in POSIX environments breaks on Windows or inside locked containers.
    3. Missing state checks: Shell commands return unformatted text, preventing the harness from verifying file state between search and edit without extra disk reads.

    omp pulls file system operations, text search, and syntax analysis into a compiled Rust native core linked to the Bun runtime.

    In-Memory Rust Native Engine Dispatch Architecture diagram of Oh My Pi's Rust native core connected to in-memory search, worktree walking, AST parsing, and hashline verification engines. RUNTIME Agent Loop Bun CLI execution process DIRECT FFI COMPILED CORE Rust Native Core Zero-fork in-process Linked native binary In-Process Ripgrep Engine Fast multi-threaded regex search in memory Tree-Walking & Worktree Engine Instant worktree setup & git isolation AST Parsing & Highlighting tree-sitter syntax trees & structural edits Hashline Signature Verification Cryptographic content-hash anchor validation All operations execute in-process without OS process fork overhead

    When omp searches a repository, it calls its internal Rust search engine. When it inspects symbols or tracks file changes across git worktrees, the Rust core resolves queries in memory.

    In-process execution removes process startup delay, enforces memory safety, and runs on macOS, Linux, and Windows without platform shims.

    Hashline: Content-Anchored Editing

    File editing causes more agent failures than any other tool call.

    Standard agents use search-and-replace blocks or unified diffs:

    <<<< SEARCH
    const count = 1;
    ====
    const count = 2;
    >>>>

    A single whitespace mismatch, a duplicate line matching earlier in the file, or a drifted line number breaks the patch. The model enters a retry loop, burns tokens, and corrupts surrounding code.

    omp replaces string-matching diffs with Hashline, a content-anchored editing protocol.

    Hashline Mechanics

    When omp reads a file, its Rust engine annotates each line with a short 2-3 character content hash and tags the file with a unique snapshot hash:

    [src/server/auth.ts#A1B2]
    1:f1 import { verifyToken } from "./jwt";
    2:8c 
    3:3d export function authenticate(req: Request) {
    4:e9   const token = req.headers.get("authorization");
    5:0a   if (!token) return null;
    6:d4   return verifyToken(token);
    7:7b }

    To edit the file, the model sends line-anchored patch commands:

    [src/server/auth.ts#A1B2]
    PUT 5.=5:
    +   if (!token) throw new UnauthorizedError();

    The harness enforces three checks before writing to disk:

    1. File tag check: The file must match snapshot [auth.ts#A1B2]. If a user or background process edited the file, the tag changes and omp rejects the edit.
    2. Line hash check: Line 5 must have hash 0a. If lines shifted, the harness catches the mismatch.
    3. Targeted write: The harness replaces the target range without modifying surrounding lines.
    Hashline Content-Anchored Editing Verification Loop Flowchart illustrating Hashline patch validation, atomic disk application, and reject-and-replan recovery cycle. 01 · READ Read Snapshot [auth.ts#A1B2] with Line Hashes 02 · PLAN Plan Line Anchors (Target line 5 hash: 0a) 03 · PATCH Send Hashline Command: PUT 5.=5: +code Verification Gate File tag [#A1B2] & line 5 == 0a? YES 05 · COMMIT Apply to Disk Atomic, deterministic disk commit NO (DRIFT) 06 · REJECT Reject Patch Before Disk Write Block corrupted diff mutation Return Fresh Snapshot [#C3D4] Emits updated file tag & line hashes RE-ANCHOR ✓ Zero corrupted edits from drifted context

    Benchmark Results

    Can Bölük published a 540-task benchmark across 16 models (3 runs per task, fresh sessions) comparing standard string-replace edit formats against Hashline:

    ModelBaseline Pass RateHashline Pass RateNet GainToken Reduction
    Grok Code Fast 16.7%68.3%+61.6% (10x)-
    Grok 4 Fast----61% tokens
    Gemini 3 FlashBaseline+5.0%+5.0%-
    MiniMax M2.1Baseline>2x Baseline>2x-
    16-Model AverageBaselineBaseline + 15%+15.0%Substantial

    Grok Code Fast 1 improved from 6.7% to 68.3% with identical model weights, prompts, and instructions. The only change was replacing text diffs with Hashline.

    On Grok 4 Fast, total token consumption dropped by 61% because the model avoided multi-turn edit retry loops.

    A failed edit usually indicates that the model generated valid code but tripped on a brittle string-matching parser. Hashline removes that failure mode.

    Semantic Intelligence: Built-In LSP and DAP

    Most coding agents treat code as raw text. To rename a function in a TypeScript monorepo, an agent runs grep, finds 20 occurrences, and issues 20 text edits. It misses barrel file re-exports or alters identical property names on unrelated types.

    omp integrates Language Server Protocol (LSP) and Debug Adapter Protocol (DAP) into the tool surface.

    LSP for Symbol-Aware Refactors

    omp connects to language servers for TypeScript (vtsls/tsserver), Go (gopls), Python (pyright/ruff), and Rust (rust-analyzer).

    The model uses semantic tools instead of regular expressions:

    • lsp.rename: Renames a symbol across the workspace, updating imports, definition sites, and re-exports in one step.
    • lsp.references: Finds all true call sites and usages of a function or type.
    • lsp.diagnostics: Reads compiler errors and type warnings from the language server after an edit.
    • lsp.codeActions: Applies compiler quick-fixes and organizes imports.
    LSP Cross-File Semantic Symbol Rename Sequence diagram tracing lsp.rename call from the agent model through the harness and language server to multi-file codebase updates. Agent Model omp Harness LSP (vtsls) Codebase Files lsp.rename("newAuth") textDocument/rename WorkspaceEdit (14 files) Apply 14 edits via Hashline Success: 14 files done

    DAP for Runtime Debugging

    When a standard agent debugs a runtime error, it adds console.log or print() statements, runs the test suite, parses stdout, and repeats. This process wastes tokens and pollutes the context window.

    omp includes a DAP client that connects to debuggers like dlv (Go), debugpy (Python), or lldb-dap (C/C++/Rust).

    The model can:

    1. Set conditional breakpoints at target lines.
    2. Step over and step into execution frames.
    3. Inspect variable values and call stacks in memory.
    4. Evaluate expressions in the running process.
    Agent Action:
    dap.set_breakpoint(file="src/billing/calculator.go", line=84, condition="amount < 0")
    dap.continue()
    -> Breakpoint hit at line 84
    -> Variables in scope: { amount: -50.00, currency: "USD", userTier: "ENTERPRISE" }

    The agent inspects memory state directly, identifies the root cause in one turn, and applies the fix.

    Orchestration: Worker Pools and Typed Contracts

    In tools like Claude Code, starting a subagent runs a second chat loop that returns a natural language summary to the parent. The parent must read and parse multiple paragraphs of prose.

    omp models multi-agent orchestration like an operating system process table:

    Worker Pools, Isolated Worktrees and Typed JSON Contracts Architecture diagram of multi-agent orchestration showing parent agent launching isolated worktree workers with peer hub communication and typed JSON yields. PARENT ORCHESTRATOR Parent Agent (task tool) Spawns up to 32 parallel workers ISOLATED GIT WORKTREES Worker 1 Worktree: /wt/auth Auth API endpoints & token verification Worker 2 Worktree: /wt/db Postgres schema & migration scripts Worker 3 Worktree: /wt/tests End-to-end integration & validation suite agent://Worker1/files Typed JSON payload agent://Worker2/schema Typed JSON payload agent://Worker3/status Typed JSON payload Direct typed schema delivery back to parent orchestrator

    Orchestration Components

    1. The task Batch Tool: The parent launches up to 32 parallel workers in one tool call with a shared context header and distinct task assignments.
    2. Worktree Isolation: Every worker executes in an isolated git worktree. Sibling agents cannot overwrite shared files during execution.
    3. Typed Yield Contracts: Each subagent defines a JSON Schema for its return payload. When the worker completes, it yields a structured JSON object, accessible by URL paths like agent://<worker_id>/output.
    4. The hub Communication Bus: Subagents exchange point-to-point messages across the in-process hub bus without routing through the parent.
    5. Persistent Execution Kernels: omp provides persistent Python and Bun VM kernels (eval). The kernel retains state across turns, and scripts inside the kernel call agent tools over a loopback bridge via @tool decorators.

    omp also provides intent triggers in natural language:

    • ultrathink: Allocates maximum reasoning budget and enforces multi-turn plan verification.
    • orchestrate: Spawns parallel subagent teams to implement independent components concurrently.
    • workflowz: Transforms a user prompt into a formal multi-stage contract managed by the task engine.

    Memory: Mnemopi, Snapcompact, and Local Workers

    Long-running agent sessions face context window exhaustion and rising token costs. omp manages memory and context through three subsystems:

    Mnemopi Structured Memory

    omp stores cross-session knowledge in Mnemopi, a local SQLite backend with vector embeddings and graph relations:

    • retain: Stores architectural facts, project conventions, and user preferences.
    • recall: Queries memory by semantic similarity or project tags.
    • reflect: Compresses completed sessions into distilled models for future sessions.

    Subagents inherit the parent session memory state, ensuring shared context across parallel runs.

    Snapcompact Visual Compression

    Standard agents summarize old conversation turns into text when hitting context limits. Text summaries often drop variable names, line numbers, and edge cases.

    omp uses snapcompact. The engine renders session snippets into pixel-font PNG images on device:

    Snapcompact Visual Context Compression Pipeline Pipeline diagram showing older session conversation turns compressed into on-device pixel-font PNG images and fed into vision LLMs at 1/3 token cost. 01 · CONTEXT HISTORY Old Session Turns (Nearing Limit) SNAPCOMPACT RASTERIZER 02 · VISUAL ARTIFACT Pixel-Font PNG (Rendered Locally) Zero token loss · Preserves exact code structure VISION API INGESTION 03 · MULTIMODAL REASONING Main LLM Vision Input ~1/3 token cost compared to raw prompt text Active Generation & Edit Loop Preserves line numbers, diff markers & identifier context Compresses conversation history into images without losing syntax detail
    The model reads the rendered history through vision input at roughly **one-third the token cost** of raw input text.

    Local Model Workers

    To avoid spending cloud tokens on bookkeeping, omp runs local models on-device using transformers.js (such as Qwen 1.7B, Gemma 1B, or LFM2 1.2B).

    These local workers run in background threads to handle:

    • Session titling
    • Entity and keyword extraction for memory storage
    • Formatting diff markers

    This offloads routine tasks from the primary frontier model, reducing cost and latency.

    Trade-Offs: When Pi Wins vs When omp Wins

    A 30-task evaluation by StandardCompute and Composio tested Pi against omp on identical real-world coding benchmarks:

    MetricPi (pi-mono)omp (oh-my-pi)
    Task Success Rate (30 tasks)20 / 30 (66.7%)17 / 30 (56.7%)
    Cost Per Success$0.028$0.103 (3.7x higher)
    Median Duration132.2 seconds272.4 seconds (2x slower)
    Average Tokens Per Task558,885742,283 (33% more)
    Harness ArchitectureMinimalist 4-tool shellMaximalist 31-tool IDE engine

    Pi won on benchmark speed and cost for three reasons:

    1. Tool Overload on Simple Tasks: On single-file edits or simple scripts, omp’s extensive tool schemas (LSP, DAP, task schemas, memory) consume tokens and add decision overhead for the model.
    2. Setup Latency: Provisioning worktrees, querying language servers, and indexing memory takes time. For a 10-line fix, Pi’s read + edit loop completes in seconds.
    3. Token Usage: Rich schemas and structured yields use more tokens per turn than Pi’s minimal prompt.

    omp still ranked second out of eight tested coding harnesses, outperforming Claude Code, Codex, and OpenCode on the same model weights.

    Choosing Between Pi and omp

    Strategic Decision Map: Pi Agent vs Oh My Pi A 2x2 consultant scenario matrix mapping repository context depth against harness complexity to choose between Pi Agent and Oh My Pi. MAXIMAL IDE HARNESS MINIMAL SHELL HARNESS SINGLE-FILE MONOREPO 01 · MONOREPO / MAXIMAL IDE Oh My Pi (omp) Domain Multi-package TypeScript, Go & Rust, cross-file LSP renames, DAP runtime breakpoints, parallel worktree swarms. ★ Maximum Reliability on Deep Repos 02 · SINGLE-FILE / MINIMAL SHELL Pi Agent (pi-mono) Fast single-file edits, lightweight scripting, tool chaining, sub-second latency, lowest token overhead. ✓ <1,000 tk prompt & terminal agility 03 · SINGLE-FILE / MAXIMAL IDE Tool Overload Zone LSP & worktree provisioning overhead exceeds the complexity of small single-file fixes and scripts. ⚠ Excessive token & decision cost 04 · MONOREPO / MINIMAL SHELL Context Drift Danger Zone Brittle search-and-replace text diffs and blind grep queries miss barrel files and silently corrupt package imports. ⚠ High failure rate on large refactors

    Choose Pi when you:

    • Want a minimal, transparent harness with zero background overhead.
    • Work on single-file fixes, scripts, and glue tasks between other tools.
    • Prefer writing custom extensions in TypeScript.
    • Need the lowest token cost and fastest time-to-first-token.

    Choose omp when you:

    • Maintain multi-package TypeScript, Go, or Python monorepos where text replacement breaks imports.
    • Need parallel subagents working in isolated git worktrees without merge collisions.
    • Need debugger integration (breakpoints, stepping, stack inspection) rather than print statements.
    • Require cross-session memory and structured project knowledge tracking.
    • Build automated agent systems that require typed JSON contracts instead of chat prose.

    The Bottom Line

    The harness shapes agent capability as much as the model weights.

    Giving a model read, write, and bash works for simple tasks, but fails when edits drift or imports break across packages.

    Can Bölük’s work on omp demonstrates that engineering a hardened Rust core, content-anchored hashline editing, native LSP/DAP protocols, and typed worker pools can turn a struggling model into a reliable software engineer.

    Minimalist tools like Pi remain ideal for fast, low-overhead tasks. For large codebases and autonomous multi-file workflows, the harness must function as an IDE wired into the execution loop.


    Experimenting with coding agent harnesses or building multi-agent workflows? I’d love to hear what architecture patterns are working in your stack. Reach out on LinkedIn.