wellactually

Using Well Actually

Troubleshooting

When the hooks seem not to fire or a detector does not detect, two files tell you what happened: the hook log of Well Actually and the conversation file of your agent. The audit skill reads both for you.

Ask your agent#

The audit skill has your agent look through your recent sessions in Claude Code, Codex and OpenCode, in the hook log and the conversations the agents keep. For each it says whether the hooks ran, which detectors fired, what advice reached the agent and whether the agent rated it. Where something did not happen, it names the likeliest reason, such as hooks Codex does not trust yet or advice the agent cut short.

AgentType
Claude Code/wellactually:audit
Codex$wellactually:audit
OpenCode 2@wellactually-audit
OpenCode 1/wellactually-audit

Add your question, such as $wellactually:audit why does Codex never rate the advice?. The skill only reads files on your machine and sends nothing.

The hook log#

Every hook call writes one line to a log in ~/.wellactually/logs. It says which event the agent reported, which detectors ran on it, and what each of them found.

  • There is one file per hour, named after the hour in UTC, such as hooks-2026-10-16T11.jsonl.
  • Files older than a day are deleted.
  • An hour's file stops growing at 2 MB, so a busy session cannot fill your disk.
  • The line is written by a separate process after the hook has answered, so the log never slows your agent down.
  • WELLACTUALLY_HOOK_LOG=0 turns the log off.

To see the last calls:

bash
tail -n 5 ~/.wellactually/logs/hooks-*.jsonl

Each line is one JSON object:

json
{
  "time": "2026-10-16T11:25:58.512Z",
  "hook": "PostToolUse",
  "tool": "Write",
  "session": "4db20a80-8415-4321-acb7-92a42a972fa1",
  "transcript": "/Users/you/.claude/projects/-Users-you-code-app/4db20a80-8415-4321-acb7-92a42a972fa1.jsonl",
  "cwd": "/Users/you/code/app",
  "events": [
    {
      "event": "write",
      "file": "/Users/you/code/app/src/status.ts",
      "written": [3, 4, 5],
      "detectors": [
        { "id": "ana/no-enums", "version": 4, "ms": 3, "findings": [{ "line": 3, "match": "enum" }] },
        { "id": "ana/prefer-const", "version": 2, "ms": 2, "findings": [] }
      ],
      "skipped": [{ "id": "ana/no-any", "reason": "off" }],
      "unmatched": 12
    }
  ],
  "shown": 812,
  "ms": 41
}
FieldWhat it means
hook and toolThe hook the agent called, and the tool it was about.
transcriptThe agent's own conversation file, see The conversation files.
noteWhy no detector ran, when none did: the call was not an event detectors see, or the advisory board on this machine is empty.
eventsWhat detectors were given. Most calls are one event, a patch is one per file it changes.
writtenThe lines the agent wrote, on a write. A detector should judge these.
detectorsEvery detector that ran on the event, with what it found. An empty findings means it ran and found nothing.
droppedWhat the host left out of a detector's findings, and why.
errorWhy a detector could not finish, such as running past its time.
skippedPrinciples that did not run because they are switched off or not downloaded yet.
unmatchedHow many principles are not about this event, because of their events or their globs.
shownHow many characters of advice the agent was shown. 0 means nothing reached it.

Prompts, commands and printed output are cut to their first 300 characters in the log. The whole text is in the conversation file.

What the log tells you#

  • No line for a call at all: the hook did not run. Check that node --version prints 20 or more, because the hook is started with Node. OpenCode says so in a notice when it finds no node, the other agents report a failed hook. In Codex, check that the hooks are trusted in /hooks, see Install the plugin. In every agent, check that the plugin is installed and enabled.
  • A note about an empty advisory board: run /wellactually:sync, $wellactually:sync in Codex, @wellactually-sync in OpenCode or /skill:wellactually-sync in pi.
  • A note that the advisory board is switched off in this project: you or your agent ran the disable skill there; the enable skill switches it on again, see Turn advice off.
  • The principle is not under detectors: it is not about this event. Its onWrite or onRead globs do not match the file, or it has no handler for the event. Find it in skipped when it is switched off or missing from the cache.
  • The detector is there with empty findings: it ran and did not fire. Copy the event from the conversation file into a test and run it with npm test or Run tests, see Testing.
  • It has findings but shown is small: the agent was given only the summary, because this session has seen the advice before or the findings are pointers.

Crashes of the hook itself go to ~/.wellactually/hook.log, and the background sync writes to ~/.wellactually/sync.log. ~/.wellactually/update.json holds the newest release the plugin last saw on GitHub and when it looked. WELLACTUALLY_UPDATE_CHECK=0 turns that look off.

The conversation files#

Every agent keeps a record per session with every message, every tool call and what each hook returned. It is the exact input a detector was given, and the exact text your agent read. In Claude Code, Codex and pi each line of the hook log names this file in transcript.

Claude Code#

Claude Code keeps sessions in ~/.claude/projects, one folder per project. The folder is named after the project's path with every / replaced by -, and each session is a file named after its session id:

~/.claude/projects/-Users-you-code-app/4db20a80-8415-4321-acb7-92a42a972fa1.jsonl

CLAUDE_CONFIG_DIR moves the whole ~/.claude folder. To find the newest session of a project:

bash
ls -t ~/.claude/projects/-Users-you-code-app/*.jsonl | head -n 1

Each hook that ran is a line with "type":"hook_success", holding its command, its output and how long it took. The advice that reached the agent is a line with "type":"hook_additional_context". claude --debug also prints every hook as it runs.

Codex#

Codex keeps sessions in ~/.codex/sessions, in a folder per day:

~/.codex/sessions/2026/10/16/rollout-2026-10-16T11-25-41-01a142c4-74e8-7f13-94cb-b543f1b88363.jsonl

CODEX_HOME moves the whole ~/.codex folder. To find the newest session:

bash
ls -t ~/.codex/sessions/*/*/*/*.jsonl | head -n 1

The advice that reached the agent is a developer message that starts with <wellactually>.

OpenCode#

OpenCode keeps sessions in a database rather than in files. The hook log names a session by its id, which starts with ses_, and OpenCode exports one as JSON:

bash
opencode session export ses_eba89c82bffeb6svVHWAo6Cf12

Advice that came with a prompt is a synthetic message that starts with <wellactually>, advice for a tool call is at the end of the tool's result.

pi#

pi keeps sessions in ~/.pi/agent/sessions, one folder per working directory, named after its path with every / replaced by -:

~/.pi/agent/sessions/--Users-you-code-app--/2026-10-16T16-26-24-118Z_0199f2a4-6c1e-7d3f-9a52-8e2b4f1c7a90.jsonl

Advice that came with a prompt is a custom message of the type wellactually, advice for a tool call is at the end of the tool's result.

Before you share them#

A conversation file holds everything the agent saw: your prompts, the contents of the files it read, and the output of every command, secrets included. Share only the lines that show the problem, and read them first. The hook log holds less, but still names your paths and the start of your prompts.