- POST /companies/{slug}/directives: free-form shareholder message becomes
an objective (reuses manager decomposition), logs directive.received
- Objective rollup now emits a CEO-voiced milestone.update event via one
pool call (plain-text fallback if the LLM call fails)
- _chat_structured retries once on empty/invalid JSON from the pool
(observed empty-content responses breaking protocol extraction)
- Dashboard: per-company shareholder textarea + CEO updates feed; refresh
skips DOM rewrite while a textarea is focused
Verified end-to-end: directive -> 3 tasks -> rework after handoff block ->
rollup -> CEO milestone update; gaswatch index.html now on-brand.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>