# Event Hub

> Consume DAG/kanban/agent task events; dedupe and aggregate for Queen.

- Skill: `jajabong/event-hub` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add jajabong/event-hub`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jajabong/event-hub/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: jajabong (https://skillmd.com/u/jajabong)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/jajabong/event-hub

---


# Queen Event Hub

Unified read-only consumer for task events from three sources:
DAG dispatcher (`events.jsonl`), Kanban (`task_events` SQLite), and natural
agent tasks (`delegate_task` / `terminal background`).

## When to use
- Need a single deduped view of "did run X complete, did any task block?"
- Aggregate N task completions into one notification; surface blocked/critical immediately.
- Cross-run timeline for a run_id regardless of source.

## Schema (authoritative: ADR-003)
Unified event: `{event_id, source, run_id, task_id, ts, type, severity, payload}`.
- `event_id` = sha1(source:source_key:ts)[:16]
- `type` in {started, completed, failed, blocked, run_started, run_ended}
- `severity` in {info, warning, critical}
- Mapping table lives in `~/hermes-wiki/decisions/ADR-003-queen-event-schema.md`.
  Change the ADR first, then the code.

## Commands
```bash
HUB=~/.hermes/skills/queen-dispatch/event-hub/scripts/hub.py
# ingest a dispatcher run's events.jsonl
python3 $HUB ingest --source dispatcher --path <run_dir>/events.jsonl --run-id <id>
# ingest kanban task_events (SQLite, read-only)
python3 $HUB ingest --source kanban --path <kanban.db> --run-id <id>
# ingest agent events (JSONL: {delegation_id, ts, ok, summary})
python3 $HUB ingest --source agent --path <agent.jsonl> --run-id <id>
# notify: default|burst|quiet
python3 $HUB notify --policy default
# timeline for a run
python3 $HUB show --run-id <id>
```

## Behavior
- Dedup: event_id persisted to `<artifact_root>/_event-log.jsonl`; duplicate event_id is skipped.
- Default `--artifact-root` is `~/.hermes/artifacts/queen` (same parent as dispatcher run_dir).
  Log lands at `~/.hermes/artifacts/queen/_event-log.jsonl` — NOT nested under `queen/queen/`.
- Notify default: blocked/critical standalone alert + one aggregated summary per run.
- Notify quiet: only critical/warning, one line each.
- Never edits source artifacts. Read-only consumer.

## Source mapping (read-only consumers)
| Source      | Input path                              | Notes                                              |
|-------------|------------------------------------------|----------------------------------------------------|
| dispatcher  | `<run_dir>/events.jsonl`                | Auto-written by dispatcher at run end; no extra config needed. |
| kanban      | `<kanban.db>` (SQLite, `task_events`)   | Read via `mode=ro`; fallback/query surface only.   |
| agent       | `<agent.jsonl>` (one JSON per line)     | `{delegation_id, ts, ok, summary}`                 |

`status.json` (dispatcher) and kanban status tables are NOT ingested into the
event stream — they exist for status queries and as fallback surfaces. The
event stream is `events.jsonl` only. Pointing `ingest --path` at `status.json`
would be silently empty / wrong.

## Pitfalls
- Do not duplicate the mapping table in code beyond the minimal projection.
- `--artifact-root` defaults to `~/.hermes/artifacts/queen` (matches dispatcher run_dir parent).
- Kanban db opened read-only (`mode=ro`); never write to it.
- After a dispatcher run finishes, `<run_dir>/events.jsonl` is already on disk —
  just point `ingest --source dispatcher --path <run_dir>/events.jsonl`.
  Do NOT point ingest at `status.json`.

