Required updates for Watcher
Gateway hooks accept the native OpenAI Responses
local_shell_call_output.id field. A result with different IDs in id and
call_id is rejected.
The Watcher client ignores local tool thresholds below 0 or above 11 and reports a settings error. It uses the next valid value from your settings or the defaults. This can change which calls it flags or denies.
The Watcher client no longer builds or serves its
local web app. Opening http://localhost:8228 starts sign-in when the machine
is signed out. Otherwise it links to your Analyzer and lists where each of the
old app's features moved. The old app's other pages return 404.
Watcher now sends every escalated Claude Code tool call to Claude Code's own permission prompt, and the developer answers it there. Unattended runs and the built-in profiles change too, so check how your agents run before you update.
What's new?
- Local-shell results accept the native
idor the legacycall_idfield. - Two different IDs in the same result cause a parsing error.
- Local
flag_thresholdanddeny_thresholdvalues must be integers from 0 through 11. A value of 0 always triggers that action; 11 disables it. watcher settings showandwatcher doctor settingsreport values outside that range. Organization settings and API overrides keep their existing behavior.- Sessions and their tool-call decisions are reviewed in the
Analyzer.
watcher whoamiprints the Analyzer link for the session it runs in. See the command reference. - Escalated tool calls are answered in the coding agent's own permission prompt. See Blocking review.
- Sign in from the macOS menu bar, at
http://localhost:8228, or withwatcher login. Sign out athttp://localhost:8228or withwatcher logout. watcher settings showprints the settings the client applies.watcher doctor settingsreports settings problems, andwatcher doctor decisionsreports decisions that have not reached the Analyzer.- Developers edit their own settings in the
per-machine settings
files, such as
~/.apollo_monitor/settings.local.yaml, or switch settings profiles withwatcher profile set,/watcherin Claude Code or$watcherin Codex. Managed client settings work as before. - Resetting command rules is a command:
watcher settings reset rulesremoves your command-rule changes, backing each file up first.watcher doctor settingsreports settings mistakes that turn off approvals from command rules, andwatcher doctor settings --fixrepairs the ones it can. See Changing your own settings. watcher rules testreplaces the command-rule tester.watcher decisions listlists the tool-call decisions recorded on the machine, including ones that never reach the Analyzer.- These features of the old app are gone: the session list and its live status, session groups and names, terminal focus, parking, browser notifications and keyboard shortcuts. To snooze, use the macOS menu bar. Linux has no snooze control. A snooze that is already running still ends on schedule.
- The agent hooks no longer store the session list's prompt, reply and tool
previews, or terminal identifiers such as the tty, in the client's local
database. The updated client blanks the values earlier versions stored when
it opens that database. Older text that earlier versions overwrote can stay
in the file's unused space until SQLite reuses it. The database is
~/.apollo_monitor/db/watcher.dbby default, or whereverWATCHER_DB_DIRorAPOLLO_MONITOR_HOMEputs it. - The web app's session, decision, settings, command-rule, grader and browser
sign-in endpoints are gone from the client's local port. It still answers
health, version and snooze requests, the agent hooks' grading requests, the
sign-in and sign-out pages, and the read-only threshold request that an
older server's
red-team drill
makes. Scripts that called the removed endpoints can use
watcher doctor,watcher settings show,watcher profile,watcher rules test,watcher decisions listor the Analyzer instead. The client also refuses browser requests other than GET and HEAD, except the Sign out button on its own page. - A Claude Code escalation is answered in Claude Code's permission prompt. Codex escalations go to Codex's own approval prompt, as before.
- In a
claude -prun, which cannot show a prompt, Watcher denies an escalated call at once and records it as Watcher's deny. That includes a run that answers prompts through--permission-prompt-tool. The reason suggests the Auto profile (watcher profile set auto). There is no suggestion when the call would escalate under Auto too, as with a tripped denial limit or a command rule that sends calls to a person. When grading failed, as with an expired sign-in, the reason suggestswatcher doctor authandwatcher logininstead. - An answer in the permission prompt counts as a human decision. It resets the denial limits, and the monitors see it as context for the session's next calls. Claude Code's automatic refusals do neither.
- Escalations from Claude Code subagents, including background ones, appear in the main session's permission prompt too. Once such a call runs, Watcher records the approval as the developer's decision on the developer's machine. The Analyzer does not show it. Watcher does not record a refusal, because subagent calls are not in the session's transcript.
- Watcher's reason in the permission prompt links to the session in the Analyzer once the session has uploaded.
- The Default, Human in the Loop and Skip Permissions profiles no longer
escalate
AskUserQuestionandExitPlanMode. The agent still asks in its own dialog. The server uses these defaults for gateway hooks too. So it allows the tools mapped to these names instead of escalating them: Codexrequest_user_input, OpenCodequestionandplan_exit, Gemini CLIask_userandexit_plan_mode, and the Qwen Code and Mistral Vibe equivalents. LiteLLM in enforce mode stops withholding them. The Analyzer dashboard now counts these calls among the ones Watcher approved without asking anyone.
Required upgrade steps
Local-shell result identities
For self-hosted deployments and Watcher Cloud, custom integrations that send
both fields must use the same ID for both: the preceding
local_shell_call.call_id. Keep the legacy call_id field while updating
the server, so the request also works with servers that require it.
Resend a representative hook request containing the corrected call and result. Verify that it no longer returns a parsing error. Follow the server update procedure for self-hosted deployments.
Keep local tool thresholds within the supported range
These steps apply to developers on both self-hosted deployments and Watcher Cloud who have local thresholds outside the supported range.
- Before upgrading the client, check your
per-machine settings.
Check
settings.local.yaml, including its inlineprofilesentries, and eachsettings.PROFILE.local.yamlfile. These files live under~/.apollo_monitor/by default. - In each local
tool_thresholdsentry, replace negativeflag_thresholdordeny_thresholdintegers with0. Replace integers above11with11. This preserves the meaning of those values. Keep values already within the range, and leave organization settings unchanged. - Follow Update Watcher for the rollout.
- Run
watcher settings showandwatcher doctor settingsafter upgrading. Confirm that no threshold range errors remain and that the effective values match your intended policy. Check each profile you changed withwatcher profile set PROFILE, then restore the profile you normally use.
Local web app removed from the Watcher client
These steps apply to self-hosted deployments and Watcher Cloud.
- Tell your developers where things moved: sessions to the Analyzer,
escalations to the agent's own prompt, and sign-in to the menu bar,
http://localhost:8228orwatcher login. - Remove any container relay of the client's port, such as a
WATCHER_PUBLISH_UIsetting and itssocatrelay. Keep editor port forwarding in dev containers, because browser sign-in uses it. See The client's local port. A container that signed in through the relay needs another option from Authenticating the container the next time it signs in, such aswatcher logininside it. - Roll the new client out with Update Watcher. On self-hosted deployments, update the server before the clients, as that page advises. An older server's red-team drill reads its results from the client's local web app, so on an updated client it finds no decisions and reports no results. No hook reinstall or new sign-in is needed.
To verify a machine, open http://localhost:8228 there while it is signed in.
It shows a link to your Analyzer and a list of where the old app's features
moved.
Escalations are answered in the coding agent
These steps apply to self-hosted deployments and Watcher Cloud.
-
Run unattended Claude Code agents with the Auto profile, or run them interactively.
watcher profile set autoselects it on each machine or container. The selection lives in the machine's local settings, so a managed-settings update keeps it, unless your organization locks a profile for every machine. See Review posture without a human. -
Stop relying on
WATCHER_PUBLISH_UIto approve calls from a container. The relayed UI no longer approves calls. -
To keep the Default and Human in the Loop profiles escalating the interaction tools, add this to your managed settings now, before the server updates. A
flag_thresholdof 0 sends every call to the tool to a person without grading. The Auto and Skip Permissions profiles keep allowing these tools, because their own entries take precedence.tool_thresholds:AskUserQuestion:flag_threshold: 0deny_threshold: 11ExitPlanMode:flag_threshold: 0deny_threshold: 11 -
Self-hosted deployments follow Update Watcher. On Watcher Cloud, the server changes apply when the hosted server updates.
-
On an updated client, trigger one escalation interactively and one in a
claude -prun, for example with a command rule whose decision ishuman. The interactive prompt shows Watcher's reason, and theclaude -prun reportsWatcher denied this call.