kanta.ctx already existed as a user-writable namespace for migrations;
since LogEvent carries the kanta instance, ev.kanta.ctx is also the way
for applications to pass per-connection metadata to their logemit
callbacks, including for creation/bootstrap events. No API change needed.
Every emitted event now carries the originating Kanta instance so logemit
callbacks can reach application state attached to it. The header property
gains a setter, formalizing restyle-then-delegate: assign ev.header and
return truthy to keep the default diff routing with a custom header.
All event kinds now share one shape: a one-line header plus an optional
diff body for changes. LogEvent.header is a lazy property covering every
kind (change, aborted, created, migrated), and default_emit reduces to
logging the header plus routing diff_lines to the .diff child logger.
Custom emitters can tap the same blocks - header, diff_lines, Line,
format_diff - instead of reimplementing formatting per message type.
The aborted event now carries the transaction user, resolved through the
logfmt chain against the pre-transaction state so it matches change
headers. Default rendering: '<action> by <user> transaction aborted: <e>'.
User resolution factored into _build_logfmt/_resolve_user helpers shared
by the change and abort paths.
The rollback warning is now a LogEvent (kind='aborted', WARNING level,
carrying the exception) dispatched via emit_event so logemit callbacks can
handle or restyle it. Default rendering: action in transaction color
without quotes, followed by ' transaction aborted: {exc}' in default
color.
emit_event now swallows and reports any failure, including crashes in the
built-in default_emit formatting itself; log_change routes through it.
logfmt chain callbacks that raise are logged and treated as fall-through,
and logmigr callbacks get on_error reporting like fatal_error handlers,
so a broken logging callback can no longer abort a transaction or open.
Demo: raw user ids in v0 logs, logfmt-resolved names in v1 logs.
All change-related output (transactions, bootstrap, migrations) is now
described by a mutable LogEvent carrying full state plus the preferred
logger and level, and dispatched through emit_event. @kanta.logemit
callbacks receive the event and decide what is logged where: falsy return
marks it handled, truthy passes it (possibly modified) down the chain,
with default_emit - Kanta's own formatting, now just another emitter - as
the fallback. Pretty header and diff lines are lazy event properties.
New kanta.tty module: Line builder (call to append content, .colorname
arms a palette color for the next call with automatic folded reset,
width/align padding), a mutable Colors palette storing bare SGR params
(0 clears, sequential last-wins stacking), and strip_ansi/displaywidth/pad
helpers that count wide chars and emoji correctly.