Woken No-Op Sentinel
When a background event re-wakes a session that had already finished, Omniscio teaches every engine to answer with one canonical sentence, detects it as a whole-message match, hard-hides the throwaway reply and does not re-ping you, so a pointless background wake becomes a true no-op.
What it is
When a background event re-wakes a session that had already finished — a
Bash run_in_background completing, a --cloud run, a Monitor watch, a
ScheduleWakeup, or Omniscio's 30-minute "Please continue." fallback — the agent
sometimes has genuinely nothing left to do. Without this feature it posts a
throwaway "all done, nothing to do" follow-up that clutters the chat and can
re-flag the session as needing you.
Omniscio instructs every agent — Claude and the non-Claude engines alike — to reply, in that exact situation, with ONE canonical sentence:
Nothing to do here. Everything was already finished before this background wake-up.
Omniscio deterministically detects that sentence and:
- hard-hides the throwaway reply from the transcript, and
- does not re-ping you (if the session was already waiting on you, it stays exactly there — no fresh chime).
The wake becomes a true no-op.
This works for every engine, not just Claude. The non-Claude engines (Codex, Gemini, OpenCode, slim-ACP, and the rest) are taught the same sentence and get the same hide + no-re-ping at their own turn-conclusion (via the engine-agnostic sibling — see the contracts below), so a pointless background wake is a true no-op no matter which engine a session runs on.
Where to find it
The core feature is on by default, invisible, and safe — there is no Settings
toggle for it. Hidden replies are still revealed by the per-session "Show system
messages" toggle (which renders the turn whole for auditing). An operator kill
switch exists as the AMC_DISABLE_WOKEN_NOOP_SENTINEL=1 environment variable
(disables the instruction AND the hide/no-ping; takes effect on restart).
One opt-in setting — "Prevent mistaken 'nothing to do' replies" (default OFF). Sometimes a re-woken session (often a finished automation) mistakes a short message you typed for an automated nudge and wrongly answers it with the no-op sentence. Turn this setting on (Settings → the session waiting / keep-going area) and Omniscio's automatic "keep going" nudges self-identify as coming from the app (not you), and agents are told any message without that marker is really from you — so a terse message like "add this" is no longer taken for a background wake. It ships OFF, and a mistake that does slip through is already cleaned up automatically (see the misfire recovery below), so this just makes the mistake rarer.
The setting also covers the "Please continue" nudge a crash or restart revival
sends (see Crash recovery). Until 2026-09-12 it did not: those
revivals hardcoded their text and never read the setting, so turning it on fixed the
keep-going nudges and left every automatic revival still looking exactly like you had
typed it. A nudge you send yourself — the manual Nudge button, or a continue over
the command line — stays unmarked either way, because that one really is from you.
How it behaves
How it works
- Instruct — a short fragment is folded into the single system-prompt the spawned CLI already receives (the same channel as the "you're running inside Omniscio" note). It tells the agent the exact sentence to emit when an automated background wake-up resumes it after all work is finished — including when a question it already asked is still unanswered: if the automated wake changed nothing it emits the sentinel rather than re-stating the question (re-stating would open a fresh turn that buries the decision you still need to make). The instruction is explicit that this is for automated wakes ONLY: anything a person actually sends — even a bare key, path, or single word — is real input the agent must act on, never a no-op (the 2026-06-19 fix below). It also tells the agent the one sentence overrides a project or persona instruction to "always report what you did / be transparent after every action" and must be sent verbatim — so a verbose automation persona (e.g. a tweet-router) no longer rewords it into a status echo that leaks to the inbox (the 2026-08-11 fix).
- Detect — Omniscio matches the agent's reply against the canonical sentence as a
whole-message exact match (tolerating only case / whitespace / dash-style /
a trailing period). It first drops a leading
▸ Extended thinkingactivity tag — the marker Omniscio prepends when the agent thinks for a moment before replying — so a "thought-first" no-op still matches (that tag is exactly what left most of these showing before). It strips ONLY that thinking tag: a message that did real work (any substantive tool line survives the strip), or merely quotes the sentence, or adds a question, never matches — so a real reply is never hidden by accident. - Hide — only on a genuine background-wake turn (Omniscio's backend knows the difference; the agent can't fake it). The throwaway reply is hidden at render.
- No re-ping — if the session was already in "Needs You" before the wake, Omniscio silently puts it back there (no sound, no popup; the dot and badge are unchanged). If instead the agent had been mid-background-wait and is now genuinely done, you DO get pinged once — the honest "it's finished" signal. This silent restore ALSO fires when a re-wake left an already-pending decision (a question / plan / permission you have not answered) UNCHANGED — sentinel or not. So even a non-sentinel do-nothing wake (the agent ran a quick command or wrote a sentence first) can no longer re-chime or bury the decision; the pending question stays your live "Needs You" ask. That reply stays visible in the thread (only the exact sentinel is hard-hidden), so a wake that genuinely surfaced something new is never lost (the 2026-06-17 "buried question" fix).
When a real message gets the no-op by mistake (2026-06-19)
The sentinel is for automated wakes only — but a model can misjudge. In the incident that prompted this fix, a user pasted the API key the agent had been blocked on, and the agent treated the bare key as a background wake-up and replied "Nothing to do here." — ignoring it. Two guards now make that safe:
- It can never be hidden. The hard-hide + no-re-ping fire ONLY on a genuine automated wake (Omniscio's backend marks those; a plain user message — or even a user message Omniscio had to re-run for recovery — is not one). So a no-op aimed at your message always stays visible; it is never silently swallowed.
- Omniscio re-sends your message. If the agent fires the no-op sentinel at a real message you sent, Omniscio automatically re-delivers that message once so the agent actually responds, and drops a short "that was from you — re-sending it" note. It does this at most once per message (so it can never loop), and a legitimate automated "Please continue." no-op is never re-sent.
Update (2026-06-26) — paused sessions too. The re-send above originally engaged only when your message reached a session whose process was still alive. A session that had been paused while waiting on you — then resumed by a genuine "Please continue" — took a different internal path (a fresh respawn) that skipped the guard, so the agent could answer your "Please continue" with "Nothing to do here." over the still-open question. That gap is closed: the respawn path now marks your message as genuine exactly like the live path, so the same backstop re-drives it. (An automated "Please continue." that crash-recovery sends itself is still correctly treated as automated and never re-driven.)
Update (2026-08-15) — the leftover reply now collapses once we've re-sent it. The two guards above kept the mistaken "Nothing to do here." fully visible so a genuinely unanswered message could never be swallowed. But once Omniscio has actually re-sent your message (the common case — the "that was from you — re-sending it" note is proof it fired), that leftover reply is just superseded noise. It now folds to the same one-line "Background check-in" marker as every other stray no-op — you see the friendly re-sending note and your real answer, not the confusing "background wake-up" bubble. One click still expands it, and "Show system messages" reveals the raw turn. If Omniscio could NOT re-send (rare — e.g. it already retried once), the reply stays fully visible, exactly as before, so an unanswered message is never hidden. This is display-only and heals already-affected sessions the next time you open them. (The live report that prompted it: "Check again" → the agent no-op'd it → Omniscio re-sent and answered 90 seconds later, but the bogus bubble had stayed on screen.)
When a no-op did a quick check first (2026-06-18)
The hide above is deliberately strict: it only hides a reply that is nothing but the sentence. If the agent ran a quick file-check or command before saying "nothing to do", Omniscio will not hard-hide it — that tool might have done real work, and a hidden message is hard to get back. So that reply stays in the transcript.
But it still shouldn't grab your attention. So Omniscio does two gentler, fully reversible things instead:
- It won't scroll you to it. When you open the session, the view (and the green "final message" frame) lands on your last real reply, never on the throwaway — this is the case that prompted the fix.
- It collapses — by default when it ends in the exact sign-off (2026-08-05). When the reply ends with Omniscio's exact "Nothing to do here…" sentence after that quick check (the "verify, then sign off" shape — the live row that prompted this), the whole turn folds to the same one-line "Background check-in" marker with no setting to turn on, and even as the newest message — a double-check that changed nothing shouldn't sit between you and your real answer. A reply that instead trails off into something other than the exact sentence still honors the opt-in "Hide background check-ins" setting (Settings → Sessions). Either way, click to expand and read exactly what the agent checked — nothing is deleted. This folds no matter how long the wrap-up narration is (a 2026-08-06 fix — a longer "here's what I verified" write-up used to slip past the fold and render in full); only a genuine deliverable — a heading, list, code block, or a question — is ever spared from the fold.
Both are one click away from the full message, which is why Omniscio can do them even though it won't take the irreversible step of fully hiding the reply.
When a rate-limit resume's no-op buried the answer (2026-06-30)
The hard-hide (above) fires only on a genuine background-wake turn Omniscio's backend
stamped. But one resume path deliberately does not set that stamp: when a
rate-limit clears or the load balancer rebalances a session, Omniscio re-wakes it with
a system-injected "Please continue" that carries no turnBoundary marker (the
2026-06-26 genuine-user fix keeps the hard-hide off that path so a real "Please
continue" you sent is never swallowed). If that resume lands on a session that had
already posted its real final answer, the agent correctly replies with the exact
sentinel — but with no stamp, the reply was neither hard-hidden nor split into its
own turn. It merged into the turn that held your real answer and, because Omniscio
paints a turn's last real reply as the body, the "Nothing to do here…" line
became the visible message and your real answer collapsed into that turn's
"N comments" activity zone. (Reported from a real session whose "~35 states"
answer vanished behind two such no-ops.)
Two builder changes fix it — both display-only, nothing is deleted:
- Split the no-op into its own turn. A dropped auto-response now also acts as a turn boundary when the run that follows it ends in the exact sentinel (a whole-message match, so a real continuation like "Working…" → "Done." never trips it). Your real answer stays its turn's visible final reply, and each no-op gets its own turn.
- Collapse that no-op by default. A turn opened by such a split is flagged
isWokenNoOpAckand folds to the one-line "Background check-in" marker regardless of the "Hide background check-ins" setting (the exact sentinel is unambiguous and a no-op never re-pings, so it is always safe to fold once superseded — the same default-fold the canonical wait sentinel gets). One click still expands it.
When the no-op had no boundary at all (2026-07-01)
The 2026-06-30 split above needed something to split at: a dropped "Please continue" auto-response row sitting between your answer and the no-op. But a background wake can arrive with no such row and no stamp either — a session held running on a "Waiting on a background process…" hold that spontaneously resumes hours later and emits the sentinel. (Reported from a real session whose 2:49pm answer was buried by a 5:18pm "Nothing to do here" — a wake path none of the earlier fixes had covered.)
Rather than teach the backend to stamp yet another wake path (this bug class had already been patched four times, once per newly-found wake), the fix moves the guard to where the symptom actually shows — the transcript builder — and keys it on the sentence itself:
- Split on the exact sentinel, boundary or not. When a background reply is the exact "Nothing to do here…" sentence and it would otherwise bury a real answer above it, that reply is given its own turn — the same whole-message match as before, so a genuine "Working… → Done." continuation still never splits. Because it keys on saved text (not an upstream marker), it covers every wake path at once, and it heals sessions that were already broken the next time you open them.
- Same fold. The split-off turn is
isWokenNoOpAckexactly like the 2026-06-30 case, so it collapses to the one-line "Background check-in" marker; your real answer is the visible reply. The per-session "Show system messages" toggle still shows the raw, un-split turn for auditing.
When the no-op is REWORDED, not Omniscio's exact sentence (2026-07-01, belt-and-suspenders)
The split above keys on Omniscio's exact instructed sentence. But an agent can improvise a differently-worded no-op — "nothing further to do", "nothing more to do", "nothing left to do", "nothing left to run" (the "to run" stem added 2026-08-05, hidden-final recurrence #14) — through a wake path that also left no marker. That reworded no-op could still bury your answer. So the same split now also fires on the fuzzy "nothing-to-do" family, reusing Omniscio's existing, backtested background-ack detector (no new matcher). Two things keep it safe:
- A real reply is never moved. The reused detector refuses to match anything long, anything with a question, or anything that's a real deliverable (a heading / list / code) — so a genuine answer that merely mentions "nothing to do" is left alone. It even ignores "nothing to do with the build" and "nothing to do but wait." And the split only ever fires on a no-op that comes after a real answer (a direct reply to you is the first message of its turn, which is never split).
- A reword is un-buried but not aggressively hidden. Unlike the exact sentence (which always folds to the one-liner), a reworded no-op is tagged only as a "background check-in": your answer stays the visible reply and the view lands on it, and the reword collapses to the one-liner only if you've turned on "Hide background check-ins." A reword is a heuristic match, not Omniscio's own guaranteed sentence, so it is treated more conservatively. The irreversible hard-hide stays exact-only.
When the no-op was a standalone reply to an automated poll (2026-08-05)
Every fix above un-buries a no-op that sits after a real answer. But a background wake can make the "Nothing to do here…" the only thing in its turn, with no real answer above it to protect. The case that surfaced this: a session being driven by another session (a stress-test "driver") received an automated check-in poll, and the agent correctly replied with just the sentence. That reply was the first (and only) message of its turn, so none of the earlier un-buriers touched it — they only fire when there is an answer above to protect — and the wake was not one Omniscio's backend stamps, so the full line rendered.
The transcript builder now folds that standalone reply to the same one-line "Background check-in" marker, keyed on two things together:
- It IS Omniscio's exact sentence (a whole-message match) — a real answer, or a reworded no-op, is never touched by this path.
- The turn was opened by something OTHER than you — an automated poll or a system resume, not a message you actually sent. A no-op that answered your message stays fully visible (and Omniscio re-delivers your message so it gets a real answer), and a dev-pipeline phase report is never folded even if its wording happens to match. Only a no-op answering an automated, non-you open folds.
As always this is the reversible fold, not the permanent hide — one click expands it, and the per-session "Show system messages" toggle shows the raw turn.
When a late "auto-landed" note un-folded the no-op (2026-09-02)
Two identical background-wake no-ops, three minutes apart, in the same session: the first collapsed to the one-line "Background check-in" marker, the second rendered in full — leaving "Nothing to do here. Everything was already finished before this background wake-up." as the session's visible last word.
The two replies were byte-identical. The difference was 25 minutes later: the auto-lander appended a "Couldn't auto-land …" note to the transcript, and a note that arrives after a turn has closed joins whatever turn is still open — the second no-op's. Omniscio protects those landed / couldn't-land notes from being swallowed by a fold, and it did that by cancelling the fold — which un-folded the throwaway reply along with it.
The fix mirrors what the hard-hide already does: keep the fold, and paint the note beside the marker. So a no-op that a land note lands in now shows one quiet "Background check-in" line plus the green "Auto-landed …" (or amber "Couldn't auto-land …") row — both visible, neither burying the other. A genuine status check-in is unchanged: it still stays fully open next to the note, because it carries a real reason you were pinged.
When a crash killed the turn first (2026-09-13)
Every un-burier above protects a settled answer sitting above the no-op — that is what tells Omniscio the reply belongs to a background wake rather than to you. When the app crashes mid-turn there is no settled answer to find: the work row is left unfinished, holding only tool activity and no closing sentence. So when crash-recovery resumed the session and the agent correctly answered with the one canonical sentence, nothing split it off — it merged into the turn you had opened, and with no wake signal left to read, the throwaway rendered in full as the last word under your own message. (Reported from a live session whose 11:04 go-ahead ended on a 12:08 “Nothing to do here”.)
A crash-recovery resume is now enough on its own: when the reply to one is the exact sentence, it gets its own turn and folds to the usual one-line “Background check-in” marker, with no setting to turn on. Your message and all the work above it are untouched and stay fully visible; one click still expands the fold, and “Show system messages” still reveals the raw turn. Display-only, and it heals already-affected sessions the next time you open them.
Two limits keep it safe:
- If the agent had not started work yet, nothing folds. No work row above the resume means your message was dropped on the floor unanswered — that is precisely what you need to see, so the reply keeps rendering in full.
- Only the exact sentence. A reworded no-op still needs a settled answer above it before anything is folded, exactly as before.
Relationship to "Hide background check-ins" (background-ack)
These are siblings, not duplicates:
- Background-ack ("Hide background check-ins", Settings → Sessions, off by default) FUZZILY matches status/progress reports ("Tests green (exit 0). Build still running.") and collapses them to a one-line expandable marker.
- Woken no-op (this page) matches ONE deterministic instructed sentence meaning "literally nothing to do" and hard-hides it (default on), with its own no-re-ping.
The deterministic sentence buys the precision needed to hide + suppress the ping
by default; the fuzzy detector stays opt-in. Background-ack additionally carries a
nothing-to-do rule family as an opt-in backup — it catches natural rewordings
("nothing further to do") and, unlike this default-on hider, reaches non-Claude
(Codex) sessions, which are never taught Omniscio's exact sentence.
For agents
Key files
| File | Role |
|---|---|
src/shared/woken-noop-sentinel/detect.ts |
Canonical phrase + metadata key + detectWokenNoOpSentinel |
src/main/process/spawn-build.ts |
Instruction constant + resolveWokenNoOpSentinelPrompt |
src/main/services/woken-noop-sentinel-flag.ts |
AMC_DISABLE_WOKEN_NOOP_SENTINEL kill switch |
src/main/process/streaming-finalizer.ts |
Finalize: HIDE stamp (snapshot-gated) + turnSentinelMisfire latch |
src/main/process/user-message-router.ts |
turnWasGenuineUserMessage arming for BOTH delivery paths (shared markTurnGenuineUserMessage; live writeToStdin + auto-resume noteResumedTurnGenuineUserMessage) + per-message re-drive budget reset |
src/main/services/session/session-service.ts |
Auto-resume relaunch arms the genuine-user flag after launch() (noteResumedTurnGenuineUserMessage, both --resume + context-transfer branches) |
src/main/process/process-manager.ts |
restoreStatusSilently + noteResumedTurnGenuineUserMessage delegator |
src/main/process/ndjson-event-handlers.ts |
armTurnBoundary (pre-wake snapshot) + handleTurnComplete gate dispatch |
src/main/process/ndjson-auto-disposition.ts |
tryWokenNoOpSilentFinish (no-re-ping) + tryWokenNoOpMisfireRecover (re-drive a real message) |
src/shared/real-conversation-turns.ts |
isWokenNoOp turn flag (reads the stamp) + the buried-answer split: shouldSplitAtDroppedAutoResponse (boundary-row case) and shouldSplitBeforeSpontaneousWokenNoOp (no-boundary spontaneous case) |
src/renderer/src/features/sessions/TurnGroup.tsx |
Render-time hard-hide |
Contracts (invariants + tests): .claude/memory/contracts/woken-noop-sentinel-contract.md (Claude) · .claude/memory/contracts/external-woken-noop-contract.md (the non-Claude engines).
Related
The sentinel is one of several guards that decide what a finished turn looks like on screen, so it is closest to Aborted-response recovery and Agent message display. The revive-and-continue path whose nudge it also governs is documented on Crash recovery.
Last verified 2026-09-23