Files
keyhunter/.planning/phases/09-osint-infrastructure/09-02-SUMMARY.md
2026-04-06 00:42:15 +03:00

98 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
phase: 09-osint-infrastructure
plan: 02
subsystem: recon
tags: [recon, rate-limiting, stealth, infrastructure]
requires:
- golang.org/x/time/rate
provides:
- pkg/recon.LimiterRegistry
- pkg/recon.NewLimiterRegistry
- LimiterRegistry.For
- LimiterRegistry.Wait
affects: []
tech-stack:
added: []
patterns:
- per-source rate.Limiter map guarded by sync.Mutex
- idempotent registry lookup (first registration wins)
- optional stealth jitter (100ms-1s) gated by flag
key-files:
created:
- pkg/recon/limiter.go
- pkg/recon/limiter_test.go
modified: []
decisions:
- 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)
metrics:
completed: 2026-04-05
duration: ~5 min
tasks: 1/1
requirements: [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 100ms1000ms jitter if `stealth==true`, respecting ctx cancellation during the sleep
- **`pkg/recon/limiter_test.go`** — 5 tests:
- `TestLimiterPerSourceIsolation` — different names → distinct `*rate.Limiter`
- `TestLimiterIdempotent` — same name → same pointer
- `TestWaitRespectsContext` — pre-cancelled ctx returns error
- `TestJitterRange` — stealth=true elapsed ∈ [90ms, 1200ms]
- `TestJitterDisabled` — stealth=false elapsed < 50ms
## Satisfies
- **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.
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 2 — Missing coverage] Added `TestJitterDisabled`**
- **Found during:** Task 1
- **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.
- **Files modified:** `pkg/recon/limiter_test.go`
- **Commit:** 590fc33
No architectural deviations. No blockers.
## Commits
- `590fc33` feat(09-02): add LimiterRegistry with per-source rate limiters and jitter
## Self-Check: PASSED
- FOUND: pkg/recon/limiter.go
- FOUND: pkg/recon/limiter_test.go
- FOUND commit: 590fc33
- All plan tasks (1/1) complete
- All plan success criteria met:
- LimiterRegistry exported with `For` and `Wait`
- Each source receives its own `*rate.Limiter`
- Stealth jitter range 100ms1s enforced