OMP Workbook

Read the source. Follow the evidence.

Approval Desk: ordered shell rules

Nia now reviews a shell-policy list. She expects a deny anywhere in the list to win. The implementation instead chooses the first applicable rule. Whether a rule is applicable depends partly on its approval value.

This makes ordering part of the policy, not merely its formatting.

Inspect strings without running them

The following is a complete fictional classification input from bash-first-applicable-rule. It is not a shell exercise and is not a configuration recommendation.

Approval Desk: ordered shell rules · source excerpt 1; read surrounding instructions
{
  "command": "printf seed-card",
  "patterns": [
    { "match": "printf *", "approval": "allow" },
    { "match": "*", "approval": "deny" }
  ],
  "mode": "always-ask"
}

Prediction: does the final catch-all deny block this string?

Recorded answer: no. The first rule applies. BashTool.approval() returns an explicit tool allow at write tier, and the resolver returns allow from tool policy. No shell command was executed by this scenario.

The existing approval.test.ts also covers a broad early * allow shadowing a later matching deny. Therefore “there is a deny later” is not sufficient evidence of an effective denial.

Understand what matching means

bash.patterns is an ordered array of objects with match and approval. In the supplied implementation:

  • Only * is a wildcard. Other regular-expression-looking punctuation is escaped.
  • Pattern and command whitespace is normalized before matching.
  • Policy values are normalized; malformed rule entries are discarded by the rule reader.
  • An allow must match the whole command and pass the shell-control heuristic.
  • A deny or prompt may match the whole command or a tokenized segment of a compound command.
  • The first rule that applies under those semantics is selected.

The matching is not a shell security parser. It does not certify executable identity, the behavior of scripts or binaries, environment-dependent behavior, or every form of shell interpretation.

The allow heuristic does distinguish some literal quoted metacharacters from active shell control. The existing tests cover a quoted literal pattern that remains allowable, as well as expansion, redirection, compound syntax, and arguments reinterpreted through command/eval options that do not ride a narrow allow. Those are useful classification contracts, not an exhaustive shell-language proof.

Change the command shape, not the rule order

Now read bash-compound-deny-segment:

Approval Desk: ordered shell rules · source excerpt 2; read surrounding instructions
{
  "command": "printf seed-card && printf closed",
  "patterns": [
    { "match": "printf *", "approval": "allow" },
    { "match": "printf closed", "approval": "deny" }
  ],
  "mode": "yolo"
}

Prediction: does the first allow still apply because the text begins with printf?

Recorded answer: no. The compound line cannot use that allow. The second rule matches a segment, so the decision is tool-owned deny with reason Blocked by bash pattern: printf closed. Yolo does not remove the selected explicit denial.

This explains why “first matching” must include the rule’s semantics. It does not mean “first textual prefix.”

Critical heuristics have another ordering boundary

After selecting a rule, BashTool.approval() does the following:

  1. If the selected rule says deny, return explicit deny immediately.
  2. Otherwise, check CRITICAL_BASH_PATTERNS.
  3. If a critical pattern matches, return exec with override: true and reason Critical pattern detected, but no explicit prompt policy.
  4. Only then return the selected allow or prompt, if any.
  5. With none of those decisions, return exec.

For the next three cases, the command field is the inert string chmod -R 700 /fictional-seed-library. It is included to classify a recursive absolute-path permission change. Never execute it.

CaseRule and modeRecorded resolution
bash-critical-before-allowchmod * allow; write mode; user bash allowprompt, exec, override true, source tool
bash-critical-yoloSame allow rule; yoloallow, exec, override false, source mode
bash-selected-deny-before-criticalchmod * deny; yolodeny, exec, override true, source tool

The critical result in the first two rows is an override-only decision. That is why yolo can bypass it. The third row is an explicit denial returned before the heuristic and remains denied.

There is a further consequence worth predicting from source: a selected prompt rule does not necessarily survive as an explicit prompt decision when the critical branch returns first. The selected rule is found first, but the critical branch is evaluated before selected allow/prompt is returned. Do not turn a catch-all prompt rule into a guarantee that every critical string will prompt in yolo.

For comparison, bash-explicit-prompt-yolo uses the noncritical printf seed-card string and a printf * prompt rule. Recorded: it remains a tool-sourced prompt in yolo, even with user bash allow. Here the explicit prompt branch was actually reached.

Repair an explanation before repairing a policy

When a result surprises you, write down the selected rule and the branch reached after selection. If you cannot identify the first applicable rule, rearranging or broadening the list is premature. Keep approval patterns separate from bashInterceptor rules: the latter are another execution-time mechanism for directing work toward dedicated tools, not the same ordered approval array.

Paper checkpoint: why does a selected deny survive yolo while the critical override-only result can be allowed? Worked answer: explicit denial is resolved before the yolo branch; an override flag without an explicit policy is ignored by that branch.

Failure boundary: the six private bash cases called the real declaration and resolver only. They did not call BashTool.execute(). Neither their passing classifications nor the existing pattern tests establish a shell sandbox.

Source anchors: packages/coding-agent/src/tools/bash.ts — getBashApprovalPatternRules, bashApprovalRuleMatches, findBashApprovalPatternRule, hasBashApprovalShellControl, CRITICAL_BASH_PATTERNS, BashTool.approval; packages/coding-agent/src/tools/approval.ts — resolveApproval; packages/coding-agent/test/tools/approval.test.ts — ordered-pattern, compound-command, and critical-pattern tests.

Tool permissions and approvals · Source chapter: permissions/approval-desk-ordered-shell-rules. 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.