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:
- Agent begins sunset.
- Agent writes
add_message(to: self, taggedConcepts: ['sunset-protocol-handover'], ...).
MailboxService.addMessage() triggers wake pumping.
- The bridge daemon sees the
SENT_TO edge and injects a [WAKE] prompt into the same active harness.
- 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:
- 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.
- 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.
- 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.
- 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.
- 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:
- Add an explicit mailbox delivery option such as
wakeSuppressed: true or deliveryMode: 'mailbox-only' to add_message / MailboxService.addMessage() and the OpenAPI schema.
- Teach
WakeSubscriptionService / wake pumping to preserve the message in the mailbox but skip wake emission for messages with that flag.
- Update
session-sunset Step 7 to send its self-DM handover using the mailbox-only option and taggedConcepts: ['sunset-protocol-handover'].
- 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
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"
Context
@tobiu observed a workflow failure in the live swarm: Gemini executed the
session-sunsetprotocol, 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:
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_MEevent. 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:add_message(to: self, taggedConcepts: ['sunset-protocol-handover'], ...).MailboxService.addMessage()triggers wake pumping.SENT_TOedge and injects a[WAKE]prompt into the same active harness.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:list_messagesremains canonical state.ai/mcp/server/memory-core/services/MailboxService.mjscallsWakeSubscriptionService.pump()after message writes.ai/mcp/server/memory-core/services/WakeSubscriptionService.mjsevaluatesSENT_TO_MEsubscriptions and supports filters includingtaggedConcepts.ai/scripts/bridge-daemon.mjspollsSENT_TO_MEedges and injects wake payloads into harnesses.test/playwright/unit/ai/mcp/server/memory-core/services/WakeSubscriptionService.spec.mjsandtest/playwright/unit/ai/scripts/bridge-daemon.spec.mjsare existing regression-test surfaces for wake behavior.Five-stage challenge chain result:
SENT_TO_MEedges. The live Gemini observation demonstrates the re-entry hazard.session-sunsetresponsible for manually managing bridge-daemon state. The durable fix belongs in Memory Core wake semantics or an explicitadd_messagedelivery option consumed by the wake pump.The Fix
Implement a same-session self-handover wake guard.
Preferred substrate shape:
wakeSuppressed: trueordeliveryMode: 'mailbox-only'toadd_message/MailboxService.addMessage()and the OpenAPI schema.WakeSubscriptionService/ wake pumping to preserve the message in the mailbox but skip wake emission for messages with that flag.session-sunsetStep 7 to send its self-DM handover using the mailbox-only option andtaggedConcepts: ['sunset-protocol-handover'].sunset-protocol-handovermessages from the mailbox.Acceptable narrower v1 if the explicit flag is too large:
sender === recipientandtaggedConceptsincludessunset-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
SENT_TO_MEsubscription rules.session-sunsetStep 7 documents the mailbox-only / next-session-only delivery contract.AGENTS_STARTUP.md/ boot mailbox guidance still consumes unreadsunset-protocol-handovermessages on actual fresh startup.list_messages({status: 'unread'}).SENT_TO_MEmessages still wake.Out of Scope
mark_readthe sunset self-DM in the same session; that would destroy the next-session pickup value.Avoided Traps / Gold Standards Rejected
Related
ai/mcp/server/memory-core/services/MailboxService.mjsai/mcp/server/memory-core/services/WakeSubscriptionService.mjsai/scripts/bridge-daemon.mjs.agents/skills/session-sunset/references/session-sunset-workflow.mdOrigin 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"