[DOCS] Background task notifications are not documented as explicitly marking "no human input has occurred" so SDK consumers and Notification-hook handlers cannot rely on the v2.1.205 anti-fabrication guarantee
Documentation Type
Incorrect/outdated documentation
Documentation Location
https://code.claude.com/docs/en/agent-sdk/typescript#sdktasknotificationmessage
Section/Topic
The SDKTaskNotificationMessage (TypeScript) and TaskNotificationMessage (Python) reference entries, the Notification hook matchers for agent_needs_input / agent_completed in the Hooks reference, and the "Agent view sends a notification…" paragraph on agent-view.md. None of these surfaces mention the v2.1.205 guarantee that the runtime explicitly marks the notification as "no human input has occurred" so an approval-looking string embedded in a task's output or summary cannot be acted on.
Current Documentation
The Agent SDK TypeScript reference describes SDKTaskNotificationMessage as the notification a background task produces when it completes, fails, or is stopped:
###SDKTaskNotificationMessageNotification when a background task completes, fails, or is stopped. Background tasks includerun_in_backgroundBash commands, [Monitor](#monitor) watches, and background subagents. ``typescript type SDKTaskNotificationMessage = { type: "system"; subtype: "task_notification"; task_id: string; tool_use_id?: string; status: "completed" | "failed" | "stopped"; output_file: string; summary: string; usage?: { total_tokens: number; tool_uses: number; duration_ms: number; }; uuid: UUID; session_id: string; };``
The Python reference mirrors this in TaskNotificationMessage. The Agent SDK TypeScript reference also describes the synthetic follow-up turn that the SDK injects after a background task finishes and tells readers to check origin: { kind: "task-notification" } to route or suppress those follow-ups:
Theoriginfield forwards the [SDKMessageOrigin](#sdkmessageorigin) of the user message that triggered this result. When a background task finishes and the SDK injects a synthetic follow-up turn, the resultingSDKResultMessagecarriesorigin: { kind: "task-notification" }. Check this field to distinguish results that answer your prompt from results emitted for background-task follow-ups, so you can route or suppress the latter.
The Hooks reference documents the matching Notification hook event with two agent-specific matchers (agent_needs_input, agent_completed), both of which the text describes as firing only while agent view is open:
| Matcher | When it fires | | :--------------------- | :--------------------------------------------------------------------------------------------------------------------- | |agent_needs_input| A background session starts waiting on your input. Fires only while agent view is open in a terminal | |agent_completed| A background session finishes or fails. Fires only while agent view is open in a terminal |
The Agent View reference describes the same notifications going through the terminal notification channel:
As of v2.1.198, while agent view is open, Claude Code also sends a notification through your configured terminal notification channel when a local background session starts needing your input, finishes, or fails. Sessions that run on a schedule, such as/loopsessions, notify only when they need your input. Notifications use the samepreferredNotifChannelsetting as the rest of Claude Code and fire theNotificationhook with theagent_needs_inputoragent_completedtype.
None of these four surfaces says that the notification is explicitly marked as "no human input has occurred," and none says that this marking is what prevents a fabricated in-transcript approval embedded in a task's output, summary, or hook payload from being acted on by Claude.
What's Wrong or Missing?
A. The v2.1.205 anti-fabrication guarantee is undocumented on the surfaces that need it most
The v2.1.205 changelog states:
Background task notifications now explicitly state that no human input has occurred, preventing fabricated in-transcript approvals from being acted on
This is a security fix that matters to three different audiences:
- Agent SDK consumers building their own approval flows off
SDKTaskNotificationMessage/TaskNotificationMessageneed to know that the message Claude emits to drive a follow-up turn is explicitly framed as "no human input," so an attacker who controls a background task's output file (or itssummaryfield) cannot convince Claude that the user approved something by writing an approval-looking string in that text. - Hook authors receiving
agent_needs_input/agent_completedpayloads need to know that the runtime already treats the notification as non-user input for downstream Claude calls, so they do not have to invent their own filter and so they understand what guarantee the matcher type implies. - Users running Agent View who receive a terminal/desktop notification when a background session finishes or needs input need to know that the notification text never counts as a user reply, even when it appears inside a quoted block or command-style line in the terminal notification channel.
The current SDKTaskNotificationMessage description only says it is a notification "when a background task completes, fails, or is stopped" — it does not say that the runtime has explicitly labeled this surface as not user input. The Notification hook matchers describe when they fire but not what they guarantee. The Agent View paragraph describes where the notification goes (terminal channel, hook) but not that the notification is non-user input by construction.
B. The existing "synthetic follow-up turn" paragraph on the SDK TypeScript page covers routing, not the anti-fabrication guarantee
The SDK TypeScript page already explains that background-task follow-ups carry origin: { kind: "task-notification" } so consumers can distinguish them from real user turns. That paragraph is the closest the docs come to the v2.1.205 guarantee, but it is scoped to the SDKResultMessage origin field and to the SDK consumer's routing logic. It does not state that the underlying notification text itself explicitly says no human input has occurred, and it does not connect to the Notification hook or Agent View surfaces at all.
C. The earlier "scheduled task / webhook trigger deliveries" fix (v2.1.x changelog line 365) covered a related surface but was not backported to the type definition or hook reference
The changelog already records a closely related fix:
Fixed scheduled task and webhook trigger deliveries being treated as keyboard input; they now classify as task notifications and can no longer approve a pending action or set the session title in auto mode
That fix made task notifications (the same surface) unable to approve pending actions. The v2.1.205 entry is the next iteration of that guarantee, applied to background task notifications more broadly. Both fixes share the same documentation surface (Notification hook matchers, agent-sdk SDKTaskNotificationMessage / TaskNotificationMessage, and the Agent View notifications paragraph), and that surface currently says nothing about either guarantee.
Suggested Improvement
Add a short note on each affected surface describing the v2.1.205 guarantee, using language consistent with the v2.1.198 / v2.1.199 "no message from any agent counts as your approval" wording already used in sub-agents.md:863.
Option A — Add to SDKTaskNotificationMessage (Agent SDK TypeScript reference)
Add a sentence immediately under the existing prose at https://code.claude.com/docs/en/agent-sdk/typescript#sdktasknotificationmessage:
The notification is delivered to Claude with an explicit marker that no human input has occurred, so any approval-looking text embedded inoutput_file,summary, or a downstream hook payload cannot be acted on as the user's approval. Mirror this marker in your own routing so an approval claim in a notification cannot trigger an action that requires human consent.
Mirror the same sentence in TaskNotificationMessage in the Agent SDK Python reference.
Option B — Add to the Notification hook matchers
Add a sentence after the existing agent_needs_input / agent_completed rows in https://code.claude.com/docs/en/hooks:
Theagent_needs_inputandagent_completedmatchers deliver the notification to Claude with an explicit marker that no human input has occurred. A hook payload that looks like a user approval therefore cannot be acted on as the user's approval by the receiving session.
Option C — Add to the Agent View notifications paragraph
Add a sentence at the end of the existing paragraph at https://code.claude.com/docs/en/agent-view (around the preferredNotifChannel paragraph that fires the Notification hook):
The notification Claude Code delivers through this channel is explicitly marked as no human input having occurred, so an approval-looking string in the notification text or in the background task's output cannot be acted on as the user's approval.
At minimum, apply Option A and one of Option B or Option C so the SDK consumer reference and the human-facing surface both describe the same guarantee.
Impact
Medium - Makes feature difficult to understand
Additional Context
Affected Pages:
| Page | Line(s) | Context |
|------|---------|---------|
| https://code.claude.com/docs/en/agent-sdk/typescript | ~3098-3119 | SDKTaskNotificationMessage type definition and prose |
| https://code.claude.com/docs/en/agent-sdk/python | ~1704-1730 | TaskNotificationMessage type definition and prose |
| https://code.claude.com/docs/en/hooks | ~1884-1899, ~1930-1946 | Notification hook matcher table for agent_needs_input / agent_completed, and the input schema |
| https://code.claude.com/docs/en/agent-view | ~132 | "Agent view sends a notification…" paragraph about preferredNotifChannel and the Notification hook |
| https://code.claude.com/docs/en/interactive-mode | ~241-262 | "Background Bash commands" section that explains run_in_background Bash task IDs without describing the non-user-input guarantee on notifications |
Total scope: 5 pages affected.
Version: v2.1.205 introduced the guarantee; v2.1.198 introduced the agent_needs_input / agent_completed Notification hook matchers and Agent View notification paragraph that should describe it.
Cross-references: The same anti-fabrication guarantee language should be added to interactive-mode.md "Background Bash commands" and to the Agent SDK Python TaskNotificationMessage entry so TypeScript and Python SDK consumers see the same wording. The agent-view.md Version history table at the bottom of the page currently stops at v2.1.202 and would also need a v2.1.205 row that mentions this change alongside the other v2.1.205 notifications change ("Fixed background tasks in the web and mobile Remote Control panels showing stale Running status…").
Other useful context: The same guarantee appears in the SDK TypeScript page's existing prose around origin: { kind: "task-notification" } (~line 1119), which tells SDK consumers how to route background-task follow-ups. That paragraph is the closest the docs come today to describing the non-user-input nature of background task notifications, but it is scoped to the SDKResultMessage origin field and is not connected to the Notification hook or Agent View surfaces.
Use live https://code.claude.com/..., https://platform.claude.com/..., orhttps://support.claude.com/... URLs only.