Phase 3 / Wave 1 / ε. Adds an opt-in helper that lets the user's
Hermes assistant read notifications they've explicitly granted
access to via Android's NotificationListenerService — the same
public API Wear OS, Android Auto, and Tasker have used for over
a decade. Disabled by default; user controls grant/revoke via
Android Settings → Notification access.
Three pieces (all PHASE3-ε marker-blocked in shared files):
* Phone — HermesNotificationCompanion (NotificationListenerService
subclass) + NotificationModels + NotificationCompanionSettingsScreen
(About / Status / Test sections, mirrors VoiceSettingsScreen). Cold-
start buffer up to 50 envelopes, drops on relay-offline (matches
smartwatch-out-of-range semantics). Skips notifications with no
human-readable content.
* Server — NotificationsChannel with collections.deque(maxlen=100)
for LRU-by-time eviction. Wired into RelayServer __init__ + _on_message
dispatch. In-memory only, lost on restart by design.
* Tool — android_notifications_recent(limit=20) registers via
tools.registry, hits /notifications/recent over loopback (no auth
needed for loopback callers, matches /media/register trust model).
Stdlib urllib.request only.
No new session grant type (reuses existing chat grant trust boundary
per spec). ChannelMultiplexer.sendNotification() wrapper for the
outbound path. python -m py_compile clean on all touched/new files.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>