{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://github.com/vu1n/puck/schema/event.schema.json", "title": "PuckWireEvent", "description": "The locked wire contract for POST /api/events. Anything that watches the world (Claude Code hooks, build wrappers, mail/Discord watchers) speaks this shape to whatever daemon is listening — Python today, Rust later. Policy (scoring, interruption taste) lives in the TS engine, never here.", "type": "object", "required": ["source", "type", "title"], "additionalProperties": false, "properties": { "id": { "type": "string", "description": "Producer-assigned id; server generates one if absent." }, "ts": { "type": "string", "format": "date-time", "description": "Event time; server stamps receipt time if absent." }, "source": { "enum": ["claude", "build", "mail", "discord", "calendar", "browser"], "description": "Lowercase on the wire; the engine maps to its SourceId." }, "type": { "type": "string", "minLength": 1, "description": "Source-specific kind, e.g. task_completed, tests_failed, mention." }, "title": { "type": "string", "minLength": 1, "description": "One-line human summary of what happened." }, "summary": { "type": "string", "description": "Optional longer detail. Keep it abstract — no raw message bodies (anti-creep rule)." }, "payload": { "type": "object", "description": "Opaque source-native data (e.g. the raw Claude hook JSON). Stored, never interpreted by the server." } } }