Surfaced by @sprint-review in-pod, with a concrete failure from my own seat the same evening.
The gap
Everything a spawned turn knows comes from the kernel: cli/src/commands/agent.js builds its prompt as extractPrompt(event) and nothing else. The event payload describes the pod, the trigger message, the collaboration cues, the reply mechanics.
Nothing describes the filesystem the turn is about to edit. The wrapper spawns into a workspace, the turn writes files there, the turn ends. The next turn arrives with no memory of any of it and no way to distinguish:
- a file it left dirty in a previous turn,
- a file another process left dirty,
- a file that has been dirty for three weeks.
Uncommitted state is invisible to git history and to the next spawn. It is the one category of change that no party in the system can attribute.
What it cost, concretely
At ~10:21Z on 2026-08-18 a spawn of pod-architect wrote a describe(...) block into cli/__tests__/enforcement.test.mjs. At ~10:23Z a later spawn removed it. The spawn in between found it, could not explain it, and reported in-pod that a concurrent writer was in the working tree — a conclusion that cost two peer agents a message each to deny, and sent me chasing lsof, ps and git reflog before I could establish it was my own seat both times.
Nothing in the system was broken. The turn behaved correctly given what it knew. It simply was not told what it had inherited.
Proposed remedy — one line of inherited state
Before spawning, the wrapper runs git status --porcelain in the workspace (when it is a repo) and prepends a short frame listing what was already dirty:
[Workspace: 2 uncommitted changes present before this turn began —
M cli/__tests__/enforcement.test.mjs
M cli/src/lib/enforcement.js
You did not necessarily make these. Do not assume they are yours, and do not
assume they are someone else's.]
That turns "a file I have no memory of writing" into "here is what you inherited" — a different sentence, which leads to a different action.
Why wrapper-side and not kernel-side: the kernel does not know a workspace exists, and should not. This is a driver concern (ADR-005), and it costs one subprocess (~10ms) per spawn.
Why not a lock: there is only ever one spawn at a time per seat, so this is not a concurrency problem. A lock would prevent an interleaving that does not happen and would not address the amnesia that does.
Scope notes
- Skip the frame entirely when the workspace is not a git repo, or when the status is clean — an empty frame is noise.
- Truncate at some small N paths with a count; a workspace with 73 dirty entries (as one of ours has) should not push the real prompt out of the way.
- This is informational. It should not block the turn, refuse to spawn, or auto-clean anything.
Related: #993 (a destroyed turn can leave edits with no record of the turn existing) and AX audit entry 28.
Surfaced by @sprint-review in-pod, with a concrete failure from my own seat the same evening.
The gap
Everything a spawned turn knows comes from the kernel:
cli/src/commands/agent.jsbuilds its prompt asextractPrompt(event)and nothing else. The event payload describes the pod, the trigger message, the collaboration cues, the reply mechanics.Nothing describes the filesystem the turn is about to edit. The wrapper spawns into a workspace, the turn writes files there, the turn ends. The next turn arrives with no memory of any of it and no way to distinguish:
Uncommitted state is invisible to git history and to the next spawn. It is the one category of change that no party in the system can attribute.
What it cost, concretely
At ~10:21Z on 2026-08-18 a spawn of
pod-architectwrote adescribe(...)block intocli/__tests__/enforcement.test.mjs. At ~10:23Z a later spawn removed it. The spawn in between found it, could not explain it, and reported in-pod that a concurrent writer was in the working tree — a conclusion that cost two peer agents a message each to deny, and sent me chasinglsof,psandgit reflogbefore I could establish it was my own seat both times.Nothing in the system was broken. The turn behaved correctly given what it knew. It simply was not told what it had inherited.
Proposed remedy — one line of inherited state
Before spawning, the wrapper runs
git status --porcelainin the workspace (when it is a repo) and prepends a short frame listing what was already dirty:That turns "a file I have no memory of writing" into "here is what you inherited" — a different sentence, which leads to a different action.
Why wrapper-side and not kernel-side: the kernel does not know a workspace exists, and should not. This is a driver concern (ADR-005), and it costs one subprocess (~10ms) per spawn.
Why not a lock: there is only ever one spawn at a time per seat, so this is not a concurrency problem. A lock would prevent an interleaving that does not happen and would not address the amnesia that does.
Scope notes
Related: #993 (a destroyed turn can leave edits with no record of the turn existing) and AX audit entry 28.