Skip to content

feat(id): shared abuse evaluator core — buckets, structured refusal, counter registry (#3881) - #3891

Merged
dezren39 merged 2 commits into
mainfrom
queue/5845-3881-abuse-core
Nov 1, 2026
Merged

dezren39 merged 2 commits into
mainfrom
queue/5845-3881-abuse-core

Conversation

@dezren39

@dezren39 dezren39 commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

P0-A core of #2244 (design #2033 in PR #3834; defaults from #2032). New module only — nothing is wired into frames/HTTP/world chat (that is Packet B), and no existing path changes behavior.

What

New pkgs/id/src/abuse.rs (std-only, time injected as now_ms for determinism):

Tests

Unit tests cover: defaults vs the design, frame bucket drain/refill, byte bucket drain/refill, endpoint allowance shared across connections, per-peer connection cap (incl. close freeing a slot and a different peer's separate cap), pre-auth bucket separation, refusal retry bounds (floor, cap, permanent = none), and counter increments + snapshot.

Verified standalone on the laptop with rustc --edition 2024 --test (the module is std-only): 8/8 pass. Full cargo test + clippy for the crate run in CI on this PR — the laptop's cold target dir for a fresh worktree could not finish a cargo build inside the shift budget, so the task is parked for the CI result.

Queue: task 5845 (repo-health-code-pilot), lane A.

Closes #3881


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

…3881)

P0-A core of #2244 (design #2033, defaults #2032). New std-only
module pkgs/id/src/abuse.rs; nothing is wired into existing paths
and no existing limiter changes behaviour (Packet B integrates).

- AbusePolicy defaults: authorized endpoint 60 frames/s burst 180
  and 512 KiB/s burst 4 MiB; pre-authorization 10 frames/s burst 30;
  max 4 concurrent connections per peer.
- AbuseEvaluator: per-endpoint frame/byte token buckets (integer
  milli-token arithmetic, injected now_ms) shared across all of an
   endpoint's connections — more streams do not multiply allowance.
- Refusal: the one structured refusal contract — reason
  (rate_limited | budget_exhausted | blocked_by_operator |
  unauthorized) + retry_after_ms clamped to 1s..60s for temporary
  refusals, absent for permanent operator blocks.
- CounterRegistry: per-(local node, remote endpoint) frame/byte
  counters with a deterministic snapshot API.

Unit tests (8/8 via standalone rustc --test; cargo/CI verification
on the PR): defaults, frame/byte drain+refill, shared allowance
across connections, per-peer connection cap, pre-auth bucket
separation, retry bounds, counter increments + snapshot.
@dezren39
dezren39 requested a review from a team as a code owner November 1, 2026 17:45
@coderabbitai

coderabbitai Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 35 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: bce0d1d5-e130-488c-bc73-4d101afacc08
Commits

Reviewing files that changed from the base of the PR and between f54b043 and 162b374.

Files selected for processing: 2
  • pkgs/id/src/abuse.rs
  • pkgs/id/src/lib.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-01T18:27:15.581866Z 162b374 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4d20bddd90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkgs/id/src/abuse.rs
Comment on lines +321 to +323
self.endpoints
.entry(endpoint)
.or_insert_with(|| EndpointState::new(&policy, now_ms))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bound retained state for inactive endpoints

For a long-lived evaluator handling successive distinct endpoint keys, every open_connection or traffic check permanently inserts an EndpointState. close_connection only removes the connection ID, and neither the endpoint map nor the counter registry has an eviction or pruning path. Consequently, even peers that send one pre-authorization frame and disconnect retain allocations indefinitely; the per-peer connection cap does not bound this growth. A standalone test with 10,000 such peers confirmed that all entries remain after advancing time by a day. Add bounded retention or idle-expiry handling for endpoint state and associated counters, while preserving depleted buckets long enough to prevent reconnects from resetting allowances.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 162b374. Retained state is now bounded by pruning on both stores:

  • AbuseEvaluator::prune_idle_endpoints(now_ms) evicts endpoint states with no open connections whose four buckets have all fully refilled. A fully-refilled, connection-less state is indistinguishable from a never-seen endpoint, so eviction changes no admission decision (covered by a test: an evicted endpoint gets its full fresh burst; endpoints with open connections or partially drained buckets are kept).
  • The counter registry now stamps each row with its last-recorded-traffic time, and CounterRegistry::prune(now_ms, retention_ms) (exposed as AbuseEvaluator::prune_counters) drops rows idle past the caller-chosen retention. The module docs direct callers to run both periodically and to snapshot before pruning if lifetime totals are needed.

New tests: prune_evicts_only_idle_fully_refilled_endpoints, prune_counters_drops_rows_idle_past_retention.

@dezren39

dezren39 commented Nov 1, 2026

Copy link
Copy Markdown
Member Author

@codex review

Head 162b374 fixes the P2 retained-state finding (see the reply on that thread) and adds pruning tests for both the endpoint map and the counter registry.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 162b374098

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

id(comms): P0-A core — shared abuse evaluator, token buckets, structured refusal, counter registry (phase of #2244)

1 participant