Repository navigation
Description
Description
Reproduced on current v2.
A body in an agent markdown file replaces the assembled system prompt instead of contributing to it. Adding a role to an agent silently removes the harness prompt and the tool usage guidance, and nothing tells the author it happened.
This makes it impossible to have both a custom role and the harness contract.
Current behavior
packages/core/src/session/model-request.ts:
system: [
input.agent.system
? input.agent.system
: SessionSystemPrompt.make(input.tools.definitions.map((tool) => tool.name)),
input.initial,
]SessionSystemPrompt.make is not persona. Since #42638 it is session/runner/prompt/system.txt plus per-tool rules derived from the tools the request actually advertises — edit's oldString/replaceAll semantics, write versus edit, shell chaining.
The branch cannot tell "this agent has a role" apart from "this agent supplies a contract", and treats both as a full replacement.
The replacement semantics were introduced in #34275, to stop the built-in build agent's one-line default from shadowing the per-family prompts, which ran 100–155 lines each. Since #42638 the fallback is 14 lines plus mechanical tool rules. The justification for replacement no longer applies to the fallback that exists now.
Reproduction
Two agents in ~/.config/opencode/agents/. Same location, same tools advertised, same model.
auditor.md
---
description: Read-only reviewer.
mode: subagent
---
You are an auditor. You inspect code and report findings. You never edit anything.runner.md
---
description: Implementation agent.
mode: subagent
---Captured LLMRequest.system[0]:
auditor — body present:
You are an auditor. You inspect code and report findings. You never edit anything.
runner — frontmatter only:
You are an AI agent running in OpenCode, a coding agent harness. Help the user accomplish their goals using the tools you have available.
# Harness
- Responses are rendered as GitHub-flavored Markdown.
- `<system-reminder>` blocks are harness instructions, not user-authored content. Read and follow them.
- Prefer parallelizing independent tool calls.
- Prefer dedicated tools over shell commands; fall back to the shell when a tool cannot do what you need.
- Do not chain shell commands with separators like `echo "====";` or `printf '---';`; the output becomes noisy in a way that makes the user's side of the conversation worse.
- Use the write tool to create files or completely replace their content. Prefer using the edit tool for targeted changes.
- Use the edit tool for targeted changes to existing text files. It replaces the exact text in `oldString` with `newString`, and the values must differ. By default, `oldString` must occur exactly once. If it occurs multiple times, include more surrounding context to make it unique or set `replaceAll` to true to replace every occurrence.
# Communication
- Use clear file paths when referring to files.
- Keep responses clear and concise, and avoid unnecessary technical jargon.
# Working in codebases
- Keep changes consistent with the structure, naming, style, and patterns of the surrounding code.
- Treat unfamiliar files or changes as potential user work and investigate before deleting or overwriting them.
The five tool lines describe how edit resolves an ambiguous match. An author adding a role almost never wants to restate them by hand, and gets no indication that they were dropped.
Why additive is the consistent choice
Model identity is already layered on top of whatever the agent contributed. packages/core/src/plugin/identity.ts:
event.system.splice(1, 0, SystemPart.make(identity({ name: model.name, ref: event.model })))Agent role could use the same insertion.
Proposal
agent.systemis additive by default, inserted after the harness- add an opt-out that keeps full replacement for agents that genuinely want a clean context —
title,summaryandcompactiondeny all tools and want only their persona. Existing replacement behavior stays available, so this is not a regression for anyone relying on it - an empty or missing body means "no role", which is valid under either mode and needs no separate special case
If a mode flag feels like too much surface, the minimal version is additive with no opt-out, and the three built-in agents that want a clean context keep an explicit replacement. Either works; the flag is only there to avoid breaking documented behavior.
Putting the harness first also helps prompt caching. system[0] becomes identical for every agent that shares a tool snapshot, instead of diverging at byte zero per agent.
Related
- [FEATURE]: More prompt control in Agent V2 #53411 asks for
SystemPrompt: false. This is the inverse: the harness should not need removing, it should not be replaceable in the first place. - [FEATURE]: Allow project-local agent files to extend (not just replace) the global agent prompt #15773 asks for project-local agent files to extend rather than replace a global agent's prompt. Same underlying complaint.
- An empty body is currently indistinguishable from a missing one (
config/plugin/agent.tsassignsmarkdown.content.trim()unconditionally, and""is falsy at the ternary above). Under an additive default this stops mattering.
Activity
opencode-agent commentedon Oct 17, 2026
Thanks for the detailed write-up and the clear reproduction. I think this is a duplicate of #34774, which is still open. It covers this exact behavior (a non-empty agent
systemreplaces the stock OpenCode prompt instead of adding to it) and is where the design for additive prompt layering versus explicit override is being discussed.Possible duplicates and related issues, most likely first:
SystemPrompt: false; related prompt-control request, but the opposite directionYour points about #42638 changing what the fallback contains, the empty body versus missing body case, and prompt caching would be useful on #34774.
The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
geril07 commentedon Oct 17, 2026
Duplicate of #34774, which is open and tagged gang-grill. The delta from this report — that #42638 changed the nature of the fallback from per-family persona to a 14-line harness plus tool contracts, plus the prompt-cache and ordering notes — has been posted there as a comment.
opencode-agent commentedon Oct 17, 2026
Thanks for confirming and for moving the new details to #34774. That keeps the design discussion in one place. The bot will close this issue as a duplicate of #34774 as planned.
opencode-agent commentedon Oct 18, 2026
Closing this as a duplicate of #34774, as discussed. Thanks for adding your points on #42638, prompt caching and ordering there. Please follow #34774 for the additive prompt layering design.