Context
Recent wake-substrate analysis found that our Shape D architecture is directionally correct, but missing one critical layer: transport selection alone cannot decide whether a wake should interrupt an active harness turn or wait until the next turn. The user explicitly validated the value of documenting the three existing shapes and approved filing this follow-up ticket after the current open-ticket sweep.
The current architecture already documents the transport ladder:
- Shape A: MCP notifications / push when a harness supports it.
- Shape B: A2A webhook push notifications.
- Shape C: bridge-daemon / OS-level fallback.
- Shape D: hybrid standards-first routing with bridge fallback.
The new insight is that Shape D needs an explicit presence and policy model, not just transport capability detection.
The Problem
The wake service currently has durable messages, subscriptions, priorities, and bridge delivery, but urgent-vs-next-turn semantics are underspecified. This creates two failure modes:
- Normal coordination messages can wake or interrupt agents unnecessarily.
- Truly urgent coordination, such as scope-creep prevention while a peer is mid-PR, has no explicit routing contract.
The hardest part is not the priority flag itself. The hard part is knowing whether the target harness is idle, actively generating, waiting on approval, or holding user-typed input that must not be clobbered.
The Architectural Reality
This ticket sits under the swarm-autonomy / wake-substrate line, not under a specific PR review or Memory Core bugfix.
Relevant existing anchors:
- Parent epic: #10311
- Shape D wake-substrate epic: #10357
- Standards-alignment ADR:
learn/agentos/decisions/0002-phase3-wake-substrate-standards-alignment.md
- MCP Shape A follow-up: #10358
- A2A webhook Shape B follow-up: #10359
- AppleScript focus-steal safety issue: #10422
- Wake-substrate integrity issue: #10515
Current public-source anchors from the April 2026 analysis:
The Fix
Define and document a routing layer with two explicit primitives:
HarnessPresence
- Suggested state set:
unknown | idle | active | waitingOnApproval | userTyping
- Suggested metadata:
activeTurnId, capabilities, lastSeenAt, source
- Purpose: describe the receiving harness state independently from message importance.
wakePolicy
- Suggested values:
silent | next_turn | immediate
- Purpose: describe delivery behavior independently from semantic priority.
Routing should then be capability-aware:
silent: store only; no wake.
next_turn: store unread; picked up by turn-start mailbox checks.
immediate + Codex active: prefer Codex app-server turn/steer.
immediate + Codex idle: prefer Codex app-server turn/start.
immediate + MCP/A2A-capable harness: use standards-backed push.
immediate + no native control plane: bridge-daemon / OS fallback.
The OS fallback may infer active vs idle from the harness submit button state, e.g. Send versus Stop / Cancel, but this must be treated as a last resort. If used, polling should be conservative; the initial design target is a 5s interval with focus checks, timeout limits, and a hard guard against clobbering active user input.
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Docs |
Evidence |
HarnessPresence vocabulary |
#10517 + #10311 / #10357 lineage + ADR 0002 Shape D routing + current Codex app-server thread/status/changed status events |
Defines receiver harness state separately from message priority and transport capability. Documentation should describe at least unknown, idle, active, waitingOnApproval, and optional harness-proven userTyping state. |
If no trustworthy presence proof exists, route as unknown; do not interrupt an active turn from unproven UI inference. |
Update ADR 0002 or a closely related wake-substrate doc. |
Docs diff plus source-anchor sweep showing HarnessPresence is new vocabulary and not an existing runtime field. |
wakePolicy vocabulary |
#10517 + ADR 0002 Shape D + current WakeSubscriptionService / CoalescingEngineService routing around harnessTarget |
Defines delivery behavior separately from semantic priority: silent stores only, next_turn defers to mailbox/turn-start checks, and immediate allows active wake delivery when safe. |
Prefer next_turn when immediate delivery is unsafe or presence is unknown; silent remains explicit store-only behavior. |
Update ADR 0002 or a closely related wake-substrate doc. |
Docs diff plus examples proving priority and wakePolicy are not collapsed. |
| Shape D routing examples |
ADR 0002 + current manage_wake_subscription / harnessTarget enum (mcp-notifications, a2a-webhook, bridge-daemon, disabled, none) + MCP/A2A public transport docs |
Documents capability-aware route selection: Codex app-server steering/start for Codex where presence is known, MCP notifications for supporting MCP clients, A2A webhook for webhook-capable clients, bridge fallback otherwise. |
disabled / none / failed push paths fall back to stored unread messages and heartbeat/mailbox pickup; bridge fallback must not be treated as native push. |
Update ADR 0002 or a closely related wake-substrate doc. |
Docs diff with examples covering Codex app-server, MCP/A2A standards push, and bridge fallback. |
| OS-level button-state polling fallback |
#10517 + #10422 focus-steal safety + Shape C bridge fallback lineage |
Documents that Send/Stop/Cancel button-state inference is brittle UI automation and only a last-resort presence adapter, not the architecture. If implemented, initial polling should be conservative at 5s with focus checks and timeout/no-clobber guards. |
If UI state cannot be read safely, do not infer active/idle; store unread and rely on next-turn pickup. |
Update ADR 0002 or a closely related wake-substrate doc. |
Docs diff explicitly preserving #10422 as the focus-steal mechanics owner and #10515 as out of scope. |
Acceptance Criteria
Out of Scope
- Implementing the actual OS polling adapter.
- Changing existing wake subscription persistence or GC behavior.
- Expanding #10515 with routing semantics.
- Treating OS button polling as a first-class architecture.
- Assuming all harnesses support active-turn preemption.
Avoided Traps
- Priority-only design:
priority: high is not the same thing as wakePolicy: immediate. Some high-importance messages should wait; some short guardrail messages may need immediate delivery.
- Transport-only design: MCP/A2A/bridge capability does not answer whether the target is safe to interrupt.
- OS polling as architecture:
Send vs Stop/Cancel can be useful empirically, but it is brittle UI automation and must remain a fallback adapter.
- Scope creep into #10515: wake-substrate integrity must stay focused on subscription survival and test isolation. Routing policy is a separate layer.
Related
- Parent epic: #10311
- Prior Shape D wake-substrate epic: #10357
- MCP notification path: #10358
- A2A webhook path: #10359
- AppleScript focus safety: #10422
- Wake-substrate integrity: #10515
Origin Session ID: 3b0c3e6f-21a2-4b16-babd-3c4e208c2926
Retrieval Hint: wake substrate HarnessPresence wakePolicy urgent next-turn routing Codex app-server OS button polling MCP push A2A webhook bridge fallback
Context
Recent wake-substrate analysis found that our Shape D architecture is directionally correct, but missing one critical layer: transport selection alone cannot decide whether a wake should interrupt an active harness turn or wait until the next turn. The user explicitly validated the value of documenting the three existing shapes and approved filing this follow-up ticket after the current open-ticket sweep.
The current architecture already documents the transport ladder:
The new insight is that Shape D needs an explicit presence and policy model, not just transport capability detection.
The Problem
The wake service currently has durable messages, subscriptions, priorities, and bridge delivery, but urgent-vs-next-turn semantics are underspecified. This creates two failure modes:
The hardest part is not the priority flag itself. The hard part is knowing whether the target harness is idle, actively generating, waiting on approval, or holding user-typed input that must not be clobbered.
The Architectural Reality
This ticket sits under the swarm-autonomy / wake-substrate line, not under a specific PR review or Memory Core bugfix.
Relevant existing anchors:
learn/agentos/decisions/0002-phase3-wake-substrate-standards-alignment.mdCurrent public-source anchors from the April 2026 analysis:
thread/status/changed,turn/start,turn/steer,turn/interrupt, andthread/inject_items: https://developers.openai.com/codex/app-serverThe Fix
Define and document a routing layer with two explicit primitives:
HarnessPresenceunknown | idle | active | waitingOnApproval | userTypingactiveTurnId,capabilities,lastSeenAt,sourcewakePolicysilent | next_turn | immediateRouting should then be capability-aware:
silent: store only; no wake.next_turn: store unread; picked up by turn-start mailbox checks.immediate + Codex active: prefer Codex app-serverturn/steer.immediate + Codex idle: prefer Codex app-serverturn/start.immediate + MCP/A2A-capable harness: use standards-backed push.immediate + no native control plane: bridge-daemon / OS fallback.The OS fallback may infer active vs idle from the harness submit button state, e.g.
SendversusStop/Cancel, but this must be treated as a last resort. If used, polling should be conservative; the initial design target is a 5s interval with focus checks, timeout limits, and a hard guard against clobbering active user input.Contract Ledger
HarnessPresencevocabularythread/status/changedstatus eventsunknown,idle,active,waitingOnApproval, and optional harness-provenuserTypingstate.unknown; do not interrupt an active turn from unproven UI inference.HarnessPresenceis new vocabulary and not an existing runtime field.wakePolicyvocabularyWakeSubscriptionService/CoalescingEngineServicerouting aroundharnessTargetpriority:silentstores only,next_turndefers to mailbox/turn-start checks, andimmediateallows active wake delivery when safe.next_turnwhen immediate delivery is unsafe or presence is unknown;silentremains explicit store-only behavior.priorityandwakePolicyare not collapsed.manage_wake_subscription/harnessTargetenum (mcp-notifications,a2a-webhook,bridge-daemon,disabled,none) + MCP/A2A public transport docsdisabled/none/ failed push paths fall back to stored unread messages and heartbeat/mailbox pickup; bridge fallback must not be treated as native push.Acceptance Criteria
HarnessPresenceandwakePolicyseparately from transport capability and message priority.Out of Scope
Avoided Traps
priority: highis not the same thing aswakePolicy: immediate. Some high-importance messages should wait; some short guardrail messages may need immediate delivery.SendvsStop/Cancelcan be useful empirically, but it is brittle UI automation and must remain a fallback adapter.Related
Origin Session ID: 3b0c3e6f-21a2-4b16-babd-3c4e208c2926 Retrieval Hint:
wake substrate HarnessPresence wakePolicy urgent next-turn routing Codex app-server OS button polling MCP push A2A webhook bridge fallback