Skip to content

Fix permission-audit.sh: read durable plugin audit log instead of rotated server logs #1

Description

@skwid138

Summary

permission-audit.sh currently returns 0 events because its data source has effectively disappeared. Make it useful again by reading a durable source.

Root cause

permission-audit.sh reads opencode's standard server log files for asking records. In this single-user setup, one long-running server process is attached to by many short-lived TUI-attach client sessions. Each client spawns its own log file, and opencode's ~10-file log retention rotates the server log (the only one containing asking records) out of the pool. Result: every retained log is a TUI-attach client with zero asking records, so the script reports no permission events even when the user is being prompted constantly.

Proposed fix

Read the command-normalizer plugin's durable audit log instead:

  • ~/.local/share/opencode/permission-audit-plugin/audit.log — JSONL, one record per processed bash command node: {ts, sessionID, agent, callID, command_node_text}. Span observed: ~1.3 days and growing (not subject to opencode's log rotation).

Optionally augment with native opencode data:

  • Standard opencode logs (when a server log is still retained).
  • ~/.local/share/opencode/opencode.db (SQLite, ~1.37 GB) — permission/event tables, if usable.

Key caveat

Neither current source records the actual ask/allow/deny DECISION. The plugin's audit.log logs command nodes; debug.log logs only pass-through: / rewrite: normalization events. To reconstruct "what was I prompted for," the command nodes must be replayed against the live opencode.jsonc ruleset (glob match, longest-non-star-literal-prefix wins, default ask) — done manually this session via a throwaway /tmp/classify.py. The audit script should incorporate this replay logic, or consume a decision field once the plugin records one (see the command-normalizer research issue).

The original "not reliant on the plugin" design goal can be relaxed if native opencode logs + sqlite can augment and improve on the plugin logs.

Acceptance criteria

  • permission-audit.sh returns real prompt data over a multi-day window.
  • Reads the plugin's durable audit.log (and/or native sources).
  • Reconstructs ask/allow/deny by replaying nodes against the live ruleset, or consumes a recorded decision.
  • Granularity caveat (compound commands fragment into command nodes) documented in output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort/mediumModerate implementation effort.priority/normalNormal priority.status/acceptedAccepted and ready to be worked.type/maintenanceChore, refactor, dependency, or repository maintenance.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions