Jitter range fixed at 100ms + rand[0,900)ms per plan spec (max ~1000ms)
First For() call wins; later rate/burst arguments are ignored to preserve token state
Added TestJitterDisabled as extra guard (Rule 2
correctness)
completed
duration
tasks
2026-04-05
~5 min
1/1
RECON-INFRA-05
Phase 09 Plan 02: LimiterRegistry Summary
Per-source rate limiting foundation using golang.org/x/time/rate with optional stealth jitter, keyed by source name via a mutex-guarded registry.
What Was Built
pkg/recon/limiter.go — LimiterRegistry type with:
NewLimiterRegistry() constructor (empty map)
For(name, r, burst) *rate.Limiter — idempotent lookup; creates on first call, returns the same pointer on subsequent calls
Wait(ctx, name, r, burst, stealth) error — acquires limiter (via For), blocks on limiter.Wait(ctx), then sleeps a random 100ms–1000ms jitter if stealth==true, respecting ctx cancellation during the sleep
pkg/recon/limiter_test.go — 5 tests:
TestLimiterPerSourceIsolation — different names → distinct *rate.Limiter
RECON-INFRA-05 — "each source owns its own limiter — no centralization". Verified via TestLimiterPerSourceIsolation.
Partial foundation for RECON-INFRA-06 (stealth jitter) — fully wired into the engine in plan 09-03.
Verification
go test -run 'TestLimiter|TestWait|TestJitter' -count=1 -v \
./pkg/recon/limiter.go ./pkg/recon/limiter_test.go ./pkg/recon/source.go
Result: 5/5 PASS.
Tests were executed via explicit file list because sibling plans in the same wave (09-03, 09-04) have landed test files (engine_test.go, robots_test.go) whose implementation files are still in flight. This is expected parallel-wave behavior and does not affect the correctness of this plan's code. Once all wave-1 plans merge, go test ./pkg/recon/... will run the full suite.
go vet ./pkg/recon/limiter.go ./pkg/recon/source.go is clean.
Issue: Plan tested jitter upper/lower bounds with stealth on, but did not assert the negative case — a regression that applied jitter even when stealth=false would go undetected.
Fix: Added TestJitterDisabled asserting elapsed < 50ms when stealth=false.