## Read\,&#32;write\,&#32;and exec are tiers

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

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

### Learn the baseline matrix first

The resolver ranks&#32;`read`&#32;below&#32;`write`&#32;below&#32;`exec`\.&#32;With no explicit policy or active override changing the decision\,&#32;the matrix is exact\:

| Approval mode | Read tier | Write tier | Exec tier |
| --- | ---: | --- | --- |
| `always-ask` | allow | prompt | prompt |
| `write` | allow | allow | prompt |
| `yolo` | allow | allow | allow |

The name&#32;`always-ask`&#32;therefore does&#32;**not**&#32;mean every call prompts\.&#32;It automatically admits read\-tier calls at this baseline layer\.

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

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

### An omitted declaration is a useful counterexample

Cover the expected result for&#32;`approval-undeclared-exec`\.&#32;It supplies the fictional tool name&#32;`seed_note`\,&#32;no declaration\,&#32;and mode&#32;`write`\.

**Prediction\:**&#32;does the absence of an execution\-related name make this an automatically allowed call\?

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

The same default applies to an unannotated MCP tool at this resolver\.&#32;An MCP\-looking name does not itself establish a lower tier\.&#32;The existing&#32;`approval.test.ts`&#32;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 operation | Declaration | Boundary to retain |
| --- | ---: | --- |
| Ordinary&#32;`ReadTool`&#32;path | Usually read | URL reads can make network requests\;&#32;some specialized reads escalate\. |
| `ReadTool`&#32;or&#32;`GrepTool`&#32;targeting&#32;`ssh://` | exec | The higher tier does not grant remote access\. |
| `HubTool`&#32;peer&#32;`send`\,&#32;inbox\,&#32;waits\,&#32;and job&#32;`cancel` | read for these declared forms | Messaging\,&#32;consuming an inbox\,&#32;or cancelling a job can change agent\/job state\. |
| `HubTool`&#32;process&#32;`send`&#32;with a process name and no peer target | exec | Process input is classified differently from a peer message\. |
| Ordinary filesystem&#32;`WriteTool`&#32;target | write | The tier is not a workspace\-containment guarantee\. |
| `ManageSkillTool` | write | Its managed\-skill storage is not simply the current workspace\. |
| `EvalTool` | exec | A harmless\-looking cell does not lower this static declaration\. |

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

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

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

### Use tiers to predict a gate\,&#32;not to certify a program

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

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

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

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