feat(leveva): per-user KNOCK throttle (charybdis knock_delay) — P11 slice 209
Closes the last documented gap in the KNOCK throttle family (slices 198/199/200).
Slice 200's per-channel cooldown stops a chorus spamming one channel's operators;
it did nothing about one user spraying KNOCKs across many *fresh* channels. This
adds charybdis's per-user `knock_delay` (default 300s).
- Reuse `KnockThrottle` as a generic per-key cooldown; second `ServerContext`
field `knock_user_throttle` keyed by the knocker's UID (folds injectively).
- New `cooling`/`arm` peek/arm split: the command peeks both throttles and arms
neither unless the knock is delivered (charybdis updates its clocks on success
only). `admit` retained; a unit test pins `admit == cooling-then-arm`.
- `KNOCK_DELAY_USER_SECS = 300` const beside `KNOCK_DELAY_CHANNEL_SECS`.
- Command gate answers `712 ERR_TOOMANYKNOCK` if either window is cooling,
notifying nobody; per-user peeked first.
Tests: store units (cooling-does-not-arm, window-not-permanent, admit==split);
command units (second knock to a fresh channel is 712 with no 710; per-user is
per-user not global; per-channel test rewritten with distinct knockers); new
`knock_user_throttle_proptest.rs` (clock-tracking + arbitrary-key totality).
New `testutil::run_as` dispatches as a named client. `knock_user_throttle`
added to the 60 hand-rolled ServerContext test literals (slice-206 churn).
Gate: cargo test -p leveva green (1949 lib + all knock proptests/golden/s2s);
clippy -p leveva --tests clean; build --workspace 0 warnings.