Symptom

The KRILL_DEMO_CONTROL file-channel hook understood select / view / center / fit / reset / screen:swarm / screen:canvas / scroll:fleet — all navigation and selection. There was no way to make the client avatar open its speech bubble with narration text, so demo context that couldn’t be shown on the canvas (why a node won, what a phase label means) had to be added by hand in post-production voice-over.

Root cause

Not a bug — a missing capability. The underlying plumbing already existed: ScreenCore.announceDialog(text: String) sets the backing _demoDialog state, avatareSpeechBubbleContent exposes it, and ClientScreen already renders it as a speech bubble whenever no menu is open (production already uses this path for the “servers unreachable” notice). DemoControl’s command vocabulary in composeApp/src/desktopMain/kotlin/krill/zone/main.kt simply never routed a command to it.

Fix

Prevention

When a ScreenCore capability is added for one caller (production UI, a menu action) but is generically useful for demo/automation, wire it into the DemoControl vocabulary in the same PR rather than leaving it as a gap that has to be discovered and filed separately later.