Records who changed what, and is the mechanism statistics will read — one
event table rather than two logs that drift apart.
The table is deliberately generic (action + target + JSON metadata) so a new
action needs no migration. Writes never throw: a kick must not fail because
its log entry could not be written, since the kick already happened.
Leaving is recorded as a different action from being removed. The same route
serves both, and a log that conflates them misleads exactly when it matters.
Actor is nullable with ON DELETE SET NULL: the event outlives the account, and
a log that vanished with its actor would be worthless. Reads are gated on
MANAGE_SPACE rather than a new permission bit, which would default to nobody
until every role was re-edited. Paging uses the snowflake id, stable even for
two events in the same millisecond, and an action this build does not know
still renders a row.