$ cat blog/subagent-alarm-noise

Your agent's subagents shouldn't wake you up

A turn alarm is only useful if it means "a human is needed". Orchestrator fan-out almost broke that promise — and the obvious fix didn't work.

Agent Island's whole job is one promise: when a Claude Code or Codex thread finishes and it's genuinely your turn, you get interrupted — a full-screen alarm, a sound, a button that takes you back to the thread. That promise dies the moment the alarm fires for turns nobody is waiting on.

Orchestrated runs are exactly that. Point Codex at a big task and it fans out child threads — spawned executors, review passes, compaction runs. Each one writes a rollout file to ~/.codex/sessions just like a real session, and each one "finishes a turn" every few minutes. With a naive scanner, that's a popup storm: dozens of alarms an hour, none of them actionable. Users quite reasonably read it as "the alarm is broken".

The fix that didn't work

Every Codex rollout starts with a session_meta line that carries an originator field. Automation traffic is easy to spot there: codex exec runs, probes, bridges. Version 1.4.1 filtered on those substrings, and it did kill part of the noise.

Then a report came in that subagent threads were still popping alarms — from inside the Codex app. The dump of real session files explained it in one line:

"originator": "Codex Desktop"   // an interactive session you opened
"originator": "Codex Desktop"   // a spawned subagent you never touched

A spawned subagent carries the same originator as a session you opened by hand. From that field alone, the two are indistinguishable. The filter was checking the wrong signal.

Where the real markers live

The separator turned out to be on session_meta itself. Machine-driven threads carry spawn markers that interactive sessions never have:

  • thread_source: "subagent" and a non-empty parent_thread_id — orchestrator children;
  • source: {"subagent": …} objects for spawned/review/compact threads, {"internal": …} for probes — while direct sessions carry a plain string like "cli";
  • "exec" / "mcp" source strings for headless automation.

Against a corpus of 77 real rollouts on the machine that hit the bug, keying on those markers filtered 61 machine threads and kept all 16 interactive sessions. The originator check stays only as a backstop for old-style automation.

Two tiers, one toggle

Not all machine threads deserve the same treatment, so the scanner now applies two tiers:

  • Automationexec runs, MCP traffic, internal probes. Never surfaced. Nobody sits watching a batch run.
  • Subagents — orchestrator children. Silent by default, but there's a Settings toggle ("Alarm on subagent threads") for people who genuinely babysit their fan-out and want every child's finish to interrupt them.

The toggle matters more than it looks: all three subagent markers co-occur on the same rollouts, so every one of them has to honor the setting. Filter even one marker unconditionally and the toggle silently does nothing — a bug we caught in review before it shipped.

A scar about case sensitivity

One earlier iteration used an allowlist — "keep sessions whose originator starts with codex". The Codex app reports Codex Desktop, capital C. The prefix check missed it, every desktop session got classified as automation, and alarms went completely silent for the people who needed them most. Two lessons survived: match case-insensitively, and prefer denylisting the known-machine markers over allowlisting "what looks human" — new legitimate originators keep appearing, and an allowlist fails closed on exactly the wrong side.


This filter ships in Agent Island 1.5.1 on both macOS and Windows, storm-collapse included: even with subagent alarms opted in, a burst of finishes collapses to a single alarm for the newest turn.