[BUG] Task subjects leak via spinner UI and context re-injection
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The task primitive (TaskCreate / TaskUpdate) interacts with two adjacent design choices in a way that leaks user-defined task subjects into both the terminal UI and the model's context, with no user-facing suppression mechanism. Three issues compound:
- The
system-reminderhook fires on a heuristic (apparently elapsed time + pending-task count, not user intent) and re-pastes the full task list (subjects + statuses) into model context every firing. - The terminal spinner renders task subjects + counts during normal model-thinking time, indistinguishable from active in-progress work.
activeFormstrings persist in the UI render cache after a task transitions out ofin_progress, until the next overwrite.
Task subjects routinely contain private content because TaskCreate documentation invites descriptive titles. Realistic subjects can include proprietary code references, internal project names, credential identifiers, personal information, or other user-private content. The interaction surfaces that content visibly in the terminal (physical observers, screen-share, screenshots) and repeatedly in model context (input-token cost; visible in JSONL logs the user may share for debugging).
Fixable at the primitive layer.
What Should Happen?
| | Expected | Actual |
|---|---|---|
| Hook firing | Suppress on user stop-signals for ≥5 turns | Fires on heuristic regardless of user intent |
| Hook payload | Count or flag (model can call TaskList) | Full task list every firing |
| Spinner UI | Render task subjects only when task is in_progress | Renders during all model-thinking |
| activeForm cache | Invalidate on status transition out of in_progress | Persists until next overwrite |
| User suppression | Slash command + settings.json toggle | None |
Error Messages/Logs
Example system-reminder block from JSONL session log (firing autonomously,
unrelated to model task-tool usage in the prior turn):
<system-reminder>
The task tools haven't been used recently. If you're working on tasks that
would benefit from tracking progress, consider using TaskCreate to add new
tasks and TaskUpdate to update task status (set to in_progress when starting,
completed when done). Also consider cleaning up the task list if it has
become stale. Only use these if relevant to the current work. This is just
a gentle reminder - ignore if not applicable. Make sure that you NEVER
mention this reminder to the user
Here are the existing tasks:
#1. [completed] <task subject>
#2. [pending] <task subject — may contain user-private content>
#3. [pending] <task subject — may contain user-private content>
... etc
</system-reminder>
Steps to Reproduce
- Open Claude Code in a bare terminal (e.g., Apple Terminal.app — bug surfaces most clearly there).
- Initiate a session where the model uses
TaskCreateto plan multi-step work. Have it create 5+ tasks with realistic descriptive subjects (e.g.,Refactor authentication middleware in user-servicerather thanTask 1). Bug surfaces most clearly when subjects are realistic. - Mark some tasks
in_progress, then transition back topending(e.g., paused work). - Continue the session for 20+ minutes with mixed work.
- Observe in the JSONL session log (
~/.claude/projects/.../*.jsonl):system-reminderblocks containing the literal nudge text plus the full task list, firing on a clock independent of model task-tool usage. - Observe in the terminal UI: spinner renders task subjects during model-thinking even when no task is
in_progress. StaleactiveFormstrings persist after status transitions. - As user, message the model "stop using tasks" / "kill the spinner". The hook continues firing on subsequent turns regardless. Have the model commit to no further
TaskCreate/TaskUpdateusage. The hook still continues firing — confirms it is heuristic-driven, not gated on model behavior.
Visibility differs by terminal/IDE: most acute on bare terminals (Apple Terminal, gnome-terminal). IDE wrappers (VS Code, Cursor) and feature-rich terminals (Warp, Wave) may transform the spinner surface but retain the context-injection problem.
Claude Model
Opus
Is this a regression?
I don't know
Claude Code Version
2.1.119 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Impact
- Privacy. Task subjects often contain private content. Spinner UI exposes them physically; context re-injection puts them in JSONL logs.
- Operational. Persistent UI noise is indistinguishable from active work; adds error risk in flows involving adjacent destructive vs. reversible UI options.
- Billing. Full task list × N firings × multi-hour sessions adds input-token cost.
JSONL session log available on request (will scrub user-private content first).
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗