feat: add distributed rate limiting with sliding window algorithm
- RateLimiter trait with check_rate(key, config) -> RateResult
- InMemoryRateLimiter: DashMap-based sliding window log per key
- RateLimitConfig: configurable max_requests and window duration
- RateResult: allowed/remaining/retry_after_secs for Retry-After headers
- Lazy GC of expired entries (every 60s)
- Thread-safe concurrent access via DashMap
- 5 unit tests: limit enforcement, independent keys, remaining counter, concurrency