Explore, with the pen taken away

Read-only exploration: letting an agent look without letting it touch

Ask a coding agent to work out how your auth path reaches the database and it will read files, run greps, open a test, and quite possibly rewrite something on the way. The rewrite happens during the deciding, not during the doing. By the time you read the result, the repository has already moved and reviewing it has turned into archaeology.

Disclosure: I build Ordewell, and a read-only envelope is how its planner works. The interesting part is not the flag. It is what the flag does and does not promise, and there is one failure mode in this area that is worse than having no read-only mode at all.

Exploration is the phase that surprises you

A build request is bounded. You asked for rate limiting on the public route, so a competent agent touches the limiter and maybe the config. An exploration request is unbounded by nature: to say how auth reaches the database, the agent has to decide which files are relevant, and that decision is made by looking. Looking invites edits, because the cheapest way to test a hypothesis about a codebase is to change it.

Three things go wrong in that window. Unrelated files pick up changes that look like yours. The agent's own summary of the codebase becomes the thing you are reviewing, and you cannot tell which parts are findings and which are inventions. And if the session is long enough, the work it eventually does rests on edits it made to its own context on the way. None of those are model-quality problems. They are a permission problem.

What read-only means in each CLI

Read-only is not a property of a model. It is a property of a process, and every coding CLI spells it differently. In Ordewell a planning session is started with the strongest form each harness exposes:

The guarantee is enforced at spawn, not by asking the model politely in a prompt. That distinction holds up under pressure: when a planning session requests a write anyway, it gets a refusal rather than a permission dialog.

a write request from the planner
request  Write(src/auth/session.ts)
deny     The Ordewell planner is read-only.
         Mutation belongs to the runners that execute the plan.

Read-only never means the agent sits still. To explore anything it has to run commands, and most of those are inspection: listings, grep, git log, reading a test file. Those run unprompted, because prompting on a read is how an agent turns into a dialogue box. Anything outside that read-only surface is classified before it runs and denied, and the classifier has to understand the shell it is in rather than pattern-match a string, since dir under cmd.exe and dir in a POSIX shell are not the same program.

The envelope is per task, not just per planner

The planner is the obvious place for a read-only session. It is not the only one. A plan usually contains a step whose whole deliverable is understanding: measure the current query counts, confirm which module owns session refresh, list every caller before the signature changes. Those steps want to run in the same envelope, so in Ordewell mode is an assignment on the task like its runner and model.

bash
ordewell task-mode 6          # prints the modes this runner exposes, current one starred
ordewell task-mode 6 plan     # keep this task read-only when the plan runs

The useful part is that it is a line in an artifact you read before execution, so an analysis step cannot silently become a code change because the agent got ambitious halfway through. If the task's real output is a decision, say so in the plan and the executor keeps its hands off.

The failure mode that is worse than no sandbox

Here is the part worth knowing before you trust any read-only setup, mine included. A read-only session that cannot run commands does not stop and tell you. It answers from memory, plus whatever it can fetch from the web, and produces a confident plan about a codebase it never read.

A concrete instance, because this is not hypothetical: on Ubuntu 24.04, AppArmor restricts unprivileged user namespaces, so Codex's bubblewrap sandbox fails to start and every command the planner runs dies with an error about the network interface. The agent still replies. What it replies with is a guess shaped like a plan.

The repair is to find out which sandbox actually works on that machine instead of assuming. Ordewell asks the binary rather than reading /proc or /etc/apparmor.d, because it is the same question put to the thing that has to answer it, and it costs one short process. If bubblewrap cannot start, Codex is pointed at its earlier Landlock backend, which needs no namespace and still denies the writes that make read-only planning read-only. If both fail, the honest reading is that Codex cannot explore on this machine at all, and that is a different problem than a plan you dislike.

What a read-only envelope does not give you

Running it

The planner runs read-only by default, and nothing in the plan executes until you say go, so exploring costs you nothing but the plan itself.

bash
npm install -g ordewell

AI_PROVIDER=claude-code ordewell plan --goal "Map how request auth reaches the database layer"
ordewell task-mode 6 plan
ordewell run

If you want the wider argument for separating the thing that decides from the thing that writes, plan-first orchestration covers when that shape wins, and assigning an executor per task is where the runner, model and mode decisions live. The verification side is the other half of the same question: an envelope controls what an agent may change, and a marker decides whether it actually did the job.