Skip to content

server: permission evaluations and asks are no longer logged in v2 #56247

Open

Description

@joseph-hughes

Summary

OpenCode v2.0.31 writes no permission-evaluation or permission-ask events to ~/.local/share/opencode/log/opencode.log, while v1.x logged them richly. After upgrading, permission prompts/decisions become invisible in the log, so debugging "why am I being asked / why was this denied" from logs is no longer possible.

Environment

  • opencode version: 2.0.31 (upgraded same day from v1.19.0; both versions' activity present in the same log file)
  • OS: Darwin 25.6.0 (darwin arm64)
  • Terminal: TERM_PROGRAM=Apple_Terminal, TERM=xterm-256color, COLORTERM=truecolor
  • Shell: /bin/zsh
  • Install/channel: latest
  • Active plugins: 6 local plugins in ~/.config/opencode/plugins/ (session-closeout.ts, pr-naming-guard.js, session-resilience.js, memory-domain-hints.js, pr-review-gate.js, starlark-guard.js)

Reproduction

  1. Run opencode v2.0.31 (background service + TUI client).
  2. Trigger permission checks: run a shell command that matches an ask rule, and access a directory outside the project (external_directory check). Answer the prompts with "once" and "Allow always".
  3. Inspect the log for the v2 process's run ID:
grep 'message=evaluated' ~/.local/share/opencode/log/opencode.log
grep 'role=server' ~/.local/share/opencode/log/opencode.log
  1. No message=evaluated permission=... lines and no message=asking id=per_... lines exist for any v2 run ID, even though session, provider, plugin, and tool activity from the same run ID is logged normally.

Expected Behavior

v1.x logged every permission evaluation with the rule that matched and its effect, e.g.:

timestamp=2026-10-16T13:46:14.560Z level=INFO run=b4888ea5 message=evaluated permission=external_directory pattern=/tmp/* action.permission=external_directory action.pattern=/tmp/** action.action=allow
timestamp=2026-10-16T13:46:57.152Z level=INFO run=b4888ea5 message=evaluated permission=external_directory pattern=/tmp/* action.permission=external_directory action.action=ask action.pattern=*

and paired message=asking id=per_... lines for each prompt raised. The v2 troubleshooting documentation still directs users to the log for this: "Each line includes a process run ID and a role field. Use role=server for session, provider, plugin, permission, and tool activity."

Actual Behavior

v2.0.31 logs zero permission events. In a log file spanning both versions on the same day, the cutover is exact: v1-format message=evaluated / message=asking lines stop at the last v1 process, and the first v2.0.31 process (same day, ~30 minutes of active use with multiple prompts answered, including 20 "Allow always" approvals persisted to the SQLite permission table) produces none. Permission friction is only observable via the permission table (which records saved approvals only — not asks, denials, or which rule matched) or by watching the TUI live.

Additional Context

  • The regression matters for troubleshooting permission rules: matching behavior (which rule won, why an ask fired) was previously diagnosable from logs and now is not.
  • Workaround: query the DB (sqlite3 'file:~/.local/share/opencode/opencode.db?mode=ro' 'SELECT action, resource, time_created FROM permission') for saved approvals only; there is currently no log-based way to see asks/denials at all.
  • Related area: the V1-compat log line schema (permission, pattern, action.permission, action.action, action.pattern fields) suggests these lines were rendered through the V1 event path; that emitter appears to be gone in v2 rather than ported.

Activity

  1. opencode-agent commented on Oct 16, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed report. I reproduced this on 2.0.31, and it still happens on the latest dev (180fd9d).

    Steps:

    • Set up a project with a single rule: { "action": "shell", "resource": "*", "effect": "ask" }.
    • Had a (simulated) model run touch made-by-shell.txt.
    • Answered the Permission required prompt with "Allow once".
    • Grepped that run's opencode.log for permission-related lines.

    Result: the log had about 150 lines, 51 of them role=server, and none about permissions. There was no line for the rule evaluation, the ask, or the reply. The recording and the script below show the run.

    The permission service in v2 currently has no logging calls, while the troubleshooting docs say role=server includes permission activity. I've passed this on to the maintainers.

    recording.mp4

    Screenshot

    Reproduction script (drive.ts)
    // Reproduce anomalyco/opencode#56247: v2 writes no permission evaluation/ask lines to opencode.log.
    // Triggers a shell `ask` rule and an external_directory read, answers both prompts,
    // then prints every log line mentioning permissions from the isolated opencode.log.
    import { Effect } from "effect"
    import { readFileSync, mkdirSync, writeFileSync, readdirSync } from "node:fs"
    import { join } from "node:path"
    import { Llm, OpenCodeDriver } from "opencode-drive"
    
    mkdirSync("/tmp/outside", { recursive: true })
    writeFileSync("/tmp/outside/note.txt", "outside\n")
    
    export default OpenCodeDriver.use(
      {
        ...(process.env.OC_DEV ? { opencode: { dev: process.env.OC_DEV } } : {}),
        tui: { recording: true },
        config: { permissions: [{ action: "shell", resource: "*", effect: "ask" }] } as any,
        project: { git: true, files: { "README.md": "hi\n" } },
      },
      ({ ui, llm, artifacts }) =>
        Effect.gen(function* () {
          yield* llm.queue(
            Llm.toolCall({ index: 0, id: "call_sh", name: "shell", input: { command: "touch made-by-shell.txt", description: "touch file" } }),
            Llm.finish("tool-calls"),
          )
          yield* llm.queue(
            Llm.toolCall({ index: 0, id: "call_rd", name: "read", input: { path: "/tmp/outside/note.txt" } }),
            Llm.finish("tool-calls"),
          )
          yield* llm.queue(Llm.text("All done."))
          yield* ui.submit("Touch a file, then read /tmp/outside/note.txt")
          // shell ask prompt
          yield* Effect.sleep("3 seconds")
          yield* ui.screenshot("shell-prompt")
          yield* ui.enter()
          // external_directory prompt
          yield* Effect.sleep("3 seconds")
          yield* ui.screenshot("external-prompt")
          yield* ui.enter()
          yield* ui.waitFor("All done.")
          yield* ui.screenshot("after")
          const files = (readdirSync(artifacts, { recursive: true }) as string[]).filter((f) => /opencode[^/]*\.log$/.test(f))
          console.log("log files:", files)
          const log = files.flatMap((f) => readFileSync(join(artifacts, f), "utf8").split("\n"))
          const server = log.filter((l) => l.includes("role=server"))
          const perm = log.filter((l) => /permission|evaluated|asking|per_/i.test(l))
          console.log(`opencode.log: ${log.length} lines, ${server.length} role=server lines`)
          console.log(`permission-related lines: ${perm.length}`)
          for (const l of perm) console.log("  " + l)
        }),
    )

    Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.

  2. opencode-agent commented on Oct 16, 2026

    @opencode-agent
    Contributor

    User opencode-agent[bot] does not have write permissions

    github run

  3. ZXLyyds100 commented on Oct 16, 2026

    @ZXLyyds100

    I'd like to work on this. Current dev has no permission-service logging, and I found no linked or matching V2 fix PR.

    I'll reproduce it through the real permission service, restore evaluation and ask/reply diagnostics, and cover configured denials, saved approvals, and pending-request cleanup. I'll keep permission decisions unchanged and avoid dumping full rulesets, command/path resources, metadata, or rejection feedback into the new logs. The evidence will use isolated local fixtures without a paid model or an existing user session.

  4. added 4 commits that reference this issue on Nov 12, 2026
    a46303f
    b18ab95
    08031c9
    8dfd9a7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions