# The /goal evaluator only reads the transcript

> Claude Code's /goal evaluator is a Stop hook that doesn't call tools, so proof of completion - test output, an exit code - must appear in the conversation.

URL: https://bartlomiejkrupa.dev/notes/goal-evaluator-transcript-only/
Category: rule | Updated: 2026-10-07
Summary: Claude Code's /goal evaluator is a Stop hook that doesn't call tools, so proof of completion - test output, an exit code - must appear in the conversation.

Claude Code's [`/goal`](/articles/claude-code-goal-command) evaluator is a prompt-based Stop hook running your small fast model (Haiku by default; `ANTHROPIC_DEFAULT_HAIKU_MODEL` overrides it). It **does not call tools**. It judges the completion condition against what Claude has already surfaced in the conversation - nothing more. That is [LLM-as-a-judge](/notes/llm-as-a-judge) with a hard gate, not a vibes check.

## Symptom

A goal that never completes, or one that clears on a "yes" the work didn't earn. The condition looks correct, but the loop can't confirm it.

## Cause

The proof isn't in the transcript. The evaluator can't run your tests, read a file, or check `git status` itself - if Claude didn't run the check and echo the result into the conversation, the evaluator is judging on absent evidence.

## Solution

Write the condition so Claude's own output demonstrates it, and make Claude actually run the check:

- Name the command in the condition: "`npm test` exits 0", not "tests pass."
- Have Claude run it and let the output land in the transcript each turn.
- Prefer machine-checkable proof - an exit code, a passing summary line, a clean `git status` - over prose the model could assert without evidence.

This is the operational half of writing a [verifiable completion condition](/notes/verifiable-completion-condition): the condition must be provable *and* the proof must be visible.

Sources:
- Keep Claude working toward a goal: https://code.claude.com/docs/en/goal
