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
Summary
permission-audit.shcurrently returns 0 events because its data source has effectively disappeared. Make it useful again by reading a durable source.Root cause
permission-audit.shreads opencode's standard server log files foraskingrecords. 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 containingaskingrecords) out of the pool. Result: every retained log is a TUI-attach client with zeroaskingrecords, 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:
~/.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.loglogs command nodes;debug.loglogs onlypass-through:/rewrite:normalization events. To reconstruct "what was I prompted for," the command nodes must be replayed against the liveopencode.jsoncruleset (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.shreturns real prompt data over a multi-day window.audit.log(and/or native sources).