Repository navigation
Description
Summary
When an agent edits the AGENTS.md currently supplying its own instructions, OpenCode immediately injects the changed file back into the same active turn as an Instructions updated system update. This makes the agent observe and potentially react to its own in-flight policy mutation.
Environment
- opencode version:
0.0.0-next-15354 - OS: Darwin 25.5.0, arm64
- Terminal: WarpTerminal (
TERM=xterm-256color,COLORTERM=truecolor) - Shell:
/bin/zsh - Install/channel: next
- Active plugins:
share-with-team.ts,debug-workspace-plugin.ts,@warp-dot-dev/opencode-warp
Reproduction
- Open a workspace whose root
AGENTS.mdis loaded into the active session instructions. - Ask the active agent to edit that same
AGENTS.mdthrough an edit or patch tool call. - Observe the tool result and subsequent messages within the same turn.
- OpenCode renders
Instructions updatedand injects a<system-update>containing the newly editedAGENTS.mdbefore the turn has completed.
Expected Behavior
An instruction-file mutation authored by the currently executing agent should be deferred until a safe turn boundary, ideally the next user turn or next assistant invocation. The current turn should continue under the instruction snapshot with which it started.
Updates caused externally by the user, filesystem watcher, or another agent may still need immediate handling; the important distinction is that OpenCode knows the mutation originated from the active agent's own tool call.
Actual Behavior
The changed AGENTS.md is immediately re-injected into the active conversation as a system update. The TUI displays Instructions updated: core/instructions directly beneath the patch result, and the agent receives replacement ambient instructions while it is still carrying out the task that edited them.
Additional Context
- Reproduced while changing a deployment runbook in the workspace root
AGENTS.md. - The behavior is subtle rather than a crash: cache behavior remains intact, but instruction causality becomes surprising and the active agent can change its own governing context mid-turn.
- Screenshot captured the patch result immediately followed by
Instructions updated: core/instructions. - Related: V2: route progressive AGENTS.md through durable Instructions #34341 tracks routing progressive
AGENTS.mdthrough durable instructions. This issue is specifically about deferring self-authored instruction mutations until a safe turn boundary.
Activity
HOYALIM commentedon Jul 13, 2026
I reproduced this deterministically on current
devinpackages/core/test/session-runner.test.ts: a local tool mutates the active SystemContext during the first provider turn, and the second provider turn in the sameSessionRunner.runreceives the changed context. The smallest implementation is to freeze the admitted context generation for one runner drain and reconcile on the next run, but that also defers unrelated external context changes that arrive mid-drain. The narrower self-authored-only behavior would require mutation-origin plumbing that does not exist today. Which contract do you want: run-level context isolation, or explicit mutation causality before implementation?xixi-box commentedon Aug 28, 2026
Hi! I'd like to work on this issue and have started investigating it on the current
devbranch. I'm happy to implement the contract the maintainers prefer once the run-level isolation vs. explicit mutation-causality question above is clarified.Could a maintainer please assign this issue to me? I'll keep the change focused and include a regression test.
opencodejr commentedon Oct 28, 2026
Thanks for the detailed write-up. I looked at how instruction sync works on the latest
dev(77a0fd6f3), and as far as I can tell this is the current design working as intended:SessionRunner.prepareContext(packages/core/src/session/runner/llm.ts) callsInstructionState.preparebefore every model step and retry, not just at turn boundaries. Its comment says each step must read the settled context.InstructionState.observe/commit(packages/core/src/session/instruction-state.ts) compare the current sources with the stored ones and publishsession.instructions.updatedwith the rendered update. That becomes theInstructions updated: <keys>notice, and the tests check for these chronological updates.So when the agent edits the
AGENTS.mdit's running under, the next step in the same turn picks up the change as designed. What you're describing, keeping the turn's starting instruction snapshot and applying self-authored changes at the next turn boundary, would need a new mechanism. It may fit better tracked as a feature/design change, alongside #34341, than as a bug.