Context (revised 2026-05-28 — scope refinement)
Polyphony workflows are moving from blocking \human_gate\ nodes to a gate compression pattern: \ ype: notification\ + \script:\ poll-loop. The workflow fires a domain signal ('PR #N ready for review'), the user gets a toast, does the thing, and the workflow's poll script detects the resolution. PlateSpinner is the user-facing surface.
What PlateSpinner needs
P0 — Event parsing + CTA rendering
- Parse \ ype: notification\ events from .events.jsonl. Extract the polyphony domain signal envelope (kind, severity, cta_url, cta_kind, correlation_id, expires_at, subject, work_item_id).
- Render CTA buttons based on \cta_kind\ → button label/icon mapping. Clicking opens \cta_url\ in the default browser.
- Severity-gated toast routing: \�ction_required\ → toast + badge + card. \warning\ → badge + inline. \info\ → inline only.
P1 — Correlation-based lifecycle
- Auto-dismiss on resolution: When a signal with matching \correlation_id\ and severity \info\ arrives, clear/resolve the earlier \�ction_required\ card. Decrement tray badge.
- Expiry enforcement: Clear signals whose \�xpires_at\ has passed. Prevent stale toasts.
- Dedup: Same \correlation_id\ doesn't re-fire a toast (e.g., during poll retries).
P2 — Tray badge
- 'N waiting on you' badge on the tray icon — count of unresolved \�ction_required\ signals across all active runs.
CTA kind → button mapping (proposed)
| \cta_kind\ |
Button label |
Behavior |
| \ |
|
|
| eview_pr\ |
'Review PR' |
Opens PR URL |
| \merge_pr\ |
'Merge PR' |
Opens PR URL |
| \�pprove_plan\ |
'Review Plan' |
Opens plan PR URL |
| \ |
|
|
| esolve_conflict\ |
'Resolve' |
Opens conflict artifact |
| \�iew_evidence\ |
'Review Evidence' |
Opens evidence PR URL |
Explicitly out of scope
- Two-way RPC back to conductor (NEVER)
- Hosting polling logic (that's a workflow \script:\ step)
- Replacing conductor dashboard for execution monitoring
Relationship
Part of Epic #521 (self-contained orchestration). Depends on:
Design Reference
.squad/decisions/inbox/bach-on-error-notifications-design-2026-05-28T155810-0700.md\ §2.1–2.4
Context (revised 2026-05-28 — scope refinement)
Polyphony workflows are moving from blocking \human_gate\ nodes to a gate compression pattern: \ ype: notification\ + \script:\ poll-loop. The workflow fires a domain signal ('PR #N ready for review'), the user gets a toast, does the thing, and the workflow's poll script detects the resolution. PlateSpinner is the user-facing surface.
What PlateSpinner needs
P0 — Event parsing + CTA rendering
P1 — Correlation-based lifecycle
P2 — Tray badge
CTA kind → button mapping (proposed)
Explicitly out of scope
Relationship
Part of Epic #521 (self-contained orchestration). Depends on:
Design Reference
.squad/decisions/inbox/bach-on-error-notifications-design-2026-05-28T155810-0700.md\ §2.1–2.4