MediaWikiMemberBlocker logs the rendered status of a failed block or unblock ($status->__toString(), at the two error calls). Core builds those statuses with the target's name: ipb_already_blocked in BlockUser::placeBlockInternal() and ipb_cant_unblock in UnblockUser::unblockUnsafe(). A member's username is their address, so deactivating a member who already carries a block that does not lock them out (a partial or expiring one — the guard before the log line returns early only for a block that does), or reactivating one whose block is already gone, writes the address in clear onto the MemberAccess log channel, where everything else keeps it hashed.
#30 closes the same hole in both mailers by logging the status's message keys instead of its rendering; the blocker should do the same. To reproduce in an integration test: place a partial block on a member by hand, deactivate them, and assert the log does not carry the address.
AI-authored — Claude Code, Fable 5 (max); found by a review subagent (Opus 5) while reviewing PR 30 and filed by the orchestrating session for @JeroenDeDauw; not yet human-reviewed; verified by reading the blocker and core's BlockUser/UnblockUser status construction, not reproduced live.
MediaWikiMemberBlockerlogs the rendered status of a failed block or unblock ($status->__toString(), at the twoerrorcalls). Core builds those statuses with the target's name:ipb_already_blockedinBlockUser::placeBlockInternal()andipb_cant_unblockinUnblockUser::unblockUnsafe(). A member's username is their address, so deactivating a member who already carries a block that does not lock them out (a partial or expiring one — the guard before the log line returns early only for a block that does), or reactivating one whose block is already gone, writes the address in clear onto theMemberAccesslog channel, where everything else keeps it hashed.#30 closes the same hole in both mailers by logging the status's message keys instead of its rendering; the blocker should do the same. To reproduce in an integration test: place a partial block on a member by hand, deactivate them, and assert the log does not carry the address.