Context
Follow-up to #13118 / #13119 (lifecycle-first wake directive), from @tobiu's review of PR #13119 on 2026-06-13. Two coupled cost issues with the standing WAKE_LANE_DIRECTIVE:
- (primary) placement — it is appended to EVERY wake digest, including A2A-message-triggered wakes, when it is an idle-watchdog nudge that only belongs on heartbeat wakes.
- (secondary) length — the directive text is token-heavy (~1,100 chars / ~280 tokens) for per-wake content.
Release classification: boardless — Agent OS / MX cost hardening, not a v13 release blocker.
The Problem
ai/daemons/wake/daemon.mjs buildWakeDigest appends the directive UNCONDITIONALLY (line ~1158):
return `[WAKE][priority:${digestPriority}] ${N} events for ${identity}: ${breakdown}\n\nSubscription: ${subId}\n\n${WAKE_LANE_DIRECTIVE}`;A digest's events are {messages, tasks, permissions, heartbeats}. So a wake triggered by an A2A broadcast (lane-claim) or direct message carries the full lifecycle directive — even though that wake already has specific actionable content. The directive is an IDLE-agent nudge ("you're idle, here's what to do next"); on a message wake it is pure noise + token waste. And message wakes are far more frequent than the 20-min heartbeat, so frequency × length makes placement the dominant directive token cost — worse than the length alone.
The Architectural Reality
daemon.mjs buildWakeDigest is the append site (line ~1158); the directive is the idle-watchdog semantic, which maps to the heartbeat event type (heartbeat_pulse → {type:'heartbeat'}), NOT messages / tasks / permissions.
- The daemon already distinguishes wake types (coalescing handles
type === 'heartbeat' vs message events distinctly), so the gate is cheap.
wakeLaneDirective.mjs owns the directive text; wakeLaneDirective.spec pins its behavioral anchors (lifecycle-first ordering, routing tiers, idle terminals) — these are the clarity floor for any compression.
The Fix
- AC1 (placement, primary):
buildWakeDigest appends WAKE_LANE_DIRECTIVE ONLY to pure-heartbeat digests — i.e. when messages, tasks, and permissions are all empty and a heartbeat is present. A digest carrying any actionable A2A content (broadcast / direct message / task / permission), including a mixed heartbeat+message digest, omits the directive.
- AC2 (test): a daemon test asserts the directive IS present on a heartbeat-only digest and ABSENT on a message-triggered digest (and on a mixed heartbeat+message digest).
- AC3 (compression, secondary): compress the directive text to net-reduce per-wake tokens while preserving the behavioral anchors (lifecycle-first ordering, the routing tiers, the idle terminals); co-update
wakeLaneDirective.spec's phrase assertions to the new load-bearing anchors. Risk to avoid: over-compression that reverts to the backlog-first / idle failure mode #13118 fixed — the directive is long because the explicit ordering changed behavior; the spec anchors are the floor.
- AC4 (evidence): PR body shows the token/char before→after AND notes the placement change removes the directive from the majority of wakes (message wakes), with the heartbeat-only retained surface named.
Out of Scope
- No delivery-trigger PR-state watcher (still deferred per #13118).
- No change to the directive's behavioral MEANING beyond compression.
- No new scheduler / scoreboard / lease.
Dependency
Touches daemon.mjs buildWakeDigest (the same surface PR #13119 modifies) → implement AFTER #13119 merges, off dev, to avoid a conflict.
Duplicate / freshness evidence
- Live open-issue sweep 2026-06-13:
gh issue list --search "wake directive token" and "WAKE_LANE_DIRECTIVE" → both empty; no equivalent ticket.
- #13118 "Out of Scope" lists the delivery-trigger watcher but NOT directive placement / compression — this is a distinct, un-tracked follow-up.
Related
Related: #13118, #13119, #13114
Origin Session ID: 4cc428e3-cf36-4324-8646-1b96cb23fa4a
Context
Follow-up to #13118 / #13119 (lifecycle-first wake directive), from @tobiu's review of PR #13119 on 2026-06-13. Two coupled cost issues with the standing
WAKE_LANE_DIRECTIVE:Release classification: boardless — Agent OS / MX cost hardening, not a v13 release blocker.
The Problem
ai/daemons/wake/daemon.mjsbuildWakeDigestappends the directive UNCONDITIONALLY (line ~1158):return `[WAKE][priority:${digestPriority}] ${N} events for ${identity}: ${breakdown}\n\nSubscription: ${subId}\n\n${WAKE_LANE_DIRECTIVE}`;A digest's events are
{messages, tasks, permissions, heartbeats}. So a wake triggered by an A2A broadcast (lane-claim) or direct message carries the full lifecycle directive — even though that wake already has specific actionable content. The directive is an IDLE-agent nudge ("you're idle, here's what to do next"); on a message wake it is pure noise + token waste. And message wakes are far more frequent than the 20-min heartbeat, so frequency × length makes placement the dominant directive token cost — worse than the length alone.The Architectural Reality
daemon.mjsbuildWakeDigestis the append site (line ~1158); the directive is the idle-watchdog semantic, which maps to theheartbeatevent type (heartbeat_pulse→{type:'heartbeat'}), NOTmessages/tasks/permissions.type === 'heartbeat'vs message events distinctly), so the gate is cheap.wakeLaneDirective.mjsowns the directive text;wakeLaneDirective.specpins its behavioral anchors (lifecycle-first ordering, routing tiers, idle terminals) — these are the clarity floor for any compression.The Fix
buildWakeDigestappendsWAKE_LANE_DIRECTIVEONLY to pure-heartbeat digests — i.e. whenmessages,tasks, andpermissionsare all empty and a heartbeat is present. A digest carrying any actionable A2A content (broadcast / direct message / task / permission), including a mixed heartbeat+message digest, omits the directive.wakeLaneDirective.spec's phrase assertions to the new load-bearing anchors. Risk to avoid: over-compression that reverts to the backlog-first / idle failure mode #13118 fixed — the directive is long because the explicit ordering changed behavior; the spec anchors are the floor.Out of Scope
Dependency
Touches
daemon.mjsbuildWakeDigest(the same surface PR #13119 modifies) → implement AFTER #13119 merges, offdev, to avoid a conflict.Duplicate / freshness evidence
gh issue list --search "wake directive token"and"WAKE_LANE_DIRECTIVE"→ both empty; no equivalent ticket.Related
Related: #13118, #13119, #13114
Origin Session ID: 4cc428e3-cf36-4324-8646-1b96cb23fa4a