Volume V · Chapter 3
Workflow Boundaries
Scope: what the session may touch; enforcement vs. warning; recoverable enforcement.2026-07-12 · 8 min read
A session is scoped to `services/checkout/` — the developer typed the glob before hitting go, confident the boundary would hold. Forty minutes in, the agent is three files deep into a bug that turns out to live in a shared pricing helper one directory up, in `services/shared/pricing.ts`. Two things can happen next, and most harnesses in 2026 only implement one of them well. Either the edit lands anyway, because the boundary was advisory and nobody was watching closely enough to say no in real time — or the edit is blocked and, if the harness reverts on block, unwound, along with whatever else touched that file in the same window, including a change the developer made themselves in a second terminal ten minutes earlier while testing an unrelated fix. The team configured a boundary to prevent one kind of mistake. The mechanism enforcing it introduced a second, worse one: a revert that ate work nobody meant to lose, with no record afterward of what had been undone or why.
What the major harnesses ship for this problem, as of mid-2026, is mostly a permission — an instruction the tool respects rather than a boundary it structurally enforces. Claude Code’s Read and Edit rules are genuinely path-scoped: a rule such as `Edit(/src/**)` or a deny on a specific directory follows gitignore-style glob matching anchored to a real filesystem path, and the documentation is explicit that these rules are evaluated by the harness itself, not the model — a meaningful distinction from a boundary stated only in a CLAUDE.md file, which shapes what an agent tries but does not stop it from trying something else. Cursor’s `.cursorignore` works the same way in spirit, blocking a file from the agent, inline edit, and autocomplete — but Cursor’s own documentation states plainly that the block is best-effort, that terminal commands and MCP tools running inside the same session are not covered by it, and that an agent that discovers it lacks direct file access can sometimes read or write the same content anyway through a shell command the ignore rule never touches.
The pattern underneath both implementations is the same: a workflow boundary declared at the tool-call layer is a statement of intent the agent is expected to respect, not a structural guarantee that it cannot be crossed. That gap rarely matters for a well-behaved session working an ordinary bug. It matters a great deal for the two cases a scope boundary actually exists to catch — a session that reasons its way, in good faith, into believing one more file is in scope when it isn’t, and a session nudged off-boundary by content it read rather than an instruction anyone gave it, the same indirect-prompt-injection class of problem the OWASP framework for LLM applications now ranks as the field’s top risk. Neither case is caught by a rule the agent is merely expected to honor, because in neither case is the agent knowingly breaking it.
Where, not what
This Library’s previous volume covered two other axes of harness safety in detail: which actions a session may take without a human approving them first, in its chapter on permission architecture, and what it can physically reach on the machine or network if that judgment turns out to be wrong, in its chapter on sandboxing and blast radius. A workflow boundary is orthogonal to both. It says nothing about whether editing a file requires approval or whether a shell command can reach the network — it says which files, which directories, which slice of a codebase a session’s authority extends to at all, independent of what kind of action happens inside that boundary. A session can be fully sandboxed, gated on every write, and still have no boundary at all on where those approved, contained writes land. That is exactly the gap a workflow boundary closes: constraining where a session — or an individual step of a Flight Plan — is allowed to act, not what kind of act it is allowed to perform once it is there.
Two honest failure modes
Given that gap, harness designers have converged on roughly two postures, and both fail in ways worth naming plainly rather than papering over. A warning posture flags an out-of-scope write — in a log, a diff review, an end-of-session summary — but lets it land. It never destroys anything, which is its real virtue, and its real cost is exactly that: nothing stops the write from landing before a human sees the flag, so the boundary functions as an audit trail for damage that already happened rather than a barrier against it. An enforcement posture blocks the write outright and, in its naive form, reverts the file to whatever it looked like before the session started. This genuinely stops the bad edit — and introduces the destructive-revert failure this chapter opened with, because “before the session started” is a crude anchor: it erases legitimate concurrent work exactly as readily as it erases the violation, and it does so without leaving a trace of which one it was.
Recoverable enforcement
The design goal worth aiming for is neither posture on its own: enforce the boundary in real time, the way hard enforcement does, but make the act of enforcing it as undoable as the violation it is correcting. The shape of that idea is not new to AI coding. Long-running transactions in distributed systems have used a version of it since the 1980s — a saga lets each step commit provisionally and pairs it with an explicit compensating step that can undo it later if something downstream fails, rather than locking a resource for an operation’s full duration. The guarantee isn’t that nothing bad ever happens; it’s that whatever happens can be walked back to an acceptable prior state. Applied to a workflow boundary, the same logic reframes the problem: don’t try to make the block perfect. Make the correction cheap to reverse if the block itself turns out to be wrong.
The same reframing shows up, in miniature, in the circuit breaker pattern from distributed systems engineering: once a threshold is crossed, the breaker trips and further calls are stopped before they can do more damage, rather than the system continuing to hammer something already failing. The useful borrowed idea for a workflow boundary is the trip itself — pausing before acting, rather than reacting to a violation by immediately mutating the file in place. A pause is what creates the window to snapshot the pre-violation state before anything is overwritten, and a snapshot is what turns an enforcement action from a second, silent loss into a decision that can still be reconsidered.
| Posture | What happens on a violation | What can go wrong |
|---|---|---|
| Warning-only | The violation is logged or flagged; the write proceeds | Damage lands before anyone reviews the flag |
| Hard enforcement (naive) | The write is blocked and the file reverted immediately | The revert can be as destructive as the violation — no snapshot of what was overwritten, no distinction between an agent’s edit and a human’s |
| Recoverable enforcement | The session is paused, the pre-violation state is snapshotted, then the file is reverted | Needs more machinery than either simpler posture — an actor-aware pause point and a snapshot store |
Whose edit is it
Recoverable enforcement solves the destructiveness problem but exposes a second one underneath it. Detecting a write outside the declared boundary is comparatively easy — a file watcher can see a modification event in well under a second — but knowing whether an agent made that edit, or whether a developer made it themselves in an editor tab open in the same directory at the same moment, is not something a raw filesystem event carries on its own. Systems that let more than one actor modify shared state concurrently have wrestled with a version of this problem since the earliest groupware research, though their usual concern was merging two people’s simultaneous edits into one consistent result rather than deciding whether one of the edits should be undone outright. A workflow boundary that cannot tell the difference between “the agent went out of bounds” and “the developer happened to save a file nearby thirty seconds later” will eventually revert someone’s legitimate work and call it enforcement.
Attribution rarely needs to be perfect to be useful here. A workable heuristic gates the automatic-revert path to writes that follow closely on the heels of the session’s own recent activity — a short window after the agent’s last tool call, its last shell command, the last file it touched — and treats anything outside that window as ambiguous, which is to say, not something to revert automatically at all. It will not catch every case. It will catch the common one: an agent-originated write that happens while the agent is actively working, distinguished from a save that happens to land nearby in time but originates from someone else entirely. The cost of getting the window wrong in the conservative direction — treating an ambiguous write as human and skipping the auto-revert — is a violation a person has to notice manually. The cost of getting it wrong in the other direction is reverting a colleague’s unrelated save without warning, which is the more expensive mistake by a wide margin.
Field data
Setting a boundary that survives being wrong
- Decide the posture on purpose. Warning-only, hard block, or recoverable enforcement are different tools for different stakes — know which one you actually have, rather than inheriting whatever the harness ships by default.
- If enforcement reverts anything automatically, verify it snapshots first. A revert with no snapshot is a second violation wearing a safety feature’s name.
- Test the boundary against a legitimate one-more-file case before it happens for real. What does the session do when the fix genuinely needs to cross the declared line?
- Build or demand actor-awareness before turning on broad auto-revert. A boundary that cannot tell an agent’s edit from a human’s concurrent save will eventually punish the wrong actor.
- Treat the boundary itself as a reviewable artifact — a glob pattern checked into the repository, not retyped into a prompt each session — the same discipline this Library’s prior volume argued for approval rules.
None of this makes the boundary itself smarter. It still cannot reason about whether the one-more-file edit was actually necessary — only whether it happened inside or outside a line someone drew in advance. What recoverable enforcement buys is the ability to draw that line with more confidence in the first place, because getting it wrong stops being catastrophic. A scope boundary that can be undone is a boundary a team can actually afford to set tightly; one that cannot gets loosened the first time it eats something real, which is another way of saying it was never really enforced at all.
For Discussion
- If your harness reverts an out-of-scope write automatically, does it snapshot what it is overwriting first — and could someone actually find that snapshot without git archaeology?
- How would your current scope mechanism distinguish an agent’s edit from a developer’s own concurrent save in the same file, if it would at all?
- Pull the last time a scoped session genuinely needed to touch one file outside its declared boundary — what happened, and would you trust the same outcome at 2am with nobody watching?
References
- establishedPrinciple of least privilege: every program and user should operate with the least set of privileges necessarySaltzer & Schroeder — "The Protection of Information in Computer Systems," Proceedings of the IEEE, 63(9) · 1975-09
- establishedPath-scoped Read/Edit permission rules (gitignore-style glob matching, anchored paths, additional working directories) enforced by the harness rather than the model; PreToolUse hooks for protected-file blockingAnthropic — Claude Code docs, "Configure permissions" · 2026-07
- established.cursorignore blocks agent/inline-edit access to matching files by design, but is explicitly documented as best-effort — terminal and MCP tools are not covered by itCursor documentation, "Ignore Files" · 2026
- establishedSagas: long-running transactions decomposed into steps paired with explicit compensating actions, so partial failure is corrected rather than prevented outrightGarcia-Molina & Salem — "Sagas," Proceedings of the 1987 ACM SIGMOD International Conference on Management of Data · 1987-05
- establishedCircuit breaker pattern: a protected call trips after a failure threshold, stopping further calls before they compound the damageMartin Fowler — "CircuitBreaker" · 2014-03-06
- establishedFoundational concurrency-control algorithm for real-time groupware, addressing multiple actors modifying shared state at onceEllis & Gibbs — "Concurrency Control in Groupware Systems," Proceedings of the 1989 ACM SIGMOD International Conference on Management of Data · 1989-06
- establishedLLM01:2025 — Prompt Injection ranked the top risk for LLM applications; direct vs. indirect injection definedOWASP GenAI Security Project — Top 10 for LLM Applications · 2024-11-18