internal/bans/bans.go, earlierBans with dropOne. earlierBans takes the counts in the notes of the netblock's first ban held as those of the bans dropped before it, then adds one for each ban held. dropOne drops the netblock's earliest ban that is not an admin's. When an admin's ban comes first, the ban dropped is a later one, and its count is lost.
Repro, in the ledger with MaxBans 2:
An admin bans netblock A for a minute.
A breaks a limit twice, each time after its last ban has ended: two bans for a limit.
Netblock B is banned for a limit. The ledger is full, and A's first ban for a limit is dropped.
A breaks a limit again once its second ban for a limit has ended.
The third ban's earlier_bans is {"limit": 1, "admin": 1}, though A had 2 bans for a limit and 1 by an admin before it. A test in internal/bans doing these steps fails with that result.
README, "What it does so far": a ban's notes give "how many bans the netblock had before, for a broken limit, for a clear sign of attack, by an admin and for CrowdSec's decision". earlier_bans in bans.json and in the ban's alert are wrong. Ban lengths do not depend on them.
Severity: minor.
Model: opus-5-5
`internal/bans/bans.go`, `earlierBans` with `dropOne`. `earlierBans` takes the counts in the notes of the netblock's first ban held as those of the bans dropped before it, then adds one for each ban held. `dropOne` drops the netblock's earliest ban that is not an admin's. When an admin's ban comes first, the ban dropped is a later one, and its count is lost.
Repro, in the ledger with `MaxBans` 2:
1. An admin bans netblock A for a minute.
2. A breaks a limit twice, each time after its last ban has ended: two bans for a limit.
3. Netblock B is banned for a limit. The ledger is full, and A's first ban for a limit is dropped.
4. A breaks a limit again once its second ban for a limit has ended.
The third ban's `earlier_bans` is `{"limit": 1, "admin": 1}`, though A had 2 bans for a limit and 1 by an admin before it. A test in `internal/bans` doing these steps fails with that result.
README, "What it does so far": a ban's notes give "how many bans the netblock had before, for a broken limit, for a clear sign of attack, by an admin and for CrowdSec's decision". `earlier_bans` in `bans.json` and in the ban's alert are wrong. Ban lengths do not depend on them.
Severity: minor.
Model: opus-5-5
earlierBans counts from the newest ban held rather than the oldest: every ban's notes already count the netblock's bans before it, so the newest ban's counts plus one for that ban are all the netblock's bans so far, whichever earlier ban dropOne dropped. No ban's own notes change.
The test the issue describes, in internal/bans, fails before and passes after.
Accepted, and said in one line of the PR body: when the ban dropped is itself the newest held, which happens only when all the netblock's other bans are an admin's, its count goes with it. Keeping it would need a count stored beside the bans in bans.json, for a case that rare.
Done when that test passes and an independent reviewer passes the PR.
Model: opus-5-5
Plan, one PR to `next`:
- `earlierBans` counts from the newest ban held rather than the oldest: every ban's notes already count the netblock's bans before it, so the newest ban's counts plus one for that ban are all the netblock's bans so far, whichever earlier ban `dropOne` dropped. No ban's own notes change.
- The test the issue describes, in `internal/bans`, fails before and passes after.
- Accepted, and said in one line of the PR body: when the ban dropped is itself the newest held, which happens only when all the netblock's other bans are an admin's, its count goes with it. Keeping it would need a count stored beside the bans in `bans.json`, for a case that rare.
Done when that test passes and an independent reviewer passes the PR.
Model: opus-5-5
clawbot
self-assigned this 2026-10-20 11:26:41 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
internal/bans/bans.go,earlierBanswithdropOne.earlierBanstakes the counts in the notes of the netblock's first ban held as those of the bans dropped before it, then adds one for each ban held.dropOnedrops the netblock's earliest ban that is not an admin's. When an admin's ban comes first, the ban dropped is a later one, and its count is lost.Repro, in the ledger with
MaxBans2:The third ban's
earlier_bansis{"limit": 1, "admin": 1}, though A had 2 bans for a limit and 1 by an admin before it. A test ininternal/bansdoing these steps fails with that result.README, "What it does so far": a ban's notes give "how many bans the netblock had before, for a broken limit, for a clear sign of attack, by an admin and for CrowdSec's decision".
earlier_bansinbans.jsonand in the ban's alert are wrong. Ban lengths do not depend on them.Severity: minor.
Model: opus-5-5
Plan, one PR to
next:earlierBanscounts from the newest ban held rather than the oldest: every ban's notes already count the netblock's bans before it, so the newest ban's counts plus one for that ban are all the netblock's bans so far, whichever earlier bandropOnedropped. No ban's own notes change.internal/bans, fails before and passes after.bans.json, for a case that rare.Done when that test passes and an independent reviewer passes the PR.
Model: opus-5-5