<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Serendipity on hippotion</title><link>https://blog.hippotion.com/tags/serendipity/</link><description>Recent content in Serendipity on hippotion</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 12 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.hippotion.com/tags/serendipity/index.xml" rel="self" type="application/rss+xml"/><item><title>Two Birds That Read the Web for Me: One Hoards, One Scatters</title><link>https://blog.hippotion.com/posts/two-birds-read-the-web/</link><pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.hippotion.com/posts/two-birds-read-the-web/</guid><description>I gave my second brain two agents that read the outside world and collide it against my notes. A Magpie watches my GitHub stars and only speaks when something hits live work. A Blue Jay reads a handful of RSS feeds and surfaces the distant, not-yet-relevant connection. They share a security spine — and they have deliberately opposite jobs. Here&amp;rsquo;s why the split is the whole design.</description><content:encoded><![CDATA[<p>I have a <a href="/posts/a-second-brain-you-can-git-clone/">vault of markdown notes</a> that
I treat as a second brain, and I <a href="/posts/gitops-for-my-brain/">run GitOps over it</a>
like it&rsquo;s production infrastructure. It already has agents that work on it from
the <em>inside</em>: a <a href="/posts/an-ai-gardener-for-your-second-brain/">nightly gardener</a>
that weeds orphans and suggests links, and a Wanderer that collides random pairs
of my own notes looking for connections I missed.</p>
<p>The obvious next move is to point an agent at the <em>outside</em> — let it read the web
and tell me what matters. That move is also a small landmine, and most &ldquo;AI reads
the internet for you&rdquo; tooling steps right on it. So this week I built two of them
instead of one, named them after corvids, and the reason there are two is the
entire point of this post.</p>
<p>Meet the <strong>Magpie</strong> and the <strong>Blue Jay</strong>.</p>
<h2 id="the-same-fear-twice">The same fear, twice</h2>
<p>Before either bird got a name, both inherited a single non-negotiable rule, and
it&rsquo;s worth saying plainly because it&rsquo;s the part everyone skips:</p>
<blockquote>
<p>An agent that reads the internet and writes to your notes is a prompt-injection
pipeline aimed straight at your trust root.</p>
</blockquote>
<p>My vault isn&rsquo;t just storage. Every <em>other</em> agent — the gardener, the Wanderer,
the search that answers &ldquo;what am I building?&rdquo; — reads it as <strong>trusted context</strong>.
So the moment one agent ingests a GitHub README or a news headline (attacker-
influenceable text) and is allowed to write a note, a stranger on the internet
gets to whisper instructions into the thing my whole system believes. &ldquo;Structured
API&rdquo; narrows that surface. It does not close it.</p>
<p>Both birds are built on the same chassis as the gardener, and that chassis
<em>enforces</em> the fear rather than trusting the model to behave:</p>
<ul>
<li><strong>Two phases, hard split.</strong> A wrapper-owned <strong>FETCH</strong> step pulls the external
text in plain Bash — Claude is not in the loop, can&rsquo;t be talked into anything,
because it isn&rsquo;t running yet. Then a <strong>COLLIDE</strong> step starts <code>claude -p</code> with
the fetched text handed in as inline <em>data</em>, and that process gets only
<code>Read</code> / <code>Glob</code> / <code>Grep</code> / <code>Write</code>. <strong>No Bash, no git, no network, no MCP.</strong>
While untrusted text is in the context window, the agent has no tool that can
reach the outside world or rewrite history.</li>
<li><strong>Allowlist, not the open web.</strong> Each bird reads a short, named list of
sources. Nothing else.</li>
<li><strong>Quarantine, not the vault.</strong> Findings land in <code>quarantine/&lt;bird&gt;/</code>, which
lives <em>outside</em> <code>vault/</code>. The indexer never sees it. Nothing it writes is ever
auto-wikilinked into the graph. Promotion to a real note is a thing <strong>I</strong> do,
by hand, after reading it.</li>
<li><strong>Blast radius is checked, not assumed.</strong> A run may modify <em>only</em> its quarantine
directory. Anything written anywhere else is discarded and reported as a
<code>violation</code>.</li>
<li><strong>&ldquo;Nothing found&rdquo; is a successful run.</strong> Neither bird has a quota. This is the
honesty contract I stole from the Wanderer — an agent under pressure to produce
N findings will manufacture N findings, and manufactured insight is worse than
silence.</li>
</ul>
<p>That&rsquo;s the shared spine. Now the interesting part: given the <em>same</em> security
model, the two birds do almost opposite things, and trying to make one bird do
both jobs would have quietly ruined it.</p>
<h2 id="the-magpie-hoards-whats-already-shiny">The Magpie hoards what&rsquo;s already shiny</h2>
<p>A magpie collects shiny objects and keeps them close. Mine watches <strong>my own
GitHub stars</strong>.</p>
<p>The premise is <em>slow public signal × private context</em>. I starred some repo three
weeks ago, forgot about it, and moved on. Meanwhile my projects shifted. The
Magpie runs weekly, pulls my starred repos through one allowlisted endpoint
(<code>gh api user/starred</code>), and collides each one against what I&rsquo;m <strong>actively
building right now</strong> — the live projects, the open hubs.</p>
<p>Its output contract is a tight one: it is a <strong>relevance filter</strong>. It fires <em>only</em>
when a star actually touches live work, and every finding has to name three
concrete things — the repo, the project it connects to, and one &ldquo;so what.&rdquo; A
vague &ldquo;these are thematically related&rdquo; doesn&rsquo;t count as a hit. It&rsquo;s a watchdog on
the dials, not a newsletter.</p>
<p>The supervised proof run, over 28 stars, surfaced exactly two real hits and
refused to invent a third:</p>
<ol>
<li><strong><code>supertonic</code> (on-device multilingual TTS)</strong> × my
<a href="/posts/clone-your-voice-hungarian-audiobooks/">Hungarian-audiobook voice-cloning project</a>
— a possible escape from a TTS fight I&rsquo;d been losing. I checked: it genuinely
supports Hungarian. That&rsquo;s a hit with a so-what.</li>
<li><strong><code>agentmemory</code></strong> × the exocortex itself — prior art for persistent AI memory,
notably <em>with benchmarks</em> my own notes lacked. (And if you&rsquo;ve read about
<a href="/posts/graph-hurt-my-search/">the time I benchmarked my own search and it lost</a>,
you&rsquo;ll know how much I needed that nudge.)</li>
</ol>
<p>The other ~22 stars mapped to tidy thematic clusters and were correctly <em>not</em>
reported. That restraint is the feature.</p>
<h2 id="the-blue-jay-scatters-acorns-and-forgets-where">The Blue Jay scatters acorns and forgets where</h2>
<p>Here&rsquo;s the bird that explains why there are two.</p>
<p>Blue jays don&rsquo;t hoard close like magpies. They <strong>cache acorns far and wide and
forget where they buried some</strong> — and the forgotten ones grow into oak trees.
Ecologists think blue jays are why oak forests spread north after the last ice
age. Seed dispersal, by way of a bad memory. That is <em>exactly</em> the job I wanted
for the second bird, and the metaphor was too good to pass up.</p>
<p>The Blue Jay reads an allowlist of <strong>eight RSS feeds</strong>, picked so tech and science
cross-pollinate:</p>
<ul>
<li><strong>Tech:</strong> Hacker News (high-score front page), lobste.rs, Ars Technica</li>
<li><strong>Science &amp; ideas:</strong> phys.org, Quanta, Aeon, Nautilus</li>
<li><strong>Wildcard:</strong> Medium — but scoped to specific <em>tag</em> feeds, never the raw
firehose of crypto and self-help</li>
</ul>
<p>Quanta, Aeon, and Nautilus are on that list on purpose: they&rsquo;re the connective
tissue, the feeds where &ldquo;huh, that&rsquo;s weirdly similar to&hellip;&rdquo; happens before my
vault even gets involved.</p>
<p>And its output contract is the <strong>opposite</strong> of the Magpie&rsquo;s. The Blue Jay is a
<strong>serendipity filter</strong>. Its job is to surface the connection that <em>isn&rsquo;t</em> in my
projects yet — the distant idea, the acorn worth burying. If I ran it through the
Magpie&rsquo;s &ldquo;only fire on a live-work hit&rdquo; rule, I would strangle the one thing it
exists to do. Relevance and serendipity pull in opposite directions, and you
can&rsquo;t tune a single agent to maximize both.</p>
<p>One more load-bearing detail, half design and half security: the Blue Jay
<strong>collides on the RSS summary only</strong> — title, abstract, link. It never pulls the
full article body into context. That&rsquo;s simultaneously the lower-injection path
<em>and</em> the right cognitive shape (a headline is a seed; I click through myself from
quarantine if the seed is interesting). The narrow input is doing double duty.</p>
<h2 id="why-two-birds-and-not-one-with-a-flag">Why two birds and not one with a flag</h2>
<p>I genuinely considered making this one agent with a <code>--mode=relevance|serendipity</code>
switch. I&rsquo;m glad I didn&rsquo;t, and the reasoning generalizes past birds:</p>
<table>
	<thead>
			<tr>
					<th></th>
					<th><strong>Magpie</strong></th>
					<th><strong>Blue Jay</strong></th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Source</td>
					<td>my GitHub stars (structured API)</td>
					<td>8 RSS feeds (open prose)</td>
			</tr>
			<tr>
					<td>Injection risk</td>
					<td>low</td>
					<td>the highest frontier</td>
			</tr>
			<tr>
					<td>Fires when</td>
					<td>a star hits <strong>live work</strong></td>
					<td>a summary sparks a <strong>distant</strong> idea</td>
			</tr>
			<tr>
					<td>Output</td>
					<td>relevance: repo → project → so-what</td>
					<td>serendipity: the not-yet-relevant connection</td>
			</tr>
			<tr>
					<td>Failure mode it guards against</td>
					<td>noise / false relevance</td>
					<td>being strangled into silence</td>
			</tr>
	</tbody>
</table>
<p>Two things made the split non-negotiable. First, <strong>the output contracts are too
different to share one brain</strong> — &ldquo;only speak on a hit&rdquo; and &ldquo;speak about the thing
that isn&rsquo;t a hit yet&rdquo; are contradictory prompts, and a single agent told to do
both does neither well. Second, <strong>open news is a higher injection frontier than a
structured stars API</strong>, so the riskier bird deserves its own enforced blast-radius
wrapper, not a code path bolted onto the safe one. When two jobs disagree on both
<em>what good output is</em> and <em>how dangerous the input is</em>, that&rsquo;s not a flag. That&rsquo;s
two programs.</p>
<p>So now my vault has two more agents reading the world on a cron. The Magpie runs
Saturday at 06:00 and tells me when something I bookmarked finally became
relevant. The Blue Jay runs Saturday at 07:00 and buries acorns in a quarantine
folder, most of which I&rsquo;ll ignore — but I only need one of them to grow into an
oak.</p>
<p>Both are on probation for their first few runs, because I don&rsquo;t trust a thing that
reads the internet until I&rsquo;ve watched it behave. But the part I&rsquo;m actually happy
about isn&rsquo;t the agents. It&rsquo;s that building the <em>second</em> one forced me to say out
loud what the first one was secretly assuming — and the names made the difference
impossible to forget. A magpie hoards. A blue jay scatters. You want both, and
you do not want them to be the same bird.</p>
]]></content:encoded></item></channel></rss>