Files
zooqueenandHanzo Dev 24b428491f chat: give bans a real store, and restore the fix the fork dropped
Two independent defects met in one feature, and either one alone made
`BAN_VIOLATIONS=true` a trap.

The store. `keyvMongo` backed `ViolationTypes.BAN` and
`CacheKeys.ENCODED_DOMAINS` and threw `Mongoose connection not ready`
the moment either was touched — `MONGO_URI` is unset and every
collection is served from SQLite. Both namespaces hold state that must
outlive the process: forgetting a ban un-bans a banned user, forgetting
an encoded domain orphans every action tool that used it, so
`standardCache`'s process memory is not a substitute. `durableCache`
adds SQLite as the fallback store instead — a two-column `keyv` table on
the one `sharedDatabase()` connection the document store already holds,
so there is no second writer racing for the WAL lock. Redis still wins
when it is configured; nothing about that path changes.

The middleware. Upstream #12324 fixed `checkBan`'s `!!(ipBan||userBan)`
coercion and the four defects it hid. The fork took that commit's tests
and lost its implementation, so `checkBan.js` still read
`Number(true.expiresAt)` → `NaN`: expired bans were never cleaned up,
the memo was written with no expiry at all, and an IP-keyed entry
blocked whoever next inherited that address — permanently. The test
suite did not merely fail, it crashed the runner on an unhandled
rejection from the un-awaited `banCache.set`. Restored, on the hanzo
imports.

Also: `redisClients.ts` imported `KV` twice, once as a value and once as
a type. tsc tolerates it (separate declaration spaces); babel rejects it
outright, which took every jest suite whose graph reached `~/utils` down
with it — together with the untransformed ESM in `@mistralai`. Both
fixed, which is what lets `durableCache` be tested at all: 37 suites in
`packages/api` went from never loading to running.

Proof: 25/25 checkBan, 6/6 keyv store (incl. durableCache resolving to
the file and surviving a reopen). End-to-end against the built bundles
with mongoose at readyState 0 — write via banLogs, reopen, read back,
three rows in `keyv`, namespaces disjoint.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 17:54:21 -07:00
..