signal.raise
Schema
Input = { kind?: 'decision' | 'insight' | 'reminder' | 'alert' | 'question' | 'celebration', // default 'insight' title: string, // max 160 chars body?: string, // max 4000 chars options?: Array<{ id: string, label: string, hint?: string }>, // max 6 — one-tap answers priority?: 'low' | 'normal' | 'high' | 'urgent', // default 'normal' dueAt?: string, // ISO 8601 action?: Record<string, unknown>, // opaque to the skill; interpreted by whoever answers it}
Output = { signalId: string | null, delivered: boolean, note?: string,}This is how agents (and the QA reviewer, and the budget guard, and the learning loop’s reflection
pass) reach the Living Desktop from anywhere in the system
— they never touch the signals table directly, only this one adapter-backed skill. Inside a Studio
project, source is set to studio:<projectId> automatically so the desktop can trace a signal back
to the project that raised it. Every call is traced (ctx.emit) regardless of whether the desktop
adapter is actually wired, so even a context without ctx.signals leaves a visible record of what
would have been raised, with delivered: false and a plain note.
The description is explicit about restraint — “use sparingly; the desktop is quiet by default” — which is Article IX of the constitution enforced at the tool-definition level, not just in a system prompt.
Example
curl -s -X POST http://localhost:4000/api/studio/skills/invoke \ -H 'content-type: application/json' -b cookies.txt \ -d '{ "name": "signal.raise", "input": { "kind": "decision", "title": "Pick a headline for the landing page", "options": [{"id":"a","label":"Plan your week in the time it takes to make coffee."},{"id":"b","label":"One less tab open."}], "priority": "normal" } }'{ "ok": true, "output": { "signalId": "sig_4b1c...", "delivered": true } }