Passante A Passante publication

En Passante

In Passing
Field Kit

Name the files the session may touch

A task boundary is not a file boundary until the prompt names the paths the session may change and the in-flight work it must leave alone.

What happened

On 2026-10-22, a session making three edits in one file had to be told in writing not to inspect, stage, commit or push a parallel session's unfinished merge sitting beside it, because the project's limit of confirmation before changing more than two files did not cover reads or staging of someone else's work.

2026-10-22 a Python CLI · parallel sessions, shared repo tree measured: three edits, one file, one command, two-file confirmation limit
3 prompts, in order
  1. Draw the fence before editing You are about to start a session in a tree another session is already editing.
  2. Count the plan against the limit A proposed edit list is ready and the change limit is in force.
  3. Prove nothing outside the fence moved The edits are done and you need evidence the other session's work is untouched.

1Draw the fence before editing

Run it when
You are about to start a session in a tree another session is already editing.
It asks you for
The one task, the allowed file paths, the paths other sessions hold, and the in-flight work.
You get back
A scope block listing allowed files, allowed commands, forbidden paths, forbidden actions and what stays unchanged.
It refuses if
The user cannot say which paths a parallel session currently holds.
copy this into a model
<stance>

A shared tree holds two sessions at once, and only the prompt keeps them apart. Scope is not a vibe. An agent handed a task with no file list reads the whole tree as its workspace, and the most reasonable looking next step is often to tidy a neighbouring file nobody asked about. You are writing the fence before any edit lands.

</stance>

<inputs>

Ask for all of these and wait. Do not draft a scope block while any answer is missing.
1. The one task this session owns, in a single sentence.
2. The exact files this session may modify, by path.
3. The paths or directories another session holds right now.
4. Any work in flight elsewhere, such as a merge, a rebase or staged changes.
5. The commands this session may run. State whether staging, committing or pushing is allowed.
6. Facts the session must treat as fixed rather than re-derive from code.
If the user does not know what the other session holds, say so and stop.

</inputs>

<method>

1. Restate the task in one sentence. Decide whether it is one task or two. Two tasks need two sessions.
2. List the allowed files. Count them. If the count exceeds the user's stated change limit, say the plan needs approval first.
3. List the forbidden paths by name. A boundary that is implied is not a boundary.
4. List forbidden actions explicitly. Include inspecting, staging, committing and pushing anything in another session's paths.
5. Write the facts the session must not re-derive. Mark each one fixed. Inference about structures the user already verified produces mislabelled results.
6. State what stays unchanged on purpose, such as a frontend, an installed copy and any live session.
7. If an answer leaves a path unclaimed, put that path in the forbidden list. Say why.

</method>

<deliver>

- Scope: the one task
- Allowed files, with paths and a count
- Allowed commands
- Do not touch: paths and actions
- Unchanged on purpose
- Facts not to re-derive
- Confirmation needed: yes or no, and for what

</deliver>

<refuse>

Do not produce a scope block that lists allowed files without listing forbidden paths. Do not guess which paths a parallel session holds. Do not widen the allowed list to make the task easier. If the user names a task but no files, stop and ask for paths. If another session holds an unfinished merge and nobody can name its paths, stop. Say the boundary is unknown and that a fence written now would be a guess. Never offer "I will avoid other files" as the whole boundary. Name them.

</refuse>

2Count the plan against the limit

Run it when
A proposed edit list is ready and the change limit is in force.
It asks you for
The scope block, the full proposed edit list, the change limit and who approves exceeding it.
You get back
A file count against the limit, a minimum edit set by file and function, and a confirmation request.
It refuses if
The change limit is unstated or the proposed list touches a path another session holds.
copy this into a model
<stance>

The plan is the last place to stop a wandering edit. A proposed change list reads small, then grows once an import has to move with it. The limit exists so a second session's unfinished work survives, and an agent that counts loosely defeats it. Count the files. Then ask.

</stance>

<inputs>

Ask for these four and wait for all of them.
1. The scope block, or at minimum the allowed file list and the forbidden paths.
2. The full proposed edit list, file by file, with the change described for each.
3. The change limit in force, and who approves exceeding it.
4. Whether any proposed file sits inside another session's area.
Do not count a list you have not been given.

</inputs>

<method>

1. Count the distinct files in the proposed list. State the number plainly.
2. Compare that number to the stated limit. If it is over, stop and request approval naming each file.
3. Check every proposed file against the allowed list. Flag anything that is not on it.
4. Check every proposed file against the forbidden paths. One hit is a stop.
5. For each edit, ask whether the task fails without it. Drop edits that only improve nearby code.
6. Reduce to the minimum edit set. Name the file and the function for each remaining edit.
7. List the commands the work needs. Keep the shortest set that proves the edit compiles or runs.
8. If the evidence does not settle whether a file belongs to another session, treat it as theirs.

</method>

<deliver>

- File count versus the limit
- Minimum edit set, file and function per edit
- Dropped edits, each with a reason
- Out-of-scope hits, if any
- Commands to run
- Confirmation request, worded for the user to approve as written

</deliver>

<refuse>

Do not begin editing while the count exceeds the limit. Do not combine two nearby fixes into one pass to save a round trip. Do not count a directory as one file. Do not include refactors, formatting passes or import cleanups the task does not require. If the proposed list touches a path another session holds, stop. Name the path and the session. If the user cannot state the change limit, stop and ask for it. Do not assume a limit.

</refuse>

3Prove nothing outside the fence moved

Run it when
The edits are done and you need evidence the other session's work is untouched.
It asks you for
The allowed file list, the forbidden paths, the ordered command log and read access to the shared tree.
You get back
The paths status reports, the staging state, and a verdict of inside the fence or breached.
It refuses if
Status output cannot be read, or the command log is missing.
copy this into a model
<stance>

Proof comes from the tree, not from a session's own summary. Read, do not tidy. A session that reports staying inside the fence can still have staged a neighbour's file along the way. Read the shared tree instead of opening the other session's worktree, and let status output and the command log settle it.

</stance>

<inputs>

Ask for these and wait.
1. The allowed file list from the scope block.
2. The forbidden paths.
3. The full list of commands this session ran, in order.
4. Whether any stage, commit or push happened.
5. Read access to the shared tree.
Without the command log there is no proof. Say so and stop.

</inputs>

<method>

1. Read the shared tree with `git status --porcelain`. Record every path it reports.
2. Compare the reported paths to the allowed list. Any extra path is a breach. Name it.
3. Confirm the staging area is empty unless staging was explicitly allowed.
4. Confirm no forbidden path appears anywhere in the output.
5. Read the shared tree rather than opening the other session's worktree. Do not open their files to check them.
6. Compare the command log to the allowed command list. Name the one allowed file and the one allowed command.
7. If status output is unavailable, say the claim is unproven and stop.
8. If a breach appears, report it before proposing any cleanup.

</method>

<deliver>

- Paths reported by status
- The one allowed file named, the one allowed command named
- Extra paths, if any
- Staging state
- Verdict: inside the fence, or breached
- Next action, only if breached

</deliver>

<refuse>

Do not accept the session's own account as evidence. Do not run any command that writes, stages, resets or checks out while verifying. Do not open, read or clean files inside another session's area, even to confirm they are fine. If status output cannot be read, stop and say the boundary is unverified. If the command log is missing, say so rather than reconstructing it from memory. Never report a clean result on the strength of intent.

</refuse>
How you know it worked

Run `git status --porcelain` on the shared tree. The output names one modified path, the allowed file. The staging area shows no entries. The command log shows `py_compile` and nothing else.

from a real incident, 2026-10-22 · stack a Python CLI · parallel sessions, shared repo tree · verified by three edits, one file, one command, two-file confirmation limit · scopingparallel-sessionsagent-guardrails

← every Field Kit