fix(convey): escape the notification badge
_createCard interpolated n.badge raw into innerHTML while every neighbouring field, including n.app, n.title, and n.message, was escaped, so a caller could inject markup through the badge. The value is caller-controlled end to end: sol notify --badge is free-form and websocket.js forwards raw callosum payloads into show().
_updateCard already assigned the badge with textContent, so initial render and update render disagreed. This aligns them on the safe behaviour.
Found while auditing the icon-contract change. It is the same class of defect that change closes for icon, in the same renderer, but a different field, hence a separate commit.
The test helper assertNoPayload was tightened to match event-handler markup only inside a real tag, because correctly escaped output legitimately contains the literal text onerror.