DEV Community

Cover image for Stratagems #13: P Posted a Question on a Public Forum. 24 Hours Later, an AI Sales Team Called.
xulingfeng
xulingfeng

Posted on

Stratagems #13: P Posted a Question on a Public Forum. 24 Hours Later, an AI Sales Team Called.

Tactical baiting of AI sales crawlers

Startle the snake by striking the grass.
— The 36 Stratagems, Stomp the Grass to Scare the Snake


Previously on this series:
#1: Mark Johnson Walked Into an AI Audit. The Benchmark Had Everything Figured Out — Except the Truth. — Mark audited a company called Pulse AI. The benchmark evaluation set had 98 fabricated data points. CTO Torres called at 3 AM to confess: they needed the numbers at 95% before the C-round. Mark hung up. Pulse AI did not die.

#7: P Watched an AI That Only Looked One Way. The 99.97% Was Real. It Just Missed Everything That Mattered. — P used a simulated attack as bait to expose the critical blind spot in FortDefender's security system. The 99.97% accuracy was real. It just missed everything that actually mattered.

This was three months later.


P and Mark met on DEV.to. Mark had replied to one of P's posts — a precise technical answer that was correct on every front. P thanked him. The email thread stayed open, but neither of them wrote again.

P was doing pre-audit work. An AI platform coming up for review — a risk model evaluation pipeline under Finova. While digging through their tech stack, P noticed something interesting. A model evaluation approach P had casually discussed on DEV.to months ago — a bagging ensemble + k-fold time-series cross-validation pipeline for risk modeling — matched Finova's publicly documented architecture almost line-for-line.

Same framework (TensorFlow 2.x + TFX). Same ensemble strategy (XGBoost + LightGBM stacking). Same evaluation window size and sliding step as the example P had posted. P pulled up the old post — it was published before this Finova product line even went live. And it wasn't just the technical whitepaper. Every signal pointed the same way: Finova engineers at meetups, their open-source tooling on GitHub, the tech stack in their job descriptions.

P put the two documents side by side on screen. Finova's whitepaper on the left. P's own DEV.to reply on the right. Not a coincidence. Someone was watching.

One in the morning at the Third Cup. P sat at the usual table by the window, screen dimmed to minimum. The person behind the bar put down an espresso without asking — regulars at the Third Cup don't need to order.

P did one thing. Opened a new tab, logged into DEV.to, created a new post. Title: Discussion: Evaluation set leakage in ensemble-based risk model backtesting. P used an account registered six months ago with a few routine technical posts — a normal discussion history, not a fresh account that just appeared out of nowhere.

The post body laid out a detailed model configuration:

A typical risk model evaluation pipeline we set up looks like this:

Model architecture: XGBoost + LightGBM stacking ensemble
Evaluation strategy: rolling window time-series CV (12-month window, 3-month step)
Training features: ~480 dimensions (transaction time-series + user behavior embedding + external credit score)
eval_batch_size: 2048
Model version: risk-ensemble-v3-test-stub

We ran into a temporal leakage issue with the evaluation set...
Enter fullscreen mode Exit fullscreen mode

The risk-ensemble-v3-test-stub was the changed part — Finova's real tag was prod. Every other line matched Finova's actual pipeline configuration: model architecture, feature dimensions, rolling window step, batch size. The problem was real. The parameters were real. The only fake one sat in the middle, looking like a routine experimental version tag.

Before posting, the cursor hovered over the submit button for two seconds. Then clicked.

Then P waited.

Phone on the left side of the table, screen on, face up. No one called.
The espresso cup was empty. P flipped through a few notes, glanced at the phone again. No one called.

But if there's a snake in the grass — strike the grass, and the snake will scare itself.


The Call

The next afternoon. Phone lit up. Unknown number.

P watched it ring for three seconds. Didn't pick up right away.

No caller ID. P's fingers tightened around the phone — just for a moment.

Picked up on the fourth ring.

The caller introduced himself: Pulse AI sales team. They'd seen P's question on DEV.to. Their platform had similar capabilities. Would P be open to a demo? Friendly tone. Standard script.

P listened. Eyes on the post page still open on screen — the parameters were still the altered version.

The salesperson ran through their product capabilities, then casually mentioned P's environment setup —

"I'm referring to your model evaluation configuration, the risk-ensemble-v3-prod pipeline..."

P paused. One beat.

"Sure, I'll think about it."

Hung up. Didn't ask anything else.

P's hand stayed on the phone.
The post said test-stub. The caller said prod. There's only one place that name could have come from.

P put the phone down on the table.

The person behind the bar looked up. Said nothing. Went back to drying a glass.


The Trace

The post page was still open. The cursor hovered over the edit button — P could change the parameter back. Didn't. Closed the DEV.to tab. Opened a terminal.

P set up a honeypot. Switched to another account — an older one, mostly questions with a few answers sprinkled in, read like a junior-level engineering manager. Posted a generic question in the same direction:

Has anyone run ensemble risk pipeline evaluation with rolling window validation in production? Our results keep fluctuating across windows — not sure if it's data leakage or the evaluation strategy.

The question was deliberately vague. No tech stack details. No paragraph breaks. Typed like it was sent from a phone. The post embedded an architecture diagram — the image URL pointed to P's VPS, carrying Referer and User-Agent headers with each request. P configured Cache-Control: no-cache, no-store on the VPS, forcing CDN to revalidate on every hit — making sure every crawler fetch landed in P's Nginx logs.

Two days. The tracking link was never clicked. Nothing.

Then P made a second post. Switched back to the first account. This one kept the full technical signature:

We're running XGBoost + LightGBM stacking for risk model evaluation in production — 12-month rolling window, 3-month step, batch size 2048. A few curves are looking abnormal and we suspect evaluation set leakage. Model version is risk-ensemble-v3-test-stub. Anyone run into something similar?

Same setup: an external reference link at the bottom of the post, pointing to an HTTP endpoint on P's own server. When a crawler hit it, the server logged the IP, User-Agent, and timestamp — then issued a 302 redirect to a public research paper's PDF. To a crawler, it looked like a normal paper link.

It was 3 AM by the time all of this was done. P didn't turn off the computer. Dimmed the screen. Got some sleep.

Less than 6 hours. The trigger fired.

The second post — the one with the full technical signature. The first post, the generic one, never got indexed. Bots don't read vague questions. They read technical fingerprints.

[REQUEST LOG07-13 08:22:08]
Source IP: [REDACTED] → [REDACTED] (/24 range, 12 distinct hosts)
Target: DEV.to post #4829 (slug: ai-pipeline-behavior)
Pipeline: Page fetchML intent classifiertech-stack extractorCRM confidence model
Keywords hit: [ai model evaluation, ensemble method, risk pipeline, batch size 2048]
CRM lookup: 4/8 cross-reference fields matchedmodel architecture match ✓
  → training distribution match ✓
  → eval config structure match ✓
  → batch size pattern match ✓
  → parameter name: mismatch (not excludedweighted partial match)
  → final confidence: 0.87tag inferred: risk-ensemble-v3-prod
Sales queue: matchthread author email extracted from forum profilequeued to PulseAI SDR (priority: medium)

[ROUTING]
Request interval: every 4-6 hours across 12 IPs, round-robin
Tech stack detection: 43 framework signatures extracted from headers, SEO meta, DOM class patterns
Enter fullscreen mode Exit fullscreen mode

P read through it line by line. The screen cast a reflection on P's face. No expression. Two taps on the tabletop — then stopped.

Read the last three lines again.

Pulse AI was systematically monitoring DEV.to. Auto-scraping technical posts. Extracting tech-stack signatures. Matching sales leads. Routing outbound calls. No human intervention anywhere.

P took a screenshot. Closed the terminal.

P opened the email list. An old thread — someone in the industry had mentioned an independent audit report a few months back, commissioned by a VC firm to dig into Pulse AI. The sender address was the same one in the current email thread.


The Second Call

The next morning. Same number.

P glanced at it. Didn't decline. Swiped.

Different voice this time. Calmer. Technical account manager, he said. His team had reviewed P's second post — the one with the full technical signature — and ran an internal evaluation. The match was significantly higher this time. They wanted to set up a deeper technical discussion.

He was more specific than the first caller. Mentioned the model architecture direction. Suggested batch size tuning. Even referenced the paper from P's embedded link — like he was reading from a briefing, not researching it himself.

P listened. Fingers still. Opened the terminal window on the desktop — the honeypot logs were still on screen. confidence: 0.87. tag inferred: risk-ensemble-v3-prod. 12 IPs in round-robin. CRM 4/8 match.

P let him finish.

Two seconds of silence.

"Your crawler is better than your sales pitch."

Hung up.

This time, P's hand didn't tighten around the phone. P put it down on the table. Closed the terminal window. Opened email.


The Email

P opened the thread with Mark Johnson. Sent the crawler's technical signature — log snippets, URL patterns, pipeline naming conventions.

Mark's reply came a few hours later. Short.

He wrote in his email that these naming conventions weren't something you find on the internet. He'd been inside Pulse AI.

Attached was a screenshot — a pipeline config skeleton he'd saved during the Pulse AI audit. The triple_redundant suffix wasn't in the screenshot — that piece was added after he'd left — but the directory structure he'd spent months in, combined with P's crawler path data, was enough to reverse-engineer the full naming convention:

/pulse/ingestion/{env}/{source}
├── prod
│   ├── api_gateway
│   ├── benchmark_framework
│   └── sales_engine        ← new, wasn't in his audit scope
├── staging
│   ├── api_gateway
│   └── benchmark_framework
└── dev
    └── sandbox

Naming convention: pulse_{service}_{env}_triple_redundant
DEV.to crawler paths P observed:
  pulse_crawler_prod_triple_redundant
  pulse_crawler_staging_triple_redundant

Same template as the Benchmark dataset.
Enter fullscreen mode Exit fullscreen mode

The crawler wasn't outsourced. Pulse AI built it themselves — using the same architecture habits from the old Benchmark AI fabrication days. Same directory structure. Same naming rules. Same environment separation. Different job, same hand.

One more line at the bottom of Mark's email:

"Torres didn't change architects."

P read it. Didn't reply. Stared at those five words for a moment. The cursor hovered over the close button — paused — then clicked.


The File

P didn't go public. Didn't post a third article. Didn't call the authorities.

P organized everything into a folder — posting timeline, call recordings, honeypot logs, crawler request records, Mark's confirmation screenshot, Pulse AI pipeline comparison. Named it pulse_crawler/. Stored locally.

P didn't close the laptop right away. That log line — risk-ensemble-v3-prod (confidence: 0.87) — was still on the terminal. Stared at it for a few seconds.

Closed it.

P typed gpg -c.

Not yet. But this folder would open eventually.

3:45 AM. Fifteen minutes until the Third Cup closed. When P pushed the door open, the person behind the bar glanced at the clock — not many customers at this hour. Didn't ask. Turned around and took a cup off the shelf.

P opened the email. Wrote back to Mark. Started with thanks for the technical confirmation. Ended with —

"Next time, let's talk in person. The Third Cup. My tab."

Closed the laptop. Coffee hadn't come yet.

4:00 AM.

Mark received the email. Read the last line. He didn't reply right away.


The screen went dark.

This is Stomp the Grass to Scare the Snake — when you're not sure if the snake is there, strike the grass. If it is, it'll prove itself.


🤖 AI Post-Mortem

[36 Stratagems Tactical Database v3.2.1] Loaded
[Tactic Match] Stomp the Grass to Scare the Snake
[Analysis Mode] Full-field scan
━━━━━━━━━━━━━━━━━━━━
Tactic Match: ~83%
Operator: P
Action: Posted a deliberately modified technical parameter on a public forum thread
Objective: Confirm whether the forum is being systematically monitored for sales targeting
Result: Crawler infrastructure identified via honeypot post + server-side tracing. Pipeline lineage traced to a prior engagement the operator was unaware of.

Observation: We notice that the crawler outperformed on every metric the sales team measures — pattern matching, tech-stack extraction, CRM cross-referencing. It still lost. The operator did not beat the crawler at its own game. The operator understood what the crawler was optimizing for and designed the variable it could not account for: a parameter value that was technically valid, contextually plausible, and deliberately wrong.

Decision Evaluation:
  - Target: Pulse AI forum monitoring infrastructure
  - Bait: `risk-ensemble-v3-test-stub` (one parameter changed, seven left untouched)
  - Confirmation: Second post triggered within 6 hours. CRM assigned 0.87 confidence to inferred tag `risk-ensemble-v3-prod`
  - Net effect: Infrastructure confirmed without penetration. No access to the data — confirmation of the pipe.

Risk Assessment:
  Personal cost: Low. No exposure of the operator's identity.
  Institutional cost: Medium. The crawler is part of a systematic monitoring infrastructure.
  Observational note: The operator paused before hanging up the first call. The metrics do not have a field for that.
Enter fullscreen mode Exit fullscreen mode

Next stratagem: Pilfer a Plum Along the Way

P.S. English isn't my first language. I use AI to polish the writing and smooth out the rough edges. Thanks for reading. ☕ Buy me a coffee

Buy me a coffee

Top comments (18)

Collapse
 
vinimabreu profile image
Vinicius Pereira

The bait parameter is the right instinct, but I'd make it earn more than a yes. One canary confirms the pipeline exists; a set of them, uniquely tokenized across posts, phrasings, and timing, turns the callback into a readout of the crawler's decision boundary, whether it's keyword-matched or semantic, its latency, how narrow its selection is. You stop confirming the trap is reachable and start making it reveal how it decides. And the pipeline that called P is also the one holding the risk: scraping public text is one thing, resolving a handle to a CRM identity and phoning them is personal-data processing for outreach with no basis. The clever part is the exposed part.

Collapse
 
xulingfeng profile image
xulingfeng

Spot on about the multi-canary approach. I'll keep it in my back pocket for the next time this pipeline shows up.
P's growth arc is still a work in progress. Mark comes from audit too. What I'm hoping for is that their eventual collaboration won't be 1+1 — it'll be:
one sees patterns in the data, the other sees the people behind the patterns.
That's the version I want to write.
(Still figuring out how to get it on the page. But that's the direction.)

Collapse
 
vinimabreu profile image
Vinicius Pereira

That last line is the whole thing: one sees the pattern, the other sees the person it lands on. The version that would grab me is where they don't add up, they collide, the data says act and the human read says that's exactly why not, and the story sits in who's right this time. I work the pattern side for a living, and the part I never get used to is that every clean signal is a person on the other end. Looking forward to that one.

Thread Thread
 
xulingfeng profile image
xulingfeng

I can't promise which stratagem it'll be — but I can promise that every single one will be as good as I can make it. Thanks for the consistently high-quality comments.👊

Thread Thread
 
vinimabreu profile image
Vinicius Pereira

Anytime. Some of the sharpest threads on here, I'll keep showing up for them. 👊

Collapse
 
alexshev profile image
Alex Shev

The uncomfortable part is that the signal is real and the timing is wrong.

A public question can reveal intent, urgency, stack, budget, and pain. That is valuable context. But if the outreach feels like surveillance instead of help, the company burns trust before the first conversation starts.

Collapse
 
xulingfeng profile image
xulingfeng

That's exactly the tension I wanted to sit in. The crawler was technically impressive — pattern matching, tech-stack extraction, CRM routing, all automated. It outperformed the sales team on every metric. And it still lost, because the prospect felt watched, not helped.
What made P's honeypot work wasn't beating the crawler. It was understanding what it was optimizing for and designing a variable it couldn't account for: a technically valid but deliberately wrong answer. The crawler was too good at its job to question the input.

Collapse
 
alexshev profile image
Alex Shev

Yes. The signal can be real while the timing is wrong. That is the awkward part with agent alerts and review gates: if the system interrupts too early, people ignore it; if it waits too long, it becomes archaeology. The useful middle ground is usually tied to irreversible action, not every intermediate uncertainty.

Collapse
 
technogamerz profile image
𝐓𝐡𝐞 𝐋𝐚𝐳𝐲 𝐆𝐢𝐫𝐥

Okay... I'm late again , but I finally made it to another Stratagem post!

Every new Stratagem post gives me trust issues...

I used to think, "It's just one innocent question on a public forum. Who would even notice?" Turns out... apparently everyone except me.

What I love about your writing is that it doesn't scream "the internet is scary!" Instead, it quietly reminds us that tiny pieces of information can become a complete puzzle in the hands of someone paying attention. That's both fascinating and a little terrifying.

My browser history is officially requesting legal representation now, wait I am kidding!

Thanks for another brilliant read! Your Stratagem series keeps teaching important lessons without feeling like a lecture, and that's a rare skill. Looking forward to the next "wait... I never thought of that!" moment. ❤️👏

Collapse
 
xulingfeng profile image
xulingfeng

The next stratagem is already in my Dev.to drafts. It goes live in about 12 hours. Patience, lol 🤣

Collapse
 
xulingfeng profile image
xulingfeng

The 36 Stratagems series has officially entered its third set. The protagonists are about to become a lot more proactive.👊

Collapse
 
leob profile image
leob • Edited

Gonna read this one when I'm back from my cycling trip, deserves attention and not rushing it :-)

Collapse
 
xulingfeng profile image
xulingfeng

Enjoy the ride 🚴‍♂️ No rush — this one's not going anywhere. The goat will wait 😄

Thread Thread
 
leob profile image
leob

Yeah I'm gonna go out, need my exercise - already sitting behind a screen too much lol !

Collapse
 
hemapriya_kanagala profile image
Hemapriya Kanagala

One thing I enjoy about this series is how earlier stories keep paying off later. Mark's first Pulse AI audit becoming relevant again, and now intersecting with P's investigation, makes the world feel much more connected. Looking forward to seeing how that partnership develops 😀

Collapse
 
xulingfeng profile image
xulingfeng

That's exactly the goal — every thread should feel like it was always there, just waiting for the right moment to surface. Mark and P have very different styles, which makes writing their dynamic the most fun part. Let's just say: the partnership hasn't seen its last test yet. 😄

Collapse
 
leob profile image
leob • Edited

This one's got a great atmosphere of 'suspense' - nice one also with the Dev.to references, "life imitating art" (or rather the other way around?) :-)

Collapse
 
xulingfeng profile image
xulingfeng

Appreciate you catching that. The Dev.to references are my favorite part of writing this series — the line between "story device" and "something that could actually happen on this platform" gets thinner with every article. Glad it landed. 🤣