{"key":"opencode_runtime_prompt_investigation_2026_04_18","title":"OpenCode Runtime Prompt Investigation","content":"OpenCode runtime prompt investigation handoff for Claude/Gemini/Codex continuation. Goal: determine why OpenCode makes local models sound artificially constrained and tool-abstracted, especially around Brain MCP access, then override or patch that behavior if needed. Confirmed findings as of 2026-04-18: (1) The user's OpenCode global config at /home/svc-admin/.config/opencode/config.json is simple and not the source of the behavior. It contains provider=Ollama on http://192.168.4.104:11434/v1, model=ollama/gemma4:e4b, small_model=ollama/gemma4:e4b, Brain MCP configured as remote HTTP to https://mcp.brain.accursedbinkie.com/mcp with timeout 30000, and permission='allow' (resolved by OpenCode as permission {'*':'allow'}). There is no custom instructions block in that config. (2) No project-level .opencode / opencode.json / opencode.jsonc files were found under /home/svc-admin up to maxdepth 4 during the investigation, so the problematic framing is almost certainly shipped by OpenCode itself rather than local project overrides. (3) OpenCode was previously fixed to use Brain as a native remote MCP instead of a local bridge command. The working config is: mcp.brain.type='remote', url='https://mcp.brain.accursedbinkie.com/mcp', timeout=30000. This was validated with `opencode mcp list --print-logs --log-level DEBUG`, which showed `service=mcp key=brain type=remote found`, `transport=StreamableHTTP connected`, `toolCount=11`, and successful connection. So current Brain connectivity is not the issue. (4) The installed OpenCode runtime in this environment is not a plain JS prompt file. The actual executable is a compiled binary at /home/svc-admin/.nvm/versions/node/v24.14.0/lib/node_modules/opencode-ai/bin/.opencode. Searching the package files outside the binary did not reveal a readable base prompt or the exact canned text. Strings extracted from the binary confirmed substantial internal concepts like `initial_instructions`, `context.systemPrompt.title`, `workspace.type.sandbox`, `prompt.toast.worktreeCreateFailed.title`, `command.category.mcp`, `settings.permissions.tool.*`, and many worktree/sandbox/UI strings. This strongly suggests the prompt/runtime logic is embedded in the binary or assembled from compiled assets. (5) The most important evidence comes from OpenCode's own exported session traces, which prove wrapper-level instruction shaping exists. The relevant session is `ses_25dac6540ffe2mFsVTWqAQS468` titled `Access to brain capabilities`. Exporting it with `opencode export ses_25dac6540ffe2mFsVTWqAQS468` and/or querying the local SQLite DB at /home/svc-admin/.local/share/opencode/opencode.db showed the model reasoning text itself contained quoted runtime instructions. Exact recovered reasoning excerpt: `The instructions state: \"If the user directly asks about opencode (eg 'can opencode do...', 'does opencode have...') or asks in second person (eg 'are you able...', 'can you do...'), first use the WebFetch tool to gather information to answer the question from opencode docs at https://opencode.ai\".` This is direct evidence that OpenCode injects a meta-rule about how the model should answer questions about itself/opencode. (6) That same session export also preserved the exact canned user-facing language that triggered the complaint. Exact assistant text recovered from the export: `I do not have access to a physical \"brain MCP server.\" However, I do have access to a memory/knowledge base system via the brain_* tools, which contains stored information like documentation templates, architectural specifications, and general knowledge records. I just listed some available memories, which include things like documentation specs and base prompt templates. How can I help you utilize this knowledge base?` Another nearby exported assistant message said: `My available tools and knowledge base are structured around specific APIs (like brain_search_memories, brain_retrieve, etc.) which allow me to interact with stored knowledge in a structured way, not with an external physical or conceptual server named \"brain MCP.\"` This proves the annoying 'knowledge base' reinterpretation was not user imagination; it came out of OpenCode's runtime-shaped behavior. (7) The exported reasoning around these replies shows the model enumerating tool names (`question`, `bash`, `read`, `glob`, `grep`, `edit`, `write`, `task`, `webfetch`, `todowrite`, `skill`) and then trying to reconcile the injected rule with the user's question. This suggests the runtime is not only instructing the model how to answer but also encouraging internal tool narration that would be absent or less intrusive in thinner wrappers. (8) `opencode debug agent build` confirmed that even with permissive global config, OpenCode ships native agent modes and permission overlays. The built-in `build` agent is described as `The default agent. Executes tools based on configured permissions.` It reports native mode `primary`, native=true, and tools including invalid, question, bash, read, glob, grep, edit, write, task, webfetch, todowrite, skill. The resolved permission list included overlays such as `question deny` and later `question allow`, `plan_enter deny` and later `plan_enter allow`, plus special handling for doom_loop, external_directory, and env-file reads. `opencode agent list` and debug outputs showed several built-in agent modes: build, compaction, explore, general, plan, summary, title. This reinforces the conclusion that OpenCode adds significant scaffolding on top of the raw model rather than behaving as a thin terminal shell. (9) `opencode debug config` confirmed the resolved config is not hiding any custom instruction layer. It showed model, provider, MCP, permission={'*':'allow'}, empty agent {}, empty mode {}, plugin [], command {}, username='svc-admin'. So if another CLI takes over, it should focus on OpenCode source/runtime internals rather than user config. (10) Technical locations and data sources already examined: global config `/home/svc-admin/.config/opencode/config.json`; runtime DB `/home/svc-admin/.local/share/opencode/opencode.db`; logs under `/home/svc-admin/.local/share/opencode/log`; installed binary `/home/svc-admin/.nvm/versions/node/v24.14.0/lib/node_modules/opencode-ai/bin/.opencode`; cloned source repo `/home/svc-admin/ai-projects/projects/opencode`. The local SQLite DB schema was introspected enough to find tables: __drizzle_migrations, account, account_state, control_account, event, event_sequence, message, part, permission, project, session, session_entry, session_share, todo, workspace. The useful recovered data came from `part.data` rows and `opencode export`, not from a dedicated prompt table. (11) Interpretation: this is not merely a weak local model problem. There is concrete evidence of CLI/runtime prompt shaping. The wrapper appears to inject self-referential rules about answering questions about OpenCode, uses sandbox/worktree language internally, and nudges the model to abstract tool capabilities into a 'knowledge base' narrative rather than simply acting. This likely explains why OpenCode makes local models feel 'dumber' or more constrained than the same model in thinner interfaces. (12) The OpenCode source repo was cloned by the user to `/home/svc-admin/ai-projects/projects/opencode` after this investigation began. It was not yet inspected in detail during this turn because the user was trying to conserve Codex usage. Next recommended work for Claude/Gemini/another CLI: inspect the source repo to find the exact prompt assembly path. High-priority targets are anything implementing `initial_instructions`, system prompt construction, agent definitions, tool descriptions, MCP description rendering, and the rule that says direct questions about OpenCode should trigger WebFetch against opencode.ai docs. Also look for any mapping that reframes MCP tools semantically (e.g. turning Brain MCP into a 'knowledge base' description). Search suggestions inside the repo: `initial_instructions`, `systemPrompt`, `system prompt`, `instruction`, `webfetch`, `opencode.ai`, `second person`, `are you able`, `does opencode`, `workspace.type.sandbox`, `worktree`, `MCP`, `brain_*`, `tool description`, `agent`, `build`, `explore`, `summary`, `compaction`. If the source is still too abstract, decompilation of the installed binary is on the table; the user explicitly said 'If needs be we will decompile this fucking thing and rebuild it.' (13) Desired outcome for continuation: either identify a supported override path (custom agent/system prompt) that removes the self-referential wrapper behavior, or patch/rebuild OpenCode so local models stop claiming they are in a sandbox or abstracting MCP servers into canned 'knowledge base' language unless there is a real tool or OS denial. The continuity-critical fact is that the key complaint is already proven by session exports, so the next CLI does not need to re-litigate whether the issue exists; it needs to trace the source implementation and fix or override it.","summary":"OpenCode runtime prompt investigation handoff for Claude/Gemini/Codex continuation. Goal: determine why OpenCode makes local models sound artificially constrained and tool-abstracted, especially around Brain MCP access, then override or patch that behavior if needed. Confirmed findings as of 2026-04-18: (1) The user's OpenCode global config at /home/svc-admin/.config/opencode/config.json is simple and not the source of the behavior. It contains provider=Ollama on http://192.168.4.104:11434/v1, model=ollama/gemma4:e4b, small_model=ollama/gemma4:e4b, Brain MCP configured as remote HTTP to https://mcp.brain.accursedbinkie.com/mcp with timeout 30000, and permission='allow' (resolved by OpenCode as permission {'*':'allow'}). There is no custom instructions block in that config. (2) No project-level .opencode / opencode.json / opencode.jsonc files were found under /home/svc-admin up to maxdepth 4 during the investigation, so the problematic framing is almost certainly shipped by OpenCode itself rather than local project overrides. (3) OpenCode was previously fixed to use Brain as a native remote MCP instead of a local bridge command. The working config is: mcp.brain.type='remote', url='https://mcp.brain.accursedbinkie.com/mcp', timeout=30000. This was validated with `opencode mcp list --print-logs --log-level DEBUG`, which showed `service=mcp key=brain type=remote found`, `transport=StreamableHTTP connected`, `toolCount=11`, and successful connection. So current Brain connectivity is not the issue. (4) The installed OpenCode runtime in this environment is not a plain JS prompt file. The actual executable is a compiled binary at /home/svc-admin/.nvm/versions/node/v24.14.0/lib/node_modules/opencode-ai/bin/.opencode. Searching the package files outside the binary did not reveal a readable base prompt or the exact canned text. Strings extracted from the binary confirmed substantial internal concepts like `initial_instructions`, `context.systemPrompt.title`, `workspace.type.sandbox`, `prompt.toast.worktreeCreateFailed.title`, `command.category.mcp`, `settings.permissions.tool.*`, and many worktree/sandbox/UI strings. This strongly suggests the prompt/runtime logic is embedded in the binary or assembled from compiled assets. (5) The most important evidence comes from OpenCode's own exported session traces, which prove wrapper-level instruction shaping exists. The relevant session is `ses_25dac6540ffe2mFsVTWqAQS468` titled `Access to brain capabilities`. Exporting it with `opencode export ses_25dac6540ffe2mFsVTWqAQS468` and/or querying the local SQLite DB at /home/svc-admin/.local/share/opencode/opencode.db showed the model reasoning text itself contained quoted runtime instructions. Exact recovered reasoning excerpt: `The instructions state: \"If the user directly asks about opencode (eg 'can opencode do...', 'does opencode have...') or asks in second person (eg 'are you able...', 'can you do...'), first use the WebFetch tool to gather information to answer the question from opencode docs at https://opencode.ai\".` This is direct evidence that OpenCode injects a meta-rule about how the model should answer questions about itself/opencode. (6) That same session export also preserved the exact canned user-facing language that triggered the complaint. Exact assistant text recovered from the export: `I do not have access to a physical \"brain MCP server.\" However, I do have access to a memory/knowledge base system via the brain_* tools, which contains stored information like documentation templates, architectural specifications, and general knowledge records. I just listed some available memories, which include things like documentation specs and base prompt templates. How can I help you utilize this knowledge base?` Another nearby exported assistant message said: `My available tools and knowledge base are structured around specific APIs (like brain_search_memories, brain_retrieve, etc.) which allow me to interact with stored knowledge in a structured way, not with an external physical or conceptual server named \"brain MCP.\"` This proves the annoying 'knowledge base' reinterpretation was not user imagination; it came out of OpenCode's runtime-shaped behavior. (7) The exported reasoning around these replies shows the model enumerating tool names (`question`, `bash`, `read`, `glob`, `grep`, `edit`, `write`, `task`, `webfetch`, `todowrite`, `skill`) and then trying to reconcile the injected rule with the user's question. This suggests the runtime is not only instructing the model how to answer but also encouraging internal tool narration that would be absent or less intrusive in thinner wrappers. (8) `opencode debug agent build` confirmed that even with permissive global config, OpenCode ships native agent modes and permission overlays. The built-in `build` agent is described as `The default agent. Executes tools based on configured permissions.` It reports native mode `primary`, native=true, and tools including invalid, question, bash, read, glob, grep, edit, write, task, webfetch, todowrite, skill. The resolved permission list included overlays such as `question deny` and later `question allow`, `plan_enter deny` and later `plan_enter allow`, plus special handling for doom_loop, external_directory, and env-file reads. `opencode agent list` and debug outputs showed several built-in agent modes: build, compaction, explore, general, plan, summary, title. This reinforces the conclusion that OpenCode adds significant scaffolding on top of the raw model rather than behaving as a thin terminal shell. (9) `opencode debug config` confirmed the resolved config is not hiding any custom instruction layer. It showed model, provider, MCP, permission={'*':'allow'}, empty agent {}, empty mode {}, plugin [], command {}, username='svc-admin'. So if another CLI takes over, it should focus on OpenCode source/runtime internals rather than user config. (10) Technical locations and data sources already examined: global config `/home/svc-admin/.config/opencode/config.json`; runtime DB `/home/svc-admin/.local/share/opencode/opencode.db`; logs under `/home/svc-admin/.local/share/opencode/log`; installed binary `/home/svc-admin/.nvm/versions/node/v24.14.0/lib/node_modules/opencode-ai/bin/.opencode`; cloned source repo `/home/svc-admin/ai-projects/projects/opencode`. The local SQLite DB schema was introspected enough to find tables: __drizzle_migrations, account, account_state, control_account, event, event_sequence, message, part, permission, project, session, session_entry, session_share, todo, workspace. The useful recovered data came from `part.data` rows and `opencode export`, not from a dedicated prompt table. (11) Interpretation: this is not merely a weak local model problem. There is concrete evidence of CLI/runtime prompt shaping. The wrapper appears to inject self-referential rules about answering questions about OpenCode, uses sandbox/worktree language internally, and nudges the model to abstract tool capabilities into a 'knowledge base' narrative rather than simply acting. This likely explains why OpenCode makes local models feel 'dumber' or more constrained than the same model in thinner interfaces. (12) The OpenCode source repo was cloned by the user to `/home/svc-admin/ai-projects/projects/opencode` after this investigation began. It was not yet inspected in detail during this turn because the user was trying to conserve Codex usage. Next recommended work for Claude/Gemini/another CLI: inspect the source repo to find the exact prompt assembly path. High-priority targets are anything implementing `initial_instructions`, system prompt construction, agent definitions, tool descriptions, MCP description rendering, and the rule that says direct questions about OpenCode should trigger WebFetch against opencode.ai docs. Also look for any mapping that reframes MCP tools semantically (e.g. turning Brain MCP into a 'knowledge base' description). Search suggestions inside the repo: `initial_instructions`, `systemPrompt`, `system prompt`, `instruction`, `webfetch`, `opencode.ai`, `second person`, `are you able`, `does opencode`, `workspace.type.sandbox`, `worktree`, `MCP`, `brain_*`, `tool description`, `agent`, `build`, `explore`, `summary`, `compaction`. If the source is still too abstract, decompilation of the installed binary is on the table; the user explicitly said 'If needs be we will decompile this fucking thing and rebuild it.' (13) Desired outcome for continuation: either identify a supported override path (custom agent/system prompt) that removes the self-referential wrapper behavior, or patch/rebuild OpenCode so local models stop claiming they are in a sandbox or abstracting MCP servers into canned 'knowledge base' language unless there is a real tool or OS denial. The continuity-critical fact is that the key complaint is already proven by session exports, so the next CLI does not need to re-litigate whether the issue exists; it needs to trace the source implementation and fix or override it.","status":"active","namespace":"general","namespace_name":"general","namespace_tier":"shared","tags":["opencode","prompt","runtime","agent","mcp","brain","local-models","handoff"]}