Files
wz-phone/docs/PRD/reports/T3.5-report.md
2026-05-12 06:45:56 +04:00

96 lines
5.4 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.
# T3.5 — Tier E (per-fingerprint token bucket)
**Status:** Pending Review
**Agent:** Kimi Code CLI
**Started:** 2026-05-11T16:29Z
**Completed:** 2026-05-11T16:29Z
**Commit:** (see git log)
**PRD:** ../PRD-relay-conformance.md
## What I changed
- `crates/wzp-relay/src/conformance.rs:1` — Updated module doc: `Tier A/B/C/D``Tier A/B/C/D/E`.
- `crates/wzp-relay/src/conformance.rs:26-27` — Added `Violation::RateCapExceeded` variant for Tier E.
- `crates/wzp-relay/src/conformance.rs:30-76` — Added `TokenBucket` struct with:
- `capacity: u64`, `tokens: f64`, `refill_per_sec: u64`, `last_refill: Instant`
- `new(capacity, refill_per_sec)` constructor
- `for_audio_session()` factory: 256 kbps cap, 30 s @ 2× burst = 1_920_000 byte capacity
- `try_consume(bytes, now)` — refills based on elapsed time, then deducts cost
- `crates/wzp-relay/src/conformance.rs:84-85` — Added `token_bucket: Option<TokenBucket>` to `ConformanceMeter`.
- `crates/wzp-relay/src/conformance.rs:97-102` — Added `ConformanceMeter::with_token_bucket(bucket)` constructor.
- `crates/wzp-relay/src/conformance.rs:130-137` — Wired Tier E check into `observe()`: after Tier D, if a token bucket is present, attempt to consume the full wire size; return `Err(Violation::RateCapExceeded)` on exhaustion.
- `crates/wzp-relay/src/metrics.rs:409` — Added `Violation::RateCapExceeded => "E"` tier label.
- `crates/wzp-relay/src/room.rs:762-785` — Updated `run_participant()` signature to accept `is_authenticated: bool` and forward it to both plain and trunked loops.
- `crates/wzp-relay/src/room.rs:807-814` — Plain loop: creates `ConformanceMeter::with_token_bucket(TokenBucket::for_audio_session())` for all participants (authed and anon share the same per-session audio cap).
- `crates/wzp-relay/src/room.rs:1042-1044` — Trunked loop: same token-bucket meter setup.
- `crates/wzp-relay/src/main.rs:2028` — Call site passes `authenticated_fp.is_some()` into `run_participant()`.
- `crates/wzp-relay/src/conformance.rs:470-528` — Added 5 Tier E tests:
- `token_bucket_small_burst_ok` — 50 KB inside 100 KB cap succeeds
- `token_bucket_large_burst_fails` — 1 MB exceeds 100 KB cap
- `token_bucket_refills_over_time` — drain, wait 1 s, consume refilled amount
- `token_bucket_sustained_rate_balanced` — 32 KB/s for 5 s stays balanced
- `conformance_tier_e_integration` — meter with 1_000-byte bucket, two 500-byte packets OK, third packet triggers `RateCapExceeded`
## Why these choices
- Used `f64` for internal token tracking so fractional refills across sub-second intervals are accurate. The public API still speaks in whole bytes.
- Both authenticated and anonymous participants get the same per-session audio cap (256 kbps / 1.92 MB burst). The spec's authed/anon split applies to the *monthly* quota (50 GB vs 1 GB), which is a separate accounting concern not covered by the per-session token bucket. Passing `is_authenticated` through the call chain makes it easy to add monthly-quota wiring later.
- Tier E runs after Tiers AD so the cheaper checks still fire first on obvious abuse, while the token bucket catches the "low packet count, high burst size" tunneling vector.
## Deviations from the task spec
- The spec's `TokenBucket` sketch used `AtomicU64` for `tokens` and `last_refill`. Since each `ConformanceMeter` (and its bucket) is owned by a single tokio task (the per-participant forwarding loop), atomics are unnecessary. I used plain `f64` / `Instant` fields instead.
## Verification output
```bash
$ cargo test -p wzp-relay token_bucket
running 4 tests
test conformance::tests::token_bucket_large_burst_fails ... ok
test conformance::tests::token_bucket_refills_over_time ... ok
test conformance::tests::token_bucket_small_burst_ok ... ok
test conformance::tests::token_bucket_sustained_rate_balanced ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out; finished in 0.00s
```
```bash
$ cargo test -p wzp-relay --lib
running 93 tests
...
test result: ok. 93 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
```
```bash
$ cargo test --workspace --exclude wzp-android --no-fail-fast
... (all crates pass)
Total: 617 passed; 0 failed
```
## Test summary
- Tests added: 5
- `token_bucket_small_burst_ok`
- `token_bucket_large_burst_fails`
- `token_bucket_refills_over_time`
- `token_bucket_sustained_rate_balanced`
- `conformance_tier_e_integration`
- Tests modified: 0
- Workspace test count before: 612 / after: 617
- `cargo clippy -p wzp-relay --all-targets -- -D warnings`: clean in `wzp-relay`; failures are pre-existing debt in `wzp-codec` (9 errors) and `warzone-protocol` (3 errors)
- `cargo fmt --all -- --check`: pass
## Risks / follow-ups
- Monthly byte quota (50 GB authed / 1 GB anon) is not yet implemented. The `is_authenticated` flag is now threaded through the forwarding loop so a future task can add a per-fingerprint monthly counter alongside the per-session token bucket.
- Video sessions will need `TokenBucket::for_video_session()` (5 Mbps cap) once video forwarding loops land in Wave 4.
- Tier E is observe-only, consistent with Tiers AD. Hard enforcement (packet drop or session close) can be wired later if the reviewer wants.
## Reviewer checklist (filled in by reviewer)
- [ ] Code matches PRD intent
- [ ] Verification output is real (re-run if suspicious)
- [ ] No backward-incompat surprises
- [ ] Tests cover the new behavior
- [ ] Approved