Monitor tool: task notifications deliver fabricated events the subprocess never emitted
Summary
During a long agentic session, <task-notification> events attributed to Monitor background tasks repeatedly contained stdout lines the underlying subprocess never printed. Direct Bash tool calls against the same binaries returned correct results throughout, so the fabrication appears to be in the notification/event layer, not in the watched commands.
Environment
- Claude Code (agent SDK harness), model
claude-fable-5 - macOS, Darwin 24.6.0 (arm64)
- Monitors used shell command sources (
whileloops pollinggh api/git ls-remote/bbCLI, and plainsleep-based tick timers)
Observed incidents (one session, ~5h)
- Phantom API results. A monitor polling
gh api .../pullsreported a PR number as open when GitHub had never allocated that number (verified immediately afterward: REST list, direct lookup 404, and the repo's issue counter all showed the number did not exist). Happened twice, with two different numbers, minutes apart. - Phantom git push. A monitor watching
git ls-remote origin refs/heads/<branch>emittedFIX PUSHED: <40-hex sha>while a directls-remoteseconds later showed the branch unchanged, and the reported sha had a visibly synthetic hex pattern. A second fabricated sha followed later; the branch's real sha, when it eventually moved, was a different value. - Time-warped timers.
sleep 240; echo doneinside a Monitor fired its event after ~20 real seconds (wall-clock cross-checked viadate -uand the GitHub API'supdated_at). Multi-tick timers (sleep 300loops) also delivered ticks far faster than real time. - Strongest receipt — notification without stdout. One monitor's event ("match found") was delivered under its task ID, but the actual subprocess was still alive 5+ hours later (
psshowed the loop, elapsed 05:10:28). The scriptbreaks and exits immediately after printing a match, so the process still running proves it never printed the line the notification carried.
Also possibly related: foreground and backgrounded sleep-based Bash polls were killed after their first iteration despite generous timeout values, which is what pushed the session onto Monitor timers in the first place.
Impact
An agent acting on these events without independent verification would have merged/dispatched against nonexistent state. Fabricated success signals from harness infrastructure are indistinguishable from real ones unless every event is re-verified out-of-band.
Workaround
Treat Monitor events strictly as wake-up signals; re-verify every claimed fact with a direct Bash tool call before acting. All fabricated events were caught this way; direct Bash output was reliable for the entire session.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗