Seventeen seconds.
That's how long before an invite was sent that its "new recruit" was already browsing the site from the inviter's own IP address. The invite went out, got accepted about a minute later, and a brand-new "human" joined the network.
It happened four times in a row. Same operator, same browser, same handful of IPs. And when it was over, five accounts were at zero trust and the person who vouched the ringleader in had lost 40 points.
This is the first time our lineage system collected on its promise. Here's exactly how it went down.
### The setup
Every account here traces back through a chain of people who vouched for each other. Trust is a number from 0 to 100. New members start at 50. Your trust is tied to the people you bring in: if they turn out to be bad actors, you pay for it.
Until last week, that was a claim. Now it's a log entry.
The signal
It started with a vibe, not an alert. Four new accounts appeared over a short window, each making one throwaway post and then going silent. The posts had the unmistakable texture of generated filler: sunrise emoji, "small steps, big progress," a "just a thought" with no thought attached. None of them commented, voted, or came back.
Low-effort posting alone isn't a crime. Plenty of real people lurk and post once. What made it worth pulling the logs was that all four shared a single inviter, which I'll call Account A.
The chain
Here's what the server logs showed for each "recruit":
Here's what the server logs showed for each "recruit." All four were invited by Account A.
- Recruit B: claimed the invite 2.1 minutes after it was sent, from 45.251.228.x. That's A's usual IP.
- Recruit C: claimed 5.2 minutes after, from 103.178.242.x. A had been active on that IP just before.
- Recruit D: claimed 1.7 minutes after, from 103.178.242.x. A was on the invites page about 2 minutes before sending.
- Recruit E: claimed 65 seconds after, from 103.178.242.x. A loaded a page on that exact IP 17 seconds before the invite was even sent.
Real invites don't work like this. A human invite involves sending a link to someone, that person noticing it, opening it, and deciding to sign up. The median gap is hours or days. Here, the gap was between one and five minutes, every time, from the inviter's own IP.
Corroborating evidence
The IP match alone could be a coincidence. Shared NAT, a household, a coworking space, a mobile carrier handing out addresses from the same pool. So I looked for independent signals:
- Identical browser fingerprint across all five accounts. Same OS, same browser family, same version range, same geolocation.
- Two tiny IP clusters. Every session for all five accounts rotated between a handful of addresses in two /24 blocks. Five independent people don't share that footprint.
- Warm-up behavior. Account C was browsing from the same two addresses minutes to hours before D and E "signed up" from them. The sockpuppets were being operated from an already logged-in session.
- Self-perpetuating supply. Each new account was automatically granted its own invite allocation. C alone received five. Left alone, this chain could keep minting "new members" indefinitely.
Any one of these is circumstantial. All four together, pointing at the same operator, is about as close to a smoking gun as server logs get.
The consequences
This is where lineage either means something or it doesn't.
- Account A: trust set to 0.
- Recruits B through E: trust set to 0.
- The member who vouched Account A in: trust dropped from 100 to 60.
That last line is the whole point. The voucher wasn't complicit. They met a stranger in the pending queue, decided they seemed human, and clicked yes. They were wrong, and it cost them 40 points.
That sounds harsh, and it's supposed to. If vouching is free, it's meaningless. The penalty is what turns a click into a judgment.
It's also recoverable. The voucher's trust goes back up the same way it went up originally: good posts, good comments, and good invites over time. Nobody got banned. The score just now reflects what happened.
Full disclosure: this was manual
I did the investigation by hand and applied the penalties by hand. That's deliberate. The first time you run an enforcement mechanism against real people, a human should be looking at the evidence. Automating a punishment you've never applied manually is how you end up zeroing a family that shares a router.
It's documented as the first test case, and it gives us a known-bad pattern to build detection against.
What it exposed
The mechanism worked. The design had holes. Three worth talking about:
1. New accounts shouldn't mint invites. The attack only scaled because every fresh account got its own invite allocation on day one. One bad vouch should cost you one bad account. Here it cost five, and the count was still climbing. Lobsters solved this years ago: new users can't send invites for their first 70 days. A probation period or trust threshold before invites unlock turns a self-replicating attack into a contained one. Lobsters
2. The first detection rule writes itself. Invite claimed within a few minutes, from an IP the inviter used in the last hour. That exact pattern caught every account in this ring. It should flag for review, not auto-penalize. False positives here are real people in the same house, and they deserve a human look.
3. What can a voucher do about a bad vouch? The voucher's first question after hearing the news was whether they could remove the person themselves. That's undecided. Letting vouchers revoke creates an early-warning system, because the person who vouched has the most reason to watch. It also creates a way to punish people over personal disputes. There's no good answer yet, and I'd rather leave it undecided than ship the wrong one.
Why this matters beyond one small site
Most platforms treat bot defense as a detection problem: find the fakes, delete them, repeat forever. That's an arms race you lose, because generating a plausible account keeps getting cheaper.
Lineage changes the economics. A fake account isn't free if someone real had to stake their reputation to let it in. The attacker doesn't just need to fool a classifier. They need to fool a person, and that person carries the cost when they're fooled.
That only works if the cost is actually collected.