Receber por email
← Voltar para o catálogo

broker

Token-efficient Claude Code workspace with parallel agents and persistent memory. Research → Plan → Implement → Validate workflow.

18estrelas
Atualizado há 3 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add coalesce-labs/catalyst

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/broker/svg)](https://www.skillteca.com.br/skills/broker)

Skills relacionadas

Ver todas de Pesquisa e Web →

Alerta por categoria

Receba novas skills de Pesquisa e Web toda segunda

1 email curto, só com as skills novas de Pesquisa e Web. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Catalyst Event Broker — Protocol Reference (CTL-303)

The broker daemon evolved from the catalyst-filter daemon (CTL-284). It adds:

  1. Structured agent identity — agent.checkin / agent.checkout events so the broker knows

who is working on what. The broker auto-derives pr_lifecycle interests from check-in data.

  1. ticket_lifecycle interest type — deterministic routing for Linear webhook events keyed on

ticket identifiers. No Groq round-trip for state changes, comments, and PR links.

  1. Auto-correlation — when an agent checks in with a ticket, the broker auto-registers a

pr_lifecycle interest the moment a PR linking that ticket appears. Agents no longer need to call filter.register pr_lifecycle explicitly.

  1. Backward compat — all CTL-284 pr_lifecycle explicit registration still works unchanged.

Groq prose classification remains for ambiguous / multi-condition interests.

Daemon Management

# Check status (broker and filter are aliases)
catalyst-broker status   # → "running (pid N)" or "stopped"
catalyst-filter status   # deprecated alias — delegates to catalyst-broker

# Start / stop / restart
catalyst-broker start
catalyst-broker stop
catalyst-broker restart

# View logs
catalyst-broker logs

Interest Types Summary

| Interest type | Routing | Use case | |---|---|---| | pr_lifecycle | Deterministic | Watch CI, reviews, merge, deployment for a known PR number | | ticket_lifecycle | Deterministic | Watch Linear state changes, comments, PR links for a ticket | | comms_lifecycle | Deterministic | Watch comms-channel messages (worker → orchestrator attention/done, orchestrator → worker directives) | | phase_lifecycle | Deterministic | Watch phase.<name>.complete.<ticket> / phase.<name>.failed.<ticket> / phase.<name>.turn-cap-exhausted.<ticket> events — orchestrator hand-off between phase agents | | (prose prompt) | Groq LLM (env-gated off; CTL-357) | Anything ambiguous, cross-cutting, or complex — set CATALYST_BROKER_PROSE_ENABLED=1 to re-enable |

1. Auto-Correlation (The Common Case — No Registration Needed)

When an agent's own ticket/PR is the concern, registration is automatic:

# catalyst-session.sh start emits agent.checkin automatically:
CATALYST_SESSION_ID=$(catalyst-session.sh start --skill oneshot --ticket CTL-275)
# ↑ The broker records: agent CTL-275 with no claimed_pr yet.

# When you later create the PR, update claimed_pr via agent.checkin:
cat >> ~/catalyst/events/$(date -u +%Y-%m).jsonl <<EOF
{"ts":"$(date -u +%Y-%m-%dT%H:%M:%SZ)","event":"agent.checkin","detail":{"session_id":"$CATALYST_SESSION_ID","ticket":"CTL-275","claimed_pr":$PR_NUMBER,"orchestrator":"${CATALYST_ORCHESTRATOR_ID:-}"}}
EOF
# ↑ The broker sees claimed_pr → auto-registers pr_lifecycle for filter.wake.$CATALYST_SESSION_ID

The oneshot skill now uses this pattern instead of calling filter.register directly. The explicit filter_register_worker function is kept for backward compat but is no longer the recommended path for new work.

2. agent.checkin Event

Emitted by catalyst-session.sh start and optionally after PR creation. Shape:

{
  "ts": "2026-05-08T07:00:00Z",
  "event": "agent.checkin",
  "detail": {
    "session_id": "sess_20260508_abcd",
    "agent_name": "ctl-275-worker",
    "ticket": "CTL-275",
    "orchestrator": "orch-2026-05-08",
    "claimed_pr": 501,
    "cwd": "/path/to/worktree"
  }
}

Fields:

  • session_id — required. Primary key in the broker's agents table.
  • agent_name — human label (defaults to session_id if missing).
  • ticket — Linear ticket identifier (e.g. "CTL-275"). Enables ticket_lifecycle auto-correlation.
  • orchestrator — parent orchestrator ID; enables stale-session watchdog routing.
  • claimed_pr — if set, broker immediately auto-registers pr_lifecycle for this agent.
  • cwd — working directory; included for diagnostics.

3. agent.checkout Event

Emitted by catalyst-session.sh end. Shape:

{
  "ts": "2026-05-08T09:00:00Z",
  "event": "agent.checkout",
  "detail": {
    "session_id": "sess_20260508_abcd",
    "status": "done"
  }
}

On checkout, the broker:

  • Marks the agent as done in the agents SQLite table.
  • Removes any auto-correlated pr_lifecycle interest (explicit registrations are preserved).

3a. worker.waiting / worker.resumed Events (CTL-403)

Emitted automatically by catalyst-events wait-for when $CATALYST_SESSION_ID is set. These events make wait loops visible to the broker so the watchdog can distinguish a legitimately waiting session from a silently dead one.

worker.waiting shape

{
  "ts": "2026-05-14T16:30:00Z",
  "event": "worker.waiting",
  "detail": {
    "session_id": "sess_20260514_abcd",
    "orchestrator": "orch-foo",
    "ticket": "CTL-275",
    "wait_for": ".attributes.\"event.name\" == \"github.pr.merged\"",
    "timeout_ms": 7200000,
    "since": "2026-05-14T16:30:00Z",
    "reason": "catalyst-events wait-for"
  }
}

worker.resumed shape

{
  "ts": "2026-05-14T18:00:00Z",
  "event": "worker.resumed",
  "detail": {
    "session_id": "sess_20260514_abcd",
    "orchestrator": "orch-foo",
    "ticket": "CTL-275",
    "outcome": "matched"
  }
}

outcome is "matched" when the wait returned a result, "timed_out" when the deadline elapsed.

Broker behavior

On worker.waiting:

  • Stores the session in the in-memory waitingSessions Map and the waiting_sessions SQLite table.
  • Resets the heartbeat timer so the session does not appear stale during the wait.
  • During watchdog ticks, any session in waitingSessions whose timeoutAt > now is skipped — it

is "legitimately waiting" and should not trigger a stale-heartbeat wake.

  • The broker.state.json file includes an waitingSessions array with all currently active waits;

the HUD dashboard's worker list reads this to overlay wait:Xm in the STATUS column.

On worker.resumed:

  • Removes the session from waitingSessions and the SQLite table.
  • Normal heartbeat-staleness tracking resumes.

Broker state file

~/catalyst/broker.state.json gains a waitingSessions array:

{
  "waitingSessions": [
    {
      "sessionId": "sess_20260514_abcd",
      "ticket": "CTL-275",
      "orchestrator": "orch-foo",
      "waitFor": ".attributes.\"event.name\" == \"github.pr.merged\"",
      "timeoutAt": "2026-05-14T18:30:00Z",
      "reason": "catalyst-events wait-for"
    }
  ]
}

Empty array [] when no sessions are currently waiting.

3b. orchestrator.status Events (CTL-405)

Emitted by the orchestrate skill at each wave transition via orchestrate-status.sh emit. These events make the orchestrator's current phase visible to the broker, the HUD, and operators, and serve as a liveness heartbeat so the watchdog does not fire stale-session wakes for an orchestrator that is actively monitoring between waves.

Event shape

{
  "ts": "2026-05-15T00:00:00Z",
  "event": "orchestrator-status",
  "orchestrator": "orch-foo",
  "detail": {
    "orchestrator": "orch-foo",
    "phase": "monitoring",
    "wave": 2,
    "active_workers": 3,
    "total_workers": 5,
    "summary": "wave 2 monitoring (3/5 active)",
    "session_id": "sess_20260515_abcd"
  }
}

phase values:

| Value | Meaning | |---|---| | dispatching | Launching workers for a wave | | monitoring | Event loop watching workers for a wave | | reviewing | Post-merge verification (Phase 5) | | paused | Waiting for human gate |

Broker behavior

On orchestrator.status:

  • Stores the entry in orchestratorStatusMap[orchId] (replaces any prior entry for that orch).
  • If detail.session_id is present, resets lastHeartbeat[sessionId] to now — so the watchdog

treats the status event as a heartbeat and skips stale-session wakes while the orchestrator is in a monitoring loop.

  • Calls persistBrokerState() to flush the update to broker.state.json.
Compartilhar X LinkedIn