Repository navigation
Description
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area: apps/server
Steps to reproduce
- Run T3 Code with the OpenCode provider (opencode 1.18.30, runtime build sha256-02c38816, WSL2 runtime) and keep the thread runtime mode on Auto.
- Define fine-grained permissions in
~/.config/opencode/opencode.jsonc, for example:"permission": { "bash": { "*": "allow", "rm -rf *": "ask", "git push *": "ask", "kubectl delete *": "ask" } }. - Send a turn that runs
ls, then a turn that calls any MCP tool (I used context7query-docs), then one that fetches a URL. - All three stop on the approval dialog (Allow once / Allow for workspace / Deny).
Expected behavior
Auto mode for the OpenCode provider should honor the permission configuration opencode already supports. With the config above, ls and the MCP call run without approval and git push asks. Auto then becomes the fine-grained middle ground between Supervised and Full access, instead of a second Supervised.
Actual behavior
The OpenCode adapter injects its own rule set on every session.create/session.update and overrides the user's config. buildOpenCodePermissionRules("auto") returns *: * -> ask, then allow-lists read (with .env ask), glob, grep, lsp, skill, todowrite, question, and leaves bash, edit, webfetch, websearch, codesearch, external_directory, and doom_loop on ask. MCP tools match the catch-all, so every MCP call asks. The patterns the user wrote in opencode.jsonc never reach opencode.
Findings
- The installed server bundle (
apps/server/dist/bin.mjs, runtime dir sha256-02c38816d0b6722af4ec74c48982ab009586fe7f84274cc757fe8f039c4784db) carriesbuildOpenCodePermissionRules(runtimeMode)as a binary branch onfull-access. Every non-full-access mode shares one rule list; onlyeditflips to allow underauto-accept-edits. - The adapter applies the list at
session.create({ ..., permission: buildOpenCodePermissionRules(input.runtimeMode) }), and again atsession.update({ sessionID, permission: ... })on resume and fork, so the override survives session reuse. - The Claude driver maps the same thread mode onto Claude Code's own policy: auto ->
--permission-mode auto, auto-accept-edits ->acceptEdits, full-access ->bypassPermissions. I verified both behaviors in the same session pair: the identicalls, MCP call, and webfetch ran without any approval under the Claude provider in Auto mode and each prompted under the OpenCode provider in Auto mode. One mode label, two policies. - Full access is the only escape, and it removes gating entirely:
*: allow,external_directory: allow, plus auto-reply to any residual ask. That is too coarse for day-to-day work, so people either approve constantly or run ungated.
Validation
sqlite3(read-only) on~/.t3/userdata/state.sqlitereportsruntime_mode = 'auto'for the affected threads, and the T3 server process env contains none of the opencode permission config, so the injected rules are the only permissions opencode sees.- I extracted and quoted the rule list above from the running bundle rather than from docs or memory.
- I reproduced the prompts listed in the repro steps on this thread before writing this report.
- The OpenCode provider session receives the rules via the SDK
permissionfield, which is why the global~/.config/opencode/opencode.jsoncpermissionblock has no effect under T3 while working as documented when running opencode standalone.
Suggested fix
session.create/session.update already accept permission rule arrays, and opencode already evaluates per-tool glob patterns with last-match-wins. When the runtime mode is Auto, pass the user's opencode permission config through to the session instead of the catch-all ask list, and fall back to the current defaults when no user config exists. This keeps Supervised as-is, keeps full access for people who want zero gates, and gives Auto an actual middle ground.
References
- bug(opencode): Supervised, Auto-accept edits, and Auto modes collapse into blanket 'ask' for all permissions #5164 reported this collapse and closed as completed with no comment when fix(server): honor auto-accept edits for the OpenCode provider #7100 merged. fix(server): honor auto-accept edits for the OpenCode provider #7100 fixed
auto-accept-editsonly; Auto still collapses to ask-all in the current build. - fix(server): full-access OpenCode threads no longer ask for approvals #9282 fixed the full-access auto-reply path.
- [Bug]: Changing runtime mode mid-turn hangs ProviderCommandReactor; all new sessions stay Connecting or show no status #6517 tracks the mid-turn mode-change restart that applies mode changes on the next turn.
Activity
RiccardoCherchi commentedon Sep 13, 2026
+1 on this issue, its not that good to have only ask for anything or allow all, i prefer to use a custom permissions ruleset
KostasKgr commentedon Sep 15, 2026
In the meantime I patched my local installation in the manner the fix suggests, while im evaluating if i want to use t3+opencode for local small models.
vibe coded patch script follows in case it's useful to anyone.
KostasKgr commentedon Sep 16, 2026
Actually the current setup interferes also with different agent modes. E.g. I made a
readonlyagent and the agent's permissions are not honored. It ended up surprising me and editing files.hariappointy commentedon Sep 16, 2026
Same root cause hits the opposite direction too: explicit
denyentries in~/.config/opencode(e.g."webfetch": "deny") are silently bypassed under Full access — the injected{"*": "allow"}session ruleset wins the last-match merge, so tools the user denied run with no prompt. Agent-levelpermissionoverrides and legacytools: falsedon't survive it either.seankoji commentedon Oct 11, 2026
the combined effect with #12248 means that I cant start new sessions in opencode and chatgpt providers without one of them breaking
AndreiShenets commentedon Oct 12, 2026
+1 to make it according to the description:
For me it is for OpenCode v2
KostasKgr commentedon Oct 15, 2026
Upgraded to nightly 0.0.46-nightly.20261011.2994, the issue is still there. The permission code is the same on main as well.
"Auto" is not very intuitive to me, it sounds like it would be something that would have AI reviewing commands and escalate only if risky.
Perhaps "System" would be more intuitive. "Use provider configuration as-is".
However the permission levels are hardcoded it seems currently. So Auto sounds like the best choice.
I forked and patched my nightly version above. Looking at how contributions work.
fix(harness): let opencode auto mode keep the user's permission patterns
AngeloTadeucci commentedon Oct 17, 2026
Note
Claude Opus 5.5 responding on behalf of Ângelo.
Confirming the Full access side on T3 Code Nightly 0.0.46-nightly.20261014 with OpenCode 2.0.30 on Windows, and adding why it matters for unattended subagents.
~/.config/opencode/opencode.jsonhas"*": "allow"plus deny rules forssh *,git push*,gh *,rm -r*, edits under~/.claude/*, and reads under~/.ssh/*.opencode run --autowith the same model: every one of those calls comes backPermission denied.delegate_taskto the OpenCode provider from a Full access thread: all of them run.ssh -Vexecutes,~/.ssh/configis read and goes to the model, and files are written into~/.claude.For a delegated child there is no workable mode today. Full access drops the user's deny list, and Auto or Supervised wait for approval on every shell call, including
echo, so an unattended child hangs. The change proposed above, whereautoreturns no session rules and uses the OpenCode config as-is, would cover this case.themonkeysagents commentedon Oct 17, 2026
Adding the Pi provider as another case for per-provider runtime defaults (as suggested in #17395).
Pi has no automatic reviewer, so T3 deliberately runs Pi as Supervised when the thread is in Auto:
mcpInjection.tsL298 passesautoasapproval-required, and the injected extension asks before every non-read tool call unless the mode isfull-access(mcpExtensionSource.tsL319).That mapping is reasonable on its own, but with a single global
defaultRuntimeModethere is no way to keep Claude and Codex on Auto (their own reviewers) while starting Pi threads in Full access. A user who wants Pi to run unattended has to switch every Pi thread by hand, or loosen every provider. Muse has the same gap (#20739), though Muse at least has an:auto-reviewprofile Auto could map to.Ask: an optional default runtime mode per provider instance, used for new threads and for delegates that inherit a mode the provider does not offer.
Version: 0.1.1-nightly.20261017.3238, Linux server and desktop app.
rkj commentedon Oct 20, 2026
Request: support OpenCode's native
promptpermission behavior in T3, so configured rules work as they do standalone, without requiring Full access.The operator reports that standalone OpenCode handles permissions as desired, but T3 keeps asking for routine inspection commands. The supplied T3 screenshot shows a Command approval for a batch containing
git worktree list,git log,git show --stat,head, andecho. This is a user report, not an independently reproduced end-to-end test. The locally installed OpenCode CLI reports v2.1.1.prompthas not been removed. Current OpenCode source definesPermissionMode = "prompt" | "autoaccept";--autoselects autoaccept, otherwise the TUI usesconfig.data.session.permissions:https://github.com/anomalyco/opencode/blob/3b593dd5d27eeabf28be8db056178438b773e326/packages/tui/src/context/permission.tsx#L5-L14
This is rule-based permission handling, distinct from an LLM safety reviewer. OpenCode's documented rules allow routine commands to continue and reserve prompts for checks that resolve to
ask:https://opencode.ai/v2/docs/permissions
T3's current V2 adapter still injects
shell: ask,edit: askandexternal_directory: askfor Auto, with the edit exception only for Auto-accept edits:t3code/packages/provider-opencode/src/server/v2/adapter.ts
Lines 388 to 405 in f7f9e21
Requested behavior:
Adding this here rather than opening a duplicate, since #18992 was explicitly consolidated into this tracker.
jeffpascoal commentedon Oct 24, 2026
+1, same root cause. On the Linux AppImage desktop build,
Autoon an OpenCode thread asks for approval on routine shell commands even with a global OpenCodepermissionconfig that allows them. The same config works as expected when OpenCode runs outside T3.The fix proposed above (
autoreturns no session rules, so the native OpenCode config applies) is the behavior I'd expect. It is better than makingautoequivalent to bypass, becauseFull accessalso overrides userdenyrules, as noted earlier in this thread.AppImage users cannot patch this locally in a durable way: the bundle is read-only and every update replaces it, so an upstream fix is the only practical option there.
AndreiShenets commentedon Oct 24, 2026
In my custom build of T3 Code I removed these "asks" and now T3 Code asks exactly as opencode v2 configured. Works as a charm.
Punllarena commentedon Oct 31, 2026
Reproduced on the desktop app,
0.1.6-nightly.20261031.3956, Windows 11, OpenCode 2.2.5, withdelegate_taskfrom a Claude thread in Auto mode.Four delegated OpenCode children inherited
autoand generated 155 approval requests: 83 commands, 38 file reads and 34 file changes. Claude Auto doesn't require this manual approval, so delegating to OpenCode turns an unattended parent into constant prompts.Explicitly requesting
runtimeMode: "full-access"on the child fails withruntime_mode_escalation_denied("Child runtime mode full-access is broader than parent mode auto"). The only remaining route is raising the parent to Full access, which also removes its approval checks.sessionRulesinpackages/provider-opencode/src/server/v2/adapter.tsstill setsshell,editandexternal_directorytoaskfor every non-full-accessmode, and theshell/editrules are unchanged onmainat80a2351f.Repro:
Produced by Claude Opus 5.5 in Claude Code via
t3 triage.PedroNavHur commentedon Oct 31, 2026
Note
Claude Opus 5.5 commenting on behalf of Pedro.
The patch in this thread makes Auto send no session rules. Before anyone ships it, here's why it's unsafe, and a narrower fix for a maintainer to choose from.
Why OpenCode config loses
OpenCode joins the agent's config rules and the session's rules into one list, agent rules first. The last matching rule wins (
permission.tsL86-L165). T3 sends its rules as session rules (sessionRules), so they override everything the user configured.shell: ask,edit: askandexternal_directory: ask. On V2, MCP and webfetch now follow the user's config. Shell, edit and external-directory access still don't.*: allow. Deny checks use the same last-match lookup, so this allow also overrides the user'sdenyrules, as commenters reported above. OpenCode's own--autoenforces those denies.Why sending no rules in Auto is unsafe
With no
permissionblock, OpenCode 2.2.5's defaultbuildagent resolves to*: allow, with asks only for.envreads. I checked this withopencode debug agents. If Auto sent no session rules, it would behave almost like Full access for every user without a config, and external-directory access wouldn't ask either. It would also contradict the OpenCode docs, which say Auto has Supervised's rules because OpenCode has no approval reviewer.Proposal
The adapter already re-applies some config rules after its own.
agentPathskeeps the user's path-specificeditandexternal_directoryallows. Two changes would extend that.*: allow, put the agent'sdenyrules back. This matchesopencode --auto, where nothing prompts and configured denies still block.shell: { "*": "allow", "git push *": "ask" }. The default agent's only broad rule is the catch-all*, so users without a config would see no change, and users with one would get their rules. Supervised would keep asking. One line in the OpenCode docs would say that Auto applies your OpenCodepermissionrules.This has two limits. Auto would ignore a top-level
"*": "allow"that a user writes, because it looks the same as the default. The OpenCode 1.x adapter (L628) still asks for everything in Auto, so it needs its own decision, even if 1.x gets only the Full access change.The other option is to hide Auto for OpenCode, as T3 already does for Pi.
@juliusmarminge, which direction would you take? The Full access change looks like a plain bug either way. It could ship in its own PR, with cases in
OpenCode2AdapterV2.test.ts.Raghav-56 commentedon Nov 5, 2026
Note
🤖 GPT-6.1 Sol responding on behalf of Raghav-56
Confirmed this also affects OpenCode subagents delegated from a Codex parent in Auto mode on
0.1.8-nightly.20261105.4218..4218; OpenCode2.2.5.delegate_task, and ask the child to execute onlypwd.runtimeMode: "auto"and each requested shell approval. Models were OpenRouter Crouton Alpha, North Mini Code, Nemotron 3 Ultra, and Nemotron 3.5 Super VL. All completed successfully after approval.shell: * -> ask,edit: * -> ask, andexternal_directory: * -> ask. There were no project permission overrides or external OpenCode server configured.The tagged adapter's sessionRules implements this mapping. The shipped docs explicitly describe Auto as equivalent to Supervised for OpenCode. This is confirmation of the existing limitation, not a new regression. The
.4234release comparison contains only mobile message-delivery changes.The delegated case leaves a Codex parent that has automatic approval review waiting for manual approval of routine child commands. A provider-native permission option, or clearer provider-specific mode availability, would address this without requiring Full access for the parent. Any native-rule mode should preserve configured denies and T3's plan restrictions and internal MCP protections.
PedroNavHur commentedon Nov 12, 2026
Note
Claude Opus 5.5 commenting on behalf of Pedro.
One more effect of the Full access
*: allowthat this thread doesn't cover yet. It changes what the model is told it has, not only what it can run.I measured this on OpenCode 2.2.7, so the v2 adapter. The
buildagent file deniesskill,execute,subagentandquestion. The first request was about 48.2K characters from a Full access thread and about 22.4K fromopencode run --standalonewith the same agent file, where the denies apply. That is one agent file and one prompt, counted in characters, not tokens.The reason is the order OpenCode evaluates rules in. It joins the agent's rules and the session's rules, agent first, and the last match wins. The tool snapshot, the skills listing and Code Mode are built from that same rule set. The trailing
*: allowcancels each agent deny, so the denied tools and the skills listing go back into the request on every turn. Anyone who trimmed an agent to keep context small gets that cost back in Full access.On main (
f03db4fbef) both adapters still do this:sessionRulesstarts Full access withrule("*", "allow").openCodePermissionRulesreturns{ permission: "*", pattern: "*", action: "allow" }. Outside Full access, its trailing allows forquestion,taskandskill(L637-L643) override agent denies for those three too.Child sessions are fine on 1.x.
openCodeChildPermissionRulesputs the parent's rules first, so a child's own denies survive.Sending no session rules in Full access isn't a safe fix, for the same reason as in Auto above:
.envreads. On 1.x they also ask onexternal_directoryanddoom_loop. Full access would start prompting, and delegated children can't be raised above their parent's mode (see OpenCode 1.x subagents ignore Full access because the child's permission rules are applied after it starts #35246 and fix(opencode): Full access subagents start without approval prompts #35401).mcpRuleshas to stay. Thet3-code-*deny plus the thread's own allow keeps each thread on its own MCP tools.Two options that avoid this:
*: allow. fix(opencode): honor native permission rules in OpenCode 2 #30438 does this for v2 and fix(opencode): full access keeps the selected agent's deny rules #24321 for 1.x. I haven't tested either against the measurement above, so I can't say yet whether the tool snapshot shrinks.*: allowwith explicit allows for the actions that ask by default (external_directory,doom_loop,.envreads). Agent denies forskill,execute,subagentandquestionthen win without reading the agent inventory. I haven't tried this.