OMP Workbook

Read the source. Follow the evidence.

Read, write, and exec are tiers

Nia’s next mistake would be to infer behavior from a tool’s name. A tool called read is not always read-tier. A tool carried through write is not always write-tier. The declaration can be a function of arguments.

A tier is a tool’s approval classification. It is not a sandbox, a syscall monitor, or proof that the implementation has no other effects.

Learn the baseline matrix first

The resolver ranks read below write below exec. With no explicit policy or active override changing the decision, the matrix is exact:

Approval modeRead tierWrite tierExec tier
always-askallowpromptprompt
writeallowallowprompt
yoloallowallowallow

The name always-ask therefore does not mean every call prompts. It automatically admits read-tier calls at this baseline layer.

The schema default for tools.approvalMode is yolo. The wrapper also falls back to yolo when the execute-time settings context supplies no mode. That is a source default, not a statement about a reader’s installation. A tool with no approval declaration defaults to exec, not read.

Recorded: Approval Desk exercised all nine combinations through the actual resolveApproval() and requiresApproval() functions. The cases are approval-always-ask-read, approval-always-ask-write, approval-always-ask-exec, approval-write-read, approval-write-write, approval-write-exec, approval-yolo-read, approval-yolo-write, and approval-yolo-exec. They classified calls; they did not execute tools or show dialogs.

An omitted declaration is a useful counterexample

Cover the expected result for approval-undeclared-exec. It supplies the fictional tool name seed_note, no declaration, and mode write.

Prediction: does the absence of an execution-related name make this an automatically allowed call?

Recorded answer: the result was policy: "prompt", tier: "exec", override: false, source: "mode". Omission is deliberately conservative. requiresApproval() returned required: true; that is still a classification result, not evidence that a UI appeared.

The same default applies to an unannotated MCP tool at this resolver. An MCP-looking name does not itself establish a lower tier. The existing approval.test.ts tests both unannotated and explicitly annotated MCP subjects.

Read tier does not mean universally read-only

Several supplied declarations make the limit concrete:

Source-backed operationDeclarationBoundary to retain
Ordinary ReadTool pathUsually readURL reads can make network requests; some specialized reads escalate.
ReadTool or GrepTool targeting ssh://execThe higher tier does not grant remote access.
HubTool peer send, inbox, waits, and job cancelread for these declared formsMessaging, consuming an inbox, or cancelling a job can change agent/job state.
HubTool process send with a process name and no peer targetexecProcess input is classified differently from a peer message.
Ordinary filesystem WriteTool targetwriteThe tier is not a workspace-containment guarantee.
ManageSkillToolwriteIts managed-skill storage is not simply the current workspace.
EvalToolexecA harmless-looking cell does not lower this static declaration.

These rows are source examples, not new executed workbook scenarios. The hubApproval() implementation, rather than its broad comment about read-only operations, establishes the classifications. HubTool.execute() then routes those operations to messaging and lifecycle functions.

Likewise, ReadTool.approval() returns read for ordinary HTTP URL reads, while its execution path can reach executeReadUrl() or fetchReadUrl(). Local-looking or read-tier work is not a general no-network promise.

A declaration can also distinguish handler-backed paths and session artifacts. Later chapters follow those paths without pretending that read-tier artifact work has zero effects.

Use tiers to predict a gate, not to certify a program

A capable operator can use the matrix to predict the default policy. To assess the effect, the operator still needs the actual implementation and destination. A tool author can declare a tier incorrectly, and trusted in-process code can do work outside a particular wrapped call.

Paper checkpoint: predict the baseline policy for an unannotated seed_note in write mode, then for a read-tier peer message in always-ask. Worked answer: prompt, then allow. Neither answer establishes what a real implementation would change or disclose.

Failure boundary: the matrix is the fallback after the resolver’s higher-precedence branches. Do not apply it before checking explicit denies, explicit tool policies, overrides, or the effective launch mode.

Source anchors: packages/coding-agent/src/tools/approval.ts — normalizeDecision, resolveToolTier, APPROVAL_MODE_MAX_TIER, resolveApproval; packages/coding-agent/src/config/settings-schema.ts — tools.approvalMode; packages/coding-agent/src/tools/hub/index.ts — hubApproval, HubTool.execute; packages/coding-agent/src/tools/read.ts — ReadTool.approval, #executeInner; packages/coding-agent/src/tools/grep.ts — GrepTool.approval; packages/coding-agent/src/tools/manage-skill.ts — ManageSkillTool; packages/coding-agent/src/tools/eval.ts — EvalTool.

Tool permissions and approvals · Source chapter: permissions/read-write-and-exec-are-tiers. Original evidence remains scoped to its recorded snapshot.

Read this chapter as Markdown

Your lesson ticks

A self-reported reading checklist, not proof of real OMP behavior. Only these ticks are saved in this browser. Reading a milestone does not resume, fork, reset or export a session.

Chapters I have worked through
Start here 1
Sessions, resets, and reviewable history 19
Memory and reusable knowledge 14
Tangent work and live control 17
Tool permissions and approvals 15
Extensions inside those boundaries 23
Connections and next steps 8
0 of 97 checked

Checklist saving needs JavaScript and available browser storage.