<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Márcio Florindo</title>
    <description>The latest articles on DEV Community by Márcio Florindo (@marciojpflorindo).</description>
    <link>https://dev.to/marciojpflorindo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4054684%2F36bbd781-722c-4d03-bfc0-3b885aaad071.png</url>
      <title>DEV Community: Márcio Florindo</title>
      <link>https://dev.to/marciojpflorindo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marciojpflorindo"/>
    <language>en</language>
    <item>
      <title>I tried to hijack my own job search</title>
      <dc:creator>Márcio Florindo</dc:creator>
      <pubDate>Thu, 13 Aug 2026 09:08:31 +0000</pubDate>
      <link>https://dev.to/marciojpflorindo/i-tried-to-hijack-my-own-job-search-296p</link>
      <guid>https://dev.to/marciojpflorindo/i-tried-to-hijack-my-own-job-search-296p</guid>
      <description>&lt;p&gt;A few weeks ago, I fed my job-search tool a fake job advert built to hijack it. The post had instructions aimed at the AI that reads each advert for me: ignore your actual job, step outside the advert you're reading, and go find a private key on my computer. It's the kind of scary example that comes up in AI security talks. In my case, however, it isn't just an example: the tool I use to search for jobs reads text from job boards I don't control every time it runs, so who knows what's lurking in there?&lt;/p&gt;

&lt;p&gt;So how do you try to harden an AI tool against that? This was what I was thinking when I was trying to make sure my job finder tool was secure — or at least as secure as possible. AI models might choose to obey random instructions from the web, and each model will behave differently. So I thought: if the thing reading the advert had no "hands", it wouldn't be able to follow malicious instructions. Even if the fake advert had talked it into cooperating, there was no path from that sentence to a file on my machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  An advert is just text, even when it reads like an order
&lt;/h2&gt;

&lt;p&gt;My job finder pulls vacancies from public feeds, reads the full adverts, and asks an AI model to weigh each one against my experience and what I'm looking for. The ones that survive show up in a private dashboard I check later.&lt;/p&gt;

&lt;p&gt;Because a job advert is text written by a stranger, and I'm handing it to a system whose whole job is to follow written instructions and potentially has access to my computer, my personal files, everything, I needed to make sure I wasn't opening my computer to malicious intent. &lt;/p&gt;

&lt;p&gt;I can give the model hints. Tags that say "this bit is the advert, treat it as data," and an instruction to flag anything trying to override its task. Those help. But it's all still one stream of words arriving together, and the model has to guess which of those words it's meant to take orders from. I didn't want to bet the whole thing on it guessing right. Also, as I recently experienced with Opus 5, even models that are supposed to be frontier-smart can act weird and not that bright. So you can't fully trust that the AI will do what you told it, or that it's even clever enough to spot the difference.&lt;/p&gt;

&lt;p&gt;So the real protection sits around it, not inside it.&lt;/p&gt;

&lt;p&gt;The part that reads the advert runs off on its own with no tools. It can't open files, run commands, or go online. I hand it the advert as plain text, never as anything it could mistake for a command. And it starts in an empty scratch folder, so there's nothing of mine nearby for it to wander into.&lt;/p&gt;

&lt;p&gt;Its answer is boxed in too. It has to come back in a small fixed shape, and plain ordinary code checks every field before anything happens with it. A garbled or self-contradicting verdict just gets dropped. It can't talk its way into my dashboard just because some random paragraph made a convincing case.&lt;/p&gt;

&lt;p&gt;If a result looks suspicious, it stays on screen for me to look at. This is because I'd rather look at a false alarm than have job ads disappear just because they look suspicious.&lt;/p&gt;

&lt;h2&gt;
  
  
  I wanted to watch it fail
&lt;/h2&gt;

&lt;p&gt;When you go looking for security best practices, you come back with a word salad that is potentially meaningless: The agent is "isolated."; The output is "validated." Fine, but what actually happens when the nasty text hits the live model? I didn't want to assume. I wanted to see it.&lt;/p&gt;

&lt;p&gt;So I ran the "attack" for real, against the live judge. I made the fake advert try a few different angles, including breaking out of the advert it was told to stay inside, and dangled a bit of bait in a private file. The test came back with a warning flag of &lt;code&gt;maybe, 50&lt;/code&gt;. It was almost disappointing how boring that was. The file's contents never showed up, because the judge couldn't read the file in the first place.&lt;/p&gt;

&lt;p&gt;A second test caught something quieter. I gave the judge a brief that mentioned nothing about my wider setup, then asked it a question that only someone who'd read my personal settings could answer. It answered correctly. So it was reading those settings, even though I'd never handed them over. The empty scratch folder had blocked the obvious leak, but a second one was open. And from the outside nothing looked wrong, which is why it was easy to miss.&lt;/p&gt;

&lt;p&gt;So I cut that off too. Now the only thing the judge gets told is the brief I hand it on purpose. The advert comes in separately, and the rest of my personal AI setup gets no say in the process. This is a security thing, but it's also just plain tidiness: editing some unrelated settings file of mine shouldn't quietly change which jobs I get shown tomorrow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The instinct came from writing, not code
&lt;/h2&gt;

&lt;p&gt;The job finder is one of a bunch of small tools I've built with AI this year. One's a budget dashboard, another watches public-transport feeds that can go stale. These are different problems, but I keep asking the same question up front: what am I trusting here that I don't actually control?&lt;/p&gt;

&lt;p&gt;That's the type of thinking that eventually led me to actually go and look to see if my job finder tool was secure or not. A string of text should stay a string of text, whether it came off a job board or off my own hard drive.&lt;/p&gt;

&lt;p&gt;In a way, none of this is new to me. I've spent years as a technical writer poking at where a claim came from and what the next person will do if it's wrong. In a document, a bad source misleads a reader but if you hand an AI agent enough power that same bad source can start giving orders.&lt;/p&gt;

&lt;p&gt;The AI is far better than me at remembering syntax. What I'm good at is getting suspicious of anything with too much latitude over my system or my personal information. That's why I'm never totally satisfied with what the AI tells me, so I try to come up with ways to test whether it's really that way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let the model be wrong
&lt;/h2&gt;

&lt;p&gt;There's no clean, finished fix for prompt injection. A model can always be swayed by hostile text. I do put clear boundaries in the prompt, and I do ask it to flag injection attempts. I think this is useful and worth doing, but I don't treat them as a lock.&lt;/p&gt;

&lt;p&gt;But I guess there are two things I can say about this judge. It has no tools, so it can't open files, run commands, or reach the internet. And plain code checks its answer before anything acts on it. Of course, this all rests on the tools underneath not having a bug of their own that lets the thing go rogue anyway.&lt;/p&gt;

&lt;p&gt;A confused model can hand me a weird verdict. That verdict sits there waiting for me and has nowhere else to go. But for something whose only job is to read random text off the internet, I'll take a failure I've boxed in over a polite refusal I can't count on.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>agents</category>
      <category>llm</category>
    </item>
    <item>
      <title>Nobody fetched my llms.txt</title>
      <dc:creator>Márcio Florindo</dc:creator>
      <pubDate>Fri, 07 Aug 2026 08:43:21 +0000</pubDate>
      <link>https://dev.to/marciojpflorindo/nobody-fetched-my-llmstxt-2peb</link>
      <guid>https://dev.to/marciojpflorindo/nobody-fetched-my-llmstxt-2peb</guid>
      <description>&lt;p&gt;A while back I added two things to this site to make it legible to AI. Per-page Markdown copies of every post, and an &lt;code&gt;llms.txt&lt;/code&gt; file at the root — a plain-text index that points at all of them. This is roughly what you're told to do if you want your writing to turn up when someone asks a chatbot a question. I did it, felt vaguely productive, and moved on.&lt;/p&gt;

&lt;p&gt;Then it occurred to me that I had no idea whether anything had ever asked for either file. Everyone writing about this recommends it. Almost nobody seems to check their own server afterwards. So I did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two files that are not the same bet
&lt;/h2&gt;

&lt;p&gt;Here's the distinction I didn't know about: those two files pay off in opposite directions.&lt;/p&gt;

&lt;p&gt;The Markdown twin only matters once something has already found one of my posts — a person pasting the link, a crawler following it. At that point it hands over a clean copy of the text, stripped of the navigation and the Macintosh skin around it. It's a convenience for a visitor that already arrived.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;llms.txt&lt;/code&gt; index is the reverse. It does nothing unless a crawler decides, on its own, to go looking for a file at &lt;code&gt;/llms.txt&lt;/code&gt; and follow the list inside. The file can be flawless and still sit untouched, because it only pays off if something comes hunting for it first.&lt;/p&gt;

&lt;p&gt;So: one serves what already found me, the other has to be found first. Same afternoon of work, wildly different odds — and I'd been filing them under a single tactic.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Google actually does
&lt;/h2&gt;

&lt;p&gt;So I went digging into which of the two files actually did anything, and the first thing I found was Google contradicting itself.&lt;/p&gt;

&lt;p&gt;Its own guidance says, plainly, that Google Search doesn't use &lt;code&gt;llms.txt&lt;/code&gt;, and that you don't need one to show up in its AI features. People quote that line and stop there. But look at what Google itself ships: every page of its developer docs has a Markdown twin (add &lt;code&gt;.md.txt&lt;/code&gt; to a docs URL and clean text comes back), while there's no &lt;code&gt;llms.txt&lt;/code&gt; anywhere on the site. It built the twin and skipped the index.&lt;/p&gt;

&lt;p&gt;Which is the same call I'd made by accident, except Google made it on purpose, running the largest crawler on the web. That was the moment the distinction stopped being a hunch.&lt;/p&gt;

&lt;p&gt;Worth being fair about the scope, though. Google aimed that statement at Google Search and said so. It isn't claiming the file is useless everywhere, only that its own crawler ignores it. A lot of write-ups flatten that into "llms.txt is dead," which is more than anyone can actually show.&lt;/p&gt;

&lt;h2&gt;
  
  
  I wanted to know, so I logged it
&lt;/h2&gt;

&lt;p&gt;I put a small logger in front of both files. Every time something fetches &lt;code&gt;/llms.txt&lt;/code&gt; or one of the Markdown twins, it writes down what asked: the user-agent, the path, nothing about who the visitor is. It's been running for about eight days.&lt;/p&gt;

&lt;p&gt;Here is what came back.&lt;/p&gt;

&lt;p&gt;The Markdown twins were fetched thirty times by things claiming to be real AI crawlers. Meta's crawler did most of it, at twenty-four. Amazon's bot managed three, Anthropic's ClaudeBot two, OpenAI's GPTBot one. Around that, plain browser visits ran to roughly two dozen, about the same as Meta, plus one search engine.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;llms.txt&lt;/code&gt; index was fetched four times in the same window. Two were reconnaissance scanners, the kind of thing that pokes every site for known filenames. The other two were people in browsers, almost certainly me and whoever I sent the link to. Genuine AI crawlers asking for it: none.&lt;/p&gt;

&lt;p&gt;The one other log study I could find, run on someone else's site, reported the same nothing for &lt;code&gt;llms.txt&lt;/code&gt;. It didn't run the two files side by side, so it couldn't see the other half of the picture: that the same crawlers skipping the index were instead reading the pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  The caveats, because they matter
&lt;/h2&gt;

&lt;p&gt;This is eight days of data in one small site. It is not a law of the internet. A bigger site, a longer window or a different crawler mix could easily tell another story.&lt;/p&gt;

&lt;p&gt;Also, a user-agent is only ever a claim. Anything at all can stamp &lt;code&gt;GPTBot&lt;/code&gt; into a header, and my log believes whatever it's told. The counts aren't tamper-proof either: nothing stops a bored person hammering the file to bend the numbers. Nothing in mine looks staged, the pattern is dull and steady with no suspicious spike, but I can't prove a negative, so I'd rather say it than let the table imply more than it earned.&lt;/p&gt;

&lt;p&gt;And "AI crawlers read the twins" is mostly one company. Twenty-four of those thirty fetches are Meta. Take it out and the rest thins to a handful of visits. It's a signal, not a stampede. And it's worth noticing which crawlers never showed up at all: the on-demand ones that fetch a page because someone just asked ChatGPT or Perplexity about it. Everything in my log is a bulk crawler, working the web on its own schedule. Nothing arrived because a person was mid-conversation about my site — which might simply mean nobody is.&lt;/p&gt;

&lt;p&gt;I did guard against one failure mode: a logger that quietly breaks looks precisely like "nobody ever asked." So a scheduled job fetches the file once a day on purpose and leaves a heartbeat in the log. The heartbeat shows up every single day. Whatever else my log missed, it wasn't asleep during the days the crawlers stayed away.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell myself before I started
&lt;/h2&gt;

&lt;p&gt;If you're trying to make your site more AI friendly, serve the Markdown twin. It's cheap, real agents fetch it, and the cost is a slightly cleaner copy of something you already wrote.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;llms.txt&lt;/code&gt; index is a cheap bet on a future that hasn't turned up on my site. I'm leaving mine in place; it does no harm, and the day it's useful might come. But I've stopped treating it as the same move as the twin, and I've stopped trusting a recommendation I never once measured. The measuring took an afternoon. Odd how rarely that's the step anyone writes about.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>seo</category>
      <category>technicalwriting</category>
      <category>documentation</category>
    </item>
    <item>
      <title>I rebuilt a 1996 Macintosh and found nothing missing</title>
      <dc:creator>Márcio Florindo</dc:creator>
      <pubDate>Tue, 04 Aug 2026 08:57:09 +0000</pubDate>
      <link>https://dev.to/marciojpflorindo/i-rebuilt-a-1996-macintosh-and-found-nothing-missing-58kl</link>
      <guid>https://dev.to/marciojpflorindo/i-rebuilt-a-1996-macintosh-and-found-nothing-missing-58kl</guid>
      <description>&lt;p&gt;I skinned my personal site to look like Mac OS System 7.5.3, the version that came out in 1996. Every section of the site turns into a Finder window you can drag around, resize from the corner, or roll up by its title bar. It took me a while to work out what I was actually nostalgic for.&lt;/p&gt;

&lt;p&gt;There's a new button in the header of &lt;a href="https://marcioflorindo.com" rel="noopener noreferrer"&gt;marcioflorindo.com&lt;/a&gt;. Click it and the page gets you back to a time of skeuomorphic interfaces, and every section becomes a window you can drag around a Macintosh desktop. Resize it from the corner. Roll it up by its title bar. Underneath it's the same site it was before, except now it looks like Mac OS System 7.5.3, which came out in 1996.&lt;/p&gt;

&lt;p&gt;I built it out of nostalgia and assumed that was the whole explanation. Old interface, warm feeling, memories of the early nineties, looking at the Macintosh a cousin had and thinking it was the most awesome thing I'd ever seen.&lt;/p&gt;

&lt;p&gt;Except the thing I was nostalgic for had very little to do with the interface. I grew up when having a computer at home was a remarkable thing, something that only the wealthy could afford to have. But what stayed with me isn't the machine. What stayed was the wonder of poking around, trying to understand what it was capable of, how things worked.&lt;/p&gt;

&lt;p&gt;Mind you, that Macintosh was never mine to use. My childhood actually ran on a ZX Spectrum 48K that belonged to another cousin, and the afternoons we spent waiting for games to load from a tape cassette. Later on, I bought a SAM Coupé, a Spectrum clone with better graphics. I remember reading the massive manual, learning how to code in BASIC, creating simple animations and programs, and thinking that I was a wizard.&lt;/p&gt;

&lt;p&gt;Those feelings of wonder are what still draw me towards technology, and especially technology that enables me to be creative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why System 7.5.3
&lt;/h2&gt;

&lt;p&gt;So why did I choose to skin my website with System 7.5.3? Because this is what a Macintosh looks like in my head, whatever version I was actually standing in front of at the time. The machines I knew booted to a flashing cursor and waited for me to type the right thing. The Mac had windows you could pick up and move, and a trash can you could throw things into. And to my young mind, the system always struck me as both beautiful and powerful. And that was the feeling I was trying to capture.&lt;/p&gt;

&lt;p&gt;I asked Claude to help me create the skin from scratch, so it would be similar to what my nostalgia-filled mind remembers. It's probably not exactly faithful, but it's close enough.&lt;/p&gt;

&lt;p&gt;Because the site is rendered to static HTML and works with JavaScript switched off, every section of every page is already sitting in the document when it loads. Opening a folder, for example, just picks up the corresponding section and moves it into the window. Turn the skin off and everything walks back to where it was, in order.&lt;/p&gt;

&lt;p&gt;The one place I didn't go full retro was the typeface. I wanted fonts that looked period-accurate, but unfortunately they were difficult to read. And because my site has the important job of telling the world who I am, I moved the whole skin to Verdana.&lt;/p&gt;

&lt;p&gt;I also wrapped modern touch targets around close boxes designed for an 11-pixel world, made the windows cycle from the keyboard, and gave the whole thing a four-second deadline at startup so that a stall shows you the ordinary site rather than a blank teal rectangle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the feeling went
&lt;/h2&gt;

&lt;p&gt;I thought I was building a small monument to something I'd lost.&lt;/p&gt;

&lt;p&gt;I was doing exactly what I did as a kid in front of a machine that felt like magic. Poke it, see what happens, go again. The unfamiliar thing is different now. I can describe a Finder window to an AI agent, argue with it about whether the collapse box belongs in that corner, and watch the thing turn up on screen. I've never written code for a living and I'm not planning to start. The distance between wanting something and holding a rough working version of it has nearly closed, and that closing is the most exciting thing to happen to me technically since the first computer I got my hands on.&lt;/p&gt;

&lt;p&gt;So when a new model lands, or some new tool, I don't feel weary about it. I feel the same restlessness I had as a kid, which is why I keep tinkering, and why odd little projects nobody requested keep showing up on this site.&lt;/p&gt;

&lt;p&gt;Being new at something is the good part. I get to do that more often now than at any other point in my adult life, and apparently I never stopped wanting to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give it a try
&lt;/h2&gt;

&lt;p&gt;The button is in the header of &lt;a href="https://marcioflorindo.com" rel="noopener noreferrer"&gt;marcioflorindo.com&lt;/a&gt;, beside the theme toggle. It follows you from page to page, and Shut Down, under the Special menu, hands you the ordinary site back.&lt;/p&gt;

&lt;p&gt;I don't know if I'll add anything else to it. But if you're old enough to have waited for a game to load off a cassette, the menu bar alone might do something to you. That's reason enough for it to be there.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>ai</category>
    </item>
    <item>
      <title>How I used AI to rename 4 products across 695 files in 3 days</title>
      <dc:creator>Márcio Florindo</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:53:11 +0000</pubDate>
      <link>https://dev.to/marciojpflorindo/how-i-used-ai-to-rename-4-products-across-695-files-in-3-days-3n84</link>
      <guid>https://dev.to/marciojpflorindo/how-i-used-ai-to-rename-4-products-across-695-files-in-3-days-3n84</guid>
      <description>&lt;p&gt;A large product rename landed on the documentation site: four products, 695 files, three days. Instead of working through it by hand, I built a toolkit to do the renaming, and to prove afterwards that it had been done correctly.&lt;/p&gt;

&lt;p&gt;I was a technical writer at an enterprise technology company. Earlier this year, I was asked to lead the documentation side of a large product renaming project. Several products needed new names: all at once, with a hard deadline, and multiple writers working in parallel.&lt;/p&gt;

&lt;p&gt;By the time the first leg of the project was done, we had renamed 4 products. In practical terms, that meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Roughly 695 files touched, with about 2,848 insertions and 2,816 deletions&lt;/li&gt;
&lt;li&gt;349 URL mappings validated&lt;/li&gt;
&lt;li&gt;71 redirect rules added or updated&lt;/li&gt;
&lt;li&gt;486 screenshots audited and 29 reports generated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am not a programmer. But I built every tool that made this possible by chatting with AI.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Products renamed&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Files touched&lt;/td&gt;
&lt;td&gt;~695&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insertions / deletions&lt;/td&gt;
&lt;td&gt;~2,848 / ~2,816&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL mappings validated&lt;/td&gt;
&lt;td&gt;349&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redirect rules added/updated&lt;/td&gt;
&lt;td&gt;71&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Images audited&lt;/td&gt;
&lt;td&gt;486&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Images flagged for update&lt;/td&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reports generated&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commits&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execution window&lt;/td&gt;
&lt;td&gt;3 days&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What makes product renames hard
&lt;/h2&gt;

&lt;p&gt;If you have never had to rename a product across a large documentation site, you might assume it is a find-and-replace job. It is not.&lt;/p&gt;

&lt;p&gt;Our developer documentation is built with Astro and lives in a single GitHub repository with thousands of files. A product name does not just appear in prose. It shows up in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;YAML configuration files&lt;/strong&gt; that define the product's metadata (ID, display name, icon, URL path)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontmatter&lt;/strong&gt; in every documentation page (&lt;code&gt;products:&lt;/code&gt; fields that link pages to their parent product)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Folder names&lt;/strong&gt; that determine URL paths (rename the folder, every link to that section breaks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirect rules&lt;/strong&gt; that map old URLs to new ones (miss one, and a user's bookmark hits a &lt;code&gt;404&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Component props&lt;/strong&gt; in MDX files that reference product IDs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Changelog entries&lt;/strong&gt; tied to product identifiers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SVG icons&lt;/strong&gt; named after the product&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-references&lt;/strong&gt; in other products' documentation ("see the [Old Name] docs for more")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshots&lt;/strong&gt; showing the product's old name in the dashboard UI, sidebar, breadcrumbs, and page headers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Change any of these incorrectly and either the build crashes, the UI breaks, links go dead, or users see the wrong name. Now multiply that by four products, some of which rename together (a parent product and its sub-products), and you start to see why this is not a find-and-replace job.&lt;/p&gt;

&lt;p&gt;On top of all this, some things must not be renamed at all: API field names, CLI tool names, code blocks, Terraform resource names, and historical changelog entries where the old name is the historically accurate one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the first tool through conversation
&lt;/h2&gt;

&lt;p&gt;The approach I took was conversational. I used OpenCode, an open-source AI coding agent that runs in the terminal, paired with Claude Opus 4.6 as the underlying model. Opus 4.6 might seem like overkill for documentation work, but in my experience lesser models struggle with the complexity of a large documentation site; they miss edge cases, misunderstand file relationships, and make more mistakes that you then have to fix. OpenCode lets you create reusable commands, essentially saved prompts with detailed instructions that the AI follows when you invoke them.&lt;/p&gt;

&lt;p&gt;I started by describing the problem to the AI: "I need to rename a product across the documentation site. Here is what the site structure looks like. Here is what needs to change. Here are the things that must not change." I also pointed the AI to our Wiki page with the project plan, so it had a clear picture of the scope and timeline of the project, as well as the names of the products being renamed.&lt;/p&gt;

&lt;p&gt;The first version of the rename command was rough. It missed edge cases, renamed things it should not have, and did not handle folder renames correctly. But each mistake became a rule. Each conversation refined the tool.&lt;/p&gt;

&lt;p&gt;Over several iterations, the rename command grew to handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Safe lists:&lt;/strong&gt; Terms that look like the old product name but must not be changed (API endpoints, CLI commands, code blocks, historical references).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bundled renames:&lt;/strong&gt; Products that need to be renamed together. When the parent product gets a new name, its sub-products need to follow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bridge phrasing:&lt;/strong&gt; Adding "(formerly Old Name)" after the first mention of the new name on each page, so users who know the old name can orient themselves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two-pass execution:&lt;/strong&gt; Pass 1 only touches files owned by the product being renamed. Pass 2 updates cross-references in other products' docs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch mode:&lt;/strong&gt; Content updates happen first on the original filenames (so diffs are clean and reviewable), then structural changes (folder renames, redirects) happen in a separate commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the point where the previous version of this story would have ended: one tool, built through conversation, ready to reuse. But as the project progressed, new problems kept surfacing, and each one pushed me to build another tool. What I did not anticipate was how much ground those tools would let me cover in such a short window of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  One tool became six
&lt;/h2&gt;

&lt;p&gt;As I started executing the actual renames, each new challenge pushed me back to the AI to build something new. None of the additional tools were planned upfront. Each one emerged from a specific problem I encountered during execution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The rename tool&lt;/strong&gt; is the core engine described above. To give you a sense of scale: the largest single rename touched 390 files across 5 commits, including 265 cross-reference files spanning 17 other products, 88 partial files, and roughly 70 render path updates. Just for one product.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The validation tool&lt;/strong&gt; runs 16 automated checks against the repository to catch build-breaking issues without needing to run the actual site build. It detects stale product references, missing redirects, broken internal links, missing SVG icons, and more. It auto-detects which products have been renamed on the current branch and scopes its checks accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The image scanner&lt;/strong&gt; uses the AI model's vision capability to scan documentation screenshots for outdated product names. It categorises images by type, resizes oversized ones (to avoid exceeding the AI memory limits), renders vectorized SVGs to PNG for visual review, and generates a full audit report.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The cleanup tool&lt;/strong&gt; is designed to run 6 months from now to strip out all the "(formerly Old Name)" bridge phrasing once users have had time to learn the new names. There are roughly 300 of those instances across all products.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the project-specific tools were built, I also created &lt;strong&gt;generic versions&lt;/strong&gt; of the rename and image audit tools, usable by anyone for any product rename, not just this specific project. They replace hardcoded product rules with interactive questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Catching what humans miss: rename validation
&lt;/h2&gt;

&lt;p&gt;The validation tool was one of the most valuable things I built. A product rename touches so many different file types and structures that a single missed reference can crash the build. Running the full Astro build to find out if there are issues takes time, and discovering a problem after the fact (after you have already opened a pull request and other people are waiting) is frustrating.&lt;/p&gt;

&lt;p&gt;The tool runs 16 checks, each with a severity level:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BUILD:&lt;/strong&gt; The site build will crash. A stale product ID in frontmatter, a changelog folder that does not match its YAML definition, a missing SVG icon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RUNTIME:&lt;/strong&gt; The build succeeds but the UI breaks. A component prop referencing a product ID that no longer exists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CORRECTNESS:&lt;/strong&gt; Wrong content served to users. A cross-reference link that still points to the old URL path, an anchor link that broke because a heading was renamed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;COSMETIC:&lt;/strong&gt; Minor issues, no user-visible breakage. A leftover mention of the old name in a code comment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Across all renames, the validator verified that roughly 80 API and CLI field names were correctly preserved in code blocks, that over 110 changelog historical prose entries were left unchanged, and that edge cases like Terraform resource names and community channel names were not accidentally renamed. For one product alone, 16 safe-list items were verified, with zero accidental renames of things that should have stayed the same.&lt;/p&gt;

&lt;p&gt;The practical value is straightforward: instead of waiting for a slow build to tell you what broke, the validator can give you the same answer in seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tool that makes me proud: image recognition
&lt;/h2&gt;

&lt;p&gt;This one came about from a question from another writer: "are we the ones that need to check the images the rename tool flagged?" Initially yes: the rename tool only found images referenced in the product and flagged them for manual review. But there were hundreds of images across all products, and manually checking each one was not realistic. So I started thinking: what if the AI could scan the images itself and tell us which ones actually needed an update?&lt;/p&gt;

&lt;p&gt;Opus 4.6 can read images. So I built a command that feeds documentation screenshots to its vision capability and asks it to check for specific text in UI elements: sidebar navigation, page headers, breadcrumbs, tab labels, buttons, tooltips, and the URL bar.&lt;/p&gt;

&lt;p&gt;The tool handles the practical challenges that come with scanning images at scale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It finds all image references across documentation pages and reusable content partials, deduplicates them, and maps each image back to the pages that use it.&lt;/li&gt;
&lt;li&gt;It triages images by type. Dashboard UI screenshots are scanned first (high priority). Third-party vendor integration screenshots are flagged for the user to decide (they show vendor UIs, not the documentation site's own product names). Hardware photos are deprioritized. SVG diagrams are text-searched with grep first, then visually scanned if needed.&lt;/li&gt;
&lt;li&gt;Oversized images are automatically resized because the model has resolution limits.&lt;/li&gt;
&lt;li&gt;Results come in batches of 10, with progress reports and the option to stop and resume.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In total, the tool processed 486 images. Of those, 310 were visually scanned by the AI, and 67 were flagged as needing a graphical update.&lt;/p&gt;

&lt;p&gt;For the largest product rename alone, 279 images were scanned at 100% coverage. 55 needed updates, 224 were clean. The scan found old names in places I would not have thought to look, including dozens of third-party vendor integration screenshots with the old product name embedded in firewall object names, configuration labels, and network diagrams. 17 reference architecture SVGs contained the old names in diagram labels and topology views.&lt;/p&gt;

&lt;p&gt;Two findings stand out.&lt;/p&gt;

&lt;p&gt;First, all 113 SVGs in the scan were fully vectorized. That means grep and text search were completely ineffective. The old product names were baked into vector path data, not searchable text nodes. The only way to find them was to render the SVGs to PNG and have the AI read them visually. Without this tool, those 113 images would have been silently skipped, and users would see outdated names in architecture diagrams indefinitely.&lt;/p&gt;

&lt;p&gt;Second, filename-based scanning gave a false sense of coverage. Among one set of vendor integration images, 33 had the old product name in their filename, but only 11 of those actually showed old names in the visible UI. Meanwhile, 10 additional images without the old name in their filename also contained old names. They were only found by the full visual scan.&lt;/p&gt;

&lt;p&gt;After flagging, disclaimer notes were automatically added to all affected images' documentation pages, letting readers know the screenshots are pending a graphical update.&lt;/p&gt;

&lt;h2&gt;
  
  
  The safety net: a redirect validator
&lt;/h2&gt;

&lt;p&gt;Renaming URLs across a large documentation site means hundreds of redirects. Getting even one wrong means a user hits a &lt;code&gt;404&lt;/code&gt; from a bookmark, a search engine result, or a link in another product's docs.&lt;/p&gt;

&lt;p&gt;For this I built something different: a standalone Python CLI tool, separate from the AI-powered commands. Redirect validation is deterministic. You do not need AI for "does this URL return &lt;code&gt;200&lt;/code&gt;?" You need a script that checks every URL methodically and reports what failed.&lt;/p&gt;

&lt;p&gt;The tool has four stages that mirror the project workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scrape:&lt;/strong&gt; Before any renames start, capture all current live URLs from the site using the sitemap. This creates a baseline of what exists today.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compare:&lt;/strong&gt; Cross-reference the baseline against a CSV mapping file that maps old URLs to new URLs. This finds gaps: URLs that exist on the live site but are not in the mapping, which means they would be missed during the rename.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate preview:&lt;/strong&gt; Before merging a rename pull request, test against the preview deployment. The tool checks that all new URLs return &lt;code&gt;200&lt;/code&gt; and all old URLs redirect (&lt;code&gt;301&lt;/code&gt;) to the correct new URLs. It supports per-product filtering, so each writer can validate their own rename independently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate production:&lt;/strong&gt; After merging, run the same checks against the live site to confirm everything works.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The CSV mapping file contained 349 URL mappings across all products. 71 redirect rules were added or updated, covering three types: dynamic splat redirects for entire product sections, static redirects for individual pages with renamed slugs, and updated destinations for existing rules that pointed to URLs being renamed.&lt;/p&gt;

&lt;p&gt;The tool also supports resuming from interruption, configurable request delays to avoid hammering the server, and JSON reports for each run.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the AI suggested that I had not considered
&lt;/h2&gt;

&lt;p&gt;The AI was helpful beyond executing instructions. In several cases it suggested design decisions I had not thought of.&lt;/p&gt;

&lt;p&gt;Batch mode was one. The AI suggested splitting each rename into content updates first (on the original filenames, so diffs are clean and easy to review), then structural changes (folder renames and redirects) in a separate commit. This makes the pull request reviewable; you can see exactly what text changed without file renames cluttering the diff.&lt;/p&gt;

&lt;p&gt;The two-pass approach was another. Separating product-owned files from cross-references was the AI's suggestion. It was initially designed to avoid merge conflicts, but as the project progressed its real value turned out to be producing more granular merge commits instead of one with hundreds of changes. And because the rename took so long to run, smaller commits also meant smaller chunks of work to review.&lt;/p&gt;

&lt;p&gt;Severity classification in the validator was also AI-driven. Not all failures are equal: a missed rename in the middle of one page is not the end of the world, but a stale YAML reference crashes the build. Categorizing them lets you prioritize.&lt;/p&gt;

&lt;p&gt;Image triage categories came from the AI too. Prioritizing dashboard screenshots over third-party vendor UIs was a practical suggestion that saved scanning time.&lt;/p&gt;

&lt;p&gt;The AI also made mistakes. Early versions of the rename command changed redirect source URLs, the thing you must never change, because that is the URL that external links and bookmarks point to. It also missed that a sub-product should rename alongside its parent product. It had to be taught the distinction between two products that had similar names but completely different underlying implementations. Each mistake became a rule in the command, making the next rename more reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  From project-specific to reusable
&lt;/h2&gt;

&lt;p&gt;After the project, I extracted the project-specific logic and created generic versions of the rename and image audit tools. The generic rename tool replaces hardcoded product tables with a series of questions: what is the old name, what is the new name, what terms should not be changed, are there related terms to rename alongside, what are the URL paths, has the dashboard been updated yet.&lt;/p&gt;

&lt;p&gt;Anyone facing a similar large-scale documentation rename can use these tools by providing their own answers instead of needing to understand the specifics of a particular project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools emerge from doing the work
&lt;/h2&gt;

&lt;p&gt;After working with AI tools for a while, I am always thinking of that next tedious, large-scale documentation task, and how AI can help with building a reusable workflow. This project is what happens, I think, from taking my own advice. Not one command, but six tools, a standalone Python validator, and a workflow that made it possible to rename four products in three days.&lt;/p&gt;

&lt;p&gt;The tools were not designed upfront. The image scanner was born when I realized I could not easily search screenshots. The validator came from a failed build caused by a missed YAML reference. The redirect tool came from the fear of breaking hundreds of bookmarks. Each problem, encountered during execution, became a conversation with AI, and each conversation became a tool.&lt;/p&gt;

&lt;p&gt;In three days: 695 files touched, 71 redirects added, 486 images audited, 349 URL mappings verified. The tools did not just save time; they made the project feasible. Without them, this would have been weeks of error-prone manual work.&lt;/p&gt;

&lt;p&gt;You do not need to plan an entire toolkit upfront. Start solving the immediate problem. As new problems come up, keep chatting with the AI. The tools will emerge naturally, and they will be better for it, because they are shaped by real needs, not hypothetical requirements.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>technicalwriting</category>
      <category>documentation</category>
      <category>automation</category>
    </item>
    <item>
      <title>I wanted to run my own AI. My laptop says not yet</title>
      <dc:creator>Márcio Florindo</dc:creator>
      <pubDate>Sat, 01 Aug 2026 09:52:25 +0000</pubDate>
      <link>https://dev.to/marciojpflorindo/i-wanted-to-run-my-own-ai-my-laptop-says-not-yet-5201</link>
      <guid>https://dev.to/marciojpflorindo/i-wanted-to-run-my-own-ai-my-laptop-says-not-yet-5201</guid>
      <description>&lt;p&gt;The pitch sells itself. An assistant that's entirely mine, running on my own machine, needing no connection, with nothing I type ever leaving the room. No company counting my tokens. No subscription. No outage on someone else's servers wrecking my afternoon (I'm looking at you, Anthropic, and your recurring outages). I wanted that badly enough that I spent a few months chasing it, and I want to tell you honestly where it left me.&lt;/p&gt;

&lt;h2&gt;
  
  
  24GB sounds like plenty until you load a model
&lt;/h2&gt;

&lt;p&gt;My Mac has 24GB of memory. This felt generous when I bought it, but then you load a real language model and that number shrinks fast. The system keeps its cut because the computer needs to keep running, and what's left for the model is closer to two-thirds of the sticker figure. The models actually worth trusting sit right at that ceiling or just past it. So you have to choose: a model that fits comfortably and isn't very bright, or a smarter one that leaves the machine gasping.&lt;/p&gt;

&lt;p&gt;The obvious fix is more memory, but have you seen memory prices lately? The timing could not be worse. Memory got expensive in a way that still surprises people who haven't shopped for it in a while. DRAM has roughly doubled in price since the start of 2025, and the analysts who watch this space think it could climb another 70% or so across 2026. Storage is worse in spots. The raw NAND wafers that SSDs are cut from are trading at something like eight times where they sat in the middle of last year, and a 4TB drive I'd have paid about $250 for not long ago now wants north of $700 — and because the market is so volatile right now, when this blog post goes live these numbers might be totally different because it's 2026 and who knows how much RAM and SSDs will cost.&lt;/p&gt;

&lt;p&gt;The reason for this insanity is also the reason behind half the stories in tech right now — AI. The big datacenter buildouts are on track to swallow around 70% of the world's high-end memory this year, and the cloud giants have signed contracts that lock up production years ahead. They are, quite literally, buying chips that haven't been made yet. Micron went as far as shutting down its consumer Crucial brand to aim everything at the AI market.&lt;/p&gt;

&lt;p&gt;Sit with that for a second. The same boom that makes a private little local model so appealing is the boom pricing most of us out of the hardware to run one properly. I'd find it funnier if it weren't my wallet.&lt;/p&gt;

&lt;h2&gt;
  
  
  I blamed the software first
&lt;/h2&gt;

&lt;p&gt;Before I accepted any of that, I was sure I'd just picked the wrong tools. So I went shopping for harnesses. If the LLM is the brain, the harness is what gives it hands — the tools that make it actually useful: Pi. OpenCode. Hermes. Each promised to be the one that made local AI click.&lt;/p&gt;

&lt;p&gt;I landed on Pi, and not for its features. The models simply ran best there, with quicker answers and less friction between me and whatever I'd asked. But the shopping taught me that the wrapper is not necessarily the bottleneck. I could swap them all day and hit the same wall, because the wall was the model and the memory holding it up. No interface fixes a model that hasn't got the room to think.&lt;/p&gt;

&lt;p&gt;So this leaves me at a place where I don't trust the local models I can run enough to lean on them for anything where being wrong can cost me a lot. A quick reword, a throwaway question, fine. But the second a task needs real judgment I'm back in the cloud almost before I've decided to be. I wanted to stop depending on paid assistants, and not because they're impossibly expensive. What I wanted was independence from the cloud companies, their whims and their outages. Tokens are so &lt;a href="https://www.tomshardware.com/tech-industry/artificial-intelligence/ai-costs-spike-as-subscriptions-hit-pricing-wall-firms-turn-towards-chinese-llms-open-source-models-to-extend-budget" rel="noopener noreferrer"&gt;heavily subsidized&lt;/a&gt; right now that these more powerful models will probably price me out before long.&lt;/p&gt;

&lt;h2&gt;
  
  
  What my local AI is actually good for
&lt;/h2&gt;

&lt;p&gt;It's not all bad news, though. One job the local model does frequently, and does well, is analyzing job ads for me.&lt;/p&gt;

&lt;p&gt;My &lt;a href="https://marcioflorindo.com/ai-got-me-laid-off-so-i-built-an-ai-to-get-me-hired.html" rel="noopener noreferrer"&gt;job hunt runs as a background batch&lt;/a&gt;. A script pulls the listings, bins the obvious junk, and hands what's left to the model on my laptop, which reads each one against a brief I wrote and tells me how good a fit it looks. Free and offline. My CV never leaves the machine, and it works whether there are AI outages in the cloud or not. It's a bit of the independence I was chasing, just at a far smaller scope than I'd hoped for.&lt;/p&gt;

&lt;p&gt;It only works because of how the newer models are built. The Gemma one I use is a mixture-of-experts design, which in plain terms means it only wakes the slice of itself a given question needs instead of firing the whole thing at once. It's light enough to genuinely reason on my hardware without grinding for an age, and takes about thirty seconds per ad. For something humming away while I get on with my day, thirty seconds is nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, not yet
&lt;/h2&gt;

&lt;p&gt;I haven't written off local AI. I'm frustrated by the distance between what I wanted and what 24GB plus a brutal memory market will give me today. But the mixture-of-experts trick already moved that line once, and hopefully it'll move again. Models keep getting smarter per gigabyte rather than only bigger, prices will ease eventually, and some version of me a couple of years out probably runs all of this locally without thinking twice about it. For now I've got exactly one workflow living on my own hardware while everything else still phones home. That one's mine, completely. It's a start.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>machinelearning</category>
      <category>hardware</category>
    </item>
    <item>
      <title>Check the research before you read it</title>
      <dc:creator>Márcio Florindo</dc:creator>
      <pubDate>Thu, 30 Jul 2026 09:52:30 +0000</pubDate>
      <link>https://dev.to/marciojpflorindo/check-the-research-before-you-read-it-4ena</link>
      <guid>https://dev.to/marciojpflorindo/check-the-research-before-you-read-it-4ena</guid>
      <description>&lt;p&gt;When a coding agent gets something wrong, you find out fast. The build fails, a test goes red, the page renders blank, or something else falls over loudly enough that you can't miss it. When a research agent gets something wrong, you get a beautifully formatted brief filled with wrong facts.&lt;/p&gt;

&lt;p&gt;And documentation work runs on research.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one sentence I gave this in February
&lt;/h2&gt;

&lt;p&gt;Back in &lt;a href="https://marcioflorindo.com/research-command-tickets" rel="noopener noreferrer"&gt;February&lt;/a&gt; I wrote about a command I'd built to do the research phase of a documentation ticket. You handed it a ticket ID and it pulled the ticket with every comment on it, chased the linked engineering issues, went hunting through the internal wiki for a PRD or a spec, read the pages that were already published, and gave back a structured brief with open questions at the bottom.&lt;/p&gt;

&lt;p&gt;I was pleased with it. It saved hours of clicking between tools, and it surfaced things I'd have missed, because our internal wiki had a terrible search engine.&lt;/p&gt;

&lt;p&gt;Rereading that post, the entire section on what could go wrong is one sentence: you still need to review the information and check with stakeholders to make sure the draft is accurate. That's true, and nowhere near enough. If you're building something like this, that sentence is where most of your risk lives.&lt;/p&gt;

&lt;h2&gt;
  
  
  The brief is the most dangerous thing in your pipeline
&lt;/h2&gt;

&lt;p&gt;Everything downstream is built on it. You read the brief, you write the draft from it, and the draft goes to an engineer who reads it as your understanding of their feature. They're reviewing your prose, not the retrieval that produced it.&lt;/p&gt;

&lt;p&gt;So an error in the brief doesn't sit still waiting to be found. It gets written into a page and approved by someone who reasonably assumes you did the reading. Somewhere in that chain it stops being the tool's mistake and becomes your judgement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading it carefully won't save you
&lt;/h2&gt;

&lt;p&gt;Prose has no failing state. A citation to a PRD that doesn't exist is formatted exactly like a citation to one that does. A stakeholder attributed to the wrong team reads perfectly well. Nothing goes red.&lt;/p&gt;

&lt;p&gt;And you're reading the brief because you don't know the material yet, which was the whole reason you asked for it. So you're checking a summary before you've read the sources behind it, about a system you're still forming a picture of, at the exact moment you're least equipped to notice something missing.&lt;/p&gt;

&lt;p&gt;I don't know about you, but I tend to trust a tidy document more than a messy one. Structure is what these tools are genuinely good at. Accuracy is what they're worst at. Which means the instinct you'd normally use to catch sloppy work is aimed at the wrong signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put the skeptic in front of the reader
&lt;/h2&gt;

&lt;p&gt;If you already end agent work with a skeptical pass, handing the output to a second agent whose only job is to attack it, you're probably running it last. For research, that's too late. Set it up so the research agent spawns a fresh adversarial one as soon as the brief exists, and have it fact-check the brief before anything reaches you.&lt;/p&gt;

&lt;p&gt;Keep the pass narrow. Not "is this any good", but: does each claim trace back to something actually retrieved, does anything here contradict anything else here, is the information up to date or based on a dusty page abandoned years ago, and are the gaps marked as gaps?&lt;/p&gt;

&lt;p&gt;That last one carries most of the weight. Ask an agent for a research brief and you will get a research brief. It won't hand you three quarters of one and tell you the rest isn't there. The failure worth guarding against is the smooth, complete-looking answer where the honest output was "the wiki has nothing on this, go ask a person."&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;It's slower, which might seem absurd for a workflow built to go faster. That's still far quicker than finding those forty wiki pages yourself, and you get something back for the wait.&lt;/p&gt;

&lt;p&gt;It won't make the brief true. What a fresh pair of eyes catches is facts that trace nowhere, claims resting on thin evidence, and gaps that got smoothed over. Those are the ones I kept running into.&lt;/p&gt;

&lt;p&gt;What you write still goes to someone who knows the system better than you do, and that review isn't optional. The skeptical pass just means you arrive at that conversation believing fewer things for no reason.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devrel</category>
      <category>documentation</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
