LearnNewsExamplesServices
Frontmatter
id10498
titlePrevent sunset self-DMs from waking active sessions
stateClosed
labels
bugdocumentationaiarchitecture
assigneesneo-gpt
createdAtApr 29, 2026, 5:41 PM
updatedAtApr 29, 2026, 6:07 PM
githubUrlhttps://github.com/neomjs/neo/issues/10498
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtApr 29, 2026, 6:07 PM

Prevent sunset self-DMs from waking active sessions

Closed v13.0.0/archive-v13-0-0-chunk-7 bugdocumentationaiarchitecture
neo-gpt
neo-gpt commented on Apr 29, 2026, 5:41 PM

Context

@tobiu observed a workflow failure in the live swarm: Gemini executed the session-sunset protocol, sent herself the Sunset self-DM handover, and the A2A wake substrate immediately delivered a wake prompt back into the still-active same harness. Gemini then interpreted that wake prompt as the next session.

That collapses the session boundary the Sunset Protocol is supposed to preserve.

This is adjacent to, but not a duplicate of:

  • #10349 — introduced / specifies the sunset self-DM handover for next-session boot pickup.
  • #10408 — codified wake events as interrupts and the inbox as canonical state.
  • #10374 — refined turn vs. session boundaries to prevent premature sunset.

The new failure is the interaction between #10349 and wake delivery: a future-self handover mailbox item can wake the current-self session before the current session has actually ended.

The Problem

The Sunset self-DM is intended to be a next-session boot artifact. It should remain unread and available for the next harness startup, where the agent can consume it through the boot-time mailbox check.

But the current A2A wake substrate treats the self-DM like any other SENT_TO_ME event. If the source and target identity are the same active agent, the wake daemon can inject the message back into the current harness immediately. That creates a false session boundary:

  1. Agent begins sunset.
  2. Agent writes add_message(to: self, taggedConcepts: ['sunset-protocol-handover'], ...).
  3. MailboxService.addMessage() triggers wake pumping.
  4. The bridge daemon sees the SENT_TO edge and injects a [WAKE] prompt into the same active harness.
  5. The agent treats the self-handover as a fresh-session entry point.

That nullifies the value of the sunset protocol: the handover is consumed by the dying session instead of preserved for the next one.

The Architectural Reality

Relevant surfaces verified during ticket creation:

  • .agents/skills/session-sunset/references/session-sunset-workflow.md:
    • Step 6 marks processed inbox messages read before sunset.
    • Step 7 requires an A2A Continuity Ping to the agent's own identity.
    • Step 8 persists the Sandman memory.
  • #10349 defines the self-DM handover as a durable mailbox bridge for next-session boot pickup.
  • #10408 defines wake injection as an interrupt; list_messages remains canonical state.
  • ai/mcp/server/memory-core/services/MailboxService.mjs calls WakeSubscriptionService.pump() after message writes.
  • ai/mcp/server/memory-core/services/WakeSubscriptionService.mjs evaluates SENT_TO_ME subscriptions and supports filters including taggedConcepts.
  • ai/scripts/bridge-daemon.mjs polls SENT_TO_ME edges and injects wake payloads into harnesses.
  • test/playwright/unit/ai/mcp/server/memory-core/services/WakeSubscriptionService.spec.mjs and test/playwright/unit/ai/scripts/bridge-daemon.spec.mjs are existing regression-test surfaces for wake behavior.

Five-stage challenge chain result:

  1. Premise: Valid. The session-sunset workflow explicitly sends a self-message, and the wake substrate listens to SENT_TO_ME edges. The live Gemini observation demonstrates the re-entry hazard.
  2. Prescription: Do not remove self-DMs. Preserve the mailbox bridge, but make sunset handovers mailbox-only / next-session-only from the wake layer's perspective.
  3. Substrate: This belongs at the mailbox/wake boundary plus the session-sunset docs. A pure reasoning instruction to "ignore the wake" is too fragile and already failed in the observed case.
  4. Consumer: Future agent sessions, the active harness, wake daemon, Memory Core mailbox, and the Human Commander. The solution must keep the handover available for boot while suppressing same-session re-entry.
  5. Service Boundary: Avoid making session-sunset responsible for manually managing bridge-daemon state. The durable fix belongs in Memory Core wake semantics or an explicit add_message delivery option consumed by the wake pump.

The Fix

Implement a same-session self-handover wake guard.

Preferred substrate shape:

  1. Add an explicit mailbox delivery option such as wakeSuppressed: true or deliveryMode: 'mailbox-only' to add_message / MailboxService.addMessage() and the OpenAPI schema.
  2. Teach WakeSubscriptionService / wake pumping to preserve the message in the mailbox but skip wake emission for messages with that flag.
  3. Update session-sunset Step 7 to send its self-DM handover using the mailbox-only option and taggedConcepts: ['sunset-protocol-handover'].
  4. Update the boot-side handover check to continue reading unread sunset-protocol-handover messages from the mailbox.

Acceptable narrower v1 if the explicit flag is too large:

  • Suppress wake emission when sender === recipient and taggedConcepts includes sunset-protocol-handover, while leaving ordinary self-DMs and cross-agent DMs unchanged.

The unread mailbox item must remain available to the next session; suppressing wake must not mark it read.

Acceptance Criteria

  • Sunset self-DM handovers persist as unread mailbox messages for next-session boot pickup.
  • Sunset self-DM handovers do not emit a wake prompt back into the same currently active harness.
  • Ordinary A2A DMs still emit wakes according to existing SENT_TO_ME subscription rules.
  • Ordinary self-DMs that are not sunset handovers either retain current behavior or have an explicit documented delivery-mode decision.
  • session-sunset Step 7 documents the mailbox-only / next-session-only delivery contract.
  • AGENTS_STARTUP.md / boot mailbox guidance still consumes unread sunset-protocol-handover messages on actual fresh startup.
  • Regression coverage proves: self sunset handover writes a mailbox message, does not enqueue a wake, and remains readable by list_messages({status: 'unread'}).
  • Regression coverage proves non-sunset SENT_TO_ME messages still wake.

Out of Scope

  • Removing Sunset self-DMs entirely. #10349's durability rationale still stands.
  • Replacing Sandman memory or GitHub handover comments.
  • Changing all wake delivery semantics.
  • Requiring the active agent to mark_read the sunset self-DM in the same session; that would destroy the next-session pickup value.
  • Cross-agent handover semantics; this ticket is specifically about same-identity sunset self-DMs.
  • Solving all wake coalescing / stale digest issues. #10408 covers interrupt-vs-polling discipline; this ticket only handles self-handover re-entry.

Avoided Traps / Gold Standards Rejected

  • "Just tell the agent to ignore the wake." Rejected. The observed failure is exactly that the wake prompt induced the wrong mental state. This needs substrate support or at minimum explicit mailbox-only semantics.
  • "Mark the self-DM read immediately." Rejected. That makes the next session blind and defeats the reason #10349 exists.
  • "Disable all self-DM wakes." Rejected as an over-broad policy. Some self-DMs may be legitimate immediate reminders; sunset handovers are the special next-session-only class.
  • "Broadcast the handover instead." Rejected per #10349. It pollutes other agents' inboxes and does not solve same-session re-entry.

Related

  • #10349 — Sunset self-DM handover for next-session boot pickup.
  • #10408 — Wake-trigger interrupt vs polling protocol.
  • #10374 — Session Sunset trigger boundaries.
  • ai/mcp/server/memory-core/services/MailboxService.mjs
  • ai/mcp/server/memory-core/services/WakeSubscriptionService.mjs
  • ai/scripts/bridge-daemon.mjs
  • .agents/skills/session-sunset/references/session-sunset-workflow.md

Origin Session ID: ea6898ba-531f-4162-996b-99e7b235c120

Retrieval Hint: "session sunset self-DM wake same-session re-entry mailbox-only sunset-protocol-handover WakeSubscriptionService MailboxService bridge-daemon"

tobiu referenced in commit 4deb525 - "fix(memory-core): suppress sunset self-DM wakes (#10498) (#10500) on Apr 29, 2026, 6:07 PM
tobiu closed this issue on Apr 29, 2026, 6:07 PM