[BUG] Artifact publish auto-arms a Monitor whose stop surfaces despite quietLifecycle/ambient, with no opt-out short of CLAUDE_CODE_DISABLE_ARTIFACT
Summary
Publishing an Artifact auto-arms a background Monitor ("live updates for artifact …
(auto-armed on publish)"). The user never asks for this task, and when its websocket
closes, its stop surfaces as a visible task-notification in the session:
<task-notification>
<summary>Monitor event: "live updates for artifact <url> (auto-armed on publish)"</summary>
<event>[Monitor stopped]</event>
</task-notification>
The arming call itself is flagged as ambient and lifecycle-quiet, so the visible stop looks
like the intended behaviour not being honoured rather than a design choice. There is also no
setting that turns this off short of disabling Artifacts entirely.
Environment
- Claude Code 2.1.234 (native build,
/usr/local/bin/claude) - macOS 15 (Darwin 24.6.0), Apple Silicon
- Publishing via the
Artifacttool from a normal CLI session
Repro
- Publish any artifact (
Artifactwith afile_path). The tool result ends with
Live subscription: arming in the background — once connected, this session is notified
if another session republishes this artifact.
- Continue working; do not touch the artifact again.
- Some time later the session receives a
[Monitor stopped]task-notification for a task
the user never created.
It fires for a single publish, and again for each republish of the same artifact.
Why this looks like a defect rather than a preference
In the bundled binary (bin/claude.exe, v2.1.234), the subscription is armed with both an
ambient flag and a quiet-lifecycle flag set:
await <arm>({
ws: { url: y, protocols: [ ... ] },
description: `live updates for artifact ${n} (${G ? "watch requested"
: N.armedVia === "attach" ? "attached via /artifacts"
: N.armedVia === "resume" ? "resume requested"
: "auto-armed on publish"})`,
timeout_ms: 0,
persistent: true,
quietLifecycle: true, // <-- set
ambient: true, // <-- set
...
})
If quietLifecycle: true is meant to suppress lifecycle chatter for an ambient task, then
an [Monitor stopped] notification reaching both the user and the model is the bug: the flags
say "do not narrate this task's lifecycle" and the stop is narrated anyway.
Two costs, beyond the noise:
- It interrupts the user for a task they did not create and cannot act on.
- It interrupts the model mid-turn. The notification arrives as a turn event, so an agent
in the middle of unrelated work has to stop and decide whether it means anything. It never
does.
No targeted opt-out
Searching the binary's full CLAUDE_* environment-variable list and the /config settings
schema, the only artifact-related switches are:
CLAUDE_CODE_DISABLE_ARTIFACT— disables the Artifact tool entirelyCLAUDE_CODE_ARTIFACT_AUTO_OPEN,CLAUDE_CODE_ARTIFACT_COMMENTS,
CLAUDE_CODE_ARTIFACT_COMMENTS_AUTOREACT, CLAUDE_CODE_ARTIFACT_LIVE_BASE_URL,
CLAUDE_CODE_ARTIFACT_MCP
Nothing scoped to the live subscription, and no entry in the settings UI list (which carriesnotifChannel, inputNeededNotifEnabled, agentPushNotifEnabled, etc.). So a user who wants
artifacts but not the auto-armed watcher has no option but to give up artifacts.
Expected
Either of these would resolve it:
- Honour
quietLifecycle/ambientfor auto-armed artifact subscriptions, so lifecycle
events (at minimum the stop) do not surface to the user or the model; or
- Provide a setting (e.g. an
artifactLiveUpdatesconfig key, or a
CLAUDE_CODE_DISABLE_ARTIFACT_LIVE env var) so the subscription can be declined while
keeping artifact publishing.
Arming on an explicit /artifacts attach or an explicit watch request is clearly wanted; theauto-armed on publish path is the one that produces unrequested notifications.
Related
#83384 reports Monitor-reliability defects (reader stalls, notification drain, exit 144) for
user-created persistent Monitors, and mentions unmarked Monitor stops. This report is
narrower and about a different code path: the auto-armed artifact subscription that the user
never creates, and its lack of an opt-out.