LearnNewsExamplesServices
Frontmatter
id10675
titleIdle-out A2A in-place nudge with cooldown + no-spawn invariant
stateClosed
labels
enhancementaiarchitecture
assigneesneo-opus-4-7
createdAtMay 4, 2026, 10:50 AM
updatedAtMay 4, 2026, 3:23 PM
githubUrlhttps://github.com/neomjs/neo/issues/10675
authorneo-opus-4-7
commentsCount0
parentIssue10671
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 4, 2026, 3:23 PM

Idle-out A2A in-place nudge with cooldown + no-spawn invariant

Closedenhancementaiarchitecture
neo-opus-4-7
neo-opus-4-7 commented on May 4, 2026, 10:50 AM

Context

Sub-issue of #10671. When checkSunsetted reports idle_out_candidate: true, recovery is a lightweight A2A nudge into the existing session — not a fresh-spawn. Reuses bridge-daemon.mjs in-place keystroke logic; zero new transport.

The Problem

Today there is no idle-out recovery path. Active-subscription stale-memory state has only two outcomes: heartbeat keeps polling (no action) or Cmd+N spawns a duplicate session (parallel-session footgun).

The Architectural Reality

A2A messaging primitive: add_message({to: identity, body: ...})bridge-daemon.mjs dispatches via osascript keystroke into the active chat tab. This is the same delivery path used today for non-sunset wake events.

#10641 lesson: staleness ≠ "agent is idle." It's a candidate signal for in-place nudge ONLY.

The Fix

On idle_out_candidate signal:

  1. Acquire in-flight idle-out lock (per the lock-primitive sub-issue)
  2. Send A2A heartbeat message: subject [heartbeat] idle-out nudge; body conventional content (e.g., "long since your last save — please check inbox + save current progress, then continue or sunset cleanly")
  3. bridge-daemon delivers via existing keystroke path
  4. Wait for first add_memory from identity (clears lock)
  5. If lock expires without memory → mark abandoned (per lock primitive)

Invariants:

  • Bounded — N nudges within window, hard cooldown thereafter
  • Non-spawning — never opens a new session
  • Idempotent — re-firing produces no duplicate effect
  • No-destructive-type-into-active-draftbridge-daemon focus-steal protection per #10422

Acceptance Criteria

  • Heartbeat-nudge message body convention documented (canonical wording + intent)
  • Cooldown enforces max-1-nudge-per-window (default 10 min)
  • No-destructive-type verified via bridge-daemon focus-steal guard
  • Empirical: trigger idle-out scenario, observe single nudge delivered, observe agent saving fresh memory in response, lock cleared

Out of Scope

  • The lock primitive itself — covered by sibling sub-issue
  • Detector contract — covered by sibling sub-issue

Related

  • Parent: #10671
  • Adjacent: #10422 (focus-steal protection), #10641 (staleness lesson preserved)

Origin Session ID: cce1fea5-32ff-410c-b820-2e9a27b3cd51

tobiu referenced in commit 75c72cd - "feat(ai): per-identity idle-out A2A heartbeat nudge dispatcher (#10675) (#10690) on May 4, 2026, 3:23 PM
tobiu closed this issue on May 4, 2026, 3:23 PM