A personal fork of Oh My Pi (omp) with model-based approval review.
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.
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 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.
The public Codex history behind the implementation studied for this port credits:
- Charley Cunningham for the foundational Guardian flow (#13692) and Smart Approvals integration (#13860);
- Won Park for the Auto-Review naming, serialization, exact-action appeal work, and rolling-window denial breaker (#18021, #18504, #19056, #19058, #22110);
- Dylan Hurd for the initial denial short-circuit (#18890);
- Jeff Harris for the
codex-auto-reviewmodel route (#18169); - Ollie Mason for the reviewer policy-template update copied by this fork (#31480); and
- Celia Chen for provider-specific reviewer model routing (#22258).
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.
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
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.
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.
Two orthogonal settings decide what gets reviewed and by whom:
tools.approvalMode(upstream-identical:always-ask|write|yolo, defaultyolo) decides which tool tiers escalate for approval.guardian.reviewer(fork-only:always|headless|off, defaultalways) 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.
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 unavailableLegacy 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/guardianopens the selector.--guardian always|headless|offdoes the same at launch./guardian statusprints the full posture: reviewer state, stored vs effective approval mode, subagents raw → resolved, and the reviewer model with its availability./guardian model [selector]pointsmodelRoles.guardianat 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.
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.
| 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.
| 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 legacyargsPreview/actionSummarystrings.startedAtMs/completedAtMs— review lifecycle timestamps.timeToFirstTokenMs— reviewer latency to its first stream event.usage— input/output/cache token buckets,reasoningTokenswhen the provider reports them, andcost, accumulated across every provider turn including rolled-back attempts and forced-verdict corrections.inspectionTrace— bounded, secret-masked evidence from the reviewer'sread/grep/globcalls.
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.
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 devbun 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-arm64Fresh 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.
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 setupbun 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.
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.tsFor the broader upstream gates:
bun run check:ts
bun run ci:test:ts
bun run ci:test:smokeGuardian 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.
This repository follows upstream Oh My Pi while keeping the Guardian delta explicit and reviewable:
guardian-ompis the only long-lived branch and carries Guardian; there is no localmain. 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 regeneratesREADME-omp.mdfrom it. Upstream's own release notes stay untouched inpackages/coding-agent/CHANGELOG.mdso 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.
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, 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.
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.
