if (params.heartbeat?.isolatedSession !== true) return true;
...
return isolatedSessionKey === session.sessionKey;
So if your wake hook queues the event on the main session, but the heartbeat run executes in a fresh :heartbeat session, the queued text can be ignored and the model just sees the normal heartbeat prompt → HEARTBEAT_OK → ok-token.
Can you check this one value?
openclaw config get agents.defaults.heartbeat.isolatedSession --json
If it’s true, try temporarily setting it to false, restart, and run the manual event test again. That would confirm the bug is: wake hooks enqueue system events to the base session, while isolated heartbeat runs don’t inspect/drain that base-session wake queue.
If it’s already false, then the next thing I’d want is the new openclaw system heartbeat last --json after your latest test — specifically whether it has a preview. A preview usually means heartbeat tool notify:false; no preview usually points to literal HEARTBEAT_OK stripping.