7f5133a08f
Adds the ephemeral host-issued admin command event nostrnests uses for kick (and future moderation actions like mute/ban): AdminCommandEvent — kind 4312. Carries one Action (currently just KICK) in `content`, an `a`-tag pointing at the room (kind-30312 address), and a `p`-tag for the target. The verb-in-content shape lets us extend with new actions without a wire schema bump. AdminCommandEvent.kick(roomATag, target) — builder. AdminCommandEvent.action() / .targetPubkey() / .room() — accessors for the recipient side. Unknown actions return null (forward-compat with verbs not yet in the enum). EventFactory — registered so LocalCache + Filter.match can decode incoming events properly. Authority enforcement is the CLIENT'S job — the relay just stores and forwards. Recipients filter on `kinds=[4312], #a=[room], #p=[me]` and only honour commands whose signer is a participant marked HOST or MODERATOR on the active kind-30312. The next commit wires that gating + the disconnect side effect into AudioRoomViewModel. Tests: * Build a kick template and verify the action/address/target tags * Round-trip parse exposes room, target pubkey and action * Unknown verb in `content` returns null from action() * Missing tags return null from accessors (no throw)