Wiki/Auction Platform/Anti-Gaming and Three Strikes: How the Auction Fights Back
01Auction Platform5 min read

Anti-Gaming and Three Strikes: How the Auction Fights Back

Rapid-bid bursts, retraction patterns, deposit timeouts — and the trigger that auto-blocklists serial offenders.

The instinct, when you read "anti-gaming," is to imagine a sophisticated machine-learning model classifying bidders into "honest" and "fraudulent." That's not what's running. What's running is two simpler things, both of which work better than they look on paper.

Continuous detection at placeBid

Every bid that comes in goes through a check before it's accepted. The check looks at the bidder's recent activity across four time windows: the last 60 seconds, the last 5 minutes, the last hour, and the last 24 hours. From that activity it computes two signals — rapid-bid count (how many bids in the shortest window) and retraction count (how many of those bids were withdrawn). The signals are weighted by platform-tunable thresholds and produce a low / medium / high suspicion score.

If the score is high, the bid is auto-rejected. If the score is medium, the bid is accepted but flagged for review on the operator's anti-gaming page. The signals stay cached on the bidder's company row, so the next bid from the same company doesn't re-run the full window query — fast enough to not slow down the bidding feed, accurate enough to catch the worst patterns.

The thresholds are tuned by ReVend OS platform admins from /admin/auction/risk-settings. The defaults are calibrated platform-wide; tenants cannot relax them at publish time.

Three-strikes auto-ban

Continuous detection catches in-the-moment misbehaviour. Three-strikes catches the pattern that's only visible across multiple auctions. The relevant strike type, in v1, is escrow_deposit_timeout — a bidder won a lot, the system created a pending-deposit escrow, and the buyer never wired the funds within the 7-day window. The escrow auto-cancels, and a strike is recorded against the buyer's company.

The strikes table (auction_strikes) is purpose-built. It records the strike type, the source context (escrow_id, deal_id, lot_id, depending on the strike), the recorded date, a JSONB details column for whatever extra context the source flow wants to attach, and a clearance trio (cleared_at, cleared_by_user_id, cleared_reason) for compliance pardons. Cleared strikes stay in the table for audit; they just no longer count toward the threshold.

The threshold is hard-coded at three strikes in 180 days. When the third active strike lands, an AFTER INSERT trigger flips companies.bidder_blocklisted to true with a system reason. The existing G3 BEFORE INSERT trigger on auction_bids then rejects every subsequent bid attempt before it reaches the placeBid logic. The bidder is, effectively, removed from the auction without anybody having to remember to remove them.

Pardons and audit

Compliance can pardon individual strikes from the admin strikes page (/admin/auction/strikes/[companyId], platform-staff only). The pardon requires a reason of at least 5 characters, written into the cleared_reason column. Compliance can also lift the full blocklist via the existing clearBidderBlocklist action. Either way, the audit row stays — the pardon is documented, not erased. Because the next time somebody asks "why is this bidder back?" the answer is in a column, not in somebody's memory.