---
module: platform.kafka
title: Kafka Topics & Event Flows
tab: Overview
order: 10
audience: dev
---

> **DRAFT · internal.** Written 2026-07-01. Topic **names** below are grounded in the Java source;
> exact per-service producer/consumer **edges** are being pinned in the per-service guides — where
> this says "consumers include," treat it as non-exhaustive until the service guide confirms.

## Why Kafka here

HiveIQ services are single-responsibility and decoupled: an **executor** does a job and produces
an event; the **record-keeping / mirror** service consumes and stores it. Kafka is for **durable
history, cross-service mirrors, and eventual propagation** — not for live state or synchronous
commands (those go over direct API). See **platform.data-architecture**.

## Topic catalog (all names verified in code)

Every topic below was grep-confirmed as a literal in the producing service's source (2026-07-01).
Consumer edges marked "(see service guide)" are not yet pinned to a listener class — check the
relevant `technical.<service>` guide.

| Topic | Producer | Consumers | Payload |
|-------|----------|-----------|---------|
| `hiveops.device.events` | devices | incident, fleet, reports, recon, vault (`DeviceEventConsumer`) | device create/update/delete → `device_summary` mirrors |
| `hiveops.fleet.task.events` | fleet | devices | fleet task lifecycle → device-scoped `DeviceFleetTask` history |
| `hiveops.incidents.created` | incident | (see service guide) | incident opened |
| `hiveops.incidents.updated` | incident | (see service guide) | incident changed |
| `hiveops.incidents.resolved` | incident | (see service guide) | incident resolved |
| `hiveops.journal.transactions.recorded` | journal | (see service guide) | parsed transaction recorded |
| `hiveops.messages` | messaging | messaging (`MessageConsumer`) | user/broadcast/action messages |
| `hiveops.reports.completed` | reports | messaging (`ReportCompletedConsumer`) | report finished → notify |
| `analytics.snapshot-ready` | analytics | (see service guide) | `SnapshotReadyEvent` — fleet metrics snapshot |
| `adoons.rule-suggestion.requested` | incident | ai (Adoons) | request AI rule suggestion (async pipeline) |
| `adoons.rule-suggestion.ready` | ai (Adoons) | incident (`RuleSuggestionResultConsumer`, group `hiveops-incident-adoons`) | AI rule suggestion result |
| `hiveops.agent.online` | remote | (see service guide) | agent registered/online (`AgentConnectionEvent`, keyed by `machineId`) |
| `hiveops.agent.offline` | remote | (see service guide) | agent marked stale/offline (timer-driven sweep) |
| `hiveops.aria.threats` | aria | aria | threat/IOC events |
| `hiveops.aria.sequences` | aria | aria | attack-sequence events |

> Note the two naming conventions in play: most topics are `hiveops.*`; the AI pipeline uses
> `adoons.*`; analytics uses a bare `analytics.snapshot-ready`. All are real — do not "normalise"
> them. Per-service producer/consumer classes are pinned in each `technical.<service>` guide.

## Key flows

- **Device mirror fan-out** — devices publishes `hiveops.device.events` on every change; four+
  services keep a local `device_summary`. **No reconciler** — a missed publish silently staleness
  one or more mirrors. See **platform.data-stores**.
- **Fleet task history** — the fleet **executor** publishes task completion; **devices** consumes
  and stores the device-scoped `DeviceFleetTask` record (source of truth for a device's task
  history, served at `GET /api/atms/{id}/fleet-tasks`). The fleet executor's own task endpoints
  are empty by design once a job finishes.
- **Adoons (AI) async pipeline** — incident → ai via Kafka (journey analysis); a legacy
  synchronous path still exists. "Adoons" is the external brand for hiveops-ai — never surface
  "AI".
- **Report completion** — reports publishes `hiveops.reports.completed`; messaging notifies.

## Serialization

Messaging uses JSON with `spring.json.trusted.packages: com.hiveops.messaging.kafka` and a
default value type of `com.hiveops.messaging.kafka.MessageEvent`. Cross-service event DTOs must be
compatible on both ends — a package/class mismatch throws on deserialize.

## Do NOT
- Do not use Kafka for live/in-flight state or synchronous commands — use a direct API.
- Do not assume a mirror self-heals — there is no reconciler; fix the producer.
- Do not invent a topic name — the catalog above is grounded in code; add new ones here.
