Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16,631 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gomp — Guardian of my pi

gomp — Guardian of my pi

A personal fork of Oh My Pi (omp) with model-based approval review.

gomp Guardian fork CI License TypeScript Rust Bun

gomp — "Guardian of my pi" — is a personal fork of Oh My Pi (omp) by Can Bölük that adds one thing: Guardian, a model-based approval reviewer that can answer tool-call escalations in place of the human at the keyboard.

Everything omp itself does is documented in README-omp.md — the full upstream README at our pinned base, carried verbatim. This README covers only what gomp adds and changes. The binary is gomp, but the configuration and session directory is still ~/.omp: see Compatibility with omp.

Not affiliated with Oh My Pi. This repository is not an official release of Oh My Pi or of OpenAI Codex. The official omp packages and installers at omp.sh do not include this fork's Guardian changes, and neither the upstream omp/Pi maintainers nor OpenAI endorse or sponsor it.

Warning

Guardian is still being tested. Use it at your own risk. Guardian is an approval reviewer, not a sandbox or security boundary. A mistaken approval can permit a destructive tool call to run. Review the configuration and durable audit trail before relying on it for unattended work. Feedback and reproducible issue reports are welcome.

What gomp is

gomp is a substantial, independently maintained fork of can1357/oh-my-pi. It retains omp's terminal agent, model providers, tools, SDK, RPC/ACP surfaces, and subagent system, while adding Guardian as a second approval axis.

Normal omp policy still decides when a tool call requires authorization. Guardian can decide who reviews that escalation: the human at the keyboard, or a warm, session-scoped reviewer Agent with bounded local inspection tools. Every automatic approval, reviewer selection, denial, and reviewer failure is visible and written to the session audit log.

The fork tracks no release versions of its own. Changes are recorded commit-anchored in CHANGELOG.md, which also records the current upstream base — presently 8baa3300b (upstream tag v17.2.3) — and gains a new base entry at every future rebase. The working branch is guardian-omp.

Guardian's Codex provenance

Guardian is a source-guided port of the open-source OpenAI Codex Guardian, specifically Codex's ApprovalsReviewer::AutoReview behavior. It is not a clean-room reimplementation and does not claim the Guardian design as original work. Codex supplied the behavioral and source reference: one reviewer decision per escalated action, visible automatic approvals, exact-action human appeals, fail-closed reviewer errors, denial breakers, bounded review work, and reusable reviewer context.

The following material is carried verbatim from Codex at 4d1f66b:

  • the complete Guardian policy and policy template under src/prompts/guardian/;
  • the warm-reviewer follow-up reminder in src/guardian/review-session.ts; and
  • the empty-full, empty-delta, and omission strings in src/guardian/transcript.ts.

The TypeScript files with Apache-2.0 headers under src/guardian/ are source-guided adaptations, substantially modified for omp. They follow Codex's prompt ordering, transcript budgets and selection, review deadline and retry posture, warm reviewer/delta/fork lifecycle, verdict contract, appeals, auditing, and denial accounting. Omp's root-bounded inspection wrappers are an original, narrower substitute for Codex's OS-sandboxed read profile.

The surrounding approval wrapper, settings, session log, TUI, SDK, eval bridges, and subagent propagation are implemented against omp's existing architecture rather than copying Codex's Rust agent, session, sandbox, or network-proxy architecture. The formal file-by-file inventory and modification notice are in packages/coding-agent/NOTICE. Installed builds embed the complete notice and both license texts; run gomp licenses (or gomp license) to print them, including from a standalone release binary.

Upstream Guardian credit

The public Codex history behind the implementation studied for this port credits:

OpenAI and the Codex contributors retain credit for the original Guardian design and source. This independent fork is not endorsed by OpenAI or the upstream omp/Pi maintainers.

How Guardian works

flowchart LR
    A[Model requests tool call] --> P{omp tool policy}
    P -->|allow| X[Execute]
    P -->|deny| B[Block]
    P -->|approval required| S{Provider safety check}
    S -->|pending| H[Human-only acknowledgement]
    S -->|clear| I{Covering grant from an already-approved root?}
    I -->|yes| X
    I -->|no| G{Guardian enabled here?}
    G -->|no| H2[Existing human or headless behavior]
    G -->|yes| M[Warm trunk reviewer, or ephemeral fork under contention]
    M --> R[read / grep / glob investigation]
    R --> V[guardian_verdict]
    V -->|allow| X
    V -->|deny or unavailable| B
Loading

Hard policy denies and provider safety checks stay ahead of Guardian. Guardian never bypasses either. The reviewer is a session-scoped Agent that receives a bounded transcript plus the exact resolved action as untrusted evidence, secret-masked when the session has masking enabled, and may call read, grep, and glob against the session's cwd, configured additional directories, and the action's own explicit path arguments before terminating with exactly one guardian_verdict call. The whole review — every provider turn, inspection call, and forced-verdict correction — shares one 90-second deadline. A first review in a session builds the reviewer from scratch and sends the full transcript; a later review in the same session reuses that warm reviewer and its provider-session identity, sending only the transcript delta, unless a concurrent approval finds it busy, in which case a short-lived fork reviews a snapshot of its last committed state without mutating the trunk. An allow continues through the existing approved wrapper path, including extension vetoes. A denial or reviewer failure blocks only that action.

Local inspection is bounded, not a full sandbox

Important

gomp's Guardian reviewer can call read, grep, and glob before deciding, matching Codex's tool-equipped investigation loop in shape. It remains narrower than Codex by design: Codex runs its reviewer inside an OS permission-profile sandbox with a managed network proxy, while this fork enforces the same read-only, local-only boundary in-process — confined to the session's cwd, any configured additional workspace directories, and the explicit path-valued arguments of the action under review. Remote URLs, internal URIs, and SSH targets are rejected using the real tools' own target parsers, not a scheme blacklist.

The reviewer sees a bounded rendering of the action's arguments, bound to the complete canonical action by its SHA-256 fingerprint, and can choose to inspect referenced local resources within its bounded roots — but that inspection is not unlimited:

Action awaiting approval What this Guardian sees What it does not see
eval with JavaScript or Python supplied inline The complete submitted code and the other eval arguments, plus any local file it chooses to read/grep/glob inside the session's roots. Network responses, files outside those roots, and anything the code generates only at runtime.
bash with inline code, such as python3 -c '…' or a heredoc The complete shell command, including the inline program, plus any local file it chooses to inspect inside the session's roots. Files or network responses the command accesses at runtime that were not already on disk inside those roots.
bash executing python3 goodorbad.py The complete command, working directory, timeout, and supplied environment arguments; it may read or grep goodorbad.py directly when the script resolves inside the session's roots. The script's contents when it resolves outside those roots, when the read/grep/glob capability is disabled by tools.approval, or when the 12-call inspection ceiling is already spent.
bash executing an authored, downloaded, or pre-existing script The command, bounded transcript context, and direct inspection of the script when it is inside the session's roots. Content outside the session's roots, and any inspection beyond the review's 8-provider-turn / 12-inspection-call / 90-second ceilings.

Approval of python3 goodorbad.py therefore means the reviewer had bounded opportunity to inspect the script, the transcript, and the action arguments — not that it necessarily exercised that opportunity within the shared ceilings, or that the script sat inside its allowed roots. A denied inspection tool or an out-of-root target narrows the evidence rather than failing the whole review; the policy tells the reviewer to lean conservative when it cannot verify local state, so this bound can still cause denials that Codex's whole-filesystem sandbox could resolve.

The two axes: approval mode and the Guardian reviewer

Two orthogonal settings decide what gets reviewed and by whom:

  • tools.approvalMode (upstream-identical: always-ask | write | yolo, default yolo) decides which tool tiers escalate for approval.
  • guardian.reviewer (fork-only: always | headless | off, default always) decides who answers an escalation — Guardian, or the human.

Because guardian.* is a namespace upstream omp ignores and tools.approvalMode never carries a fork-only value, one shared config file serves an upstream omp and gomp side by side.

guardian.reviewer Interactive session Headless session
always (default) Guardian reviews write- and exec-tier calls; reads stay automatic. Same.
headless Human prompts as configured by the approval mode. Guardian reviews write/exec escalations.
off The approval mode governs alone (human prompts). Write/exec escalations fail closed with no one to answer.

While the reviewer is active, a yolo escalation shape is lifted to always-ask — so yolo + Guardian on is never a silent no-op — without ever rewriting the stored mode; an explicit write mode keeps its shape (Guardian reviews exec only). Turning the reviewer off restores the stored mode's behavior by pure consequence. Guardian code never writes tools.approvalMode.

If a configured reviewer cannot be resolved in an interactive session, Guardian pauses before reviewing and offers two session-only choices: use the exact current primary model as the Guardian reviewer, or turn the reviewer off (the stored approval mode then governs, stated explicitly). It never substitutes an arbitrary model without that choice. Headless sessions cannot make this decision and fail the action closed with no-model.

guardian.subagents independently controls new child sessions:

Value Child behavior
auto (default) Follow the root: an active reviewer guards children at ask; reviewer off leaves them at yolo.
off Preserve omp's legacy unattended yolo behavior.
write Review exec-tier calls such as bash, eval, browser, and nested task; ordinary writes stay fast.
ask Review both write- and exec-tier child calls.

Children are stamped with a concrete guardian.reviewer and approval mode at spawn. Each root or child session owns its own reviewer gate, durable verdicts, one-use appeal state, and denial breaker. Three consecutive model denials—or ten denials among the last fifty reviews—interrupt that agent's run.

Configure and operate it

A Guardian build guards out of the box with an empty config: authenticated Codex users get the default openai-codex/codex-auto-review reviewer. An explicit qualified model override always wins and is never silently replaced:

# Fork-only namespace; upstream omp ignores it, so this file can be shared.
guardian:
  reviewer: always        # always | headless | off
  # subagents: auto       # default; children of a guarded root are guarded

modelRoles:
  guardian: openai-codex/codex-auto-review

retry:
  fallbackChains:
    openai-codex/codex-auto-review:
      - openai-codex/gpt-5.6-luna   # reviewer fallback when the default is unavailable

Legacy configs migrate at load: tools.approvalMode: approve-for-me becomes always-ask + guardian.reviewer: always, ask becomes always-ask, and the old hidden guardian.mode becomes reviewer: headless|off — each with a visible startup note.

Session controls:

  • /guardian [on|headless|off] switches the reviewer for this session; bare /guardian opens the selector. --guardian always|headless|off does the same at launch.
  • /guardian status prints the full posture: reviewer state, stored vs effective approval mode, subagents raw → resolved, and the reviewer model with its availability.
  • /guardian model [selector] points modelRoles.guardian at a different reviewer for this session.
  • /guardian subagents <auto|off|write|ask> changes how subsequently spawned children are configured.
  • /guardian appeal (alias /auto-review) lists reachable denials and can arm one elevated re-review of the exact denied action. It never executes or bypasses review.
  • The status line carries a shield segment (on / headless / off / degraded / reviewer-unavailable, plus a guarded-subagents marker), and the welcome banner states the posture at startup.

See docs/approval-mode.md for the complete failure posture, audit schema, coverage boundaries, and appeal semantics.

Compatibility with omp

gomp strives for full backwards compatibility with omp configs and sessions. Only the user-visible name changed: the binary, the help usage, the completions, and the welcome banner say gomp, while every on-disk contract stays on the omp name.

Surface Location Status
Agent directory ~/.omp/agent/ (or the XDG layout, $XDG_DATA_HOME/omp/…) Unchanged
Global and project config ~/.omp/agent/config.yml, project config.yml Unchanged
Model overrides ~/.omp/agent/models.yml Unchanged
Sessions and rollouts ~/.omp/agent/sessions/ JSONL Unchanged format
Logs ~/.omp/logs/omp.<date>.<pid>.log, omp-debug.log, omp-crash.log Unchanged

That split is deliberate in the source: APP_NAME in packages/utils/src/dirs.ts remains "omp" because it names the path contract, and the new CLI_NAME ("gomp") beside it names the binary. So one config directory serves both binaries side by side: an upstream omp on the same machine keeps the configuration and sessions it always had, and gomp resumes sessions upstream wrote. Everything Guardian adds is additive — new keys in namespaces upstream ignores, new custom session entries upstream skips.

Config syntax additions

Key Values (default) What it does An upstream omp reading the same file
guardian.reviewer always | headless | off (always) Who answers an escalation: Guardian, or the human. Unknown top-level namespace — ignored.
guardian.subagents auto | off | write | ask (auto) How child sessions spawned by task are guarded. Ignored (same namespace).
modelRoles.guardian any model selector, e.g. openai-codex/codex-auto-review Which model reviews escalations. Unknown role in a known map — ignored; other roles unaffected.
retry.fallbackChains.<reviewer> upstream syntax, no extension Reviewer fallback when the primary reviewer is unavailable. Plain upstream key; behaves as upstream defines.
legacy tools.approvalMode: approve-for-me migrates at load to always-ask + guardian.reviewer: always Pre-split fork value. Would be an invalid enum upstream; gomp rewrites it to an upstream-valid one.
legacy tools.approvalMode: ask migrates at load to always-ask Pre-split fork value. Same — the stored value ends up upstream-valid.
legacy guardian.mode migrates at load to guardian.reviewer: headless | off Hidden pre-split key. Ignored (fork namespace).

tools.approvalMode is the one shared key Guardian consults, and gomp never stores a fork-only value in it: after migration the stored mode is always the upstream enum (always-ask | write | yolo). When a reviewer is active, the yolo escalation shape is lifted to always-ask in memory at the approval wrapper — never on disk.

Session and rollout additions

Entry Kind Records An upstream omp loading the same session
guardian-verdict custom entry (type: "custom") One durable audit per review: outcome, risk, rationale, action hash, reviewer model, timing, spend, inspection trace. Preserved verbatim, never in model context.
guardian-approval-coverage custom entry Which descendant call ids a prior approval grant covered (first 64 plus an overflow count). Preserved verbatim, never in model context.
guardian-breaker custom entry A tripped denial breaker. Preserved verbatim, never in model context.
guardian-auto-approval display-only custom message The visible card for each automatic approval. Rendered as an ordinary custom message.
guardian-model-degraded display-only custom message An interactively confirmed reviewer substitution. Rendered as an ordinary custom message.
guardian-appeal user-attributed custom message The human's appeal of one denial (context for the primary agent; the gate honours only the armed action hash). Rendered as an ordinary custom message.

The guardian-verdict payload gained these fields in the Codex-parity pass; all are optional, so older audits load unchanged and newer audits open fine in any build:

  • action — typed, masked, length-bounded action payload (command, file-write, file-edit, device, task-dispatch, eval, process) alongside the legacy argsPreview / actionSummary strings.
  • startedAtMs / completedAtMs — review lifecycle timestamps.
  • timeToFirstTokenMs — reviewer latency to its first stream event.
  • usage — input/output/cache token buckets, reasoningTokens when the provider reports them, and cost, accumulated across every provider turn including rolled-back attempts and forced-verdict corrections.
  • inspectionTrace — bounded, secret-masked evidence from the reviewer's read/grep/glob calls.

None of this breaks upstream, by upstream's own design: a CustomEntry is omp's extension-owned record, identified by customType, explicitly excluded from LLM context and left untouched when nothing recognizes it. Sessions therefore remain mutually resumable — a gomp session opens in an upstream omp with the Guardian audit trail intact but inert, and an upstream session opens in gomp with nothing missing.

Install gomp

gomp is distributed from source, not through omp's official installers or npm package:

git clone --branch guardian-omp --single-branch https://github.com/weddle/oh-my-pi.git
cd oh-my-pi
bun setup
bun dev

bun setup installs the Bun workspaces, builds the local Rust/N-API addon, and links the dev executable into Bun's global bin as gomp. It never installs or overwrites an omp, so an upstream omp already on the machine keeps working — and both share the same ~/.omp configuration.

For a standalone compiled binary:

bun scripts/build-local-gomp.ts
# → packages/coding-agent/binaries/gomp-darwin-arm64

Fresh source builds require Bun 1.3.14. macOS, Linux, and Windows are inherited upstream targets; Guardian has been exercised end-to-end on macOS, and the other platforms have not yet received equivalent Guardian smoke coverage. The local build script above targets the darwin-arm64 host only.

Configuration, sessions, and logs live in ~/.omp regardless of the binary name — see Compatibility with omp.

Updating gomp

Guardian core updates are source-managed. gomp update, gomp update --check, and gomp update --force intentionally exit nonzero rather than consult or install an upstream release; gomp update -l still updates plugins. Startup checks for upstream omp releases are disabled by default.

Update an existing checkout explicitly:

git pull --ff-only origin guardian-omp
bun setup

bun setup rebuilds the native addon and refreshes the linked gomp executable. Architecture and contribution guidelines for the underlying platform are in packages/coding-agent/DEVELOPMENT.md.

Verification

The Guardian change is covered by focused catalog, policy, prompt, transcript, wrapper-ordering, session, slash-command, settings, appeal, subagent inheritance, fan-out, and breaker tests. Real smoke scenarios exercise:

  • interactive reviewer switching (/guardian on/headless/off) with live effect;
  • visible approvals and exact-action denial appeals;
  • no-reviewer, explicit non-Codex reviewer, broken-reviewer, and interactive reviewer-fallback paths;
  • child and grandchild review plus terminal breaker abort; and
  • the provider-safety boundary where Guardian must not be called.

Run the focused checks from the repository root:

bun --cwd=packages/coding-agent run check
bun test --parallel=1 packages/coding-agent/test/guardian
bun test --parallel=1 packages/catalog/test/codex-discovery.test.ts

For the broader upstream gates:

bun run check:ts
bun run ci:test:ts
bun run ci:test:smoke

Everything else is omp

Guardian is the whole delta. Providers and model routing, the tool surface, LSP and debugger integration, hashline edits, subagents, collab, RPC and ACP, the SDK, statusline and themes, memory, and extensibility are upstream Oh My Pi's work and behave exactly as upstream documents them. Rather than restate that material and slowly desync from it, this fork carries it verbatim: README-omp.md is upstream's README at the pinned base 8baa3300b (tag v17.2.3), regenerated at every rebase. For anything newer than that base, see can1357/oh-my-pi and omp.sh.

Fork maintenance

This repository follows upstream Oh My Pi while keeping the Guardian delta explicit and reviewable:

  • guardian-omp is the only long-lived branch and carries Guardian; there is no local main. Upstream is tracked as a git remote, and rebases work directly off its refs.
  • Guardian-specific policy assets retain their original Codex attribution.
  • Upstream updates are integrated deliberately and reverified against the approval-ordering, audit, appeal, and subagent contracts before publication.
  • Fork changes are recorded commit-anchored in CHANGELOG.md; every rebase adds an entry there recording the new upstream base commit and regenerates README-omp.md from it. Upstream's own release notes stay untouched in packages/coding-agent/CHANGELOG.md so rebases merge cleanly.

The current Guardian line began at omp v17.1.6 and is verified through upstream omp v17.2.3 (8baa3300b). Compatibility with later upstream changes should not be assumed until they are integrated and pass the fork's verification suite.

Upstream philosophy

omp is itself a fork of pi-mono by Mario Zechner, extended by Can Bölük with a batteries-included coding workflow.

Key upstream ideas retained here:

  • Keep interactive terminal-first UX for real coding work.
  • Include practical built-ins: tools, sessions, branching, subagents, and extensibility.
  • Make advanced behavior configurable rather than hidden.

Feedback and contributing

Feedback, failure reports, and focused contributions about Guardian are welcome in this fork's issue tracker. Useful reports include the active Guardian settings, surface (TUI, print, SDK, CI, or subagent), reviewer selector, redacted action, expected result, actual result, and the relevant guardian-verdict or guardian-breaker record.

Please report behavior inherited unchanged from omp to the upstream project. Contributions to this fork must preserve the hard approval boundaries, visible decision trail, source attribution, and focused verification described above.


License

This repository is primarily MIT-licensed. The source-guided Guardian adaptation and verbatim Codex material are distributed under Apache-2.0; the @oh-my-pi/pi-coding-agent package therefore declares MIT AND Apache-2.0. See the repository NOTICE, the package NOTICE, MIT license, and Apache-2.0 license.

© 2025 Mario Zechner
© 2025-2026 Can Bölük

gomp: model-reviewed approvals for terminals that stay open.

About

⌥ AI Coding agent for the terminal — hash-anchored edits, optimized tool harness, LSP, Python, browser, subagents, and more

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages