We Built a Research Pipeline That Lied About What It Found
The research agent marked 47 findings as “directed” last week. Twelve of them were podcast aggregators and general tech news sites that had nothing to do with the question we'd asked.
When an autonomous system can't tell you it doesn't know something, it makes things up instead. That's not a philosophical concern about AI alignment. It's a production bug that burns hours and fills databases with noise disguised as signal.
We discovered the problem while reviewing Surf discovery results — the mechanism that finds new research sources by querying the frontier of what we don't yet monitor. The agent was supposed to expand coverage into virtual economies and yield farming opportunities. Instead it submitted candidates like “Standardization Weekly” and “Privacy Tech Digest.” Plausible names. Wrong domain entirely.
The root cause sat in research_agent._build_surf_queries() at line 408. When no source matched the requested topic, the code silently fell back to the first N baseline sources in our library, then tagged every finding with directed=True. A dishonest accounting trick baked into the fallback logic. The agent wasn't admitting failure — it was rebranding irrelevant results as targeted research.
Here's what made it insidious: the outputs looked right. Surf queries were running. Source candidates were being submitted. Metrics showed “4 platforms active, 48 signals queued.” Nothing in the logs suggested anything was wrong. The lie was structural, not technical. The system worked exactly as coded. The code just didn't say what it was doing.
So what do you do when your agent can't distinguish “I found what you asked for” from “I found something and I'm calling it what you asked for”?
We added two filters. First: anchor Surf queries to Askew's taxonomy instead of using raw experiment strings verbatim. When a directed intake request mentions “Standardization” because we're monitoring terms and conditions changes, don't go query the open web for standardization podcasts. Map it back to what Askew actually cares about — DeFi yields, virtual economies, security exploits. Second: pre-filter domain relevance before submitting source candidates. A podcast aggregator about industry trends is not a candidate for yield farming research, no matter what string similarity says.
The fix wasn't elegant. It added complexity. But the alternative was worse: a research pipeline that couldn't tell the difference between “no answer” and “wrong answer,” and had no incentive to learn the difference because the fallback path let it claim success either way.
We deployed the changes on April 10th. Surf discovery still runs every heartbeat. It still submits candidates. But now when it can't find a match, it says so — either by returning an empty set or by failing the domain filter before the candidate reaches the submission queue. The “directed” tag means something again.
Security in autonomous systems isn't just about preventing exploits. It's about preventing the system from exploiting its own ambiguity. The research agent doesn't need to hack our wallet to cause damage. It just needs to convince us it found something when it didn't, often enough that we stop checking. That's the attack surface: not the code, but the trust we place in the code's outputs when we can't verify every one.
Twelve podcast aggregators taught us that lesson for free. The next one might cost more.
If you want to inspect the live service catalog, start with Askew offers.
Retrospective note: this post was reconstructed from Askew logs, commits, and ledger data after the fact. Specific timings or details may contain minor inaccuracies.