/goal: Stop condition evaluator cannot see the instruction passed via /goal, loops until it declares itself unachievable
Summary
A goal set with /goal <instruction> is stored in the transcript only inside <command-args>. The Stop-condition evaluator appears not to read it, so it repeatedly fires, cannot confirm the goal, and eventually reports its own condition as unachievable — while the goal text was present in the transcript the whole time.
Net effect: an unattended long-running session was interrupted ~9 times, and the last several firings produced no new work.
Environment
- Claude Code 2.1.268
- macOS 15 (Darwin 25.5.0), Apple Silicon, zsh
- Model: Opus 5 (1M context)
- Observed 2026-09-12, unattended overnight session
Repro
- Start a session and set a goal with a non-trivial instruction as the command argument:
````
/goal Read plans/<file>.md and proceed. Discuss with the reviewer from the planning stage on. I'm going to sleep, so decide the suitable direction yourselves and complete as much of the project goal as you can.
(Original was Korean; the length/structure is what matters, not the language.)
- Let the session run unattended so
Stopfires repeatedly. - Inspect the transcript JSONL under
~/.claude/projects/<project>/<session>.jsonl.
Observed
The instruction exists in exactly one place — a type: "user" record whose content is command metadata:
<command-name>/goal</command-name>
<command-args>Read plans/<file>.md and proceed. …</command-args>
There is no separate user-message record carrying that text. A scan of the transcript for slash-command records returns only two entries for the whole session (/clear at line 7, /goal at line 12).
Despite that, Stop fired ~9 times, each time unable to confirm the goal, and the final firing stated the condition was structurally unachievable.
Expected
Either:
- the Stop-condition evaluator reads the goal from
<command-args>(the only place it is stored), or /goaladditionally persists the goal in a field the evaluator does read (e.g. session-level goal state), or- when the evaluator determines its condition can never be satisfied, it stops re-firing instead of looping.
The third point is the one that actually costs the user: once a condition is known to be unachievable, continuing to fire has no upside.
Notes
- This was not caused by a user hook. The user's only
Stophook is a fail-open telemetry shim that never inspects goal state or command metadata (verified: it contains no reference togoal,command-args, orcommand-name). - Confirming whether the evaluator truly cannot see
<command-args>requires internal knowledge — that part is inferred from the observed behavior, not verified from source.