Skip to content

Event Kinds — Hinata Activity Event Namespace

The /events endpoint (api.michael-engineer.dev/events) ingests structured activity events from across Hinata. Every event has three required string fields plus an optional JSON payload:

FieldConstraintExample
source≤64 chars · script/script-component name in kebab-casepoll-monzo · hinata-bot-poller · refresh-tasks
kind≤64 chars · domain.action format (lowercase, snake_case action)monzo.written · bot.reply · task.closed
summary≤240 chars · one-line human-readable descriptionappended 12 transactions across 2 accounts
payloadoptional JSON object · structured machine-readable detail{"new_txs": 12, "accounts": 2}

This file is the canon for the kind namespace. Every new kind added must appear here. If a kind doesn't fit the existing domains, propose a new domain and add it below before shipping the producer.

Naming rules

  1. domain.action — single dot, exactly. No nested domains. No double-dots.
  2. Domain = lowercase, no underscores or hyphens. Single word preferred.
  3. Action = lowercase, snake_case if multi-word. Verb-shaped (past tense for completed events, present for in-flight).
  4. No personally identifiable information in kind — that goes in summary or payload. Kinds are for filtering and aggregation, not data carriers.
  5. Domains map roughly to Commanders or major subsystems — but not 1:1 (some domains are cross-cutting like vault.* and task.*).

Canonical domains

Data-producer domains (LaunchAgents that pull external data)

DomainOwnerProducer scriptsCommon kinds
monzoBulmapoll-monzo.pymonzo.written · monzo.refresh_failed · monzo.token_evicted
truelayerBulmapoll-truelayer.py (TODO)truelayer.written · truelayer.consent_expiring
trading212Bulmapoll-trading212.py (TODO)trading212.written · trading212.position_change
healthAllMightparse-apple-health.py · health-normaliser.pyhealth.imported · health.normalised
fitAllMight / Zorofit-sync.pyfit.synced · fit.weight_logged
footballBrookfootball-pl.py · football-ucl.pyfootball.fixtures_pulled · football.profile_added
pilatesZoro / AllMightpilates-researcher.pypilates.class_status · pilates.attended
mailIroh → Dashboardmail-poller.py · archive-mail-bodies.pymail.received_priority · mail.archived
audioSquidwardtranscribe-audio.pyaudio.transcribed · audio.transcription_failed
screenHinataextract-screen-time.pyscreen.time_extracted

Behaviour domains (Michael's actions logged into the system)

DomainOwnerProducerCommon kinds
smokingAllMightupdate-zoot-state.py · smoking-nudge.pysmoking.zoot_logged · smoking.streak_reset · smoking.nudge_sent · smoking.streak_pb
fitnessZoroupdate-bodybuilding.pyfitness.session_logged · fitness.pr_set
musicSquidwardchord chart save · practice timermusic.chart_saved · music.practice_logged
chartSquidwardStudio chord-chart UIchart.saved · chart.exported_html · chart.exported_pdf
quizShikamaruShogi MCQ session eventsquiz.round_completed · quiz.score_updated
nudgecalendar-nudge / smoking-nudgeTelegram outboundnudge.sent · nudge.suppressed (quiet hours)

System domains (cross-cutting infrastructure)

DomainOwnerProducerCommon kinds
taskjimmy-neutronrefresh-tasks.pytask.opened · task.closed · task.auto_closed_by_scan · task.priority_changed
vaultjimmy-neutrongit hooks (nightly-vault-diff.py + vault.diff_stats retired 2026-06-11 — Michael ruling: handover and transcripts are exhaustive)vault.commit
scoutorochimaruscout-evening.py · scout-midday.py · scout-weekly.py · scout-monthly.pyscout.daily · scout.midday · scout.weekly · scout.monthly
briefingjimmy-neutronmorning-briefing.pybriefing.sent
inboxcanarynormalise-inbox.py · inbox-clear.pyinbox.routed · inbox.assimilated · inbox.discarded · inbox.held · inbox.backlogged
telegramhinata-bot-pollertelegram-poller.pytelegram.received · telegram.parse_failed
bothinata-bot-pollerhinata-bot-poller.pybot.reply · bot.error · bot.token_refresh
calendarIrohcalendar-nudge.py · eod-calendar-sync.py · hinata-cal.pycalendar.event_created · calendar.event_deleted · calendar.day_synced
studiotrunksStudio UI eventsstudio.tab_opened · studio.search_query

Reserved / never-emit

DomainWhy
errorUse [domain].error_* instead — errors stay in their producer's domain so they're queryable alongside successes
privateIf an event would leak credentials or stigma-bearing info, restructure so the payload carries the data redacted, not the kind
test / debugDon't emit test events into the prod table; use a --dry-run flag in the producer

Privacy + payload discipline

Per credential-guardrails:

  • Never include raw credentials, tokens, OAuth secrets in payload
  • Financial amounts: pence-integers OK; raw transaction descriptions OK; full card numbers / sort codes never
  • Smoking-related payload: number-of-zoots OK; specific brand/dispensary names NOT in summary (PII-style stigma)
  • Mail payload: sender + subject OK; full body NEVER
  • Calendar payload: title + tag + time OK; meeting attendees can be PII — use attendee_count not names

If unsure, omit the field. The kind + summary alone is always queryable.

Adding a new kind — checklist

Before shipping a producer with a new event kind:

  1. Domain exists in this file? If yes, just pick an action name. If no, propose the new domain here first (one PR).
  2. Action name is verb-shaped? written, synced, received, closed — yes. transactions, data, stuff — no.
  3. No PII in kind itself? The kind is searchable; don't burn sensitive info into the literal namespace.
  4. Has a summary that reads correctly in the Activity Log? Imagine seeing the kind+summary 30 days later — would you know what happened?
  5. Payload is structured (object), not a string? Strings can't be queried; nested objects let consumers extract specific keys.
  6. Producer wraps emit_event in try/except? Endpoint downtime must never break the producer.

Migration note — existing events

These kinds were emitted before this glossary existed. They're already in the events table; new producers should follow the glossary going forward and any in-flight migrations align here.

  • monzo.written ✓ (matches)
  • health.imported ✓ (matches)
  • nudge.sent ✓ (matches)

See also

  • event-driven-architecture (TODO doctrine)
  • credential-guardrails (extension applies to event payloads)
  • 2026-05-api-connection-opportunities — the parent project this glossary unblocks