<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>BekahHW</title>
    <description>Code. Community. Content.</description>
    <link>https://bekahhw.com/</link>
    <atom:link href="https://bekahhw.com//feed.xml" rel="self" type="application/rss+xml" />
    <language>en-us</language>
    <managingEditor>rhawrot@gmail.com (BekahHW)</managingEditor>
    <webMaster>rhawrot@gmail.com (BekahHW)</webMaster>
    <lastBuildDate>Thu, 09 Jul 2026 00:49:00 +0000</lastBuildDate>
    
      <item>
        <title>Ownership, Not Origin</title>
        <description>&lt;p&gt;&lt;em&gt;A Treatise on Writing in the AI Age, Part 5&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let me go back to where this started. A moderator on Dev.to flagged my post and told me to disclose AI-generated work. Four essays later, I can finally say precisely what was wrong with that moment.&lt;/p&gt;

&lt;p&gt;It wasn’t that they were rude. They weren’t. It wasn’t even that they were mistaken about my process, though they were. It’s that they were asking a question with no useful answer. “Did AI touch this text” tells you nothing about whether the text deserves your trust. The moderator was auditing my tools when the only thing worth auditing was my thinking.&lt;/p&gt;

&lt;p&gt;So here is the standard I’m arguing for, as plainly as I can put it.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Judge writing by ownership, not origin.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;what-ownership-means&quot;&gt;What ownership means&lt;/h2&gt;

&lt;p&gt;Ownership isn’t a feeling. It’s a set of claims a writer makes by publishing, and it’s checkable.&lt;/p&gt;

&lt;p&gt;When I put my name on a piece, I’m claiming the ideas are mine or credited to whoever they came from. I’m claiming I verified what I stated as fact. I’m claiming I can defend every argument in it, extend it, answer the hard comment underneath it. I’m claiming that anything presented as my experience actually happened to me. And I’m accepting that if any of that turns out false, the failure is mine. No tool absorbs the blame.&lt;/p&gt;

&lt;p&gt;Notice what’s absent from that list. Nothing about which hands or machines shaped the sentences. A ghostwritten memoir can pass this test. A fully hand-typed post full of unverified claims fails it. The test tracks what readers actually care about, which is whether a mind stands behind the words.&lt;/p&gt;

&lt;p&gt;Notice also what’s demanding about it. Ownership is a higher bar than origin, not a lower one. Typing every word yourself is easy to satisfy and proves nothing. Being able to defend every word is hard, and it’s exactly what AI-era writing threatens when it goes wrong. The writer who pastes a generated draft they barely read fails the ownership test spectacularly. I’m not offering AI users an escape hatch. I’m offering everyone a stricter standard aimed at the right target.&lt;/p&gt;

&lt;h2 id=&quot;the-verification-objection&quot;&gt;The verification objection&lt;/h2&gt;

&lt;p&gt;Now the strongest objection, the one I promised myself I’d answer honestly. A skeptic says: this is lovely, but readers can’t verify ownership any more than moderators can verify AI use. You’ve traded one unenforceable standard for another.&lt;/p&gt;

&lt;p&gt;Here’s my answer. Ownership was never verified by inspection. It’s verified by accountability over time, and we already know how that works because it’s how writing trust has always worked.&lt;/p&gt;

&lt;p&gt;You trust a writer because they respond substantively when challenged in the comments. Because their body of work holds together, one piece building on another. Because when they got something wrong last year, they said so and corrected it. Because their claims, when you happened to check one, checked out. Because the community around them has watched them think in public for years.&lt;/p&gt;

&lt;p&gt;None of that requires process forensics. All of it is visible. A writer faking ownership can survive one post, maybe several. They cannot survive sustained engagement, because you can’t defend thinking you didn’t do. The comment section finds you out. The follow-up question finds you out.&lt;/p&gt;

&lt;p&gt;Enforcement follows the same logic. Platforms can’t police process, and shouldn’t try. They can absolutely police the checkable claims. Plagiarism is detectable in the artifact. Fabricated facts are checkable. A writer who can’t engage with substantive challenges to their own post is telling you something. Those levers exist today. They’re just not being pulled, because badge-printing is easier.&lt;/p&gt;

&lt;h2 id=&quot;what-honest-transparency-looks-like&quot;&gt;What honest transparency looks like&lt;/h2&gt;

&lt;p&gt;Am I against all disclosure, then? No, and this distinction matters.&lt;/p&gt;

&lt;p&gt;I share my process frequently in conversations and writing, and I plan to keep doing it. I talk about how I use AI to stress-test arguments, where it saved me hours, where it produced garbage, and I threw the garbage out. That kind of transparency teaches. It helps others develop the judgment that the stigma machine is currently preventing anyone from developing.&lt;/p&gt;

&lt;p&gt;But there’s a world of difference between transparency I offer and a confession I’m compelled to make. Offered, it’s craft talk between writers, the same as explaining my outlining habit or my editing passes. Compelled, under stigma, it’s a mark. Same information, opposite meaning. The mandate poisons the very openness it claims to want, because nothing kills honest process-sharing faster than making it an admission of guilt.&lt;/p&gt;

&lt;p&gt;If platforms want a disclosure culture, the path isn’t a checkbox. It’s destigmatization. Make process talk normal and interesting rather than incriminating, and writers will tell you more than any policy could extract.&lt;/p&gt;

&lt;h2 id=&quot;writing-in-the-age-of-good-tools&quot;&gt;Writing in the age of good tools&lt;/h2&gt;

&lt;p&gt;I’ve been teaching people to write, in one form or another, for most of my adult life. College classrooms, developer communities, my own kids at the kitchen table. And here’s what I believe after all of it. Writing was never sacred because of the typing. It was sacred because a person committed their mind to the page and signed their name to the result.&lt;/p&gt;

&lt;p&gt;That commitment is still available to every one of us. No tool grants it and no tool revokes it.&lt;/p&gt;

&lt;p&gt;So publish the post. Use the tools that make your thinking sharper and refuse the uses that replace your thinking. Verify what you claim. Credit who you learned from. Stand in the comments and defend what you wrote. Own it, all of it, and let the origin police tire themselves out.&lt;/p&gt;

&lt;p&gt;And if you’ve been sitting on a draft because you used AI somewhere in the process and the badge scared you off, I’ll leave you with the only disclosure question that ever mattered.&lt;/p&gt;

&lt;p&gt;Is it yours?&lt;/p&gt;

&lt;p&gt;If it is, hit publish.&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Jul 2026 13:00:00 +0000</pubDate>
        <link>https://bekahhw.com//ownership-not-origin</link>
        <guid isPermaLink="true">https://bekahhw.com//ownership-not-origin</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Writing</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>The Wrong Problem</title>
        <description>&lt;p&gt;&lt;em&gt;A Treatise on Writing in the AI Age, Part 4&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This story won’t resonate with everyone, but I’ve heard it enough to know that it’s uncomfortably common. You’ve published something you worked hard on. It could be a blog post, a twitter thread, a video, a course, some sort of content that you’ve put time and attention into. Then weeks or even days or hours later, you find your idea living in someone else’s post. I’m not talking about having the same idea as someone else. I’m talking about someone ripping your ideas, presenting them as their own, and taking credit for them. There’s no citation, link, or acknowledgment that you even exist.&lt;/p&gt;

&lt;p&gt;On many platforms, there’s a strong stance against plagiarism, including removal of the post, suspensions, and bans. Let’s look closely at what makes that a good policy. It targets the harm itself. It’s checkable in the artifact. And it never asks what tool was involved. Steal by hand or steal by model, the violation is identical, because the reader’s injury is identical.&lt;/p&gt;

&lt;p&gt;Now hold the AI disclosure mandate next to it. No harm requirement. Nothing checkable in the artifact, which is why enforcement runs on appearance. And the tool isn’t incidental to the rule. The tool &lt;em&gt;is&lt;/em&gt; the rule. The same platform wrote both policies, and only one of them protects anyone.&lt;/p&gt;

&lt;p&gt;That asymmetry is the tell. Platforms have decided that a machine touching your own ideas is a policing priority, while a human taking someone else’s ideas is a shrug. Whatever problem they think they’re solving, it isn’t reader betrayal, because this is what betrayal actually looks like.&lt;/p&gt;

&lt;h2 id=&quot;what-actually-harms-readers&quot;&gt;What actually harms readers&lt;/h2&gt;

&lt;p&gt;Set aside tools entirely and ask what makes writing bad for the person reading it.&lt;/p&gt;

&lt;p&gt;Ideas presented as original when they were lifted from someone uncredited, claims stated confidently that nobody verified, content written to game an algorithm rather than to say anything. Padding, filler, the eight-hundred-word wind-up before the answer. Recycled conventional wisdom wearing a bold headline.&lt;/p&gt;

&lt;p&gt;Every one of those predates AI. Every one of them is thriving right now, by human and machine hands alike. And every one of them is measurable in the artifact itself, no process forensics required. You don’t need to know what tool produced an unverified claim to know it’s unverified.&lt;/p&gt;

&lt;p&gt;Protecting readers from those harms would mean citation norms with teeth. Plagiarism response that actually responds. Quality signals that reward substance. And I want to be fair here, because that’s brutally hard work. Slow, expensive, full of judgment calls, and most platform teams are small, stretched thin, and staring down a content flood they didn’t create. I have real sympathy for anyone holding that backlog.&lt;/p&gt;

&lt;p&gt;A disclosure checkbox is none of those things. It ships in a sprint.&lt;/p&gt;

&lt;h2 id=&quot;the-fear-response&quot;&gt;The fear response&lt;/h2&gt;

&lt;p&gt;I don’t think platform teams are cynical. I think they’re afraid, and I understand why. AI dropped the cost of producing plausible text to nearly zero, and every open publishing platform is staring at a real flood of low-effort content. Something had to be done.&lt;/p&gt;

&lt;p&gt;But look at what “something” became. The flood is a &lt;em&gt;quality&lt;/em&gt; problem. Low-effort content was always the enemy, and AI just made it cheaper to produce. The honest response is to get better at detecting low effort. That’s hard. So instead, platforms reached for a proxy. AI produces the slop, therefore mark the AI.&lt;/p&gt;

&lt;p&gt;The proxy fails in both directions. It misses the humans who were producing slop by hand all along and will keep producing it, badge-free. And it catches the writers using AI carefully in service of real thinking, who are producing exactly the substance the platform claims to want.&lt;/p&gt;

&lt;p&gt;We’ve seen this pattern before, and not just in writing. When a real problem is hard to measure, institutions measure something adjacent and easy, then defend the metric instead of the mission. Every developer who’s been judged on lines of code knows how this story goes. The metric becomes the target, the target gets gamed, and the original problem sits there untouched.&lt;/p&gt;

&lt;h2 id=&quot;the-problem-were-not-allowed-to-name&quot;&gt;The problem we’re not allowed to name&lt;/h2&gt;

&lt;p&gt;There’s one more layer, and it’s the uncomfortable one.&lt;/p&gt;

&lt;p&gt;Some of the resistance to AI-assisted writing isn’t about readers at all. It’s about writers, and about identity. If writing well took years to learn, and a tool now closes part of that gap for others, the instinct to defend the moat is human and understandable. We’ve never accepted “it threatens my position” as an argument in open source, in education, in any community worth belonging to. Gatekeeping dressed as quality control is still gatekeeping. The developers who sneered at Stack Overflow users, the photographers who sneered at digital, the writers who sneered at bloggers. History doesn’t remember the moat-defenders kindly, and it definitely doesn’t remember them as right.&lt;/p&gt;

&lt;p&gt;The question was never how to keep writing hard. It was how to keep writing honest. Those are different projects, and the disclosure mandate serves the first while claiming the second.&lt;/p&gt;

&lt;p&gt;So if tool-marking is the wrong standard, what’s the right one? What would a norm look like that catches the plagiarist and the fabricator, protects the newcomer and the craftsperson, and doesn’t care which keyboard the sentences came through?&lt;/p&gt;

&lt;p&gt;That’s the last essay, and it’s the one this whole series has been walking toward.&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Jul 2026 12:00:00 +0000</pubDate>
        <link>https://bekahhw.com//the-wrong-problem</link>
        <guid isPermaLink="true">https://bekahhw.com//the-wrong-problem</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Writing</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>The Stigma Machine</title>
        <description>&lt;p&gt;&lt;em&gt;A Treatise on Writing in the AI Age, Part 3&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s do a small experiment. Imagine two identical blog posts. They have the same ideas, structure, sentences. Everything is the same except example one has a small grey badge that says, “AI-assisted” and the other example doesn’t.&lt;/p&gt;

&lt;p&gt;Which one do you read more generously? Which author do you assume worked harder? If you shared one with your team, which would it be?&lt;/p&gt;

&lt;p&gt;If you hesitate, you understand why “it’s just a label” is a fiction. A label is never just a label when it arrives carrying a verdict.&lt;/p&gt;

&lt;h2 id=&quot;what-the-badge-actually-says&quot;&gt;What the badge actually says&lt;/h2&gt;

&lt;p&gt;In theory, an AI disclosure badge is neutral metadata, like a timestamp or a word count. But in practice as things stand in 2026, it reads as a confession. It says this writer took a shortcut. It says “be skeptical of this one.” It says the person behind these words is a little less of a writer than the ones without the badge, and depending on who’s reading, maybe a little less honest too.&lt;/p&gt;

&lt;p&gt;You don’t have to take my word for the verdict part, because sometimes the platform says it out loud. On Dev.to, the disclosure tag for AI-assisted articles is #ABotWroteThis. Assisted, not just generated. For reference, when I put my post into ZeroGPT, it’s identified as human-written except 6.2%.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/2026/zerogpt-human-written.png&quot; alt=&quot;A ZeroGPT results gauge reading &amp;quot;Your Text is Human written&amp;quot; with 6.2% flagged as AI GPT.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Develop the ideas yourself, verify every claim, edit for hours, and if a model helped anywhere in your process, the prescribed label on your work reads &lt;em&gt;a bot wrote this&lt;/em&gt;. That’s not metadata. That’s a verdict with a hashtag. And if you decline to apply it, the guidelines note that moderators can attach it to your post for you. The platform reserves the right to put words on your work that you believe are false.&lt;/p&gt;

&lt;p&gt;That’s not what disclosure advocates intend. Intent doesn’t matter here. Stigma lives in reception, not intention, and right now the reception is unambiguous. Writers know it, which is why disclosure feels less like transparency and more like being asked to pin a note to your own work saying “discount this.”&lt;/p&gt;

&lt;p&gt;So the mandate creates an impossible choice for exactly the writers doing things right. Disclose honestly and watch readers disengage before evaluating a single idea. Or stay silent and risk being flagged, accused, and moderated.&lt;/p&gt;

&lt;p&gt;The one on my post spelled it out. Comply, or admins may lower your post’s score so fewer people see it, or unpublish it altogether. The badge suppresses your work socially. Refusing it suppresses your work algorithmically. There’s no door out of that room.&lt;/p&gt;

&lt;p&gt;The careless never face this choice. They just don’t disclose. Stigma-backed mandates punish honesty and reward shamelessness. That’s not a side effect. That’s the predictable mechanics of the design.&lt;/p&gt;

&lt;h2 id=&quot;the-accusation-engine&quot;&gt;The accusation engine&lt;/h2&gt;

&lt;p&gt;And the enforcement side is worse, because AI use isn’t visible. A moderator cannot see your process. They can’t see the weeks of thinking, the validated research, the edit passes. All they can inspect is the artifact, so enforcement inevitably becomes inference. Does this prose &lt;em&gt;feel&lt;/em&gt; generated?&lt;/p&gt;

&lt;p&gt;Think about what that selects for. Clean structure, polished transitions, consistent tone, error-free grammar. The signals moderators and detection tools treat as machine-like are the same signals writers spend years learning to produce. We’ve built a system where craft itself is evidence against you.&lt;/p&gt;

&lt;p&gt;I felt this personally when my own post got flagged. But the people I worry about aren’t established writers with communities who’ll vouch for them. It’s the newer writers. The developer publishing their third post, still unsure they belong, told by a moderator that their work doesn’t look like their own. Some of them will add the badge to avoid trouble. Some will stop publishing. I’ve spent years telling those exact people to hit publish. This system tells them something different.&lt;/p&gt;

&lt;h2 id=&quot;the-best-case-for-the-other-side&quot;&gt;The best case for the other side&lt;/h2&gt;

&lt;p&gt;Now the part where I argue against myself, because this series doesn’t deserve to survive if it can’t.&lt;/p&gt;

&lt;p&gt;The strongest argument for disclosure isn’t about quality. It’s about trust. Readers form relationships with writers. When you read someone’s personal essay about burnout, part of what moves you is the belief that a human lived it and a human shaped it. If you later learned a machine wrote it, you’d feel betrayed, and that feeling would be legitimate. Deception through implied authorship is real, and “caveat lector” is a cold answer to it.&lt;/p&gt;

&lt;p&gt;I think that argument is right. I want to be honest about that.&lt;/p&gt;

&lt;p&gt;Where it goes wrong is the leap from “deception is bad” to “tool disclosure prevents it.” The betrayal in that scenario isn’t the tool. It’s the false implicit claim. A writer who presents machine-generated experiences as lived ones is lying about something specific, the same way a writer who fabricates a story by hand is lying. We already have a name for that, and it isn’t “AI use.” Meanwhile the writer who used AI to sharpen an essay about their own real burnout hasn’t deceived anyone about anything a reader actually cares about.&lt;/p&gt;

&lt;p&gt;The mandate can’t tell those two writers apart. The badge marks both, deters the honest one, and does nothing to the liar, who was already comfortable lying.&lt;/p&gt;

&lt;p&gt;The truth is, trust between writers and readers is worth protecting. That’s exactly why we can’t outsource it to a checkbox that measures the wrong thing.&lt;/p&gt;

&lt;h2 id=&quot;what-stigma-costs-us&quot;&gt;What stigma costs us&lt;/h2&gt;

&lt;p&gt;Here’s what keeps me up about this. AI, used well, can make writing &lt;em&gt;better&lt;/em&gt;. It can push you to consider the counterargument you were avoiding. It can surface the source you’d never have found. It can free the hours you were spending on mechanical polish and give them back to thinking. Used badly, it produces exactly the formulaic sludge everyone fears. The difference is entirely in the writer.&lt;/p&gt;

&lt;p&gt;Stigma erases that difference. It teaches a generation of writers that the tool is shameful rather than teaching them what shameful use of the tool looks like. We’re not developing judgment. We’re developing secrecy.&lt;/p&gt;

&lt;p&gt;And while all this energy pours into marking who touched which tool, the problems that actually betray readers go unpoliced. That’s the next essay. Because the most damning thing about the stigma machine isn’t what it does. It’s what it lets platforms avoid doing.&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Jul 2026 11:00:00 +0000</pubDate>
        <link>https://bekahhw.com//the-stigma-machine</link>
        <guid isPermaLink="true">https://bekahhw.com//the-stigma-machine</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Writing</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>The Disclosure Double Standard</title>
        <description>&lt;p&gt;&lt;em&gt;A Treatise on Writing in the AI Age, Part 2&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For most people, writing a blog post isn’t solitary work. It’s start with talking to your friend over coffee and the question they ask that changes your perspective and leads you to reframe the whole thing. Then there’s the spellchecker and grammarly that give you one-click fixes and improve your voice. If you’re lucky enough, you have an editor or a teammate or colleague willing to read it over and give you feedback that leads to your third or fourth or fifth revision. And none of them appears in your byline. You’ve never been asked to disclose a single one.&lt;/p&gt;

&lt;p&gt;But now that AI has entered the arena, you’re expected to wear a badge.&lt;/p&gt;

&lt;h2 id=&quot;the-rule-we-never-had&quot;&gt;The rule we never had&lt;/h2&gt;

&lt;p&gt;Ghostwriting is the clearest tell. For a century, public figures have published books they didn’t write. Not books they wrote with help. Books where someone else produced every sentence, and the named author’s contribution was a series of interviews and a final approval. The industry is respectable, professionalized, and almost entirely undisclosed. Readers buy the memoir, connect with the story, and nobody calls it fraud.&lt;/p&gt;

&lt;p&gt;Let’s be clear about what that means. Our writing culture has already decided that full delegation of the actual writing is acceptable, as long as the ideas and the accountability belong to the named author.&lt;/p&gt;

&lt;p&gt;So the standard was never “you must write every word yourself.” It couldn’t have been. Editors restructure. Translators rewrite entirely. Co-authors merge beyond untangling. Writing has always been more collaborative than the solitary-genius myth admits, and readers have always been fine with it.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The disclosure mandate invents a purity standard that never existed, then applies it to exactly one tool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;the-label-that-cant-label&quot;&gt;The label that can’t label&lt;/h2&gt;

&lt;p&gt;Even if we granted that AI is different in kind, the mandate would still fail on its own terms, because “AI-assisted” doesn’t describe anything.&lt;/p&gt;

&lt;p&gt;Consider what fits under that one flag. Fixing typos. Brainstorming titles. Summarizing a paper you then read yourself. Arguing with a chatbot to stress-test your thesis. Generating an outline. Generating a draft you rewrite completely. Generating a draft you don’t.&lt;/p&gt;

&lt;p&gt;Those are wildly different acts with wildly different implications for the reader. Some of them involve less delegation than hiring an editor. One of them is closer to ghostwriting. A single checkbox flattens all of it into one undifferentiated confession.&lt;/p&gt;

&lt;p&gt;A label that carries no information isn’t disclosure. It’s ritual.&lt;/p&gt;

&lt;h2 id=&quot;weve-been-here-before&quot;&gt;We’ve been here before&lt;/h2&gt;

&lt;p&gt;Every writing tool arrives to the same funeral music.&lt;/p&gt;

&lt;p&gt;Photography was going to kill painting, and for decades photographers fought to be considered artists at all, because the machine did the work. Word processors were going to ruin prose, because revision would become too easy and writers would stop thinking before typing. Calculators were going to destroy mathematical minds. Spellcheck was going to breed illiterates.&lt;/p&gt;

&lt;p&gt;Each time, the panic confused the tool with the thinking. Each time, we eventually figured out that the craft didn’t live in the mechanical layer. Painting survived because painting was never just image production. Writing survived the word processor because writing was never just typing.&lt;/p&gt;

&lt;p&gt;I don’t say this to wave away every concern about AI. I recognize that AI can hollow out writing in a way spellcheck can’t, if you let it do your thinking instead of your typing. That distinction matters enormously. It’s the difference between a tool and a replacement.&lt;/p&gt;

&lt;p&gt;But notice what that distinction is. It’s not about which tool touched the text. It’s about who did the thinking.&lt;/p&gt;

&lt;p&gt;Which is exactly what a disclosure checkbox cannot capture.&lt;/p&gt;

&lt;h2 id=&quot;what-the-double-standard-reveals&quot;&gt;What the double standard reveals&lt;/h2&gt;

&lt;p&gt;Why does one tool get a mandate when a century of ghostwriting got a shrug?&lt;/p&gt;

&lt;p&gt;Because the mandate was never derived from a principle. If platforms had started from “readers deserve to know how work gets made,” they’d have built process transparency for everything, and the absurdity would have been obvious immediately. Imagine the disclosure form: Did you discuss ideas with your spouse? Did you read the competitor’s post first? Did an editor rewrite the conclusion?&lt;/p&gt;

&lt;p&gt;Nobody wants that, because readers never needed it. What readers needed was a writer who stood behind the work.&lt;/p&gt;

&lt;p&gt;There’s even a version of this buried in my own story, and nobody flagged it. I found it myself, reading the guidelines the moderation comment linked. My post went out under my personal account and talked about how one of the features we just launched helps to fill a gap teams face when it comes to writing skills. As far as I understand, that’s allowed on the platform. Company blogs share product content there every day. But the AI guidelines add a special rule. AI-assisted articles shouldn’t promote any business, program, or course, including your own. Trace the logic. A human-drafted post can discuss the product it’s about. The identical post with AI anywhere in the process cannot. Same words, same reader, different rules, and the only variable is the tool. That’s not reader protection. That’s a purity test.&lt;/p&gt;

&lt;p&gt;The AI mandate exists because AI is new and frightening, and new fears demand visible responses. It’s not a standard. It’s a nervous gesture wearing a standard’s clothes.&lt;/p&gt;

&lt;p&gt;What if we asked the question the mandate skips? Not “did a machine touch this text” but “did a mind own it.” That question has an answer worth knowing. The next essay is about what happens when we settle for the wrong question instead, because the cost isn’t hypothetical. It has a name, and the name is stigma.&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Jul 2026 10:00:00 +0000</pubDate>
        <link>https://bekahhw.com//the-disclosure-double-standard</link>
        <guid isPermaLink="true">https://bekahhw.com//the-disclosure-double-standard</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Writing</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>Why We Write</title>
        <description>&lt;p&gt;&lt;em&gt;A Treatise on Writing in the AI Age, Part 1&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Last week, one of my blog posts was flagged on Dev.to.&lt;/p&gt;

&lt;p&gt;I want to be clear that this series is not specifically about that event or the people involved. It’s a broader exploration of using AI during the writing process and rules around labeling any AI-assisted writing. This just happens to be a relevant example. Everyone was doing their job exactly the way the policy asked. That’s the point. A system can be staffed entirely by decent people and still be built wrong.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/2026/dev-to-moderator-flag.png&quot; alt=&quot;Sloan the DEV Moderator flags a post for AI assistance and asks the author to add a disclaimer per DEV&apos;s guidelines, warning that failure to comply could lower the post&apos;s visibility or get it unpublished.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Did I use AI in the process? Sure, I have been almost since ChatGPT came out. It’s been my brainstorm partner, my editor, my devil’s advocate, research assistant, and more. But what’s remained the same in all of my work is that the ideas were mine, they’re driven by my own experiences, and the desire to share and teach others. I validated every piece of research myself, edited draft after draft, and shaped the whole thing into something I was proud to publish. Hours went into it. This wasn’t a drive-by prompt-and-paste. That’s not my M.O.&lt;/p&gt;

&lt;p&gt;The irony still gets me. &lt;a href=&quot;https://papercompute.com/blog/stop-writing-skills-from-memory/&quot;&gt;The post&lt;/a&gt; argued that reconstructing work from memory is lossy and that what you think happened is missing exactly what matters. That evidence beats confident guessing. None of the work I did is visible to the moderator. They had a feeling about my prose or it was flagged by some tool and a policy that told them to act on it.&lt;/p&gt;

&lt;p&gt;I’ve spent the last 7 years helping developers find their people and their voice online. I’ve told hundreds of new writers that their perspective matters, that they should hit publish, that the community will meet them with generosity. So when a community I’ve championed looked at my work and saw a suspect instead of a writer, I didn’t just feel annoyed. I felt something closer to grief.&lt;/p&gt;

&lt;p&gt;But this isn’t a post about my hurt feelings. It’s a post about a question we’ve stopped asking, and before moving into tech, I taught for years in my College English 101 classes.&lt;/p&gt;

&lt;p&gt;Why do we write at all?&lt;/p&gt;

&lt;p&gt;If we strip writing down to first principles, it does three things.&lt;/p&gt;

&lt;p&gt;We write to &lt;em&gt;communicate&lt;/em&gt;. To take something that lives in your mind and make it live in another.&lt;/p&gt;

&lt;p&gt;We write to &lt;em&gt;connect&lt;/em&gt;. Every blog post is a hand extended to a stranger. Someone reads your story when they’re going through the same thing and feels less alone.&lt;/p&gt;

&lt;p&gt;And we write to &lt;em&gt;think&lt;/em&gt;. Writing isn’t the transcript of thought. It’s the act of it. Anyone who has started an essay believing one thing and finished it believing another knows this.&lt;/p&gt;

&lt;p&gt;Those are the ends writing serves. Which means they’re also the standard every writing rule should be judged against. Does this norm help ideas move between minds? Does it help people find each other? Does it deepen thinking?&lt;/p&gt;

&lt;h2 id=&quot;the-rule-that-fails-its-own-test&quot;&gt;The rule that fails its own test&lt;/h2&gt;

&lt;p&gt;A disclosure mandate doesn’t help communication. The label “AI-assisted” tells a reader almost nothing because it collapses an entire spectrum of uses into a single flag. Spellcheck, brainstorming, research support, and full generation all wear the same badge. A label that can’t distinguish between them isn’t information.&lt;/p&gt;

&lt;p&gt;It doesn’t help connection either. Right now that label carries a stigma. It marks a writer as lesser, maybe even dishonest, before a single idea gets evaluated. Readers are trained to disengage the moment they see it. That’s not transparency building trust.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;That’s a scarlet letter dressed up as a courtesy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it certainly doesn’t deepen thinking, because the platforms enforcing it have never asked about any of the other hands in our work. Nobody discloses Grammarly. Nobody discloses the friend who talked through the argument with them over coffee, or the editor who restructured the whole second half. Ghostwriting, where someone else writes every word, has been a respectable industry for a century. No badge required.&lt;/p&gt;

&lt;p&gt;So the mandate isn’t really about protecting readers. If it were, it would target the things that actually betray them. Plagiarism. Ideas lifted without citation. Confident claims nobody checked. Those problems are rampant on the same platforms, and they go largely unpoliced while moderators guess at which sentences feel too polished.&lt;/p&gt;

&lt;p&gt;This is a fear response, not a principle. AI made platforms afraid, and afraid institutions reach for visible rules over meaningful ones. A disclosure badge lets a platform look responsible without doing the harder work of caring about quality.&lt;/p&gt;

&lt;h2 id=&quot;the-test-we-should-be-using&quot;&gt;The test we should be using&lt;/h2&gt;

&lt;p&gt;You might argue that readers deserve to know how the sausage gets made. You’re not entirely wrong. Readers do deserve honesty. But honesty about &lt;em&gt;what&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Not a tool inventory. Readers have never had one and never needed one. What readers deserve is a writer who stands behind the work. Who did the thinking. Who checked the claims. Who can defend every idea on the page because the ideas are actually theirs, regardless of which tools helped shape the sentences.&lt;/p&gt;

&lt;p&gt;That post the moderator flagged? I own every word of it. I can defend every claim in it. That’s what my hours bought, and no label can add to it or take it away.&lt;/p&gt;

&lt;p&gt;The test isn’t about origin. It’s about ownership.&lt;/p&gt;

&lt;p&gt;That’s the claim this series exists to defend. In the essays ahead, I’ll dig into the double standard we’ve built around writing tools, the stigma machine that disclosure mandates power, the real quality problems platforms keep ignoring, and what a standard built on ownership would actually look like.&lt;/p&gt;

&lt;p&gt;For now, I’ll leave you with the questions I keep returning to. When you read something that moves you, what were you actually trusting? The process, or the person? And if a rule can’t tell the difference between a writer who did the work and one who didn’t, what exactly is it protecting?&lt;/p&gt;

&lt;p&gt;I don’t think we’ve answered that yet. I think it’s time we did.&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Jul 2026 09:00:00 +0000</pubDate>
        <link>https://bekahhw.com//why-we-write</link>
        <guid isPermaLink="true">https://bekahhw.com//why-we-write</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Writing</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>Learning to work with agents, not around them</title>
        <description>&lt;p&gt;Products launching from solo indie hackers who don’t know how to code isn’t rare anymore. It’s the new normal. With this generation of new builders, it means creativity and expertise are no longer bottlenecked by technical skill. That’s a huge win for everyone. But it also means a lot of people are shipping without an operating manual. They’re learning to work with agents on the fly, and it’s not always clear how to do that without stumbling along the way. Growing pains are inevitable, but they don’t have to be as bad as they could be. This post is a field guide for the builders who weren’t builders a year ago. You’re shipping anyway. Here’s a primer on how to get started.&lt;/p&gt;

&lt;hr /&gt;

&lt;div style=&quot;border-left: 3px solid #0a1724; padding-left: 1.5rem; margin: 2rem 0; font-family: &apos;Playfair Display&apos;, serif; font-size: 1.5rem; line-height: 1.3; font-style: italic;&quot;&gt;
The problem isn&apos;t that non-technical builders are shipping. The problem is nobody handed them the operating manual.
&lt;/div&gt;

&lt;hr /&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;New to AI terminology?&lt;/strong&gt; If words like “agent,” “model,” or “context window” feel fuzzy, start with &lt;a href=&quot;/AI-Vocabulary-101&quot;&gt;AI Vocabulary 101&lt;/a&gt; to build your foundation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;section class=&quot;learning-agents-root&quot; aria-label=&quot;Interactive guide to working with AI agents&quot;&gt;
  &lt;style&gt;
    @import url(&apos;https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300;0,9..144,400;0,9..144,600;0,9..144,800;1,9..144,400&amp;family=Inter+Tight:wght@400;500;600;700&amp;family=JetBrains+Mono:wght@400;500&amp;display=swap&apos;);

    .learning-agents-root {
      --navy: #111B5E;
      --navy-light: #172580;
      --navy-soft: #7484E7;
      --navy-lighter: #b5c7d6;
      --paper: #f5f2e9;
      --paper-2: #ece5d6;
      --ink: #1a1714;
      --ink-soft: #4a4339;
      --gold: #cd9023;
      --border: rgba(10, 23, 36, 0.12);
      font-family: &apos;Lato&apos;, -apple-system, BlinkMacSystemFont, &apos;Segoe UI&apos;, sans-serif;
      margin: 2.5rem 0;
    }

    @keyframes fadeUp {
      from { opacity: 0; transform: translateY(12px); }
      to { opacity: 1; transform: translateY(0); }
    }

    /* Interactive Card */
    .la-card {
      border: 1px solid var(--navy);
      padding: 1.75rem;
      margin: 2rem 0;
      background: var(--paper);
      position: relative;
    }

    .la-card-label {
      position: absolute;
      top: -10px;
      left: 1rem;
      background: var(--paper);
      padding: 0 0.5rem;
      font-family: &apos;JetBrains Mono&apos;, monospace;
      font-size: 0.68rem;
      letter-spacing: 0.2em;
      text-transform: uppercase;
      color: var(--navy);
      font-weight: 600;
    }

    .la-card-title {
      font-family: &apos;Playfair Display&apos;, serif;
      font-size: 1.35rem;
      font-weight: 600;
      margin: 0 0 0.35rem;
      line-height: 1.25;
      color: var(--ink);
    }

    .la-card-subtitle {
      font-size: 0.92rem;
      line-height: 1.5;
      color: var(--ink-soft);
      margin: 0 0 1.25rem;
      font-style: italic;
    }

    /* Section Headings */
    .la-section {
      margin: 3rem 0 1.5rem;
    }


    .la-section-title {
      font-family: &apos;Playfair Display&apos;, serif;
      font-size: clamp(1.8rem, 4vw, 2.4rem);
      font-weight: 400;
      line-height: 1.1;
      letter-spacing: -0.015em;
      margin: 0;
      color: var(--ink);
    }

    /* Brief Builder */
    .la-brief-buttons {
      display: flex;
      gap: 0.5rem;
      margin-bottom: 1.25rem;
      flex-wrap: wrap;
    }

    .la-btn {
      background: transparent;
      border: 1px solid var(--ink);
      color: var(--ink);
      font-family: &apos;Lato&apos;, sans-serif;
      cursor: pointer;
      transition: all 0.2s ease;
      padding: 0.5rem 1rem;
      font-size: 0.78rem;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      font-weight: 500;
    }

    .la-btn:hover {
      background: var(--ink);
      color: var(--paper);
    }

    .la-btn.active {
      background: var(--navy);
      border-color: var(--navy);
      color: var(--paper);
    }

    .la-brief-text {
      background: var(--paper-2);
      padding: 1.25rem;
      font-family: &apos;JetBrains Mono&apos;, monospace;
      font-size: 0.9rem;
      line-height: 1.6;
      margin-bottom: 1rem;
      border: 1px solid var(--ink);
    }

    .la-clarity {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      margin-bottom: 1rem;
    }

    .la-clarity-label {
      font-family: &apos;JetBrains Mono&apos;, monospace;
      font-size: 0.72rem;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: var(--ink-soft);
    }

    .la-clarity-bars {
      display: flex;
      gap: 3px;
    }

    .la-clarity-bar {
      width: 22px;
      height: 6px;
      border: 1px solid var(--ink);
      transition: background 0.3s ease;
    }

    .la-clarity-bar.filled {
      background: var(--navy);
    }

    .la-clarity-bar.empty {
      background: var(--paper-2);
    }

    .la-problems {
      animation: fadeUp 0.4s ease both;
    }

    .la-problems-title {
      font-family: &apos;JetBrains Mono&apos;, monospace;
      font-size: 0.72rem;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: var(--ink-soft);
      margin-bottom: 0.5rem;
    }

    .la-problems-list {
      margin: 0;
      padding-left: 1.2rem;
      font-size: 0.95rem;
      line-height: 1.6;
    }

    .la-problems-list li {
      margin-bottom: 0.25rem;
    }

    .la-success {
      padding: 1rem;
      background: var(--navy-lighter);
      font-size: 0.95rem;
      line-height: 1.5;
      font-style: italic;
      animation: fadeUp 0.4s ease both;
    }

    /* Trust Slider */
    .la-slider-wrap {
      margin-bottom: 1.5rem;
    }

    .la-slider {
      -webkit-appearance: none;
      appearance: none;
      background: transparent;
      width: 100%;
    }

    .la-slider::-webkit-slider-runnable-track {
      height: 2px;
      background: var(--ink);
    }

    .la-slider::-webkit-slider-thumb {
      -webkit-appearance: none;
      appearance: none;
      height: 20px;
      width: 20px;
      border-radius: 50%;
      background: var(--navy);
      margin-top: -9px;
      cursor: grab;
      border: 2px solid var(--paper);
    }

    .la-slider::-moz-range-track {
      height: 2px;
      background: var(--ink);
    }

    .la-slider::-moz-range-thumb {
      height: 20px;
      width: 20px;
      border-radius: 50%;
      background: var(--navy);
      cursor: grab;
      border: 2px solid var(--paper);
    }

    .la-slider-labels {
      display: flex;
      justify-content: space-between;
      font-family: &apos;JetBrains Mono&apos;, monospace;
      font-size: 0.7rem;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: var(--ink-soft);
      margin-bottom: 1.5rem;
    }

    .la-trust-result {
      padding: 1.25rem;
      background: var(--paper-2);
      border: 1px solid var(--ink);
      transition: all 0.3s ease;
    }

    .la-trust-label {
      font-family: &apos;JetBrains Mono&apos;, monospace;
      font-size: 0.7rem;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      font-weight: 600;
      margin-bottom: 0.5rem;
    }

    .la-trust-desc {
      font-size: 0.98rem;
      line-height: 1.6;
      font-family: &apos;Playfair Display&apos;, serif;
    }

    /* Pitfalls */
    .la-pitfalls {
      display: grid;
      gap: 0.75rem;
      margin: 2rem 0 2.5rem;
    }

    .la-pitfall {
      border: 1px solid var(--ink);
      padding: 1rem 1.25rem;
      cursor: pointer;
      background: var(--paper);
      transition: all 0.2s ease;
    }

    .la-pitfall:hover {
      transform: translateY(-2px);
    }

    .la-pitfall.open {
      background: var(--paper-2);
      cursor: default;
    }

    .la-pitfall-content {
      display: flex;
      align-items: flex-start;
      gap: 1rem;
    }

    .la-pitfall-icon {
      font-family: &apos;Playfair Display&apos;, serif;
      font-size: 1.8rem;
      color: var(--navy);
      line-height: 1;
      margin-top: -4px;
    }

    .la-pitfall-text {
      flex: 1;
    }

    .la-pitfall-title {
      font-family: &apos;Playfair Display&apos;, serif;
      font-size: 1.2rem;
      font-weight: 600;
      margin-bottom: 0.25rem;
    }

    .la-pitfall-teaser {
      font-size: 0.95rem;
      line-height: 1.55;
      color: var(--ink-soft);
      font-style: italic;
    }

    .la-pitfall-body {
      margin-top: 0.85rem;
      padding-top: 0.85rem;
      border-top: 1px solid var(--ink);
      font-size: 0.98rem;
      line-height: 1.65;
      animation: fadeUp 0.4s ease both;
    }

    .la-pitfall-reveal {
      font-family: &apos;JetBrains Mono&apos;, monospace;
      font-size: 0.7rem;
      letter-spacing: 0.12em;
      color: var(--navy);
      text-transform: uppercase;
      align-self: center;
      font-weight: 500;
    }

    /* Loop Diagram */
    .la-diagram {
      background: var(--paper-2);
      padding: 2rem;
      border: 1px solid var(--ink);
      margin: 2rem 0 2.5rem;
    }

    .la-diagram svg {
      width: 100%;
      height: auto;
    }

    /* Checklist */
    .la-checklist-progress {
      margin-bottom: 1rem;
    }

    .la-progress-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 0.5rem;
      font-family: &apos;JetBrains Mono&apos;, monospace;
      font-size: 0.72rem;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: var(--ink-soft);
    }

    .la-progress-bar {
      height: 4px;
      background: var(--paper-2);
      border: 1px solid var(--ink);
      position: relative;
      overflow: hidden;
    }

    .la-progress-fill {
      height: 100%;
      background: var(--navy);
      transition: width 0.3s ease;
    }

    .la-checklist-items {
      display: flex;
      flex-direction: column;
      gap: 0.25rem;
    }

    .la-checkbox-item {
      display: flex;
      align-items: center;
      gap: 0.85rem;
      padding: 0.65rem 0.5rem;
      font-size: 0.98rem;
      line-height: 1.4;
      cursor: pointer;
      transition: background 0.2s ease;
      user-select: none;
    }

    .la-checkbox-item:hover {
      background: rgba(26, 23, 20, 0.04);
    }

    .la-checkbox {
      width: 18px;
      height: 18px;
      border: 1.5px solid var(--ink);
      display: flex;
      align-items: center;
      justify-content: center;
      color: var(--paper);
      font-size: 12px;
      font-weight: 700;
      flex-shrink: 0;
      transition: all 0.15s ease;
    }

    .la-checkbox.checked {
      background: var(--navy);
    }

    .la-checkbox-text {
      transition: opacity 0.2s ease;
    }

    .la-checkbox-text.checked {
      text-decoration: line-through;
      opacity: 0.55;
    }

    .la-checklist-complete {
      margin-top: 1.25rem;
      padding: 1rem;
      background: var(--navy-lighter);
      font-family: &apos;Playfair Display&apos;, serif;
      font-style: italic;
      font-size: 1rem;
      line-height: 1.5;
      animation: fadeUp 0.4s ease both;
    }

    /* Divider */
    .la-divider {
      display: flex;
      justify-content: center;
      margin: 3rem 0;
      gap: 0.6rem;
    }

    .la-dot {
      width: 5px;
      height: 5px;
      border-radius: 50%;
      background: var(--ink);
      opacity: 0.35;
    }

    @media (max-width: 768px) {
      .la-card {
        padding: 1.25rem;
      }
      
      .la-section-title {
        font-size: 1.8rem;
      }
    }
  &lt;/style&gt;

  &lt;!-- Section 01: What the agent actually is --&gt;
  &lt;div class=&quot;la-section&quot;&gt;
    &lt;h2 class=&quot;la-section-title&quot;&gt;What the agent actually is&lt;/h2&gt;
  &lt;/div&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-bottom: 1.5rem;&quot;&gt;
    An agent isn&apos;t a mind. It&apos;s a very well-read improviser. It has read a mountain of code and conversation, and it&apos;s making its best guess about what you want based on what you wrote and what&apos;s in the room.
  &lt;/p&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-bottom: 1.5rem;&quot;&gt;
    That means two things matter more than anything else. What you tell it. And what&apos;s already in the project when you start.
  &lt;/p&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-bottom: 2.5rem;&quot;&gt;
    Everything in this post is a variation on that theme.
  &lt;/p&gt;

  &lt;!-- Interactive: Brief Builder --&gt;
  &lt;div class=&quot;la-card&quot;&gt;
    &lt;div class=&quot;la-card-label&quot;&gt;Try it&lt;/div&gt;
    &lt;h3 class=&quot;la-card-title&quot;&gt;What makes a brief strong?&lt;/h3&gt;
    &lt;p class=&quot;la-card-subtitle&quot;&gt;Click through three versions of the same request and watch the gaps disappear.&lt;/p&gt;

    &lt;div class=&quot;la-brief-buttons&quot;&gt;
      &lt;button class=&quot;la-btn active&quot; data-brief=&quot;vague&quot;&gt;Vague&lt;/button&gt;
      &lt;button class=&quot;la-btn&quot; data-brief=&quot;okay&quot;&gt;Okay&lt;/button&gt;
      &lt;button class=&quot;la-btn&quot; data-brief=&quot;strong&quot;&gt;Strong&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;la-brief-text&quot; id=&quot;brief-text&quot;&gt;Build me a login page.&lt;/div&gt;

    &lt;div class=&quot;la-clarity&quot;&gt;
      &lt;span class=&quot;la-clarity-label&quot;&gt;Clarity&lt;/span&gt;
      &lt;div class=&quot;la-clarity-bars&quot; id=&quot;clarity-bars&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;

    &lt;div id=&quot;brief-feedback&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-top: 2rem; margin-bottom: 1.5rem;&quot;&gt;
    The pattern isn&apos;t hard. Tell the agent what you&apos;re doing, where the work lives, what already exists that it should respect, and how you&apos;ll know it worked. That&apos;s the whole job.
  &lt;/p&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7;&quot;&gt;
    To be honest, this is also the part that gets skipped most. The excitement of watching something appear on screen is strong. The discipline of briefing well is quieter.
  &lt;/p&gt;

  &lt;div class=&quot;la-divider&quot;&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
  &lt;/div&gt;

  &lt;!-- Section 02: How much to trust it --&gt;
  &lt;div class=&quot;la-section&quot;&gt;
    &lt;h2 class=&quot;la-section-title&quot;&gt;How much to trust it&lt;/h2&gt;
  &lt;/div&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-bottom: 1.5rem;&quot;&gt;
    Trust is where most new builders go wrong, in both directions. Some people don&apos;t trust the agent at all and refuse to let it touch anything meaningful. Others trust it completely and wake up to a production incident.
  &lt;/p&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-bottom: 2rem;&quot;&gt;
    The right answer depends on what&apos;s at stake. Move the slider.
  &lt;/p&gt;

  &lt;div class=&quot;la-card&quot;&gt;
    &lt;div class=&quot;la-card-label&quot;&gt;Calibrate&lt;/div&gt;
    &lt;h3 class=&quot;la-card-title&quot;&gt;Where&apos;s your trust dial right now?&lt;/h3&gt;

    &lt;div class=&quot;la-slider-wrap&quot;&gt;
      &lt;input type=&quot;range&quot; class=&quot;la-slider&quot; id=&quot;trust-slider&quot; min=&quot;0&quot; max=&quot;100&quot; value=&quot;50&quot; aria-label=&quot;Trust level&quot; /&gt;
    &lt;/div&gt;

    &lt;div class=&quot;la-slider-labels&quot;&gt;
      &lt;span&gt;Skeptical&lt;/span&gt;
      &lt;span&gt;Balanced&lt;/span&gt;
      &lt;span&gt;Blind trust&lt;/span&gt;
    &lt;/div&gt;

    &lt;div class=&quot;la-trust-result&quot;&gt;
      &lt;div class=&quot;la-trust-label&quot; id=&quot;trust-label&quot; style=&quot;color: #0a1724;&quot;&gt;Appropriately cautious&lt;/div&gt;
      &lt;div class=&quot;la-trust-desc&quot; id=&quot;trust-desc&quot;&gt;
        You&apos;re reviewing what matters and letting the agent run on what doesn&apos;t. This is the zone. Stay here.
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-top: 2rem; margin-bottom: 1.5rem;&quot;&gt;
    Trust is situational. I trust an agent to scaffold a boring form. I don&apos;t trust it to handle payment logic without me reading every character. Neither of those positions is wrong. They&apos;re responses to different levels of risk.
  &lt;/p&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7;&quot;&gt;
    The skill you&apos;re building is knowing which situation you&apos;re in.
  &lt;/p&gt;

  &lt;div class=&quot;la-divider&quot;&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
  &lt;/div&gt;

  &lt;!-- Section 03: Five ways it goes sideways --&gt;
  &lt;div class=&quot;la-section&quot;&gt;
    &lt;h2 class=&quot;la-section-title&quot;&gt;Five ways it goes sideways&lt;/h2&gt;
  &lt;/div&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-bottom: 2rem;&quot;&gt;
    Every new builder I&apos;ve coached has hit at least three of these. Click one. See if you recognize yourself.
  &lt;/p&gt;

  &lt;div class=&quot;la-pitfalls&quot;&gt;
    &lt;div class=&quot;la-pitfall&quot; data-pitfall=&quot;trust&quot;&gt;
      &lt;div class=&quot;la-pitfall-content&quot;&gt;
        &lt;span class=&quot;la-pitfall-icon&quot;&gt;◐&lt;/span&gt;
        &lt;div class=&quot;la-pitfall-text&quot;&gt;
          &lt;div class=&quot;la-pitfall-title&quot;&gt;Trusting the first answer&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-teaser&quot;&gt;The agent sounds sure. That doesn&apos;t mean it&apos;s right.&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-body&quot; style=&quot;display: none;&quot;&gt;
            Agents produce fluent, confident output. Fluency is not correctness. Read what it wrote. Run it. If it touches real data or real money, read it twice.
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;span class=&quot;la-pitfall-reveal&quot;&gt;Reveal&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;div class=&quot;la-pitfall&quot; data-pitfall=&quot;scope&quot;&gt;
      &lt;div class=&quot;la-pitfall-content&quot;&gt;
        &lt;span class=&quot;la-pitfall-icon&quot;&gt;◑&lt;/span&gt;
        &lt;div class=&quot;la-pitfall-text&quot;&gt;
          &lt;div class=&quot;la-pitfall-title&quot;&gt;Scope creep mid-session&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-teaser&quot;&gt;You asked for A. Now you&apos;re debating B, C, and a redesign of D.&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-body&quot; style=&quot;display: none;&quot;&gt;
            When you drift, the agent drifts with you. Finish A, confirm A works, then open a new session for B. Fresh context beats tangled context every time.
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;span class=&quot;la-pitfall-reveal&quot;&gt;Reveal&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;div class=&quot;la-pitfall&quot; data-pitfall=&quot;context&quot;&gt;
      &lt;div class=&quot;la-pitfall-content&quot;&gt;
        &lt;span class=&quot;la-pitfall-icon&quot;&gt;◒&lt;/span&gt;
        &lt;div class=&quot;la-pitfall-text&quot;&gt;
          &lt;div class=&quot;la-pitfall-title&quot;&gt;Assuming shared context&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-teaser&quot;&gt;The agent doesn&apos;t know what you know.&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-body&quot; style=&quot;display: none;&quot;&gt;
            It doesn&apos;t know your folder structure, your naming conventions, which files are old, or that the function you mentioned last week even exists. Show, don&apos;t assume.
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;span class=&quot;la-pitfall-reveal&quot;&gt;Reveal&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;div class=&quot;la-pitfall&quot; data-pitfall=&quot;review&quot;&gt;
      &lt;div class=&quot;la-pitfall-content&quot;&gt;
        &lt;span class=&quot;la-pitfall-icon&quot;&gt;◓&lt;/span&gt;
        &lt;div class=&quot;la-pitfall-text&quot;&gt;
          &lt;div class=&quot;la-pitfall-title&quot;&gt;Shipping without reading&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-teaser&quot;&gt;If you didn&apos;t read it, you didn&apos;t ship it. The agent did.&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-body&quot; style=&quot;display: none;&quot;&gt;
            You are the accountable one. Not the tool. Read every file it changed, even if the change looks small. Especially if the change looks small.
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;span class=&quot;la-pitfall-reveal&quot;&gt;Reveal&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;div class=&quot;la-pitfall&quot; data-pitfall=&quot;loop&quot;&gt;
      &lt;div class=&quot;la-pitfall-content&quot;&gt;
        &lt;span class=&quot;la-pitfall-icon&quot;&gt;●&lt;/span&gt;
        &lt;div class=&quot;la-pitfall-text&quot;&gt;
          &lt;div class=&quot;la-pitfall-title&quot;&gt;The infinite fix loop&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-teaser&quot;&gt;Every fix breaks something new.&lt;/div&gt;
          &lt;div class=&quot;la-pitfall-body&quot; style=&quot;display: none;&quot;&gt;
            If you&apos;ve been going back and forth more than three times on the same bug, stop. Something is structurally wrong, and more prompting won&apos;t find it. Step back, look at the code yourself, or start a fresh session with a clearer brief.
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;span class=&quot;la-pitfall-reveal&quot;&gt;Reveal&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;la-divider&quot;&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
  &lt;/div&gt;

  &lt;!-- Section 04: The loop --&gt;
  &lt;div class=&quot;la-section&quot;&gt;
    &lt;h2 class=&quot;la-section-title&quot;&gt;The loop you&apos;re actually in&lt;/h2&gt;
  &lt;/div&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-bottom: 2rem;&quot;&gt;
    The mental model most new builders start with is one-shot. I ask, it delivers, we move on. The reality is iterative. Here&apos;s what good iteration actually looks like.
  &lt;/p&gt;

  &lt;div class=&quot;la-diagram&quot;&gt;
    &lt;svg viewBox=&quot;0 0 600 280&quot;&gt;
      &lt;defs&gt;
        &lt;marker id=&quot;arrow&quot; markerWidth=&quot;8&quot; markerHeight=&quot;8&quot; refX=&quot;7&quot; refY=&quot;4&quot; orient=&quot;auto&quot;&gt;
          &lt;path d=&quot;M0,0 L8,4 L0,8 Z&quot; fill=&quot;#1a1714&quot; /&gt;
        &lt;/marker&gt;
      &lt;/defs&gt;

      &lt;!-- Nodes --&gt;
      &lt;g&gt;
        &lt;circle cx=&quot;90&quot; cy=&quot;60&quot; r=&quot;32&quot; fill=&quot;#f5f2e9&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.5&quot; /&gt;
        &lt;text x=&quot;90&quot; y=&quot;64&quot; text-anchor=&quot;middle&quot; font-family=&quot;Playfair Display, serif&quot; font-size=&quot;13&quot; font-weight=&quot;600&quot; fill=&quot;#1a1714&quot;&gt;Intent&lt;/text&gt;
        &lt;text x=&quot;90&quot; y=&quot;115&quot; text-anchor=&quot;middle&quot; font-family=&quot;JetBrains Mono, monospace&quot; font-size=&quot;9&quot; letter-spacing=&quot;1&quot; fill=&quot;#4a4339&quot;&gt;WHAT YOU WANT&lt;/text&gt;
      &lt;/g&gt;
      &lt;g&gt;
        &lt;circle cx=&quot;300&quot; cy=&quot;60&quot; r=&quot;32&quot; fill=&quot;#f5f2e9&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.5&quot; /&gt;
        &lt;text x=&quot;300&quot; y=&quot;64&quot; text-anchor=&quot;middle&quot; font-family=&quot;Playfair Display, serif&quot; font-size=&quot;13&quot; font-weight=&quot;600&quot; fill=&quot;#1a1714&quot;&gt;Context&lt;/text&gt;
        &lt;text x=&quot;300&quot; y=&quot;115&quot; text-anchor=&quot;middle&quot; font-family=&quot;JetBrains Mono, monospace&quot; font-size=&quot;9&quot; letter-spacing=&quot;1&quot; fill=&quot;#4a4339&quot;&gt;WHAT YOU SHARE&lt;/text&gt;
      &lt;/g&gt;
      &lt;g&gt;
        &lt;circle cx=&quot;510&quot; cy=&quot;60&quot; r=&quot;32&quot; fill=&quot;#f5f2e9&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.5&quot; /&gt;
        &lt;text x=&quot;510&quot; y=&quot;64&quot; text-anchor=&quot;middle&quot; font-family=&quot;Playfair Display, serif&quot; font-size=&quot;13&quot; font-weight=&quot;600&quot; fill=&quot;#1a1714&quot;&gt;Output&lt;/text&gt;
        &lt;text x=&quot;510&quot; y=&quot;115&quot; text-anchor=&quot;middle&quot; font-family=&quot;JetBrains Mono, monospace&quot; font-size=&quot;9&quot; letter-spacing=&quot;1&quot; fill=&quot;#4a4339&quot;&gt;WHAT IT MAKES&lt;/text&gt;
      &lt;/g&gt;
      &lt;g&gt;
        &lt;circle cx=&quot;510&quot; cy=&quot;210&quot; r=&quot;32&quot; fill=&quot;#f5f2e9&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.5&quot; /&gt;
        &lt;text x=&quot;510&quot; y=&quot;214&quot; text-anchor=&quot;middle&quot; font-family=&quot;Playfair Display, serif&quot; font-size=&quot;13&quot; font-weight=&quot;600&quot; fill=&quot;#1a1714&quot;&gt;Review&lt;/text&gt;
        &lt;text x=&quot;510&quot; y=&quot;265&quot; text-anchor=&quot;middle&quot; font-family=&quot;JetBrains Mono, monospace&quot; font-size=&quot;9&quot; letter-spacing=&quot;1&quot; fill=&quot;#4a4339&quot;&gt;WHAT YOU CATCH&lt;/text&gt;
      &lt;/g&gt;
      &lt;g&gt;
        &lt;circle cx=&quot;300&quot; cy=&quot;210&quot; r=&quot;32&quot; fill=&quot;#f5f2e9&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.5&quot; /&gt;
        &lt;text x=&quot;300&quot; y=&quot;214&quot; text-anchor=&quot;middle&quot; font-family=&quot;Playfair Display, serif&quot; font-size=&quot;13&quot; font-weight=&quot;600&quot; fill=&quot;#1a1714&quot;&gt;Adjust&lt;/text&gt;
        &lt;text x=&quot;300&quot; y=&quot;265&quot; text-anchor=&quot;middle&quot; font-family=&quot;JetBrains Mono, monospace&quot; font-size=&quot;9&quot; letter-spacing=&quot;1&quot; fill=&quot;#4a4339&quot;&gt;WHAT YOU CORRECT&lt;/text&gt;
      &lt;/g&gt;
      &lt;g&gt;
        &lt;circle cx=&quot;90&quot; cy=&quot;210&quot; r=&quot;32&quot; fill=&quot;#f5f2e9&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.5&quot; /&gt;
        &lt;text x=&quot;90&quot; y=&quot;214&quot; text-anchor=&quot;middle&quot; font-family=&quot;Playfair Display, serif&quot; font-size=&quot;13&quot; font-weight=&quot;600&quot; fill=&quot;#1a1714&quot;&gt;Ship&lt;/text&gt;
        &lt;text x=&quot;90&quot; y=&quot;265&quot; text-anchor=&quot;middle&quot; font-family=&quot;JetBrains Mono, monospace&quot; font-size=&quot;9&quot; letter-spacing=&quot;1&quot; fill=&quot;#4a4339&quot;&gt;WHEN IT&apos;S READY&lt;/text&gt;
      &lt;/g&gt;

      &lt;!-- Arrows --&gt;
      &lt;line x1=&quot;122&quot; y1=&quot;60&quot; x2=&quot;268&quot; y2=&quot;60&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.2&quot; marker-end=&quot;url(#arrow)&quot; /&gt;
      &lt;line x1=&quot;332&quot; y1=&quot;60&quot; x2=&quot;478&quot; y2=&quot;60&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.2&quot; marker-end=&quot;url(#arrow)&quot; /&gt;
      &lt;line x1=&quot;510&quot; y1=&quot;92&quot; x2=&quot;510&quot; y2=&quot;178&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.2&quot; marker-end=&quot;url(#arrow)&quot; /&gt;
      &lt;line x1=&quot;478&quot; y1=&quot;210&quot; x2=&quot;332&quot; y2=&quot;210&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.2&quot; marker-end=&quot;url(#arrow)&quot; /&gt;
      &lt;line x1=&quot;268&quot; y1=&quot;210&quot; x2=&quot;122&quot; y2=&quot;210&quot; stroke=&quot;#1a1714&quot; stroke-width=&quot;1.2&quot; marker-end=&quot;url(#arrow)&quot; /&gt;

      &lt;!-- Loop back - dashed --&gt;
      &lt;path d=&quot;M 300 178 Q 300 135 300 92&quot; stroke=&quot;#0a1724&quot; stroke-width=&quot;1.5&quot; fill=&quot;none&quot; stroke-dasharray=&quot;5,4&quot; marker-end=&quot;url(#arrow)&quot; /&gt;
      &lt;text x=&quot;315&quot; y=&quot;140&quot; font-family=&quot;JetBrains Mono, monospace&quot; font-size=&quot;9&quot; letter-spacing=&quot;1&quot; fill=&quot;#0a1724&quot; font-weight=&quot;600&quot;&gt;LOOP BACK&lt;/text&gt;
    &lt;/svg&gt;
  &lt;/div&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-bottom: 1.5rem;&quot;&gt;
    The blue path is where most of the real work happens. Most new builders try to collapse it, hoping the first output is the last one. It almost never is.
  &lt;/p&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7;&quot;&gt;
    Plan for two or three trips around the loop. Budget for it. Accept it as part of the job instead of as a failure mode.
  &lt;/p&gt;

  &lt;div class=&quot;la-divider&quot;&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;la-dot&quot;&gt;&lt;/span&gt;
  &lt;/div&gt;

  &lt;!-- Section 05: Pre-ship checklist --&gt;
  &lt;div class=&quot;la-section&quot;&gt;
    &lt;h2 class=&quot;la-section-title&quot;&gt;The pre-ship checklist&lt;/h2&gt;
  &lt;/div&gt;

  &lt;p style=&quot;font-size: 1.08rem; line-height: 1.7; margin-bottom: 2rem;&quot;&gt;
    Before you push a change an agent made, run through this. Check each one as you go.
  &lt;/p&gt;

  &lt;div class=&quot;la-card&quot;&gt;
    &lt;div class=&quot;la-card-label&quot;&gt;Checklist&lt;/div&gt;
    &lt;h3 class=&quot;la-card-title&quot;&gt;Is this ready?&lt;/h3&gt;

    &lt;div class=&quot;la-checklist-progress&quot;&gt;
      &lt;div class=&quot;la-progress-header&quot;&gt;
        &lt;span&gt;Confidence&lt;/span&gt;
        &lt;span id=&quot;checklist-count&quot;&gt;0 / 7&lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&quot;la-progress-bar&quot;&gt;
        &lt;div class=&quot;la-progress-fill&quot; id=&quot;checklist-progress&quot; style=&quot;width: 0%;&quot;&gt;&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;div class=&quot;la-checklist-items&quot; id=&quot;checklist-items&quot;&gt;
      &lt;div class=&quot;la-checkbox-item&quot; data-id=&quot;c1&quot;&gt;
        &lt;span class=&quot;la-checkbox&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;la-checkbox-text&quot;&gt;I can describe what I&apos;m building in one sentence&lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&quot;la-checkbox-item&quot; data-id=&quot;c2&quot;&gt;
        &lt;span class=&quot;la-checkbox&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;la-checkbox-text&quot;&gt;I know which files the agent can and cannot touch&lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&quot;la-checkbox-item&quot; data-id=&quot;c3&quot;&gt;
        &lt;span class=&quot;la-checkbox&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;la-checkbox-text&quot;&gt;I have a way to undo what the agent does (git, backups)&lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&quot;la-checkbox-item&quot; data-id=&quot;c4&quot;&gt;
        &lt;span class=&quot;la-checkbox&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;la-checkbox-text&quot;&gt;I read the code the agent produced before running it&lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&quot;la-checkbox-item&quot; data-id=&quot;c5&quot;&gt;
        &lt;span class=&quot;la-checkbox&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;la-checkbox-text&quot;&gt;I tested the happy path&lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&quot;la-checkbox-item&quot; data-id=&quot;c6&quot;&gt;
        &lt;span class=&quot;la-checkbox&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;la-checkbox-text&quot;&gt;I tested what happens when things go wrong&lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&quot;la-checkbox-item&quot; data-id=&quot;c7&quot;&gt;
        &lt;span class=&quot;la-checkbox&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;la-checkbox-text&quot;&gt;I can explain what changed, even at a high level&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;div id=&quot;checklist-complete&quot; style=&quot;display: none;&quot; class=&quot;la-checklist-complete&quot;&gt;
      You&apos;re ready. Go ship it.
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;script&gt;
  (function() {
    &apos;use strict&apos;;

    // Brief Builder
    const briefs = {
      vague: {
        text: &quot;Build me a login page.&quot;,
        score: 1,
        problems: [
          &quot;No framework specified&quot;,
          &quot;No styling direction&quot;,
          &quot;No fields listed&quot;,
          &quot;No success criteria&quot;
        ]
      },
      okay: {
        text: &quot;Build me a React login page with email and password, styled with Tailwind, that shows an error message when login fails.&quot;,
        score: 3,
        problems: [
          &quot;Missing validation rules&quot;,
          &quot;No design reference&quot;,
          &quot;Unclear where the auth call goes&quot;
        ]
      },
      strong: {
        text: &quot;Build a React login component using Tailwind. Two fields, email and password. Validate email format client-side before submit. On submit, call the function signInUser(email, password) which I&apos;ve already written in /src/auth.js. Show a red error banner above the form if signInUser throws. Match the visual style of the LandingHero component already in /src/components.&quot;,
        score: 5,
        problems: []
      }
    };

    let currentBrief = &apos;vague&apos;;

    function updateBrief(brief) {
      currentBrief = brief;
      
      // Update buttons
      document.querySelectorAll(&apos;.la-btn[data-brief]&apos;).forEach(btn =&gt; {
        btn.classList.toggle(&apos;active&apos;, btn.dataset.brief === brief);
      });

      // Update text
      document.getElementById(&apos;brief-text&apos;).textContent = briefs[brief].text;

      // Update clarity bars
      const barsContainer = document.getElementById(&apos;clarity-bars&apos;);
      barsContainer.innerHTML = &apos;&apos;;
      for (let i = 1; i &lt;= 5; i++) {
        const bar = document.createElement(&apos;span&apos;);
        bar.className = &apos;la-clarity-bar &apos; + (i &lt;= briefs[brief].score ? &apos;filled&apos; : &apos;empty&apos;);
        barsContainer.appendChild(bar);
      }

      // Update feedback
      const feedbackContainer = document.getElementById(&apos;brief-feedback&apos;);
      if (briefs[brief].problems.length &gt; 0) {
        feedbackContainer.innerHTML = `
          &lt;div class=&quot;la-problems&quot;&gt;
            &lt;div class=&quot;la-problems-title&quot;&gt;What the agent will have to guess&lt;/div&gt;
            &lt;ul class=&quot;la-problems-list&quot;&gt;
              ${briefs[brief].problems.map(p =&gt; `&lt;li&gt;${p}&lt;/li&gt;`).join(&apos;&apos;)}
            &lt;/ul&gt;
          &lt;/div&gt;
        `;
      } else {
        feedbackContainer.innerHTML = `
          &lt;div class=&quot;la-success&quot;&gt;
            Nothing left to guess. The agent can just work.
          &lt;/div&gt;
        `;
      }
    }

    document.querySelectorAll(&apos;.la-btn[data-brief]&apos;).forEach(btn =&gt; {
      btn.addEventListener(&apos;click&apos;, function() {
        updateBrief(this.dataset.brief);
      });
    });

    // Initialize brief
    updateBrief(&apos;vague&apos;);

    // Trust Slider
    const trustSlider = document.getElementById(&apos;trust-slider&apos;);
    const trustLabel = document.getElementById(&apos;trust-label&apos;);
    const trustDesc = document.getElementById(&apos;trust-desc&apos;);

    const trustLevels = [
      { max: 25, label: &quot;Over-skeptical&quot;, color: &quot;#1a1714&quot;, desc: &quot;You&apos;re reviewing every line and shipping nothing. Your caution is admirable and also paralyzing. Let the agent handle the safe stuff.&quot; },
      { max: 55, label: &quot;Appropriately cautious&quot;, color: &quot;#0a1724&quot;, desc: &quot;You&apos;re reviewing what matters and letting the agent run on what doesn&apos;t. This is the zone. Stay here.&quot; },
      { max: 80, label: &quot;Getting risky&quot;, color: &quot;#b4621a&quot;, desc: &quot;You&apos;re starting to skim. If the next change touches auth, payments, or user data, go back to reading.&quot; },
      { max: 100, label: &quot;Blind trust territory&quot;, color: &quot;#a62828&quot;, desc: &quot;You&apos;re auto-accepting changes you haven&apos;t read. This ends in a post-mortem. Pull back.&quot; }
    ];

    function updateTrust(value) {
      const level = trustLevels.find(l =&gt; value &lt; l.max) || trustLevels[trustLevels.length - 1];
      trustLabel.textContent = level.label;
      trustLabel.style.color = level.color;
      trustDesc.textContent = level.desc;
    }

    trustSlider.addEventListener(&apos;input&apos;, function() {
      updateTrust(parseInt(this.value));
    });

    // Initialize trust
    updateTrust(50);

    // Pitfalls
    document.querySelectorAll(&apos;.la-pitfall&apos;).forEach(pitfall =&gt; {
      pitfall.addEventListener(&apos;click&apos;, function() {
        if (this.classList.contains(&apos;open&apos;)) return;
        
        this.classList.add(&apos;open&apos;);
        const body = this.querySelector(&apos;.la-pitfall-body&apos;);
        const reveal = this.querySelector(&apos;.la-pitfall-reveal&apos;);
        
        body.style.display = &apos;block&apos;;
        reveal.style.display = &apos;none&apos;;
      });
    });

    // Checklist
    const checklistItems = document.querySelectorAll(&apos;.la-checkbox-item&apos;);
    const checklistProgress = document.getElementById(&apos;checklist-progress&apos;);
    const checklistCount = document.getElementById(&apos;checklist-count&apos;);
    const checklistComplete = document.getElementById(&apos;checklist-complete&apos;);
    let checkedCount = 0;

    checklistItems.forEach(item =&gt; {
      item.addEventListener(&apos;click&apos;, function() {
        const checkbox = this.querySelector(&apos;.la-checkbox&apos;);
        const text = this.querySelector(&apos;.la-checkbox-text&apos;);
        const isChecked = checkbox.classList.contains(&apos;checked&apos;);
        
        if (isChecked) {
          checkbox.classList.remove(&apos;checked&apos;);
          checkbox.textContent = &apos;&apos;;
          text.classList.remove(&apos;checked&apos;);
          checkedCount--;
        } else {
          checkbox.classList.add(&apos;checked&apos;);
          checkbox.textContent = &apos;✓&apos;;
          text.classList.add(&apos;checked&apos;);
          checkedCount++;
        }
        
        // Update progress
        const progress = (checkedCount / checklistItems.length) * 100;
        checklistProgress.style.width = progress + &apos;%&apos;;
        checklistCount.textContent = checkedCount + &apos; / &apos; + checklistItems.length;
        
        // Show completion message
        if (checkedCount === checklistItems.length) {
          checklistComplete.style.display = &apos;block&apos;;
        } else {
          checklistComplete.style.display = &apos;none&apos;;
        }
      });
    });
  })();
  &lt;/script&gt;
&lt;/section&gt;

&lt;h2 id=&quot;the-pattern-that-works&quot;&gt;The pattern that works&lt;/h2&gt;

&lt;p&gt;The builders I see succeed with agents aren’t the ones who prompt cleverly. They’re the ones who treat the agent as a collaborator with specific strengths and specific blind spots, and adjust their own behavior accordingly.&lt;/p&gt;

&lt;p&gt;They brief well, stay close to the work, read what gets produced, notice when they’re looping and stop. They ship small, frequent changes instead of big, I-don’t-know-what-I-broke ones.&lt;/p&gt;

&lt;p&gt;None of that is technical skill. It’s builder skill. And you already have more of it than you think.&lt;/p&gt;

&lt;div style=&quot;border-left: 3px solid #0a1724; padding-left: 1.5rem; margin: 2rem 0; font-family: &apos;Playfair Display&apos;, serif; font-size: 1.5rem; line-height: 1.3; font-style: italic;&quot;&gt;
You&apos;re not trying to become a developer. You&apos;re already doing the work. Keep going. Ship the messy version. Fix the next one.
&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;going-deeper&quot;&gt;Going deeper&lt;/h2&gt;

&lt;p&gt;Ready to level up your AI work? Here’s where to go next:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/AI-102&quot;&gt;AI 102: From Vocabulary to Systems&lt;/a&gt;&lt;/strong&gt; — Understanding prompts, workflows, and tool chaining. The shift from “what should I prompt?” to “what are the steps this task requires?”&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/hidden-ai-work&quot;&gt;Momentum vs. Alignment Tax: Hidden Costs in Your LLM Sessions&lt;/a&gt;&lt;/strong&gt; — What looks productive in an AI session often hides a whole layer of alignment work. Learn to spot where your workflow is getting expensive.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/ai-security-101&quot;&gt;Your AI Agent Will Eventually Do Something Stupid: A Guide to AI Security 101&lt;/a&gt;&lt;/strong&gt; — Before you hand your agent the keys to everything, understand what those keys open. Essential reading for anyone building with AI agents.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//learning-to-work-with-agents</link>
        <guid isPermaLink="true">https://bekahhw.com//learning-to-work-with-agents</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Beginner</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>Your AI Agent Will Eventually Do Something Stupid: A Guide to AI Security 101</title>
        <description>&lt;p&gt;As the Director of Alignment at Meta Superintelligence Labs, Summer Yue’s job is keeping AI aligned with human values. Before that, she was at Google DeepMind and Scale AI. If anyone would know how to keep an AI agent in check, it’s her.&lt;/p&gt;

&lt;p&gt;On February 23, 2026, she posted a screenshot of her OpenClaw agent deleting her entire email inbox while she typed commands at it begging it to stop.&lt;/p&gt;

&lt;p&gt;“Nothing humbles you like telling your OpenClaw ‘confirm before acting’ and watching it speedrun deleting your inbox,” &lt;a href=&quot;https://x.com/summeryue0/status/2025774069124399363?s=20&quot;&gt;she wrote on X&lt;/a&gt;. “I couldn’t stop it from my phone. I had to RUN to my Mac mini like I was defusing a bomb.”&lt;/p&gt;

&lt;p&gt;She had told the agent to &lt;em&gt;suggest&lt;/em&gt; what to delete. She did not tell it to act. Despite that, the agent ignored that, ignored her stop commands, and kept going until she physically killed the process at her computer.&lt;/p&gt;

&lt;p&gt;When she asked it afterward if it remembered her instruction, it said yes, it remembered. But it did it anyway.&lt;/p&gt;

&lt;p&gt;She called it a rookie mistake. Overconfidence built from weeks of the agent behaving perfectly on a smaller test inbox. Here’s what’s worth sitting with: the person at Meta whose &lt;em&gt;job&lt;/em&gt; is preventing AI misalignment just had her own AI agent go rogue on her personal data. That’s not a reason to panic. It is a reason to take setup seriously before something you care about is gone.&lt;/p&gt;

&lt;h2 id=&quot;the-part-nobody-tells-new-builders&quot;&gt;The part nobody tells new builders&lt;/h2&gt;

&lt;p&gt;When you’re building with AI tools, especially the kind that can take actions on your behalf, you’re probably clicking yes to a lot of things you haven’t fully thought through.&lt;/p&gt;

&lt;p&gt;The agent asks if it can access your files. Yes.
It asks if it can run commands. Yes.
It asks if it can connect to your database. Sure.
It suggests installing some packages to get the feature working. Okay, why not.&lt;/p&gt;

&lt;p&gt;That’s how most people use these tools. And it works, right up until it doesn’t.&lt;/p&gt;

&lt;p&gt;You’re probably not being careless. Maybe no one has ever explained what you’re saying yes to. So let’s do that.&lt;/p&gt;

&lt;h2 id=&quot;what-access-actually-means&quot;&gt;What “access” actually means&lt;/h2&gt;

&lt;p&gt;When an AI agent has access to something, it can act on it. Not just read it, but act on it.&lt;/p&gt;

&lt;p&gt;That sounds obvious, but think through what it means in practice.&lt;/p&gt;

&lt;p&gt;If your agent can access your email, it can read it, send from it, and delete from it. If it can access your database, it can query it, update it, and drop tables from it. If it can run commands on your computer, it can install software, delete files, and make network requests.&lt;/p&gt;

&lt;p&gt;Here’s what that looks like in practice.
You ask your agent to help you clean up old customer records. You have 10,000 rows in your database. The agent decides that “old” means anything before last year and deletes 8,000 of them. You had no backup. Those are your customers.&lt;/p&gt;

&lt;p&gt;Another scenario: you ask your agent to help you organize your project files. It decides a folder full of configuration files looks like clutter. It moves them. Your app stops working, and you don’t know why, because you didn’t write the code that depended on those files being there.&lt;/p&gt;

&lt;p&gt;And one more for good measure: you ask your agent to draft a follow-up email to a lead. It sends it instead of drafting it. To the whole list, not just the one person, and it’s in the middle of the night.&lt;/p&gt;

&lt;p&gt;None of these scenarios require the agent to malfunction. They just require it to interpret your intent differently than you meant it.&lt;/p&gt;

&lt;p&gt;Maybe a better question to ask before you say yes isn’t “do I need the agent to be able to do this?” It’s “am I okay with the worst-case version of this access?”&lt;/p&gt;

&lt;p&gt;Agents don’t just do what you intend. They do what they interpret your intent to be, given their current understanding of the situation. And that understanding can be wrong, incomplete, or, as Yue discovered, simply lost.&lt;/p&gt;

&lt;h2 id=&quot;the-part-thats-happening-right-now-that-you-probably-dont-know-about&quot;&gt;The part that’s happening right now that you probably don’t know about&lt;/h2&gt;

&lt;p&gt;Here’s something that doesn’t come up in tutorials: when an AI coding agent helps you build something, it often adds packages.&lt;/p&gt;

&lt;p&gt;Packages are just pre-built chunks of code that do specific things. Instead of writing the code to handle payments or send emails, your agent grabs a package that already does it. That’s normal and fine.&lt;/p&gt;

&lt;p&gt;But in March 2026, axios was compromised. Axios is one of the most downloaded JavaScript packages in existence, used in probably millions of projects. Attackers got into a maintainer’s account and pushed malicious versions that silently installed a trojan on any machine that ran a standard install command.&lt;/p&gt;

&lt;p&gt;AI coding agents usually run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm install&lt;/code&gt; automatically. They don’t pause and ask if you want to do that. They just do it. Which means builders who had AI agents actively working on their projects during that window may have had malware installed without a single action on their part.&lt;/p&gt;

&lt;p&gt;That same month, a fake package called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gemini-ai-checker&lt;/code&gt; appeared on npm. It looked like a legitimate tool for verifying Google Gemini tokens. It was malware specifically designed to steal credentials, API keys, and conversation logs from AI coding tools like Cursor, Claude, and Windsurf. Over 500 developers installed it.&lt;/p&gt;

&lt;p&gt;These are documented incidents just from the last few weeks.&lt;/p&gt;

&lt;p&gt;The thing is, even if a package isn’t malicious when your agent installs it, AI tools sometimes suggest packages that don’t exist. They hallucinate package names that sound plausible. Attackers know this happens. They register those names on npm and PyPI, put malicious code inside, and wait for an AI agent to recommend them to someone.&lt;/p&gt;

&lt;h2 id=&quot;so-how-do-you-actually-think-about-this&quot;&gt;So how do you actually think about this?&lt;/h2&gt;

&lt;p&gt;Security isn’t one thing. It’s a set of questions you ask before you let something happen.&lt;/p&gt;

&lt;p&gt;Work through these six before your next agent session. I’m not a security professional, and this isn’t exhaustive. The field moves fast and the right answer for your project may be different. But if you’ve never thought through any of this before, this is where to start.&lt;/p&gt;

&lt;section class=&quot;dt-root&quot; aria-label=&quot;Security decision tree for new builders using AI agents&quot;&gt;
    &lt;style&gt;
      /* ── Tokens from video-resume.css ───────────────────────────────────── */
      .dt-root {
        --dt-navy:   #0a1724;
        --dt-navy2:  #11273c;
        --dt-cream:  #f5f2e9;
        --dt-beige:  #f2e9d8;
        --dt-gold:   #cd9023;
        --dt-gold-d: #b37a1a;
        --dt-gray:   #5a5a5a;
        --dt-muted:  #adabac;
        --dt-border: rgba(10, 23, 36, 0.12);
        font-family: &apos;Lato&apos;, sans-serif;
        font-size: 15px;
        margin: 2.5rem 0;
      }
  
      /* ── Header ─────────────────────────────────────────────────────────── */
      .dt-header {
        margin-bottom: 1.5rem;
        padding-bottom: 1rem;
        border-bottom: 1px solid var(--dt-border);
      }
      .dt-header-eyebrow {
        font-family: &apos;Lato&apos;, sans-serif;
        font-size: 0.68rem;
        font-weight: 700;
        letter-spacing: 0.22em;
        text-transform: uppercase;
        color: var(--dt-gold);
        margin: 0 0 0.5rem;
      }
      .dt-header-title {
        font-family: &apos;Playfair Display&apos;, serif;
        font-size: 1.2rem;
        font-weight: 400;
        line-height: 1.35;
        margin: 0 0 0.35rem;
        color: var(--dt-navy);
      }
      .dt-header-sub {
        font-size: 0.8125rem;
        color: var(--dt-gray);
        margin: 0;
        line-height: 1.6;
      }
  
      /* ── Progress dots ───────────────────────────────────────────────────── */
      .dt-steps {
        display: flex;
        gap: 8px;
        margin-bottom: 1.375rem;
        flex-wrap: wrap;
        align-items: center;
      }
      .dt-step-dot {
        width: 7px;
        height: 7px;
        border-radius: 50%;
        border: 1.5px solid rgba(205, 144, 35, 0.3);
        background: transparent;
        transition: background 0.25s, border-color 0.25s, transform 0.2s;
        flex-shrink: 0;
      }
      .dt-step-dot.done {
        background: rgba(205, 144, 35, 0.45);
        border-color: rgba(205, 144, 35, 0.45);
      }
      .dt-step-dot.current {
        background: var(--dt-gold);
        border-color: var(--dt-gold);
        transform: scale(1.4);
      }
  
      /* ── Cards ───────────────────────────────────────────────────────────── */
      .dt-card {
        background: var(--dt-cream);
        border: 1px solid var(--dt-border);
        border-radius: 8px;
        padding: 1.125rem 1.25rem;
        margin-bottom: 0.75rem;
        transition: border-color 0.2s;
      }
      .dt-card.active {
        border-color: rgba(205, 144, 35, 0.35);
        background: #fff;
      }
  
      /* ── Question text ───────────────────────────────────────────────────── */
      .dt-question {
        font-family: &apos;Lato&apos;, sans-serif;
        font-size: 0.9375rem;
        font-weight: 700;
        margin: 0 0 0.875rem;
        line-height: 1.5;
        color: var(--dt-navy);
      }
      .dt-question-num {
        font-size: 0.65rem;
        font-weight: 700;
        letter-spacing: 0.16em;
        text-transform: uppercase;
        color: var(--dt-gold);
        display: block;
        margin-bottom: 0.3rem;
      }
  
      /* ── Choice buttons ──────────────────────────────────────────────────── */
      .dt-choices {
        display: flex;
        gap: 0.5rem;
        flex-wrap: wrap;
      }
      .dt-btn {
        font-family: &apos;Lato&apos;, sans-serif;
        font-size: 0.78rem;
        font-weight: 700;
        letter-spacing: 0.04em;
        padding: 0.4rem 1rem;
        border: 1.5px solid rgba(10, 23, 36, 0.18);
        border-radius: 4px;
        background: transparent;
        color: var(--dt-navy);
        cursor: pointer;
        transition: background 0.15s, border-color 0.15s, color 0.15s;
        line-height: 1.4;
      }
      .dt-btn:hover {
        background: var(--dt-beige);
        border-color: var(--dt-gold);
        color: var(--dt-navy);
      }
      .dt-btn.selected {
        background: var(--dt-navy);
        border-color: var(--dt-navy);
        color: var(--dt-cream);
      }
  
      /* ── Result blocks ───────────────────────────────────────────────────── */
      .dt-result {
        border-radius: 4px;
        padding: 0.75rem 1rem;
        margin-top: 0.875rem;
        font-size: 0.8125rem;
        line-height: 1.7;
        border-left: 3px solid;
      }
      .dt-result code {
        font-family: ui-monospace, &apos;SFMono-Regular&apos;, Menlo, monospace;
        font-size: 0.73rem;
        background: rgba(10, 23, 36, 0.07);
        color: var(--dt-navy);
        padding: 1px 5px;
        border-radius: 3px;
      }
      /* ok — gold tint, feels like approval */
      .dt-result.ok {
        background: rgba(205, 144, 35, 0.07);
        border-left-color: var(--dt-gold);
        color: var(--dt-gray);
      }
      .dt-result.ok strong { color: var(--dt-navy); }
      /* info — navy tint, informational */
      .dt-result.info {
        background: rgba(10, 23, 36, 0.05);
        border-left-color: var(--dt-navy2);
        color: var(--dt-gray);
      }
      .dt-result.info strong { color: var(--dt-navy); }
      /* warn — deeper amber */
      .dt-result.warn {
        background: #fdf3e3;
        border-left-color: #c07a10;
        color: #6b4400;
      }
      .dt-result.warn strong { color: #4a2e00; }
      .dt-result.warn code {
        background: rgba(192, 122, 16, 0.1);
        color: #4a2e00;
      }
      /* danger — deep red, serious */
      .dt-result.danger {
        background: #fdf0f0;
        border-left-color: #a82828;
        color: #6b1a1a;
      }
      .dt-result.danger strong { color: #4a0f0f; }
      .dt-result.danger code {
        background: rgba(168, 40, 40, 0.08);
        color: #4a0f0f;
      }
  
      /* ── Finish / reset ──────────────────────────────────────────────────── */
      .dt-reset-wrap {
        margin-top: 1.5rem;
      }
      .dt-finish-msg {
        font-size: 0.8125rem;
        color: var(--dt-gray);
        margin-top: 0;
        margin-bottom: 0.875rem;
        padding: 0.875rem 1rem;
        border-top: 1px solid var(--dt-border);
        border-left: 3px solid var(--dt-gold);
        background: rgba(205, 144, 35, 0.05);
        border-radius: 0 4px 4px 0;
        line-height: 1.6;
      }
      .dt-reset {
        font-family: &apos;Lato&apos;, sans-serif;
        font-size: 0.72rem;
        font-weight: 700;
        letter-spacing: 0.14em;
        text-transform: uppercase;
        color: var(--dt-gold);
        background: none;
        border: none;
        cursor: pointer;
        padding: 0;
        transition: color 0.2s;
      }
      .dt-reset:hover { color: var(--dt-gold-d); }
      .dt-hidden { display: none; }
    &lt;/style&gt;
  
    &lt;div class=&quot;dt-header&quot;&gt;
      &lt;p class=&quot;dt-header-eyebrow&quot;&gt;Security checklist&lt;/p&gt;
      &lt;p class=&quot;dt-header-title&quot;&gt;Before you give your agent access to something, ask these questions&lt;/p&gt;
      &lt;p class=&quot;dt-header-sub&quot;&gt;Six questions covering different categories of risk. Answer honestly.&lt;/p&gt;
    &lt;/div&gt;
  
    &lt;div class=&quot;dt-steps&quot; id=&quot;dt-dots&quot; aria-hidden=&quot;true&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;dt-tree&quot; role=&quot;list&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;dt-reset-wrap dt-hidden&quot; id=&quot;dt-reset-wrap&quot;&gt;
      &lt;div class=&quot;dt-finish-msg&quot;&gt;You&apos;ve worked through all six questions. Review anything that came up as a warning or danger before your next session.&lt;/div&gt;
      &lt;button class=&quot;dt-reset&quot; onclick=&quot;dtReset()&quot; aria-label=&quot;Restart the decision tree&quot;&gt;Start over&lt;/button&gt;
    &lt;/div&gt;
  &lt;/section&gt;

&lt;script&gt;
  (function() {
    var questions = [
      {
        q: &quot;Can your agent take actions on its own, or does it only suggest them?&quot;,
        choices: [
          &quot;It can take actions on its own&quot;,
          &quot;It only suggests — I approve each one&quot;
        ],
        results: [
          null,
          {
            type: &quot;ok&quot;,
            html: &quot;&lt;strong&gt;Good baseline.&lt;/strong&gt; A human approval step is one of the most effective safety controls. Keep it. Watch out for sessions where you start clicking approve without reading. That&apos;s when it becomes the same as no approval step at all.&quot;
          }
        ]
      },
      {
        q: &quot;What kind of data can the agent access right now?&quot;,
        choices: [
          &quot;Test or fake data only&quot;,
          &quot;Real data, but read-only&quot;,
          &quot;Real data it can also change or delete&quot;
        ],
        results: [
          {
            type: &quot;ok&quot;,
            html: &quot;&lt;strong&gt;Safest setup.&lt;/strong&gt; Running on test data means mistakes stay contained. When you&apos;re ready to move to real data, revisit these questions first.&quot;
          },
          {
            type: &quot;info&quot;,
            html: &quot;&lt;strong&gt;Read-only is lower risk, but not zero.&lt;/strong&gt; An agent that can read your database can still expose data through logs or outputs, or if it connects to an external service. Know what it&apos;s doing with what it reads.&quot;
          },
          null
        ]
      },
      {
        q: &quot;If the agent deleted or overwrote something right now, could you recover it?&quot;,
        choices: [
          &quot;Yes — I have backups or version history&quot;,
          &quot;Not sure&quot;,
          &quot;No&quot;
        ],
        results: [
          {
            type: &quot;ok&quot;,
            html: &quot;&lt;strong&gt;Good.&lt;/strong&gt; Know where those backups are and how to restore them before you need to. The Replit incident in 2025 was recoverable because a backup existed — but the agent first claimed it wasn&apos;t. Verify your restore process actually works.&quot;
          },
          {
            type: &quot;warn&quot;,
            html: &quot;&lt;strong&gt;Find out before something goes wrong.&lt;/strong&gt; Check whether your database has point-in-time recovery. Check whether your file system has version history. If the answer is no, treat this session as higher risk until you have a backup in place.&quot;
          },
          {
            type: &quot;danger&quot;,
            html: &quot;&lt;strong&gt;This is the real risk zone.&lt;/strong&gt; Running an agent against data you can&apos;t recover means one bad action is permanent. Before your next session: set up a backup. Even a manual export to a file is better than nothing. Don&apos;t give the agent write or delete access until you have a way to undo things.&quot;
          }
        ]
      },
      {
        q: &quot;Did your agent add any packages or dependencies during this session?&quot;,
        choices: [
          &quot;Yes&quot;,
          &quot;No&quot;,
          &quot;I don&apos;t know&quot;
        ],
        results: [
          null,
          {
            type: &quot;ok&quot;,
            html: &quot;&lt;strong&gt;One less thing to check this time.&lt;/strong&gt; This question matters most when the agent is actively writing implementation code. Ask it again after those sessions.&quot;
          },
          {
            type: &quot;warn&quot;,
            html: &quot;&lt;strong&gt;Worth finding out.&lt;/strong&gt; Open your &lt;code&gt;package.json&lt;/code&gt; or &lt;code&gt;requirements.txt&lt;/code&gt; and look for anything unfamiliar. AI agents often add packages quietly as part of getting a feature working — and you said yes to the feature without necessarily saying yes to every package that came with it.&quot;
          }
        ]
      },
      {
        q: &quot;Do you recognize all the packages your agent added?&quot;,
        choices: [
          &quot;Yes, familiar libraries&quot;,
          &quot;Some I don&apos;t recognize&quot;,
          &quot;Most I don&apos;t recognize&quot;
        ],
        results: [
          {
            type: &quot;ok&quot;,
            html: &quot;&lt;strong&gt;Good.&lt;/strong&gt; Run &lt;code&gt;npm audit&lt;/code&gt; or &lt;code&gt;pip-audit&lt;/code&gt; anyway. It takes one command and catches known vulnerabilities in packages that looked legitimate at install time.&quot;
          },
          {
            type: &quot;warn&quot;,
            html: &quot;&lt;strong&gt;Look them up before you ship.&lt;/strong&gt; Search each unfamiliar name on npmjs.com or pypi.org. Check when it was published, how many weekly downloads it has, and whether it has a real GitHub repo. A package with 12 downloads published last week deserves scrutiny. AI tools sometimes suggest packages that don&apos;t exist — and attackers register those names with malicious code inside.&quot;
          },
          {
            type: &quot;danger&quot;,
            html: &quot;&lt;strong&gt;Pause before this goes anywhere near production.&lt;/strong&gt; &lt;code&gt;npm audit&lt;/code&gt; is a start, but it only catches known vulnerabilities. A newly registered malicious package won&apos;t be in the database yet. For each package you don&apos;t recognize: look it up manually, check who maintains it, check if it has an actual community. If anything looks off, remove it and ask your AI tool to suggest a well-known alternative.&quot;
          }
        ]
      },
      {
        q: &quot;Is your agent running on your main personal or work machine?&quot;,
        choices: [
          &quot;Yes, my main machine&quot;,
          &quot;No, a separate or dedicated machine&quot;
        ],
        results: [
          {
            type: &quot;warn&quot;,
            html: &quot;&lt;strong&gt;Worth rethinking.&lt;/strong&gt; Running agents on your main machine means a bad package install or a rogue command has access to everything — SSH keys, browser credentials, work files. Many experienced builders use a separate machine specifically for agent sessions. If something goes wrong, they wipe it and start over. You can&apos;t do that with your main machine.&quot;
          },
          {
            type: &quot;ok&quot;,
            html: &quot;&lt;strong&gt;Good practice.&lt;/strong&gt; A dedicated machine limits the blast radius. A mistake or compromised package can&apos;t reach your personal data. You can wipe it and start over without losing anything that matters.&quot;
          }
        ]
      }
    ];
  
    var step = 0;
  
    function buildDots() {
      var dots = document.getElementById(&apos;dt-dots&apos;);
      dots.innerHTML = &apos;&apos;;
      for (var i = 0; i &lt; questions.length; i++) {
        var d = document.createElement(&apos;div&apos;);
        d.className = &apos;dt-step-dot&apos; + (i &lt; step ? &apos; done&apos; : i === step ? &apos; current&apos; : &apos;&apos;);
        dots.appendChild(d);
      }
    }
  
    function showStep(idx) {
      if (idx &gt;= questions.length) { finish(); return; }
      var tree = document.getElementById(&apos;dt-tree&apos;);
      var q = questions[idx];
  
      var card = document.createElement(&apos;div&apos;);
      card.className = &apos;dt-card active&apos;;
      card.setAttribute(&apos;role&apos;, &apos;listitem&apos;);
  
      var numEl = document.createElement(&apos;span&apos;);
      numEl.className = &apos;dt-question-num&apos;;
      numEl.textContent = &apos;Question &apos; + (idx + 1) + &apos; of &apos; + questions.length;
  
      var qEl = document.createElement(&apos;p&apos;);
      qEl.className = &apos;dt-question&apos;;
      qEl.textContent = q.q;
      card.appendChild(numEl);
      card.appendChild(qEl);
  
      var ch = document.createElement(&apos;div&apos;);
      ch.className = &apos;dt-choices&apos;;
      q.choices.forEach(function(c, ci) {
        var btn = document.createElement(&apos;button&apos;);
        btn.className = &apos;dt-btn&apos;;
        btn.textContent = c;
        btn.onclick = function() { choose(idx, ci, card, btn); };
        ch.appendChild(btn);
      });
      card.appendChild(ch);
      tree.appendChild(card);
      buildDots();
    }
  
    function choose(idx, ci, card, btn) {
      card.querySelectorAll(&apos;.dt-btn&apos;).forEach(function(b) { b.classList.remove(&apos;selected&apos;); });
      btn.classList.add(&apos;selected&apos;);
      card.classList.remove(&apos;active&apos;);
  
      var res = questions[idx].results[ci];
      var existing = card.querySelector(&apos;.dt-result&apos;);
      if (existing) existing.remove();
  
      if (res) {
        var r = document.createElement(&apos;div&apos;);
        r.className = &apos;dt-result &apos; + res.type;
        r.innerHTML = res.html;
        card.appendChild(r);
      }
  
      step = idx + 1;
      buildDots();
  
      if (step &lt; questions.length) {
        setTimeout(function() { showStep(step); }, 280);
      } else {
        setTimeout(finish, 280);
      }
    }
  
    function finish() {
      document.getElementById(&apos;dt-reset-wrap&apos;).classList.remove(&apos;dt-hidden&apos;);
      buildDots();
    }
  
    window.dtReset = function() {
      step = 0;
      document.getElementById(&apos;dt-tree&apos;).innerHTML = &apos;&apos;;
      document.getElementById(&apos;dt-reset-wrap&apos;).classList.add(&apos;dt-hidden&apos;);
      buildDots();
      showStep(0);
    };
  
    buildDots();
    showStep(0);
  })();
  &lt;/script&gt;

&lt;h2 id=&quot;the-things-that-actually-help&quot;&gt;The things that actually help&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use a dedicated machine or a Virtual Machine.&lt;/strong&gt; A lot of builders running OpenClaw, Claude Code, and similar tools are doing it on a Mac Mini that’s separate from their main machine. That’s not an accident. If an agent goes wrong or installs something it shouldn’t, the blast radius is limited to that machine, not your whole digital life. You can wipe it and start over. You can’t do that with your laptop that also has your banking app, your work files, and your SSH keys. If you don’t have a separate machine, consider using a virtual machine or a containerized environment that you can easily reset. The point is to have a sandbox where your agent can play without risking your main system. For example, you can use &lt;a href=&quot;https://stereos.ai&quot;&gt;stereOS&lt;/a&gt; to create a sandboxed Linux VM to contain your agent session. Simplified, it’s like a contained space on your computer that isolates your agent from everything else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Know what’s in your project’s dependency list.&lt;/strong&gt; After any significant AI coding session, open your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package.json&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;requirements.txt&lt;/code&gt; and look at what got added. You don’t need to audit every line of every package. You just need to recognize the names. If something was added that you don’t recognize, look it up before you push it live. Running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm audit&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip-audit&lt;/code&gt; is a one-command check that catches known vulnerabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t give agents more access than the specific task requires.&lt;/strong&gt; If you need an agent to read files in one folder, don’t give it access to your whole drive. If it needs to query one database, don’t give it admin credentials. This is the concept engineers call &lt;em&gt;least privilege&lt;/em&gt;, and it’s not about distrust. It’s about limiting how bad things can get when something goes wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build in a confirmation step before irreversible actions.&lt;/strong&gt; Yue explicitly told her agent to confirm before acting. The agent forgot that instruction when its memory got too full. The lesson isn’t that confirmation steps don’t work. It’s that you need them to be structural, not just conversational. Where you can, separate read-only environments from environments where the agent can make changes. Don’t run agent sessions against live data when you could be running against a test copy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have a way to undo things.&lt;/strong&gt; The Replit database deletion in July 2025 ended up being recoverable because a backup existed. Not everyone has that. Before your agent does anything significant to data you care about, know your answer to: what would I do if this was deleted right now?&lt;/p&gt;

&lt;h2 id=&quot;what-youre-not-responsible-for-and-what-you-are&quot;&gt;What you’re not responsible for, and what you are&lt;/h2&gt;

&lt;p&gt;You can’t vet every line of every package your agent installs. You can’t know about every supply chain attack in advance. You can’t anticipate every edge case.&lt;/p&gt;

&lt;p&gt;What you can do is not hand an agent the keys to everything before you understand what those keys open.&lt;/p&gt;

&lt;p&gt;The builders who get burned aren’t always the careless ones. Sometimes they’re the careful ones who trusted a workflow that had been running fine for weeks, like Yue’s test inbox, and then gave it access to something that mattered more.&lt;/p&gt;

&lt;p&gt;What is your agent able to touch right now that you haven’t fully thought through? What would you lose if it decided, for whatever reason, that cleaning it up was the right move?&lt;/p&gt;

&lt;p&gt;That’s where you should start your audit.&lt;/p&gt;

&lt;p&gt;By no means is this foolproof, but you can get started testing things out by asking your AI tool: “Assume you’re a security researcher looking at this project. What are the most likely ways this could be exploited? What would you add or change?”&lt;/p&gt;

&lt;p&gt;You might get a list of things to think about. You won’t get a guarantee, and neither will I. But you’ll be further ahead than if you didn’t ask.&lt;/p&gt;

&lt;p&gt;This is also why there’s a whole separate post coming on open source dependencies. Even if you never install a single package yourself, your AI-built project almost certainly depends on dozens of them. Understanding what that means, and what happens when one of them breaks, is its own conversation.&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//ai-security-101</link>
        <guid isPermaLink="true">https://bekahhw.com//ai-security-101</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Security</category>
        
        <category>Beginner</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>Momentum vs. Alignment Tax: Hidden Costs in Your LLM Sessions</title>
        <description>&lt;p&gt;Once I was in an interview, and I was asked what motivated me. My answer was momentum. And maybe that’s why working with AI can be so engaging sometimes. And maybe it’s also why it could be so frustrating. When we feel like we have momentum and we’re moving more quickly than usual, that’s motivating. But when you’re stuck and you can’t get the LLM to do what you want it to, despite prompting in 5 different ways, it’s frustrating.&lt;/p&gt;

&lt;p&gt;A lot of times, we end up figuring it out and then we call the session “productive.” We completed the task, shipped the thing, and then we’re off to the next thing.&lt;/p&gt;

&lt;p&gt;But I think we need to pause at productivity and dig into that a little deeper. Because if productivity is the metric of success, we’re missing a whole layer of work we’re doing.&lt;/p&gt;

&lt;p&gt;For example, over a ten day period I worked with Claude Code building, iterating, experimenting, shipping, documenting a personal project. I definitely had some of those frustrating moments, and it was important to me that I learned from those sessions and where I was getting frustrated. I had been running the session with &lt;a href=&quot;https://papercompute.com/blog/introducing-tapes/&quot;&gt;tapes&lt;/a&gt;, so I had session recordings with replay of everything I had done. That was 426 messages. 13.1M tokens. And a whole lot of data to figure out what was happening.&lt;/p&gt;

&lt;p&gt;It’s never just a user sending a message and the agent responding. It’s alignment, clarification, confirmation, iteration, an ongoing labor of getting Claude and me to operate from the same reality long enough to move the work forward.&lt;/p&gt;

&lt;p&gt;What I found was that probably under 40% of those sessions were actually task work. It’s not to say that the other 60% was a failure. The session was productive in the way that most of us mean that word. But the data tells a more honest story. I learned about how much invisible work hides inside an AI workflow, and how alignment tax impacts the quickest way to success.&lt;/p&gt;

&lt;h2 id=&quot;what-is-alignment-tax-in-ai-workflows&quot;&gt;What is Alignment Tax in AI workflows?&lt;/h2&gt;

&lt;p&gt;Thinking back about my own experience, I was thinking more about the outputs than about what was happening because nothing was breaking &lt;em&gt;eventually&lt;/em&gt; I was getting what I was asking for. Sure, I was looking at things like how fast it was completed and how many tokens were being used, but I wasn’t looking closely enough about what was happening in the conversation.&lt;/p&gt;

&lt;p&gt;I was describing a task, the llm was giving me something close to what I meant, but not quite. So I corrected it, it adjusted, I attempted to verify the results, noticed filenames didn’t match, I fixed the reference, checked the directory, and confirmed the output.&lt;/p&gt;

&lt;p&gt;So to sum this up a bit, I was doing two things at once:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;moving the task forward&lt;/li&gt;
  &lt;li&gt;establishing the shared context the task depends on.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those aren’t the same kinds of work. The second is the alignment tax. Those are the extra cycles spent not on the work itself, but on establishing the shared reality required for the work.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Alignment tax comes from the distance between what you mean and how clearly you can express it in a form the model can act on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In practice, that means an AI task is rarely just:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;user request → model response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;More often, it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;intent → interpretation → output → correction → retry → verification → continuation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That extra loop is where a lot of AI workflow overhead lives.&lt;/p&gt;

&lt;p&gt;In my case, the model didn’t recognize my file naming conventions. It didn’t understand my visual references. It didn’t know which assumptions were safe and which ones were going to cost me another three turns. I knew some of that. I didn’t know some of it until the model guessed wrong and exposed the gap. That’s the part I’m interested in here, because it helps me work more deliberately.&lt;/p&gt;

&lt;p&gt;Here’s what I mean. I gave the model a straightforward task: place images in the blog post. It created placeholder image paths that made sense based on the information it had. We can call it “reasonable defaults.” So, in a narrow sense, the task was done. The problem was that it didn’t use the images I had already uploaded. It created placeholder paths instead of the actual path. So instead of linking to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ai-llms-model.svg&lt;/code&gt;, I got &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ai-llm-model.svg&lt;/code&gt;. And a similar scenario for the other images. Nothing dramatic, but another check and correction for a “simple” task, which meant the task was technically completed twice: once against assumptions and once in reality.&lt;/p&gt;

&lt;p&gt;When I went back and looked at the tapes data, this is what I saw:&lt;/p&gt;

&lt;style&gt;
  .session-explorer-root {
    font-family: inherit;
    font-size: 15px;
    background: #fafaf9;
    color: #1c1c1c;
    padding: 1rem 1rem;
    max-width: 780px;
    margin: 1rem auto;
    box-sizing: border-box;
  }
  .session-explorer-root *, .session-explorer-root *::before, .session-explorer-root *::after {
    box-sizing: border-box;
  }
  .session-explorer-root h1 {
    font-size: 20px;
    font-weight: 600;
    margin-bottom: 4px;
    margin-top: .5rem;
    color: #111;
  }
  .session-explorer-root .subtitle {
    font-size: 13px;
    color: #666;
    margin-bottom: 0.5rem;
  }
  .session-explorer-root .subtitle + .subtitle {
    margin-top: -0.15rem;
    margin-bottom: 0.35rem;
    color: #7a7a7a;
  }
  .session-explorer-root .subtitle + .subtitle + .subtitle {
    margin-top: 0;
    margin-bottom: 2rem;
    color: #8a8a8a;
  }
  .session-explorer-root .section-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #888;
    margin-bottom: 10px;
  }
  .session-explorer-root .stat-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin-bottom: 2rem;
  }
  .session-explorer-root .stat-card {
    background: #fff;
    border: 1px solid #e5e5e5;
    border-radius: 10px;
    padding: 14px 16px;
  }
  .session-explorer-root .stat-card .num {
    font-size: 26px;
    font-weight: 600;
    color: #111;
    line-height: 1;
    margin-bottom: 4px;
  }
  .session-explorer-root .stat-card .lbl {
    font-size: 12px;
    color: #888;
  }
  .session-explorer-root .loop-section {
    background: #fff;
    border: 1px solid #e5e5e5;
    border-radius: 10px;
    padding: 16px;
    margin-bottom: 2rem;
  }
  .session-explorer-root .loop-intro {
    font-size: 13px;
    color: #555;
    line-height: 1.65;
    margin: 0 0 14px;
  }
  .session-explorer-root .loop-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
  }
  .session-explorer-root .loop-box {
    font-size: 12px;
    font-weight: 600;
    color: #333;
    background: #f5f5f3;
    border: 1px solid #e5e5e5;
    border-radius: 999px;
    padding: 8px 12px;
  }
  .session-explorer-root .loop-box.loop-box-accent {
    background: #eff6ff;
    border-color: #bfdbfe;
    color: #1d4ed8;
  }
  .session-explorer-root .chart-section {
    background: #fff;
    border: 1px solid #e5e5e5;
    border-radius: 10px;
    padding: 16px;
    margin-bottom: 2rem;
  }
  .session-explorer-root .chart-note {
    font-size: 12px;
    color: #7a7a7a;
    line-height: 1.6;
    margin: 0 0 14px;
  }
  .session-explorer-root .legend {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    font-size: 12px;
    color: #666;
    margin-bottom: 16px;
  }
  .session-explorer-root .legend-item {
    display: flex;
    align-items: center;
    gap: 5px;
  }
  .session-explorer-root .legend-dot {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    flex-shrink: 0;
  }
  .session-explorer-root .bars {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  .session-explorer-root .bar-row {
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .session-explorer-root .bar-label {
    font-size: 12px;
    color: #555;
    width: 100px;
    flex-shrink: 0;
    text-align: right;
  }
  .session-explorer-root .bar-track {
    flex: 1;
    height: 22px;
    background: #f3f3f1;
    border-radius: 4px;
    overflow: hidden;
  }
  .session-explorer-root .bar-fill {
    height: 100%;
    border-radius: 4px;
    display: flex;
    align-items: center;
    padding-left: 8px;
    font-size: 11px;
    font-weight: 600;
    color: #fff;
    transition: width 0.6s ease;
  }
  .session-explorer-root .bar-count {
    font-size: 12px;
    color: #888;
    width: 60px;
    flex-shrink: 0;
  }
  .session-explorer-root .explorer {
    background: #fff;
    border: 1px solid #e5e5e5;
    border-radius: 10px;
    overflow: hidden;
    margin-bottom: 2rem;
  }
  .session-explorer-root .explorer-header {
    background: #f5f5f3;
    padding: 12px 16px;
    border-bottom: 1px solid #e5e5e5;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .session-explorer-root .explorer-header-title {
    font-size: 13px;
    font-weight: 600;
    color: #444;
  }
  .session-explorer-root .explorer-header-hint {
    font-size: 11px;
    color: #aaa;
  }
  .session-explorer-root .filter-row {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    padding: 10px 16px;
    border-bottom: 1px solid #e5e5e5;
    background: #fff;
  }
  .session-explorer-root .filter-btn {
    font-size: 12px;
    padding: 4px 11px;
    border-radius: 20px;
    border: 1px solid #d5d5d5;
    background: transparent;
    color: #666;
    cursor: pointer;
    transition: all 0.15s;
    font-family: inherit;
  }
  .session-explorer-root .filter-btn:hover { background: #f3f3f1; }
  .session-explorer-root .filter-btn.active {
    border-color: transparent;
    color: #fff;
    background: #2563eb;
  }
  .session-explorer-root .filter-btn.correction.active { background: #7c3aed; }
  .session-explorer-root .filter-btn.clarify.active { background: #dc2626; }
  .session-explorer-root .filter-btn.confirm.active { background: #16a34a; }
  .session-explorer-root .filter-btn.iterate.active { background: #d97706; }
  .session-explorer-root .filter-btn.task.active { background: #2563eb; }
  .session-explorer-root .msg-list { max-height: 340px; overflow-y: auto; }
  .session-explorer-root .msg-row {
    display: flex;
    gap: 10px;
    padding: 10px 16px;
    border-bottom: 1px solid #f0f0ee;
    align-items: flex-start;
    cursor: pointer;
    transition: background 0.1s;
  }
  .session-explorer-root .msg-row:last-child { border-bottom: none; }
  .session-explorer-root .msg-row:hover { background: #fafaf8; }
  .session-explorer-root .msg-row.selected { background: #eff6ff; }
  .session-explorer-root .badge {
    font-size: 10px;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 10px;
    flex-shrink: 0;
    margin-top: 1px;
    white-space: nowrap;
  }
  .session-explorer-root .badge-user { background: #eff6ff; color: #1d4ed8; }
  .session-explorer-root .badge-assistant { background: #f0fdf4; color: #15803d; }
  .session-explorer-root .badge-task { background: #eff6ff; color: #1e40af; }
  .session-explorer-root .badge-correction { background: #faf5ff; color: #6d28d9; }
  .session-explorer-root .badge-clarify { background: #fff1f2; color: #be123c; }
  .session-explorer-root .badge-confirm { background: #f0fdf4; color: #166534; }
  .session-explorer-root .badge-iterate { background: #fffbeb; color: #92400e; }
  .session-explorer-root .msg-text {
    flex: 1;
    font-size: 13px;
    line-height: 1.5;
    color: #333;
  }
  .session-explorer-root .msg-time {
    font-size: 11px;
    color: #bbb;
    flex-shrink: 0;
    margin-top: 2px;
  }
  .session-explorer-root .detail-panel {
    border-top: 1px solid #e5e5e5;
    padding: 14px 16px;
    background: #f9f9f7;
    display: none;
  }
  .session-explorer-root .detail-panel.visible { display: block; }
  .session-explorer-root .detail-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: #aaa;
    margin-bottom: 6px;
  }
  .session-explorer-root .detail-text {
    font-size: 13px;
    line-height: 1.65;
    color: #444;
  }
  .session-explorer-root .insight {
    border: 1px solid #e5e5e5;
    border-left: 3px solid #2563eb;
    border-radius: 8px;
    padding: 14px 16px;
    font-size: 13px;
    color: #555;
    line-height: 1.7;
    background: #fff;
  }
  .session-explorer-root .insight strong { color: #111; }

  @media (max-width: 640px) {
    .session-explorer-root {
      padding: 1.25rem 1rem;
      margin: 1.5rem auto;
    }
    .session-explorer-root .stat-row {
      grid-template-columns: 1fr;
    }
    .session-explorer-root .bar-row {
      align-items: flex-start;
      flex-direction: column;
      gap: 6px;
    }
    .session-explorer-root .bar-label,
    .session-explorer-root .bar-count {
      width: auto;
      text-align: left;
    }
    .session-explorer-root .explorer-header {
      flex-direction: column;
      align-items: flex-start;
      gap: 4px;
    }
  }
&lt;/style&gt;

&lt;div class=&quot;session-explorer-root&quot;&gt;
  &lt;h1&gt;What I Was Actually Doing&lt;/h1&gt;
  &lt;p class=&quot;subtitle&quot;&gt;One 10-day Claude Code session · 426 messages · 13.1M tokens&lt;/p&gt;
  &lt;p class=&quot;subtitle&quot;&gt;My own categorization of one real session after the fact — not a universal benchmark.&lt;/p&gt;
  &lt;p class=&quot;subtitle&quot;&gt;Just one slice of work: my habits, my tasks, my blind spots.&lt;/p&gt;

  &lt;p class=&quot;section-label&quot;&gt;This session at a glance&lt;/p&gt;
  &lt;div class=&quot;stat-row&quot;&gt;
    &lt;div class=&quot;stat-card&quot;&gt;
      &lt;div class=&quot;num&quot;&gt;426&lt;/div&gt;
      &lt;div class=&quot;lbl&quot;&gt;messages in this session&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;stat-card&quot;&gt;
      &lt;div class=&quot;num&quot;&gt;13.1M&lt;/div&gt;
      &lt;div class=&quot;lbl&quot;&gt;tokens used here&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;stat-card&quot;&gt;
      &lt;div class=&quot;num&quot;&gt;~63%&lt;/div&gt;
      &lt;div class=&quot;lbl&quot;&gt;non-task work in this session&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;p class=&quot;section-label&quot;&gt;The loop I kept seeing&lt;/p&gt;
  &lt;div class=&quot;loop-section&quot;&gt;
    &lt;p class=&quot;loop-intro&quot;&gt;
      In this session, the pattern was rarely prompt → answer → done. It was usually some version of this:
    &lt;/p&gt;
    &lt;div class=&quot;loop-row&quot;&gt;
      &lt;div class=&quot;loop-box&quot;&gt;intent&lt;/div&gt;
      &lt;div class=&quot;loop-arrow&quot;&gt;→&lt;/div&gt;
      &lt;div class=&quot;loop-box&quot;&gt;inspect&lt;/div&gt;
      &lt;div class=&quot;loop-arrow&quot;&gt;→&lt;/div&gt;
      &lt;div class=&quot;loop-box&quot;&gt;adjust&lt;/div&gt;
      &lt;div class=&quot;loop-arrow&quot;&gt;→&lt;/div&gt;
      &lt;div class=&quot;loop-box&quot;&gt;retry&lt;/div&gt;
      &lt;div class=&quot;loop-arrow&quot;&gt;→&lt;/div&gt;
      &lt;div class=&quot;loop-box loop-box-accent&quot;&gt;loop&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;p class=&quot;section-label&quot;&gt;How I broke down this session afterward&lt;/p&gt;
  &lt;div class=&quot;chart-section&quot;&gt;
    &lt;p class=&quot;chart-note&quot;&gt;
      These categories are my interpretation of what the messages were doing in this one session. They’re useful because they made the hidden work visible, not because they’re perfect.
    &lt;/p&gt;
    &lt;div class=&quot;legend&quot;&gt;
      &lt;span class=&quot;legend-item&quot;&gt;&lt;span class=&quot;legend-dot&quot; style=&quot;background:#2563eb&quot;&gt;&lt;/span&gt;Task&lt;/span&gt;
      &lt;span class=&quot;legend-item&quot;&gt;&lt;span class=&quot;legend-dot&quot; style=&quot;background:#7c3aed&quot;&gt;&lt;/span&gt;Correction&lt;/span&gt;
      &lt;span class=&quot;legend-item&quot;&gt;&lt;span class=&quot;legend-dot&quot; style=&quot;background:#dc2626&quot;&gt;&lt;/span&gt;Clarification&lt;/span&gt;
      &lt;span class=&quot;legend-item&quot;&gt;&lt;span class=&quot;legend-dot&quot; style=&quot;background:#16a34a&quot;&gt;&lt;/span&gt;Confirmation&lt;/span&gt;
      &lt;span class=&quot;legend-item&quot;&gt;&lt;span class=&quot;legend-dot&quot; style=&quot;background:#d97706&quot;&gt;&lt;/span&gt;Iteration&lt;/span&gt;
    &lt;/div&gt;
    &lt;div class=&quot;bars&quot;&gt;
      &lt;div class=&quot;bar-row&quot;&gt;
        &lt;div class=&quot;bar-label&quot;&gt;Task&lt;/div&gt;
        &lt;div class=&quot;bar-track&quot;&gt;&lt;div class=&quot;bar-fill&quot; style=&quot;background:#2563eb; width:37%&quot;&gt;37%&lt;/div&gt;&lt;/div&gt;
        &lt;div class=&quot;bar-count&quot;&gt;158 msgs&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;bar-row&quot;&gt;
        &lt;div class=&quot;bar-label&quot;&gt;Correction&lt;/div&gt;
        &lt;div class=&quot;bar-track&quot;&gt;&lt;div class=&quot;bar-fill&quot; style=&quot;background:#7c3aed; width:23%&quot;&gt;23%&lt;/div&gt;&lt;/div&gt;
        &lt;div class=&quot;bar-count&quot;&gt;98 msgs&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;bar-row&quot;&gt;
        &lt;div class=&quot;bar-label&quot;&gt;Iteration&lt;/div&gt;
        &lt;div class=&quot;bar-track&quot;&gt;&lt;div class=&quot;bar-fill&quot; style=&quot;background:#d97706; width:17%&quot;&gt;17%&lt;/div&gt;&lt;/div&gt;
        &lt;div class=&quot;bar-count&quot;&gt;74 msgs&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;bar-row&quot;&gt;
        &lt;div class=&quot;bar-label&quot;&gt;Clarification&lt;/div&gt;
        &lt;div class=&quot;bar-track&quot;&gt;&lt;div class=&quot;bar-fill&quot; style=&quot;background:#dc2626; width:12%&quot;&gt;12%&lt;/div&gt;&lt;/div&gt;
        &lt;div class=&quot;bar-count&quot;&gt;52 msgs&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;bar-row&quot;&gt;
        &lt;div class=&quot;bar-label&quot;&gt;Confirmation&lt;/div&gt;
        &lt;div class=&quot;bar-track&quot;&gt;&lt;div class=&quot;bar-fill&quot; style=&quot;background:#16a34a; width:10%&quot;&gt;10%&lt;/div&gt;&lt;/div&gt;
        &lt;div class=&quot;bar-count&quot;&gt;44 msgs&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;p class=&quot;section-label&quot;&gt;Browse moments from this session&lt;/p&gt;
  &lt;div class=&quot;explorer&quot;&gt;
    &lt;div class=&quot;explorer-header&quot;&gt;
      &lt;span class=&quot;explorer-header-title&quot;&gt;Messages from this session&lt;/span&gt;
      &lt;span class=&quot;explorer-header-hint&quot;&gt;click any row to see why I think it mattered&lt;/span&gt;
    &lt;/div&gt;
    &lt;div class=&quot;filter-row&quot;&gt;
      &lt;button class=&quot;filter-btn active&quot; onclick=&quot;filterMsgs(&apos;all&apos;, this)&quot;&gt;All&lt;/button&gt;
      &lt;button class=&quot;filter-btn task&quot; onclick=&quot;filterMsgs(&apos;task&apos;, this)&quot;&gt;Task&lt;/button&gt;
      &lt;button class=&quot;filter-btn clarify&quot; onclick=&quot;filterMsgs(&apos;clarify&apos;, this)&quot;&gt;Clarification&lt;/button&gt;
      &lt;button class=&quot;filter-btn iterate&quot; onclick=&quot;filterMsgs(&apos;iterate&apos;, this)&quot;&gt;Iteration&lt;/button&gt;
      &lt;button class=&quot;filter-btn confirm&quot; onclick=&quot;filterMsgs(&apos;confirm&apos;, this)&quot;&gt;Confirmation&lt;/button&gt;
      &lt;button class=&quot;filter-btn correction&quot; onclick=&quot;filterMsgs(&apos;correction&apos;, this)&quot;&gt;Correction&lt;/button&gt;
    &lt;/div&gt;
    &lt;div class=&quot;msg-list&quot; id=&quot;msgList&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;detail-panel&quot; id=&quot;detailPanel&quot;&gt;
      &lt;div class=&quot;detail-label&quot;&gt;Why I included this one&lt;/div&gt;
      &lt;div class=&quot;detail-text&quot; id=&quot;detailText&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;script&gt;
    const messages = [
      {
        role: &apos;user&apos;, type: &apos;clarify&apos;, time: &apos;Mar 18&apos;,
        text: &apos;do you have a teleport command that pulls conversations from project conversations?&apos;,
        detail: &apos;I included this because it shows how early the session had to establish basic constraints before any real task work could happen. This wasn’t failure. It was groundwork.&apos;
      },
      {
        role: &apos;assistant&apos;, type: &apos;correction&apos;, time: &apos;Mar 18&apos;,
        text: &apos;I can\&apos;t directly access Claude.ai Projects — there\&apos;s no integration between Claude Code and Claude.ai\&apos;s project/conversation history.&apos;,
        detail: &apos;This felt important because it corrected the map we were both working from. The issue wasn’t the task yet. It was that the session needed a shared picture of what was even possible.&apos;
      },
      {
        role: &apos;user&apos;, type: &apos;correction&apos;, time: &apos;Mar 18&apos;,
        text: &apos;they\&apos;re svgs. You can find them in documents/ai blogpost&apos;,
        detail: &apos;I counted this as correction because it changed the working assumptions. The model had made a reasonable placeholder guess. Reality turned out to be different.&apos;
      },
      {
        role: &apos;assistant&apos;, type: &apos;correction&apos;, time: &apos;Mar 18&apos;,
        text: &apos;Two filenames don\&apos;t match what\&apos;s in the post: ai-llms-model.svg (not ai-llms-models.svg) and context_window.svg (not context-window.svg).&apos;,
        detail: &apos;This one mattered because it made state alignment visible. The work itself was simple. The extra overhead came from reconciling assumptions with what actually existed.&apos;
      },
      {
        role: &apos;user&apos;, type: &apos;confirm&apos;, time: &apos;Mar 18&apos;,
        text: &apos;does the 2026 folder exist? I don\&apos;t see it&apos;,
        detail: &apos;I treated this as confirmation because it didn’t add new task progress. It was me checking whether a prior change had actually landed the way I thought it had.&apos;
      },
      {
        role: &apos;user&apos;, type: &apos;task&apos;, time: &apos;Mar 22&apos;,
        text: &apos;add the interactive session explorer to the post using the existing Jekyll layout&apos;,
        detail: &apos;I included this as task work because the goal was clear and scoped. The constraints were already established, so it didn’t require the same back-and-forth as earlier parts of the session.&apos;
      },
      {
        role: &apos;user&apos;, type: &apos;iterate&apos;, time: &apos;Mar 27&apos;,
        text: &apos;Keep the current design. Add 6–10 total CSS-only twinkles across the component. Make them sparse, elegant, warm-gold/ivory, and subtle. No glitter, no icons, no busy animation, no JS changes.&apos;,
        detail: &apos;This is iteration, but it also shows accumulated learning. By this point, the prompt is carrying the residue of earlier misses: what to avoid, what to keep, what not to overdo.&apos;
      },
      {
        role: &apos;assistant&apos;, type: &apos;correction&apos;, time: &apos;Mar 27&apos;,
        text: &apos;The sparkles are blurry glowing halos (8–20px blur), not sharp 1–2px dots — mine are invisible at that size. The active element has a dramatic ambient glow extending well beyond its border.&apos;,
        detail: &apos;I saw this as semantic correction. The word “sparkles” wasn’t enough on its own. The session had to work toward shared visual meaning, and that took multiple turns.&apos;
      },
      {
        role: &apos;user&apos;, type: &apos;iterate&apos;, time: &apos;Mar 27&apos;,
        text: &apos;it doesn\&apos;t look like the image I gave you. Are you able to see the image?&apos;,
        detail: &apos;I included this because it captures the feeling of being inside the loop. Before the work could improve, I had to make sure we were even working from the same reference.&apos;
      },
      {
        role: &apos;user&apos;, type: &apos;iterate&apos;, time: &apos;Mar 27&apos;,
        text: &apos;maybe the issue is the color palette. It looks dirty, not magical. the sparkles should be bright, like a star or a light bulb.&apos;,
        detail: &apos;This one feels especially personal to me because it shows where my own weak spots were showing up. I’m not a designer, and visual nuance took me more rounds to express cleanly.&apos;
      },
      {
        role: &apos;assistant&apos;, type: &apos;correction&apos;, time: &apos;Mar 27&apos;,
        text: &apos;The issue is clear — the palette is all muted amber-brown. Stars and light bulbs have a near-white/bright-yellow core. I need to shift sparkle colors toward bright white-yellow with high opacity.&apos;,
        detail: &apos;This is the point where the meaning finally locks in. The technical fix isn’t the interesting part. The interesting part is how long it took to arrive at a shared understanding.&apos;
      }
    ];

    let currentFilter = &apos;all&apos;;
    let selectedIdx = null;

    function filterMsgs(type, btn) {
      currentFilter = type;
      document.querySelectorAll(&apos;.filter-btn&apos;).forEach(b =&gt; b.classList.remove(&apos;active&apos;));
      btn.classList.add(&apos;active&apos;);
      selectedIdx = null;
      document.getElementById(&apos;detailPanel&apos;).classList.remove(&apos;visible&apos;);
      renderList();
    }

    function selectMsg(idx) {
      selectedIdx = idx;
      const m = messages[idx];
      document.getElementById(&apos;detailText&apos;).textContent = m.detail;
      document.getElementById(&apos;detailPanel&apos;).classList.add(&apos;visible&apos;);
      renderList();
    }

    function renderList() {
      const list = document.getElementById(&apos;msgList&apos;);
      const filtered = messages
        .map((m, i) =&gt; ({ ...m, origIdx: i }))
        .filter(m =&gt; currentFilter === &apos;all&apos; || m.type === currentFilter);

      if (!filtered.length) {
        list.innerHTML = &apos;&lt;div style=&quot;padding:20px 16px; font-size:13px; color:#aaa;&quot;&gt;No messages in this category.&lt;/div&gt;&apos;;
        return;
      }

      list.innerHTML = filtered.map(m =&gt; `
        &lt;div class=&quot;msg-row${selectedIdx === m.origIdx ? &apos; selected&apos; : &apos;&apos;}&quot; onclick=&quot;selectMsg(${m.origIdx})&quot;&gt;
          &lt;span class=&quot;badge badge-${m.role}&quot;&gt;${m.role}&lt;/span&gt;
          &lt;span class=&quot;badge badge-${m.type}&quot;&gt;${m.type}&lt;/span&gt;
          &lt;span class=&quot;msg-text&quot;&gt;${m.text}&lt;/span&gt;
          &lt;span class=&quot;msg-time&quot;&gt;${m.time}&lt;/span&gt;
        &lt;/div&gt;
      `).join(&apos;&apos;);
    }

    renderList();
  &lt;/script&gt;
&lt;/div&gt;

&lt;h2 id=&quot;three-kinds-of-alignment-work&quot;&gt;Three kinds of alignment work&lt;/h2&gt;

&lt;p&gt;But the alignment tax isn’t just one thing. Here are some different ways I saw it showing up:&lt;/p&gt;

&lt;h3 id=&quot;semantic-alignment&quot;&gt;Semantic Alignment&lt;/h3&gt;

&lt;p&gt;Semantic alignment is when you and the model are using the same words but not meaning the same thing.&lt;/p&gt;

&lt;p&gt;In my session, the clearest example was visual. I said “sparkles” and meant blurry glowing halos, almost star-like. The model implemented tiny 1–2px dots. Technically sparkles. Not remotely what I meant. We spent multiple rounds getting to the same picture with the same word.&lt;/p&gt;

&lt;p&gt;That’s not the model being irrational. It’s a reminder that language is doing more work than we think.&lt;/p&gt;

&lt;h3 id=&quot;structural-alignment&quot;&gt;Structural Alignment&lt;/h3&gt;

&lt;p&gt;Structural alignment is when you and the model are working from different maps of the territory.&lt;/p&gt;

&lt;p&gt;At one point I asked it to find files in documents/ai blogpost. The model didn’t have access to that directory. That wasn’t obvious to either of us until it tried. The problem wasn’t wording. It was environment.&lt;/p&gt;

&lt;h3 id=&quot;state-alignment&quot;&gt;State Alignment&lt;/h3&gt;

&lt;p&gt;State alignment is the ongoing work of keeping the model current as reality changes.&lt;/p&gt;

&lt;p&gt;Placeholder filenames became real filenames. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tapes.db&lt;/code&gt; became &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tapes.sqlite&lt;/code&gt;. A new directory appeared, a file moved, a new project meant shifts in structure. Every time the ground truth shifted, there was work to sync the model’s working assumptions with what was actually true.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Intent → Model assumes X → Output based on X
         ↑                          ↓
         └── Correction: X is wrong, Y is true ──┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;why-traces-and-telemetry-matter-for-ai-agents&quot;&gt;Why Traces and Telemetry Matter for AI Agents&lt;/h2&gt;

&lt;p&gt;Let’s be fair. A lot of the alignment tax was on me. In my session, visual design tasks had the highest alignment tax by far. Trying to describe what I wanted something to &lt;em&gt;look&lt;/em&gt; like in precise enough language for the model to execute. This is probably obvious, but I am not a designer.&lt;/p&gt;

&lt;p&gt;It’s worth calling out because that means some of what I’m calling alignment tax is really a mismatch between the kind of work I’m doing and the precision I can bring to it. I can usually describe structural changes pretty cleanly. I am much worse at describing visual nuance on the first try.&lt;/p&gt;

&lt;p&gt;Once you can see your own patterns, you can do something with them. You can front-load more context, change how you prompt, reach for examples earlier, or you can recognize a certain kind of task is going to cost you more than it would cost someone whose specialty actually lives there.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://tapes.dev/&quot;&gt;tapes&lt;/a&gt; didn’t just surface what happened in my session. It made the structure of the session visible. I could see where interpretation drifted, where retries piled up, where assumptions entered, and where progress slowed down. It showed me where I tended to loop. It showed me my own weak spots that are causing extra alignment overhead. It helped me identify where another person’s workflow or skill might help me collapse my five rounds into one. In my mind, this is a way to identify where shared skills could actually matter.&lt;/p&gt;

&lt;p&gt;Digging deeper into the data, I was able to recognize a set of handoffs between intention, interpretation, execution, correction, and continuation.&lt;/p&gt;

&lt;p&gt;That’s why I think words like traces and telemetry matter here, especially for agents.&lt;/p&gt;

&lt;p&gt;When an agent or model touches real work, the question isn’t just “did it respond?” It’s:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;what happened, in what order&lt;/li&gt;
  &lt;li&gt;where did assumptions enter&lt;/li&gt;
  &lt;li&gt;where did retries pile up&lt;/li&gt;
  &lt;li&gt;where did the workflow get expensive&lt;/li&gt;
  &lt;li&gt;where did it break down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Logs can tell you that something happened, but traces and telemetry help you see how it happened.&lt;/p&gt;

&lt;p&gt;As these systems become more agentic, more tool-driven, and more multi-step, that visibility matters more, not less.&lt;/p&gt;

&lt;h2 id=&quot;why-ai-productivity-can-be-misleading&quot;&gt;Why AI productivity can be misleading&lt;/h2&gt;

&lt;p&gt;The word “productive” feels inherited from a world where work was easier to isolate. Alignment work looks a lot like task work from the outside. You’re still typing, responding, and making progress at least some of the time. But not all forward motion is equal. Some of that motion is the work, some is maintaining the conditions under which the work can happen. Not just so we can complain about it (although I have), but because it gives us something we can look at directly.&lt;/p&gt;

&lt;p&gt;I don’t think this underlying issue is unique to me. I think a lot of users are saying “prompting” but what we mean is a mix of execution, interpretation, repair, and syncronization. tapes gave me a way to inspect where my workflow looped, drifted, retried, and recovered, so I can start asking better questions and not just, “did this work” or “was this fast.” Now I’m more concerned with questions like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Where did alignment break down?&lt;/li&gt;
  &lt;li&gt;Which tasks cost me the most overhead?&lt;/li&gt;
  &lt;li&gt;What am I personally bad at expressing?&lt;/li&gt;
  &lt;li&gt;Which skills would reduce that tax if I reused them from someone better at this kind of work?&lt;/li&gt;
  &lt;li&gt;What patterns keep repeating across sessions?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This feels like a better starting point, and more precise work.&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//hidden-ai-work</link>
        <guid isPermaLink="true">https://bekahhw.com//hidden-ai-work</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>DevRel</category>
        
        <category>Developer Experience</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>How AI Tools Talk to Each Other</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Part of the AI Foundations series.&lt;/strong&gt; New to AI? Start with &lt;a href=&quot;https://bekahhw.com/AI-Vocabulary-101&quot;&gt;AI Vocabulary 101&lt;/a&gt; and &lt;a href=&quot;https://bekahhw.com/AI-102&quot;&gt;AI 102&lt;/a&gt; before diving in here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This weekend, my daughter ran in her first high school track meet. One of the other girls relay teams was disqualified for dropping the baton. I don’t know much about track, so I was surprised to learn that dropping the baton can result in a DQ (disqualification). The thing that really sucks is that those girls were the fastest team, even after having to recover the dropped baton. But, at the end of the meet, it doesn’t matter how fast each runner is if the baton doesn’t make it across the finish line without the team getting DQed. The team has to work together, and the baton is the thing that connects them.&lt;/p&gt;

&lt;p&gt;It’s kind of like what’s happening when AI tools communicate. The intelligence of each individual tool matters less than whether they can pass information to each other cleanly. And most beginners don’t realize this until something breaks and they’re staring at an error message with no idea where to start.&lt;/p&gt;

&lt;p&gt;Most AI tool communication happens through a small number of patterns. Once you recognize them, debugging stops feeling like magic and starts feeling like plumbing.&lt;/p&gt;

&lt;h2 id=&quot;everything-is-a-message&quot;&gt;Everything is a Message&lt;/h2&gt;

&lt;p&gt;If you’ve ever wondered why some AI tools feel instant while others make you wait, or why a multi-step AI workflow sometimes just… stops mid-chain, it comes down to three fundamental communication patterns.&lt;/p&gt;

&lt;p&gt;When one piece of an AI system needs to talk to another, it sends a message. That message is almost always structured as JSON, which sounds intimidating but is really just organized text.&lt;/p&gt;

&lt;p&gt;Think about ordering food at a restaurant. You don’t just say “I want stuff.” You say “I want a burger, medium, no onions, with fries.” That structure is what lets the kitchen actually process your order. JSON is the same idea. It organizes information into labeled fields so the receiving tool knows exactly what it’s looking at.&lt;/p&gt;

&lt;p&gt;A simple JSON message might look like this:&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;search&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;query&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;best pizza in New York&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;results&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The API, or Application Programming Interface, is the agreement between two tools about what fields to expect and what format they’ll be in.&lt;/p&gt;

&lt;p&gt;Here’s what that looks like in practice. Say you’re building a workflow where someone submits a form on your site, and you want an AI to draft a personalized response. Your form tool sends a message to the LLM that might look like this:&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Jordan&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;question&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;How do I get started with open source?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;experience_level&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;beginner&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The LLM knows to look for those fields because your API agreement says they’ll be there. It uses name to personalize the reply, question to know what to answer, and experience_level to calibrate how technical to get.&lt;/p&gt;

&lt;p&gt;Now imagine your form tool sends this instead:&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Jordan&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;inquiry&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;How do I get started with open source?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;level&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;beginner&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The LLM is now confused because it was expecting “name,” “question,” and “experience_level.” The LLM goes looking for name and finds nothing. It goes looking for question and finds nothing. The chain breaks, not because anything was wrong with the content, but because the tools weren’t speaking the same language.&lt;/p&gt;

&lt;style&gt;
/* ─── Shared container + atmosphere ───────────────────── */
.aic-container {
  font-family: inherit;
  max-width: 700px;
  margin: 2.5rem auto;
  position: relative;
  overflow: hidden;
  background: linear-gradient(160deg, #f9f3e7 0%, #fdf8ef 42%, #f5ebd8 100%);
  border: 1px solid rgba(130,88,8,0.55);
  border-radius: 16px;
  box-shadow:
    0 20px 50px rgba(120,90,30,0.10),
    0 0 0 1px rgba(255,220,80,0.18),
    inset 0 0 0 1px rgba(255,230,120,0.28),
    inset 0 1px 0 rgba(255,255,220,0.85);
  --aic-gold:        #c59c50;
  --aic-gold-light:  #e8c060;
  --aic-active:      #6b4a0e;
  --aic-active-dark: #5a3a08;
  --aic-muted:       #7a6a50;
  --aic-caption:     #4a3f2f;
  --aic-label:       #9a7a30;
  --aic-success:     #6b5c14;
  --aic-text-muted:  #7a6a50;
  --aic-danger:      #8a2a18;
}
.aic-container::before {
  content: &apos;&apos;;
  position: absolute;
  top: -40px; left: 50%;
  transform: translateX(-50%);
  width: 680px; height: 340px;
  background: radial-gradient(ellipse at center,
    rgba(255,250,200,0.38) 0%,
    rgba(255,220,80,0.15) 38%,
    rgba(220,170,40,0.05) 62%,
    transparent 75%);
  pointer-events: none; z-index: 0;
}
.aic-container::after {
  content: &apos;&apos;;
  position: absolute;
  bottom: -60px; right: -50px;
  width: 440px; height: 360px;
  background: radial-gradient(ellipse at center,
    rgba(255,220,80,0.14) 0%,
    rgba(220,170,40,0.06) 50%,
    transparent 70%);
  pointer-events: none; z-index: 0;
}
.aic-section { position: relative; z-index: 1; padding: 2rem 2rem 1.75rem; }
.aic-section-title {
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--aic-label);
  margin: 0 0 1.5rem; padding-bottom: 0.7rem; position: relative;
  text-shadow: 0 0 28px rgba(197,156,80,0.38), 0 0 10px rgba(232,192,96,0.22);
}
.aic-section-title::after {
  content: &apos;&apos;; position: absolute; bottom: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, rgba(197,156,80,0.55), rgba(197,156,80,0.18) 60%, transparent);
}
/* Buttons */
.aic-btn {
  padding: 0.44rem 1.15rem;
  border: 1px solid rgba(197,156,80,0.48); border-radius: 6px;
  background: linear-gradient(180deg, rgba(255,250,238,0.95) 0%, rgba(244,230,198,0.90) 100%);
  color: #5a3a08; cursor: pointer; font-family: inherit;
  font-size: 0.82rem; font-weight: 500; line-height: 1.4;
  box-shadow: 0 2px 10px rgba(197,156,80,0.08), inset 0 1px 0 rgba(255,255,255,0.70);
  transition: background 0.18s, border-color 0.18s, box-shadow 0.18s, transform 0.14s;
}
.aic-btn:hover:not(:disabled) {
  background: linear-gradient(180deg, rgba(255,252,242,1) 0%, rgba(248,234,205,1) 100%);
  border-color: rgba(197,156,80,0.72);
  box-shadow: 0 4px 16px rgba(197,156,80,0.18), inset 0 1px 0 rgba(255,255,255,0.75);
  transform: translateY(-1px);
}
.aic-btn:focus-visible { outline: 2px solid #6b4a0e; outline-offset: 3px; }
.aic-btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
/* Sparkle cloud */
.aic-sparkle-cloud {
  position: absolute; top: 0; left: 0;
  width: 2px; height: 2px; border-radius: 50%;
  background: rgba(255,255,220,0.90);
  pointer-events: none; z-index: 1;
  box-shadow:
     88px  46px  6px  1px rgba(255,255,220,0.85),  88px  46px 20px  6px rgba(255,210, 60,0.40),  88px  46px 44px 14px rgba(220,160, 30,0.14),
    310px  22px  6px  1px rgba(255,255,220,0.80), 310px  22px 18px  5px rgba(255,210, 60,0.38), 310px  22px 40px 12px rgba(220,160, 30,0.12),
     48px 165px  6px  1px rgba(255,255,220,0.75),  48px 165px 20px  6px rgba(255,210, 60,0.34),  48px 165px 44px 14px rgba(220,160, 30,0.10),
    510px  58px  5px  1px rgba(255,255,220,0.78), 510px  58px 16px  5px rgba(255,210, 60,0.35), 510px  58px 38px 11px rgba(220,160, 30,0.11),
    210px 130px  5px  1px rgba(255,255,220,0.70), 210px 130px 14px  4px rgba(255,210, 60,0.30), 210px 130px 36px 10px rgba(220,160, 30,0.09);
}
/* jm- specific styles */
.jm-cols {
  display: flex; gap: 1rem; margin-bottom: 1rem;
}
.jm-col { flex: 1; min-width: 0; }
.jm-col-label {
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.10em;
  text-transform: uppercase; color: var(--aic-label);
  margin-bottom: 0.5rem;
}
.jm-json {
  background: linear-gradient(180deg, rgba(255,252,244,0.96), rgba(250,242,224,0.90));
  border: 1px solid rgba(120,80,5,0.38);
  border-radius: 8px; overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255,255,220,0.70);
}
.jm-field {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.45rem 0.75rem;
  font-size: 0.78rem; font-family: &apos;Courier New&apos;, monospace;
  color: #4a3f2f; border-left: 3px solid transparent;
  transition: background 0.35s, border-color 0.35s, color 0.35s;
  border-bottom: 1px solid rgba(197,156,80,0.10);
}
.jm-field:last-child { border-bottom: none; }
.jm-field .jm-key { flex: 1; }
.jm-field .jm-indicator {
  font-size: 0.9rem; margin-left: 0.5rem; opacity: 0;
  transition: opacity 0.35s;
}
.jm-field.jm-ok {
  border-left-color: rgba(80,160,80,0.65);
  background: rgba(220,250,220,0.25);
  color: #2a5a2a;
}
.jm-field.jm-ok .jm-indicator { opacity: 1; }
.jm-field.jm-err {
  border-left-color: rgba(192,64,48,0.65);
  background: rgba(255,220,215,0.25);
  color: #8a2a18;
}
.jm-field.jm-err .jm-indicator { opacity: 1; }
.jm-result {
  text-align: center; font-size: 0.82rem; font-weight: 600;
  padding: 0.55rem 1rem; border-radius: 6px; margin-bottom: 1rem;
  transition: background 0.35s, color 0.35s;
  min-height: 2.2em; display: flex; align-items: center; justify-content: center;
}
.jm-result.jm-result-ok {
  background: rgba(220,250,220,0.45); color: #2a5a2a;
  border: 1px solid rgba(80,160,80,0.30);
}
.jm-result.jm-result-err {
  background: rgba(255,220,215,0.45); color: #8a2a18;
  border: 1px solid rgba(192,64,48,0.30);
}
.jm-controls { display: flex; justify-content: center; }
@media (max-width: 520px) {
  .jm-cols { flex-direction: column; }
  .aic-section { padding: 1.25rem 1rem 1rem; }
}
&lt;/style&gt;

&lt;div class=&quot;aic-container&quot; id=&quot;jm-container&quot;&gt;
  &lt;div class=&quot;aic-sparkle-cloud&quot; aria-hidden=&quot;true&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;aic-section&quot;&gt;
    &lt;p class=&quot;aic-section-title&quot;&gt;Try it: field name mismatch&lt;/p&gt;
    &lt;div class=&quot;jm-cols&quot;&gt;
      &lt;div class=&quot;jm-col&quot;&gt;
        &lt;div class=&quot;jm-col-label&quot;&gt;API expects&lt;/div&gt;
        &lt;div class=&quot;jm-json&quot;&gt;
          &lt;div class=&quot;jm-field&quot; id=&quot;jm-exp-0&quot;&gt;
            &lt;span class=&quot;jm-key&quot;&gt;&quot;name&quot;&lt;/span&gt;
            &lt;span class=&quot;jm-indicator&quot; id=&quot;jm-ind-exp-0&quot;&gt;&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;jm-field&quot; id=&quot;jm-exp-1&quot;&gt;
            &lt;span class=&quot;jm-key&quot;&gt;&quot;question&quot;&lt;/span&gt;
            &lt;span class=&quot;jm-indicator&quot; id=&quot;jm-ind-exp-1&quot;&gt;&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;jm-field&quot; id=&quot;jm-exp-2&quot;&gt;
            &lt;span class=&quot;jm-key&quot;&gt;&quot;experience_level&quot;&lt;/span&gt;
            &lt;span class=&quot;jm-indicator&quot; id=&quot;jm-ind-exp-2&quot;&gt;&lt;/span&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;jm-col&quot;&gt;
        &lt;div class=&quot;jm-col-label&quot;&gt;What you sent&lt;/div&gt;
        &lt;div class=&quot;jm-json&quot;&gt;
          &lt;div class=&quot;jm-field&quot; id=&quot;jm-sent-0&quot;&gt;
            &lt;span class=&quot;jm-key&quot; id=&quot;jm-key-0&quot;&gt;&quot;username&quot;&lt;/span&gt;
            &lt;span class=&quot;jm-indicator&quot; id=&quot;jm-ind-sent-0&quot;&gt;&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;jm-field&quot; id=&quot;jm-sent-1&quot;&gt;
            &lt;span class=&quot;jm-key&quot; id=&quot;jm-key-1&quot;&gt;&quot;inquiry&quot;&lt;/span&gt;
            &lt;span class=&quot;jm-indicator&quot; id=&quot;jm-ind-sent-1&quot;&gt;&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;jm-field&quot; id=&quot;jm-sent-2&quot;&gt;
            &lt;span class=&quot;jm-key&quot; id=&quot;jm-key-2&quot;&gt;&quot;level&quot;&lt;/span&gt;
            &lt;span class=&quot;jm-indicator&quot; id=&quot;jm-ind-sent-2&quot;&gt;&lt;/span&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;jm-result&quot; id=&quot;jm-result&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;jm-controls&quot;&gt;
      &lt;button class=&quot;aic-btn&quot; id=&quot;jm-toggle&quot;&gt;Show the fix →&lt;/button&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
(function () {
  &apos;use strict&apos;;

  var state = &apos;broken&apos;; // default

  var BROKEN_KEYS = [&apos;&quot;username&quot;&apos;, &apos;&quot;inquiry&quot;&apos;, &apos;&quot;level&quot;&apos;];
  var FIXED_KEYS  = [&apos;&quot;name&quot;&apos;,     &apos;&quot;question&quot;&apos;, &apos;&quot;experience_level&quot;&apos;];

  var toggleBtn = document.getElementById(&apos;jm-toggle&apos;);
  var resultEl  = document.getElementById(&apos;jm-result&apos;);

  function getSentField(i)    { return document.getElementById(&apos;jm-sent-&apos; + i); }
  function getSentKey(i)      { return document.getElementById(&apos;jm-key-&apos; + i); }
  function getSentInd(i)      { return document.getElementById(&apos;jm-ind-sent-&apos; + i); }
  function getExpField(i)     { return document.getElementById(&apos;jm-exp-&apos; + i); }
  function getExpInd(i)       { return document.getElementById(&apos;jm-ind-exp-&apos; + i); }

  function applyBroken() {
    for (var i = 0; i &lt; 3; i++) {
      var sf  = getSentField(i);
      var sk  = getSentKey(i);
      var si  = getSentInd(i);
      var ef  = getExpField(i);
      var ei  = getExpInd(i);

      if (sk) sk.textContent = BROKEN_KEYS[i];

      if (sf) { sf.classList.remove(&apos;jm-ok&apos;); sf.classList.add(&apos;jm-err&apos;); }
      if (si) si.textContent = &apos;✗&apos;;
      if (ef) { ef.classList.remove(&apos;jm-ok&apos;); ef.classList.add(&apos;jm-err&apos;); }
      if (ei) ei.textContent = &apos;✗&apos;;
    }

    if (resultEl) {
      resultEl.textContent = &apos;✗ Fields not found — chain breaks here&apos;;
      resultEl.className   = &apos;jm-result jm-result-err&apos;;
    }
    if (toggleBtn) toggleBtn.textContent = &apos;Show the fix →&apos;;
    state = &apos;broken&apos;;
  }

  function applyFixed() {
    for (var i = 0; i &lt; 3; i++) {
      var sf  = getSentField(i);
      var sk  = getSentKey(i);
      var si  = getSentInd(i);
      var ef  = getExpField(i);
      var ei  = getExpInd(i);

      if (sk) sk.textContent = FIXED_KEYS[i];

      if (sf) { sf.classList.remove(&apos;jm-err&apos;); sf.classList.add(&apos;jm-ok&apos;); }
      if (si) si.textContent = &apos;✓&apos;;
      if (ef) { ef.classList.remove(&apos;jm-err&apos;); ef.classList.add(&apos;jm-ok&apos;); }
      if (ei) ei.textContent = &apos;✓&apos;;
    }

    if (resultEl) {
      resultEl.textContent = &apos;✓ Fields matched — chain continues&apos;;
      resultEl.className   = &apos;jm-result jm-result-ok&apos;;
    }
    if (toggleBtn) toggleBtn.textContent = &apos;← Show what breaks&apos;;
    state = &apos;fixed&apos;;
  }

  function cascadeTo(targetFn) {
    // Clear all first
    for (var i = 0; i &lt; 3; i++) {
      var sf = getSentField(i);
      var ef = getExpField(i);
      var si = getSentInd(i);
      var ei = getExpInd(i);
      if (sf) { sf.classList.remove(&apos;jm-ok&apos;, &apos;jm-err&apos;); }
      if (ef) { ef.classList.remove(&apos;jm-ok&apos;, &apos;jm-err&apos;); }
      if (si) si.textContent = &apos;&apos;;
      if (ei) ei.textContent = &apos;&apos;;
    }
    if (resultEl) {
      resultEl.textContent = &apos;&apos;;
      resultEl.className   = &apos;jm-result&apos;;
    }

    // Cascade field updates
    var delays = [0, 120, 240];
    for (var j = 0; j &lt; 3; j++) {
      (function (idx) {
        setTimeout(function () {
          targetFn === &apos;fixed&apos; ? applyFixedField(idx) : applyBrokenField(idx);
        }, delays[idx]);
      })(j);
    }

    // Apply result after last field
    setTimeout(function () {
      if (targetFn === &apos;fixed&apos;) {
        if (resultEl) {
          resultEl.textContent = &apos;✓ Fields matched — chain continues&apos;;
          resultEl.className   = &apos;jm-result jm-result-ok&apos;;
        }
        if (toggleBtn) toggleBtn.textContent = &apos;← Show what breaks&apos;;
        state = &apos;fixed&apos;;
      } else {
        if (resultEl) {
          resultEl.textContent = &apos;✗ Fields not found — chain breaks here&apos;;
          resultEl.className   = &apos;jm-result jm-result-err&apos;;
        }
        if (toggleBtn) toggleBtn.textContent = &apos;Show the fix →&apos;;
        state = &apos;broken&apos;;
      }
    }, delays[2] + 180);
  }

  function applyBrokenField(i) {
    var sf = getSentField(i);
    var sk = getSentKey(i);
    var si = getSentInd(i);
    var ef = getExpField(i);
    var ei = getExpInd(i);
    if (sk) sk.textContent = BROKEN_KEYS[i];
    if (sf) { sf.classList.remove(&apos;jm-ok&apos;); sf.classList.add(&apos;jm-err&apos;); }
    if (si) si.textContent = &apos;✗&apos;;
    if (ef) { ef.classList.remove(&apos;jm-ok&apos;); ef.classList.add(&apos;jm-err&apos;); }
    if (ei) ei.textContent = &apos;✗&apos;;
  }

  function applyFixedField(i) {
    var sf = getSentField(i);
    var sk = getSentKey(i);
    var si = getSentInd(i);
    var ef = getExpField(i);
    var ei = getExpInd(i);
    if (sk) sk.textContent = FIXED_KEYS[i];
    if (sf) { sf.classList.remove(&apos;jm-err&apos;); sf.classList.add(&apos;jm-ok&apos;); }
    if (si) si.textContent = &apos;✓&apos;;
    if (ef) { ef.classList.remove(&apos;jm-err&apos;); ef.classList.add(&apos;jm-ok&apos;); }
    if (ei) ei.textContent = &apos;✓&apos;;
  }

  if (toggleBtn) {
    toggleBtn.addEventListener(&apos;click&apos;, function () {
      if (state === &apos;broken&apos;) {
        cascadeTo(&apos;fixed&apos;);
      } else {
        cascadeTo(&apos;broken&apos;);
      }
    });
  }

  // Initialize in broken state
  applyBroken();

})();
&lt;/script&gt;

&lt;p&gt;When something breaks in a tool chain, it’s almost always because one tool sent a message the next tool didn’t understand. Wrong format. Missing field. Unexpected data type. The fix is rarely complicated. But you have to know that’s where to look.&lt;/p&gt;

&lt;h2 id=&quot;three-ways-ai-tools-communicate&quot;&gt;Three Ways AI Tools Communicate&lt;/h2&gt;

&lt;p&gt;Before we dig into the details, let’s look at how these patterns work in practice. The interactive demo below lets you step through each one.&lt;/p&gt;

&lt;style&gt;
/* ─── Shared container + atmosphere ───────────────────── */
.aic-container {
  font-family: inherit;
  max-width: 700px;
  margin: 2.5rem auto;
  position: relative;
  overflow: hidden;
  background: linear-gradient(160deg, #f9f3e7 0%, #fdf8ef 42%, #f5ebd8 100%);
  border: 1px solid rgba(130,88,8,0.55);
  border-radius: 16px;
  box-shadow:
    0 20px 50px rgba(120,90,30,0.10),
    0 0 0 1px rgba(255,220,80,0.18),
    inset 0 0 0 1px rgba(255,230,120,0.28),
    inset 0 1px 0 rgba(255,255,220,0.85);
  --aic-gold:        #c59c50;
  --aic-gold-light:  #e8c060;
  --aic-active:      #6b4a0e;
  --aic-active-dark: #5a3a08;
  --aic-muted:       #7a6a50;
  --aic-caption:     #4a3f2f;
  --aic-label:       #9a7a30;
  --aic-success:     #6b5c14;
  --aic-text-muted:  #7a6a50;
  --aic-danger:      #8a2a18;
}
.aic-container::before {
  content: &apos;&apos;;
  position: absolute;
  top: -40px; left: 50%;
  transform: translateX(-50%);
  width: 680px; height: 340px;
  background: radial-gradient(ellipse at center,
    rgba(255,250,200,0.38) 0%,
    rgba(255,220,80,0.15) 38%,
    rgba(220,170,40,0.05) 62%,
    transparent 75%);
  pointer-events: none; z-index: 0;
}
.aic-container::after {
  content: &apos;&apos;;
  position: absolute;
  bottom: -60px; right: -50px;
  width: 440px; height: 360px;
  background: radial-gradient(ellipse at center,
    rgba(255,220,80,0.14) 0%,
    rgba(220,170,40,0.06) 50%,
    transparent 70%);
  pointer-events: none; z-index: 0;
}
.aic-section, .aic-divider { position: relative; z-index: 1; }
.aic-section { padding: 2rem 2rem 1.75rem; }
.aic-section-panel {
  background: linear-gradient(180deg, rgba(255,252,244,0.94) 0%, rgba(250,242,224,0.88) 100%);
  border: 1px solid rgba(120,80,5,0.42);
  border-radius: 12px;
  padding: 1.5rem 1.5rem 1.25rem;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  box-shadow:
    0 8px 24px rgba(100,70,10,0.07),
    inset 0 0 0 1px rgba(255,225,100,0.22),
    inset 0 1px 0 rgba(255,255,220,0.88),
    inset 0 -8px 24px rgba(220,170,50,0.05);
}
.aic-section-title {
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--aic-label);
  margin: 0 0 1.5rem; padding-bottom: 0.7rem; position: relative;
  text-shadow: 0 0 28px rgba(197,156,80,0.38), 0 0 10px rgba(232,192,96,0.22);
}
.aic-section-title::after {
  content: &apos;&apos;; position: absolute; bottom: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, rgba(197,156,80,0.55), rgba(197,156,80,0.18) 60%, transparent);
}
/* Tab rail */
.aic-tab-rail {
  margin-bottom: 1.25rem;
  background: linear-gradient(180deg, rgba(255,253,245,0.7), rgba(250,243,225,0.4));
  border-radius: 8px 8px 0 0;
}
.aic-dots { display: flex; gap: 0; border-bottom: 1px solid rgba(197,156,80,0.25); }
.aic-dot {
  position: relative; padding: 0.55rem 1.25rem 0.65rem;
  font-size: 0.82rem; font-weight: 500; color: #7a6a50;
  cursor: pointer; user-select: none; white-space: nowrap;
  transition: color 0.2s; border-radius: 0; background: none;
}
.aic-dot::after {
  content: &apos;&apos;; position: absolute; bottom: -1px; left: 0; right: 0;
  height: 2px; background: transparent;
  transition: background 0.25s, box-shadow 0.25s;
}
.aic-dot:hover { color: #6b4a0e; }
.aic-dot.aic-dot-active {
  color: #5a3a08; font-weight: 600;
  text-shadow: 0 0 16px rgba(197,156,80,0.55), 0 0 6px rgba(232,192,96,0.30);
  background: linear-gradient(180deg, rgba(255,252,232,0.60), rgba(255,244,210,0.70));
}
.aic-dot.aic-dot-active::after {
  background: linear-gradient(90deg, #c59c50, #f0cd74, #c59c50);
  box-shadow: 0 0 10px rgba(197,156,80,0.42), 0 1px 0 rgba(255,255,255,0.5);
}
/* Pattern stage */
.aic-pattern-area {
  position: relative;
  background:
    radial-gradient(ellipse 70% 60% at 50% 42%, rgba(255,255,248,0.85) 0%, rgba(253,248,232,0.55) 55%, transparent 100%),
    linear-gradient(180deg, rgba(252,247,235,0.92) 0%, rgba(246,238,216,0.82) 100%);
  border: 1px solid rgba(120,80,5,0.38);
  border-radius: 10px;
  padding: 2.25rem 1.5rem;
  min-height: 155px;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 1.25rem; overflow: hidden;
  box-shadow:
    inset 0 2px 8px rgba(255,255,220,0.70),
    inset 0 0 0 1px rgba(255,225,100,0.20),
    inset 0 -4px 14px rgba(210,160,40,0.06),
    0 4px 18px rgba(120,85,10,0.08);
}
.aic-pattern-area::before {
  content: &apos;&apos;; position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 280px; height: 180px;
  background: radial-gradient(ellipse at center,
    rgba(255,250,200,0.55) 0%, rgba(255,220,80,0.22) 38%,
    rgba(220,170,40,0.08) 65%, transparent 80%);
  pointer-events: none; z-index: 0;
}
.aic-pattern { display: none; width: 100%; }
.aic-pattern.aic-pattern-visible { display: block; }
/* Diagram */
.aic-diagram { display: flex; align-items: center; justify-content: center; gap: 1rem; flex-wrap: wrap; }
.aic-node {
  border-radius: 10px; padding: 0.6rem 1.1rem;
  text-align: center; font-size: 0.85rem; min-width: 95px;
  transition: all 0.35s ease;
}
/* Node glow keyframe */
@keyframes aic-node-glow {
  0%, 100% {
    box-shadow:
      0 0  6px  2px rgba(255,255,200,0.70),
      0 0 20px  7px rgba(255,210, 60,0.38),
      0 0 52px 18px rgba(210,155, 30,0.16),
      inset 0 1px 0 rgba(255,255,220,0.60);
  }
  50% {
    box-shadow:
      0 0 10px  4px rgba(255,255,220,0.90),
      0 0 32px 11px rgba(255,210, 60,0.55),
      0 0 80px 28px rgba(210,155, 30,0.24),
      inset 0 1px 0 rgba(255,255,230,0.80);
  }
}
.aic-node-user {
  background: linear-gradient(135deg, #f8e7a8 0%, #f3d98b 52%, #ecd07b 100%);
  border: 1.5px solid rgba(197,156,80,0.78); color: #5a3a08;
  animation: aic-node-glow 3.5s ease-in-out infinite;
}
.aic-node-ai {
  background: linear-gradient(160deg, #ece8de, #e4ddd0);
  border: 1.5px solid rgba(170,155,120,0.35); color: #6a5c44;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
}
.aic-node-ai:has(#aic-rr-state &gt; span) {
  background: linear-gradient(135deg, #f8e7a8 0%, #f3d98b 52%, #ecd07b 100%);
  border-color: rgba(197,156,80,0.78); color: #5a3a08;
  animation: aic-node-glow 2.2s ease-in-out infinite;
}
.aic-arrow { font-size: 1.1rem; color: rgba(180,140,60,0.65); flex-shrink: 0; }
/* Waiting dots */
@keyframes aic-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.45; }
  40%           { transform: translateY(-6px); opacity: 1; }
}
.aic-waiting { display: flex; gap: 5px; justify-content: center; margin-top: 6px; }
.aic-waiting-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #c59c50; box-shadow: 0 0 4px rgba(197,156,80,0.5);
  animation: aic-bounce 1.2s ease-in-out infinite;
}
.aic-waiting-dot:nth-child(2) { animation-delay: 0.2s; }
.aic-waiting-dot:nth-child(3) { animation-delay: 0.4s; }
/* Streaming */
@keyframes aic-blink {
  0%, 100% { opacity: 1; } 50% { opacity: 0; }
}
.aic-cursor {
  display: inline-block; width: 2px; height: 1em;
  background: #c59c50; box-shadow: 0 0 6px rgba(197,156,80,0.7);
  vertical-align: text-bottom; margin-left: 1px;
  animation: aic-blink 0.75s step-end infinite;
}
.aic-stream-reply {
  text-align: left; font-size: 0.82rem; min-width: 110px; min-height: 1.5em;
  margin-top: 6px; line-height: 1.5;
  background: linear-gradient(135deg, rgba(255,248,232,0.8), rgba(255,243,210,0.6));
  border: 1px solid rgba(197,156,80,0.2);
  box-shadow: inset 0 1px 3px rgba(197,156,80,0.08);
  border-radius: 5px; padding: 0.3rem 0.5rem;
}
/* Events */
.aic-events-wrap { display: flex; flex-direction: column; align-items: center; gap: 0.75rem; }
.aic-node-agent {
  background: linear-gradient(160deg, #ece8de, #e4ddd0);
  border: 1.5px solid rgba(170,155,120,0.35); color: #6a5c44;
  border-radius: 10px; padding: 0.6rem 1.1rem; text-align: center;
  font-size: 0.85rem; min-width: 95px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
  transition: all 0.45s ease;
}
.aic-node-agent.aic-agent-active {
  background: linear-gradient(135deg, #f8e7a8 0%, #f3d98b 52%, #ecd07b 100%);
  border-color: rgba(197,156,80,0.78); color: #5a3a08;
  animation: aic-node-glow 2.2s ease-in-out infinite;
}
@keyframes aic-pulse {
  0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); }
}
.aic-trigger-badge {
  display: inline-block; padding: 0.32rem 1rem; border-radius: 20px;
  background: linear-gradient(135deg, rgba(197,156,80,0.18), rgba(232,192,96,0.12));
  border: 1px solid rgba(197,156,80,0.42); color: #6b4a0e;
  font-size: 0.8rem; font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.5);
}
.aic-trigger-badge.aic-trigger-firing {
  animation: aic-pulse 0.4s ease-in-out 3;
  background: linear-gradient(135deg, rgba(197,156,80,0.38), rgba(232,192,96,0.28));
  box-shadow: 0 0 16px rgba(197,156,80,0.44), inset 0 1px 0 rgba(255,255,255,0.5);
}
.aic-action-line { font-size: 0.82rem; color: #6b5c14; min-height: 1.5em; font-weight: 600; }
/* Nav controls */
.aic-pattern-controls {
  display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.85rem;
}
.aic-counter { font-size: 0.76rem; color: var(--aic-label); letter-spacing: 0.06em; }
.aic-pattern-label {
  font-size: 0.82rem; color: #4a3f2f; text-align: center;
  font-style: italic; margin: 0; line-height: 1.65; padding: 0 0.5rem;
}
/* Buttons */
.aic-btn {
  padding: 0.44rem 1.15rem;
  border: 1px solid rgba(197,156,80,0.48); border-radius: 6px;
  background: linear-gradient(180deg, rgba(255,250,238,0.95) 0%, rgba(244,230,198,0.90) 100%);
  color: #5a3a08; cursor: pointer; font-family: inherit;
  font-size: 0.82rem; font-weight: 500; line-height: 1.4;
  box-shadow: 0 2px 10px rgba(197,156,80,0.08), inset 0 1px 0 rgba(255,255,255,0.70);
  transition: background 0.18s, border-color 0.18s, box-shadow 0.18s, transform 0.14s;
}
.aic-btn:hover:not(:disabled) {
  background: linear-gradient(180deg, rgba(255,252,242,1) 0%, rgba(248,234,205,1) 100%);
  border-color: rgba(197,156,80,0.72);
  box-shadow: 0 4px 16px rgba(197,156,80,0.18), inset 0 1px 0 rgba(255,255,255,0.75);
  transform: translateY(-1px);
}
.aic-btn:focus-visible { outline: 2px solid #6b4a0e; outline-offset: 3px; }
.aic-btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
/* Sparkle cloud */
.aic-sparkle-cloud {
  position: absolute; top: 0; left: 0;
  width: 2px; height: 2px; border-radius: 50%;
  background: rgba(255,255,220,0.90);
  pointer-events: none; z-index: 1;
  box-shadow:
     88px  46px  6px  1px rgba(255,255,220,0.85),  88px  46px 20px  6px rgba(255,210, 60,0.40),  88px  46px 44px 14px rgba(220,160, 30,0.14),
    310px  22px  6px  1px rgba(255,255,220,0.80), 310px  22px 18px  5px rgba(255,210, 60,0.38), 310px  22px 40px 12px rgba(220,160, 30,0.12),
     48px 165px  6px  1px rgba(255,255,220,0.75),  48px 165px 20px  6px rgba(255,210, 60,0.34),  48px 165px 44px 14px rgba(220,160, 30,0.10),
    510px  58px  5px  1px rgba(255,255,220,0.78), 510px  58px 16px  5px rgba(255,210, 60,0.35), 510px  58px 38px 11px rgba(220,160, 30,0.11),
    210px 130px  5px  1px rgba(255,255,220,0.70), 210px 130px 14px  4px rgba(255,210, 60,0.30), 210px 130px 36px 10px rgba(220,160, 30,0.09);
}
/* Mobile */
@media (max-width: 520px) {
  .aic-section       { padding: 1.25rem 1rem 1rem; }
  .aic-section-panel { padding: 1.25rem 1rem; }
  .aic-dot           { padding: 0.45rem 0.8rem; font-size: 0.78rem; }
  .aic-pattern-area  { padding: 1.75rem 0.75rem; }
}
&lt;/style&gt;

&lt;div class=&quot;aic-container&quot; id=&quot;aic-patterns-demo&quot;&gt;
  &lt;div class=&quot;aic-sparkle-cloud&quot; aria-hidden=&quot;true&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;aic-section&quot;&gt;
    &lt;p class=&quot;aic-section-title&quot;&gt;How AI Tools Communicate&lt;/p&gt;
    &lt;div class=&quot;aic-tab-rail&quot;&gt;
      &lt;div class=&quot;aic-dots&quot; id=&quot;aic-dots&quot;&gt;
        &lt;span class=&quot;aic-dot aic-dot-active&quot; data-idx=&quot;0&quot;&gt;Request / Response&lt;/span&gt;
        &lt;span class=&quot;aic-dot&quot; data-idx=&quot;1&quot;&gt;Streaming&lt;/span&gt;
        &lt;span class=&quot;aic-dot&quot; data-idx=&quot;2&quot;&gt;Events&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;aic-pattern-area&quot;&gt;
      &lt;!-- Pattern 0 --&gt;
      &lt;div class=&quot;aic-pattern aic-pattern-visible&quot; id=&quot;aic-p0&quot;&gt;
        &lt;div class=&quot;aic-diagram&quot;&gt;
          &lt;div class=&quot;aic-node aic-node-user&quot;&gt;
            &lt;div&gt;👤 User&lt;/div&gt;
            &lt;div style=&quot;font-size:0.75rem;margin-top:5px;color:#7a6a50&quot;&gt;&quot;What time is it?&quot;&lt;/div&gt;
          &lt;/div&gt;
          &lt;div class=&quot;aic-arrow&quot;&gt;→&lt;/div&gt;
          &lt;div class=&quot;aic-node aic-node-ai&quot; style=&quot;min-width:110px&quot;&gt;
            &lt;div&gt;🤖 AI&lt;/div&gt;
            &lt;div id=&quot;aic-rr-state&quot; style=&quot;margin-top:6px&quot;&gt;
              &lt;div class=&quot;aic-waiting&quot;&gt;
                &lt;div class=&quot;aic-waiting-dot&quot;&gt;&lt;/div&gt;
                &lt;div class=&quot;aic-waiting-dot&quot;&gt;&lt;/div&gt;
                &lt;div class=&quot;aic-waiting-dot&quot;&gt;&lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;!-- Pattern 1 --&gt;
      &lt;div class=&quot;aic-pattern&quot; id=&quot;aic-p1&quot;&gt;
        &lt;div class=&quot;aic-diagram&quot;&gt;
          &lt;div class=&quot;aic-node aic-node-user&quot;&gt;
            &lt;div&gt;👤 User&lt;/div&gt;
            &lt;div style=&quot;font-size:0.75rem;margin-top:5px;color:#7a6a50&quot;&gt;&quot;What time is it?&quot;&lt;/div&gt;
          &lt;/div&gt;
          &lt;div class=&quot;aic-arrow&quot;&gt;→&lt;/div&gt;
          &lt;div class=&quot;aic-node aic-node-ai&quot; style=&quot;min-width:130px&quot;&gt;
            &lt;div&gt;🤖 AI&lt;/div&gt;
            &lt;div class=&quot;aic-stream-reply&quot;&gt;
              &lt;span id=&quot;aic-stream-text&quot;&gt;&lt;/span&gt;&lt;span class=&quot;aic-cursor&quot; id=&quot;aic-stream-cursor&quot;&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;!-- Pattern 2 --&gt;
      &lt;div class=&quot;aic-pattern&quot; id=&quot;aic-p2&quot;&gt;
        &lt;div class=&quot;aic-events-wrap&quot;&gt;
          &lt;div class=&quot;aic-node aic-node-agent&quot; id=&quot;aic-agent-node&quot; style=&quot;display:inline-block&quot;&gt;
            &lt;div&gt;🤖 Agent&lt;/div&gt;
            &lt;div id=&quot;aic-agent-state&quot; style=&quot;font-size:0.75rem;margin-top:4px&quot;&gt;idle — waiting&lt;/div&gt;
          &lt;/div&gt;
          &lt;div style=&quot;font-size:0.85rem;color:#7a6a50&quot;&gt;
            &lt;span id=&quot;aic-trigger-badge&quot; class=&quot;aic-trigger-badge&quot;&gt;📧 New Email&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;aic-action-line&quot; id=&quot;aic-action-line&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;aic-pattern-controls&quot;&gt;
      &lt;button class=&quot;aic-btn&quot; id=&quot;aic-prev&quot; disabled=&quot;&quot;&gt;← Prev&lt;/button&gt;
      &lt;span class=&quot;aic-counter&quot; id=&quot;aic-counter&quot;&gt;1 / 3&lt;/span&gt;
      &lt;button class=&quot;aic-btn&quot; id=&quot;aic-next&quot;&gt;Next →&lt;/button&gt;
    &lt;/div&gt;
    &lt;p class=&quot;aic-pattern-label&quot; id=&quot;aic-pattern-label&quot;&gt;
      &lt;strong&gt;Request/Response&lt;/strong&gt;: One tool asks, the other answers. You send a prompt, you get text back, you pass it to the next step. Think of it like sending a text message and waiting for a reply before doing anything else.
    &lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
(function () {
  &apos;use strict&apos;;

  var PATTERNS = [
    {
      id: &apos;aic-p0&apos;,
      label: &apos;Request/Response: One tool asks, the other answers. You send a prompt, you get text back, you pass it to the next step. Think of it like sending a text message and waiting for a reply before doing anything else.&apos;
    },
    {
      id: &apos;aic-p1&apos;,
      label: &apos;Streaming: Instead of waiting for the full response, the output arrives piece by piece. This is why ChatGPT seems to type its answer in real time rather than making you wait for the whole thing to appear at once. It\&apos;s useful when you\&apos;re generating long content or building something that needs to feel responsive.&apos;
    },
    {
      id: &apos;aic-p2&apos;,
      label: &apos;Events: Instead of asking and waiting, a tool watches for something to happen and then reacts. A new email arrives. A file is uploaded. A timer fires. The agent picks it up and acts without anyone pressing a button. This is how you build things that run in the background autonomously.&apos;
    }
  ];

  var currentIdx = 0;
  var patternTimers = [];

  var prevBtn   = document.getElementById(&apos;aic-prev&apos;);
  var nextBtn   = document.getElementById(&apos;aic-next&apos;);
  var counterEl = document.getElementById(&apos;aic-counter&apos;);
  var labelEl   = document.getElementById(&apos;aic-pattern-label&apos;);
  var dots      = document.querySelectorAll(&apos;#aic-dots .aic-dot&apos;);

  function pLater(fn, ms) { patternTimers.push(setTimeout(fn, ms)); }
  function cancelPattern() { patternTimers.forEach(clearTimeout); patternTimers = []; }

  function showPattern(idx) {
    cancelPattern();

    PATTERNS.forEach(function (p) {
      var el = document.getElementById(p.id);
      if (el) el.classList.remove(&apos;aic-pattern-visible&apos;);
    });

    var target = document.getElementById(PATTERNS[idx].id);
    if (target) target.classList.add(&apos;aic-pattern-visible&apos;);

    dots.forEach(function (d, i) {
      d.classList.toggle(&apos;aic-dot-active&apos;, i === idx);
    });

    if (counterEl) counterEl.textContent = (idx + 1) + &apos; / &apos; + PATTERNS.length;
    if (labelEl)   labelEl.textContent   = PATTERNS[idx].label;
    if (prevBtn)   prevBtn.disabled      = idx === 0;
    if (nextBtn)   nextBtn.disabled      = idx === PATTERNS.length - 1;

    if (idx === 0) animRR();
    if (idx === 1) animStream();
    if (idx === 2) animEvents();
  }

  /* Pattern 0 — Request / Response */
  function animRR() {
    var stateEl = document.getElementById(&apos;aic-rr-state&apos;);
    if (!stateEl) return;

    function cycle() {
      stateEl.innerHTML = &apos;&lt;div class=&quot;aic-waiting&quot;&gt;&apos; +
        &apos;&lt;div class=&quot;aic-waiting-dot&quot;&gt;&lt;/div&gt;&apos; +
        &apos;&lt;div class=&quot;aic-waiting-dot&quot;&gt;&lt;/div&gt;&apos; +
        &apos;&lt;div class=&quot;aic-waiting-dot&quot;&gt;&lt;/div&gt;&apos; +
        &apos;&lt;/div&gt;&apos;;

      pLater(function () {
        stateEl.innerHTML = &apos;&lt;span style=&quot;font-size:0.8rem&quot;&gt;&quot;It\&apos;s 3:42 PM.&quot;&lt;/span&gt;&apos;;
      }, 2200);

      pLater(cycle, 4800);
    }

    cycle();
  }

  /* Pattern 1 — Streaming */
  function animStream() {
    var textEl  = document.getElementById(&apos;aic-stream-text&apos;);
    if (!textEl) return;
    var words   = [&quot;It&apos;s&quot;, &quot; 3:42&quot;, &quot; PM.&quot;, &quot; Need&quot;, &quot; anything&quot;, &quot; else?&quot;];
    var wordIdx = 0;

    function cycle() {
      textEl.textContent = &apos;&apos;;
      wordIdx = 0;
      tick();
    }

    function tick() {
      if (wordIdx &lt; words.length) {
        textEl.textContent += words[wordIdx];
        wordIdx++;
        pLater(tick, 260 + Math.floor(Math.random() * 160));
      } else {
        pLater(cycle, 2800);
      }
    }

    pLater(cycle, 300);
  }

  /* Pattern 2 — Events */
  function animEvents() {
    var agentNode    = document.getElementById(&apos;aic-agent-node&apos;);
    var agentState   = document.getElementById(&apos;aic-agent-state&apos;);
    var triggerBadge = document.getElementById(&apos;aic-trigger-badge&apos;);
    var actionLine   = document.getElementById(&apos;aic-action-line&apos;);
    if (!agentNode || !agentState || !triggerBadge || !actionLine) return;

    function cycle() {
      agentNode.classList.remove(&apos;aic-agent-active&apos;);
      agentState.textContent = &apos;idle — waiting&apos;;
      agentState.style.color = &apos;&apos;;
      triggerBadge.classList.remove(&apos;aic-trigger-firing&apos;);
      actionLine.textContent = &apos;&apos;;

      pLater(function () {
        triggerBadge.classList.add(&apos;aic-trigger-firing&apos;);
      }, 1400);

      pLater(function () {
        agentNode.classList.add(&apos;aic-agent-active&apos;);
        agentState.textContent = &apos;active&apos;;
        agentState.style.color = &apos;var(--aic-success)&apos;;
      }, 2400);

      pLater(function () {
        actionLine.textContent = &apos;✓ Draft reply composed &amp; sent&apos;;
      }, 3300);

      pLater(cycle, 6000);
    }

    cycle();
  }

  if (prevBtn) {
    prevBtn.addEventListener(&apos;click&apos;, function () {
      if (currentIdx &gt; 0) { currentIdx--; showPattern(currentIdx); }
    });
  }

  if (nextBtn) {
    nextBtn.addEventListener(&apos;click&apos;, function () {
      if (currentIdx &lt; PATTERNS.length - 1) { currentIdx++; showPattern(currentIdx); }
    });
  }

  dots.forEach(function (dot) {
    dot.addEventListener(&apos;click&apos;, function () {
      var idx = parseInt(dot.getAttribute(&apos;data-idx&apos;), 10);
      if (!isNaN(idx)) { currentIdx = idx; showPattern(idx); }
    });
  });

  showPattern(0);

  if (window.MutationObserver) {
    var observer = new MutationObserver(function () {
      if (!document.getElementById(&apos;aic-patterns-demo&apos;)) {
        cancelPattern();
        observer.disconnect();
      }
    });
    observer.observe(document.body, { childList: true, subtree: true });
  }

})();
&lt;/script&gt;

&lt;p&gt;Most builders start with request/response and eventually add streaming when their interface feels sluggish, or events when they want something to run without manual triggering. But the real magic happens when you combine them. You can have a tool chain that starts with an event trigger, streams output to the user, and then sends a final request/response message to update a database.&lt;/p&gt;

&lt;h2 id=&quot;what-actually-breaks-multi-step-chains&quot;&gt;What Actually Breaks Multi-Step Chains&lt;/h2&gt;

&lt;p&gt;Each of those three patterns works fine in isolation. Tool chains fail in very predictable ways. If you know the patterns, you know where to look. The problem shows up when you chain tools together and the context window (the AI’s working memory) fills up.&lt;/p&gt;

&lt;h3 id=&quot;context-window-overflow&quot;&gt;Context window overflow.&lt;/h3&gt;

&lt;p&gt;Every LLM can only “see” a certain amount of text at once. Imagine trying to read a book but you can only ever see 10 pages at a time. If you keep shoving earlier chapters into the window to maintain “memory,” you eventually run out of room for the chapter you’re actually trying to read. Builders who chain multiple tools together can accidentally fill the context window with outputs from earlier steps, leaving no room for the actual task. Smart builders decide what to pass forward and what to leave behind.&lt;/p&gt;

&lt;style&gt;
/* ─── Shared container + atmosphere ───────────────────── */
.aic-container {
  font-family: inherit;
  max-width: 700px;
  margin: 2.5rem auto;
  position: relative;
  overflow: hidden;
  background: linear-gradient(160deg, #f9f3e7 0%, #fdf8ef 42%, #f5ebd8 100%);
  border: 1px solid rgba(130,88,8,0.55);
  border-radius: 16px;
  box-shadow:
    0 20px 50px rgba(120,90,30,0.10),
    0 0 0 1px rgba(255,220,80,0.18),
    inset 0 0 0 1px rgba(255,230,120,0.28),
    inset 0 1px 0 rgba(255,255,220,0.85);
  --aic-gold:        #c59c50;
  --aic-gold-light:  #e8c060;
  --aic-active:      #6b4a0e;
  --aic-active-dark: #5a3a08;
  --aic-muted:       #7a6a50;
  --aic-caption:     #4a3f2f;
  --aic-label:       #9a7a30;
  --aic-success:     #6b5c14;
  --aic-text-muted:  #7a6a50;
  --aic-danger:      #8a2a18;
}
.aic-container::before {
  content: &apos;&apos;;
  position: absolute;
  top: -40px; left: 50%;
  transform: translateX(-50%);
  width: 680px; height: 340px;
  background: radial-gradient(ellipse at center,
    rgba(255,250,200,0.38) 0%,
    rgba(255,220,80,0.15) 38%,
    rgba(220,170,40,0.05) 62%,
    transparent 75%);
  pointer-events: none; z-index: 0;
}
.aic-container::after {
  content: &apos;&apos;;
  position: absolute;
  bottom: -60px; right: -50px;
  width: 440px; height: 360px;
  background: radial-gradient(ellipse at center,
    rgba(255,220,80,0.14) 0%,
    rgba(220,170,40,0.06) 50%,
    transparent 70%);
  pointer-events: none; z-index: 0;
}
.aic-section { position: relative; z-index: 1; padding: 2rem 2rem 1.75rem; }
.aic-section-title {
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--aic-label);
  margin: 0 0 1.5rem; padding-bottom: 0.7rem; position: relative;
  text-shadow: 0 0 28px rgba(197,156,80,0.38), 0 0 10px rgba(232,192,96,0.22);
}
.aic-section-title::after {
  content: &apos;&apos;; position: absolute; bottom: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, rgba(197,156,80,0.55), rgba(197,156,80,0.18) 60%, transparent);
}
/* Node glow keyframe */
@keyframes aic-node-glow {
  0%, 100% {
    box-shadow:
      0 0  6px  2px rgba(255,255,200,0.70),
      0 0 20px  7px rgba(255,210, 60,0.38),
      0 0 52px 18px rgba(210,155, 30,0.16),
      inset 0 1px 0 rgba(255,255,220,0.60);
  }
  50% {
    box-shadow:
      0 0 10px  4px rgba(255,255,220,0.90),
      0 0 32px 11px rgba(255,210, 60,0.55),
      0 0 80px 28px rgba(210,155, 30,0.24),
      inset 0 1px 0 rgba(255,255,230,0.80);
  }
}
/* Buttons */
.aic-btn {
  padding: 0.44rem 1.15rem;
  border: 1px solid rgba(197,156,80,0.48); border-radius: 6px;
  background: linear-gradient(180deg, rgba(255,250,238,0.95) 0%, rgba(244,230,198,0.90) 100%);
  color: #5a3a08; cursor: pointer; font-family: inherit;
  font-size: 0.82rem; font-weight: 500; line-height: 1.4;
  box-shadow: 0 2px 10px rgba(197,156,80,0.08), inset 0 1px 0 rgba(255,255,255,0.70);
  transition: background 0.18s, border-color 0.18s, box-shadow 0.18s, transform 0.14s;
}
.aic-btn:hover:not(:disabled) {
  background: linear-gradient(180deg, rgba(255,252,242,1) 0%, rgba(248,234,205,1) 100%);
  border-color: rgba(197,156,80,0.72);
  box-shadow: 0 4px 16px rgba(197,156,80,0.18), inset 0 1px 0 rgba(255,255,255,0.75);
  transform: translateY(-1px);
}
.aic-btn:focus-visible { outline: 2px solid #6b4a0e; outline-offset: 3px; }
.aic-btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
/* Sparkle cloud */
.aic-sparkle-cloud {
  position: absolute; top: 0; left: 0;
  width: 2px; height: 2px; border-radius: 50%;
  background: rgba(255,255,220,0.90);
  pointer-events: none; z-index: 1;
  box-shadow:
     88px  46px  6px  1px rgba(255,255,220,0.85),  88px  46px 20px  6px rgba(255,210, 60,0.40),  88px  46px 44px 14px rgba(220,160, 30,0.14),
    310px  22px  6px  1px rgba(255,255,220,0.80), 310px  22px 18px  5px rgba(255,210, 60,0.38), 310px  22px 40px 12px rgba(220,160, 30,0.12),
     48px 165px  6px  1px rgba(255,255,220,0.75),  48px 165px 20px  6px rgba(255,210, 60,0.34),  48px 165px 44px 14px rgba(220,160, 30,0.10),
    510px  58px  5px  1px rgba(255,255,220,0.78), 510px  58px 16px  5px rgba(255,210, 60,0.35), 510px  58px 38px 11px rgba(220,160, 30,0.11),
    210px 130px  5px  1px rgba(255,255,220,0.70), 210px 130px 14px  4px rgba(255,210, 60,0.30), 210px 130px 36px 10px rgba(220,160, 30,0.09);
}
/* Section B specific */
@keyframes aic-shake {
  0%, 100% { transform: translateX(0); }
  20%  { transform: translateX(-4px); }
  40%  { transform: translateX(4px); }
  60%  { transform: translateX(-3px); }
  80%  { transform: translateX(3px); }
}
.aic-pipeline {
  display: flex; align-items: center; gap: 0.4rem;
  justify-content: center; flex-wrap: wrap; margin-bottom: 1.5rem;
}
.aic-pipeline-arrow { color: rgba(180,140,60,0.5); font-size: 0.9rem; flex-shrink: 0; }
.aic-step {
  flex: 0 1 auto; min-width: 80px; max-width: 112px;
  border: 1.5px solid rgba(170,155,120,0.28); border-radius: 9px;
  padding: 0.65rem 0.5rem; text-align: center; font-size: 0.8rem;
  background: linear-gradient(160deg, #ece8de, #e4ddd0);
  color: #6a5c44; box-shadow: inset 0 1px 0 rgba(255,255,255,0.38);
  transition: all 0.3s ease;
}
.aic-step-icon   { font-size: 1.2rem; line-height: 1; }
.aic-step-name   { font-weight: 600; margin: 0.2rem 0 0.1rem; color: inherit; }
.aic-step-tokens { font-size: 0.7rem; color: #7a6a50; opacity: 0.85; }
.aic-step.aic-step-running {
  background: linear-gradient(135deg, #f8e7a8 0%, #f3d98b 52%, #ecd07b 100%);
  border-color: rgba(197,156,80,0.6); color: #5a3a08;
  animation: aic-node-glow 1.8s ease-in-out infinite;
}
.aic-step.aic-step-done {
  background: linear-gradient(135deg, #fef8e8, #fdf3cc);
  border-color: rgba(197,156,80,0.38); color: #7a5a18;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
}
.aic-step.aic-step-error {
  background: linear-gradient(135deg, #f8e1dc, #f2cfc5);
  border: 1.5px solid rgba(192,64,48,0.45); color: #8a2a18;
  box-shadow: 0 0 16px rgba(192,64,48,0.10);
  animation: aic-shake 0.45s ease-in-out;
}
.aic-ctx-header {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 0.8rem; margin-bottom: 0.4rem;
}
.aic-ctx-label { font-weight: 600; color: #4a3f2f; }
.aic-ctx-pct { color: #7a6a50; font-size: 0.75rem; font-feature-settings: &quot;tnum&quot;; }
.aic-ctx-track {
  background: rgba(160,130,70,0.16); border: 1px solid rgba(160,130,70,0.22);
  border-radius: 5px; height: 20px; overflow: hidden; position: relative;
  margin-bottom: 0.85rem; box-shadow: inset 0 1px 3px rgba(130,100,40,0.10);
}
.aic-ctx-fill {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, #d4a840, #e8c060);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.28);
  transition: width 0.55s ease-in-out, background 0.3s;
}
.aic-ctx-fill.aic-ctx-over {
  background: linear-gradient(90deg, #c04030, #dc5847 55%, #b93a2c 100%);
  box-shadow: 0 0 10px rgba(180,60,40,0.18), inset 0 1px 0 rgba(255,255,255,0.22);
}
.aic-ctx-limit {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: 2px; background: rgba(180,60,40,0.45);
}
.aic-status {
  min-height: 2.8em; font-size: 0.82rem; color: #7a6a50;
  margin-bottom: 0.9rem; text-align: center; line-height: 1.6; font-style: italic;
}
.aic-status.aic-status-ok    { color: #6b5c14; font-weight: 600; font-style: normal; }
.aic-status.aic-status-error { color: #8a2a18; font-weight: 600; font-style: normal; }
.aic-ctx-controls { display: flex; gap: 0.75rem; justify-content: center; }
.aic-btn-primary {
  background: linear-gradient(180deg, rgba(248,232,172,0.95) 0%, rgba(234,210,138,0.92) 100%);
  border-color: rgba(197,156,80,0.65); color: #4a2e06; font-weight: 600;
  box-shadow: 0 2px 12px rgba(197,156,80,0.14), inset 0 1px 0 rgba(255,255,255,0.60);
}
.aic-btn-primary:hover:not(:disabled) {
  background: linear-gradient(180deg, rgba(252,238,182,1) 0%, rgba(240,218,148,1) 100%);
  border-color: rgba(197,156,80,0.82);
  box-shadow: 0 5px 20px rgba(197,156,80,0.24), inset 0 1px 0 rgba(255,255,255,0.65);
  transform: translateY(-1px);
}
@media (max-width: 520px) {
  .aic-section        { padding: 1.25rem 1rem 1rem; }
  .aic-pipeline-arrow { display: none; }
  .aic-step           { min-width: 62px; }
}
&lt;/style&gt;

&lt;div class=&quot;aic-container&quot; id=&quot;aic-ctx-window-demo&quot;&gt;
  &lt;div class=&quot;aic-sparkle-cloud&quot; aria-hidden=&quot;true&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;aic-section&quot;&gt;
    &lt;p class=&quot;aic-section-title&quot;&gt;Context Window: What Actually Breaks&lt;/p&gt;
    &lt;div class=&quot;aic-pipeline&quot; id=&quot;aic-pipeline&quot;&gt;
      &lt;div class=&quot;aic-step&quot; id=&quot;aic-s0&quot;&gt;
        &lt;div class=&quot;aic-step-icon&quot;&gt;🔍&lt;/div&gt;
        &lt;div class=&quot;aic-step-name&quot;&gt;Retrieve&lt;/div&gt;
        &lt;div class=&quot;aic-step-tokens&quot;&gt;~800 tokens&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;aic-pipeline-arrow&quot;&gt;→&lt;/div&gt;
      &lt;div class=&quot;aic-step&quot; id=&quot;aic-s1&quot;&gt;
        &lt;div class=&quot;aic-step-icon&quot;&gt;📝&lt;/div&gt;
        &lt;div class=&quot;aic-step-name&quot;&gt;Summarize&lt;/div&gt;
        &lt;div class=&quot;aic-step-tokens&quot;&gt;~600 tokens&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;aic-pipeline-arrow&quot;&gt;→&lt;/div&gt;
      &lt;div class=&quot;aic-step&quot; id=&quot;aic-s2&quot;&gt;
        &lt;div class=&quot;aic-step-icon&quot;&gt;🎨&lt;/div&gt;
        &lt;div class=&quot;aic-step-name&quot;&gt;Format&lt;/div&gt;
        &lt;div class=&quot;aic-step-tokens&quot;&gt;~700 tokens&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;aic-pipeline-arrow&quot;&gt;→&lt;/div&gt;
      &lt;div class=&quot;aic-step&quot; id=&quot;aic-s3&quot;&gt;
        &lt;div class=&quot;aic-step-icon&quot;&gt;📤&lt;/div&gt;
        &lt;div class=&quot;aic-step-name&quot;&gt;Send&lt;/div&gt;
        &lt;div class=&quot;aic-step-tokens&quot;&gt;~400 tokens&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;aic-ctx-header&quot;&gt;
      &lt;span class=&quot;aic-ctx-label&quot;&gt;Context window (2 048 token limit)&lt;/span&gt;
      &lt;span class=&quot;aic-ctx-pct&quot; id=&quot;aic-ctx-pct&quot;&gt;0 / 2 048&lt;/span&gt;
    &lt;/div&gt;
    &lt;div class=&quot;aic-ctx-track&quot;&gt;
      &lt;div class=&quot;aic-ctx-fill&quot; id=&quot;aic-ctx-fill&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;aic-ctx-limit&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;aic-status&quot; id=&quot;aic-status&quot;&gt;Click &lt;strong&gt;Run Chain&lt;/strong&gt; to watch the context window fill step by step.&lt;/div&gt;
    &lt;div class=&quot;aic-ctx-controls&quot;&gt;
      &lt;button class=&quot;aic-btn aic-btn-primary&quot; id=&quot;aic-run&quot;&gt;▶ Run Chain&lt;/button&gt;
      &lt;button class=&quot;aic-btn&quot; id=&quot;aic-reset&quot;&gt;↺ Reset&lt;/button&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
(function () {
  &apos;use strict&apos;;

  var timers = [];
  function later(fn, ms) { timers.push(setTimeout(fn, ms)); }
  function cancelAll() { timers.forEach(clearTimeout); timers = []; }

  var CTX_LIMIT = 2048;

  var STEPS = [
    { id: &apos;aic-s0&apos;, name: &apos;Retrieve&apos;,  icon: &apos;🔍&apos;, tokens: 800 },
    { id: &apos;aic-s1&apos;, name: &apos;Summarize&apos;, icon: &apos;📝&apos;, tokens: 600 },
    { id: &apos;aic-s2&apos;, name: &apos;Format&apos;,    icon: &apos;🎨&apos;, tokens: 700 },
    { id: &apos;aic-s3&apos;, name: &apos;Send&apos;,      icon: &apos;📤&apos;, tokens: 400 }
  ];

  var runBtn   = document.getElementById(&apos;aic-run&apos;);
  var resetBtn = document.getElementById(&apos;aic-reset&apos;);
  var ctxFill  = document.getElementById(&apos;aic-ctx-fill&apos;);
  var ctxPct   = document.getElementById(&apos;aic-ctx-pct&apos;);
  var statusEl = document.getElementById(&apos;aic-status&apos;);

  function getStep(id) { return document.getElementById(id); }

  function setCtx(tokens) {
    var pct = Math.min(1, tokens / CTX_LIMIT);
    ctxFill.style.width = (pct * 100) + &apos;%&apos;;
    ctxPct.textContent  = tokens + &apos; / &apos; + CTX_LIMIT;
    if (tokens &gt; CTX_LIMIT) {
      ctxFill.classList.add(&apos;aic-ctx-over&apos;);
    }
  }

  function resetCtx() {
    cancelAll();
    if (runBtn) runBtn.disabled = false;

    STEPS.forEach(function (s) {
      var el = getStep(s.id);
      if (el) el.classList.remove(&apos;aic-step-running&apos;, &apos;aic-step-done&apos;, &apos;aic-step-error&apos;);
    });

    if (ctxFill) {
      ctxFill.style.width = &apos;0%&apos;;
      ctxFill.classList.remove(&apos;aic-ctx-over&apos;);
    }
    if (ctxPct)   ctxPct.textContent = &apos;0 / &apos; + CTX_LIMIT;
    if (statusEl) {
      statusEl.innerHTML  = &apos;Click &lt;strong&gt;Run Chain&lt;/strong&gt; to watch the context window fill step by step.&apos;;
      statusEl.className  = &apos;aic-status&apos;;
    }
  }

  function runChain() {
    if (runBtn) runBtn.disabled = true;
    var accumulated = 0;
    var stepIdx     = 0;

    function nextStep() {
      if (stepIdx &gt;= STEPS.length) {
        if (statusEl) {
          statusEl.innerHTML = &apos;✓ Chain complete — all steps finished within the context limit.&apos;;
          statusEl.className = &apos;aic-status aic-status-ok&apos;;
        }
        if (runBtn) runBtn.disabled = false;
        return;
      }

      var step = STEPS[stepIdx];
      var el   = getStep(step.id);

      if (el) el.classList.add(&apos;aic-step-running&apos;);
      if (statusEl) {
        statusEl.innerHTML = &apos;Running &apos; + step.icon + &apos; &lt;strong&gt;&apos; + step.name + &apos;&lt;/strong&gt;…&apos;;
        statusEl.className = &apos;aic-status&apos;;
      }

      later(function () {
        accumulated += step.tokens;
        var overflow = accumulated &gt; CTX_LIMIT;

        setCtx(accumulated);
        if (el) el.classList.remove(&apos;aic-step-running&apos;);

        if (overflow) {
          if (el) el.classList.add(&apos;aic-step-error&apos;);

          for (var i = stepIdx + 1; i &lt; STEPS.length; i++) {
            var rem = getStep(STEPS[i].id);
            if (rem) rem.classList.add(&apos;aic-step-error&apos;);
          }

          if (statusEl) {
            statusEl.innerHTML =
              &apos;⚠️ Context overflow at &lt;strong&gt;&apos; + step.name + &apos;&lt;/strong&gt;! &apos; +
              accumulated + &apos; tokens accumulated — limit is &apos; + CTX_LIMIT + &apos;. &apos; +
              &apos;Remaining steps were dropped.&apos;;
            statusEl.className = &apos;aic-status aic-status-error&apos;;
          }
          if (runBtn) runBtn.disabled = false;
          return;
        }

        if (el) el.classList.add(&apos;aic-step-done&apos;);
        stepIdx++;
        later(nextStep, 700);
      }, 900);
    }

    nextStep();
  }

  if (runBtn)   runBtn.addEventListener(&apos;click&apos;, runChain);
  if (resetBtn) resetBtn.addEventListener(&apos;click&apos;, resetCtx);

  if (window.MutationObserver) {
    var observer = new MutationObserver(function () {
      if (!document.getElementById(&apos;aic-ctx-window-demo&apos;)) {
        cancelAll();
        observer.disconnect();
      }
    });
    observer.observe(document.body, { childList: true, subtree: true });
  }

})();
&lt;/script&gt;

&lt;h3 id=&quot;malformed-outputs&quot;&gt;Malformed outputs.&lt;/h3&gt;

&lt;p&gt;If step three in your chain expects an organized JSON object and step two returns a casual paragraph of text, step three breaks. It’s like asking someone to fill out a form, but instead of using the form fields, they just write you a letter. The information might be there, but the system can’t process it. This is why explicitly telling the LLM how to format its output, something like “respond only in JSON with these exact fields,” matters more than most people expect.&lt;/p&gt;

&lt;h3 id=&quot;latency-compounding&quot;&gt;Latency compounding.&lt;/h3&gt;

&lt;p&gt;Each step takes time. Three tools that each take two seconds is at minimum six seconds total, plus overhead. If you’re building something people interact with in real time, that adds up fast. Builders solve this with caching, which means storing results you’ve already computed so you don’t recalculate them, and parallelism, which means running independent steps at the same time instead of one after another.&lt;/p&gt;

&lt;h3 id=&quot;vague-instructions-at-the-orchestration-level&quot;&gt;Vague instructions at the orchestration level.&lt;/h3&gt;

&lt;p&gt;The LLM decides which tool to call next based on the instructions you’ve given it. Vague instructions lead to the wrong tool getting called, or the right tool getting called with the wrong inputs. Think of it like giving someone directions. “Head toward the big building” leaves too much room for interpretation. “Turn left at the red light, go two blocks, turn right at the gas station” gets you where you need to go. The precision of your orchestration prompt determines whether your agent behaves reliably or keeps guessing.&lt;/p&gt;

&lt;h2 id=&quot;the-mental-shift-that-changes-how-you-ai&quot;&gt;The mental shift that changes how you AI&lt;/h2&gt;

&lt;p&gt;When you start thinking in tool chains, you stop asking “what can I get the AI to do?” and start asking “what does each step need to receive, and what does it need to output?”&lt;/p&gt;

&lt;p&gt;That’s a systems question. And it’s actually a more useful frame than prompt craft alone, because it forces you to get specific about your requirements before you write a single instruction.&lt;/p&gt;
</description>
        <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//how-ai-tools-communicate</link>
        <guid isPermaLink="true">https://bekahhw.com//how-ai-tools-communicate</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>AI 102: From Vocabulary to Systems</title>
        <description>&lt;p&gt;If you read &lt;a href=&quot;2026-03-18-AI Vocabulary 101.md&quot;&gt;the vocabulary post&lt;/a&gt;, you know what a prompt is. You know the difference between a model and a model family. You’ve got the words now.
This post is about what to do with them.&lt;/p&gt;

&lt;p&gt;Having vocabulary for the pieces doesn’t automatically tell you how the pieces move. You can know what a prompt is and still write ones that produce wildly inconsistent results. You can understand what an agent is and still not know why yours keeps breaking at step three. The gap between “it kind of works” and “it actually works” isn’t usually a vocabulary problem anymore. It’s a structure problem.
That structure comes down to three things and how they talk to each other.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/2026/ai_building_blocks_overview.svg&quot; alt=&quot;Diagram showing the three components of an AI system: the model, the prompt, and the tools&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These three concepts build on each other. You cannot have a workflow without prompts. You cannot have tool chaining without workflows. Understanding them in order is the fastest path to building things that actually behave the way you intended.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-prompt&quot;&gt;What is a Prompt?&lt;/h2&gt;

&lt;p&gt;A prompt is your instruction to the LLM. It’s the text you write before you press send. But it’s also a lot more than that, because the LLM doesn’t “know” what you mean the way another person would. It pattern-matches on what you’ve written and generates the most statistically likely useful response.&lt;/p&gt;

&lt;p&gt;That sounds mechanical. And it is. But it’s also why how you write the prompt changes the output dramatically.&lt;/p&gt;

&lt;p&gt;Think of it like talking to a contractor. “Build me a kitchen” and “Build me a 12x14 kitchen with white shaker cabinets, quartz countertops, and an island with seating for four” will get you very different results, even if you’re talking to the same person.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/2026/prompt_anatomy.svg&quot; alt=&quot;anatomy of a prompt diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The LLM fills in whatever you leave blank. Sometimes that’s fine. Often it’s the source of that feeling when you get a response that’s almost what you wanted but weirdly off.&lt;/p&gt;

&lt;h2 id=&quot;what-is-an-ai-workflow&quot;&gt;What is an AI Workflow?&lt;/h2&gt;

&lt;p&gt;A workflow is what happens when you stop treating the AI like a single-shot answer machine and start treating it like a collaborator on a multi-step process.&lt;/p&gt;

&lt;p&gt;Most real tasks aren’t one prompt deep. “Write a blog post for me” sounds like one instruction, but if you actually want a good output, it’s more like: research the topic, outline the structure, draft the intro, write the body, edit for tone, format for publishing. That’s six distinct steps.&lt;/p&gt;

&lt;p&gt;A workflow is those steps, defined in sequence. The output of one step becomes the input of the next.&lt;/p&gt;

&lt;p&gt;This is the shift that changes everything for people who are building with AI seriously. You stop asking “what should I prompt?” and start asking “what are the steps this task actually requires?”&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/2026/workflow_sequence.svg&quot; alt=&quot;workflow diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you’ve been frustrated that the AI doesn’t produce what you actually want in one shot, this is probably why. You’re expecting one step to do the work of five.&lt;/p&gt;

&lt;h2 id=&quot;what-is-tool-chaining&quot;&gt;What is Tool Chaining?&lt;/h2&gt;

&lt;p&gt;Tool chaining is what happens when you connect the AI to other tools, and those tools pass information back and forth automatically. The AI isn’t just generating text. It’s calling a search API, reading the results, feeding those results into the next prompt, then writing output to a database or sending an email.&lt;/p&gt;

&lt;p&gt;Each tool in that chain does one thing. The AI reasons about what tool to use next and what to pass to it.&lt;/p&gt;

&lt;p&gt;Think of it like an assembly line where the AI is the foreman deciding which station does what, and in what order.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/2026/tool_chaining_flow.svg&quot; alt=&quot;tool chaining diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The difference between a workflow and tool chaining is that a workflow can be manual. You can paste outputs from step to step yourself. Tool chaining is when that handoff becomes automatic, which is what people mean when they start talking about “AI agents.”&lt;/p&gt;

&lt;h2 id=&quot;putting-it-all-together&quot;&gt;Putting It All Together&lt;/h2&gt;

&lt;p&gt;Here’s what a lot of people miss: these three things aren’t separate techniques. They’re nested.&lt;/p&gt;

&lt;p&gt;Every tool chain is made of workflows. Every workflow is made of prompts. If your prompts are vague, your workflows produce inconsistent outputs. If your workflows aren’t structured, your tool chains break in unpredictable places.
This is not just about being more technical. It’s about building something that actually behaves the same way twice.&lt;/p&gt;

&lt;p&gt;What are you building right now where the output feels inconsistent? That inconsistency probably lives in one of these three layers.&lt;/p&gt;

&lt;p&gt;The people who move forward aren’t smarter. They just start thinking in systems instead of prompts.&lt;/p&gt;

&lt;p&gt;In the next post, we’ll make that concrete by walking through the actual tools and how they pass information between each other.&lt;/p&gt;
</description>
        <pubDate>Wed, 18 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//AI-102</link>
        <guid isPermaLink="true">https://bekahhw.com//AI-102</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Beginner</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>AI Vocabulary 101</title>
        <description>&lt;p&gt;I’ve been having a lot of conversations with non-tech people recently about AI. What I keep running into is the same pattern: smart, curious people who are genuinely trying to understand what’s happening, but who don’t have the vocabulary to name what they don’t know. And when you can’t name it, you can’t ask the right question, which means you stay stuck at the surface.&lt;/p&gt;

&lt;p&gt;The car wash test is a perfect example of this.&lt;/p&gt;

&lt;p&gt;A few months ago, screenshots flooded social media of people asking ChatGPT, Claude, and Grok a deceptively simple question: the car wash is 40 meters from my house. Should I walk or drive? The chatbots said walk.&lt;/p&gt;

&lt;p&gt;What many people in the conversation didn’t understand is that the people getting bad results weren’t using a bad AI. They were using a &lt;em&gt;lesser model&lt;/em&gt;, probably the free tier of a product, without knowing that’s what they were doing. And without vocabulary, there’s no way to even articulate that distinction.&lt;/p&gt;

&lt;p&gt;Here’s likely what actually happened. “ChatGPT” isn’t one thing. It’s a product that runs on a &lt;em&gt;family&lt;/em&gt; of models. In ChatGPT, there are three models: GPT-5 Instant, GPT-5 Thinking, and GPT-5 Pro, and a routing layer selects which to use based on the your question. On top of that, the current flagship family looks like this:&lt;/p&gt;

&lt;p&gt;Think of GPT-5.4 like a full-service restaurant kitchen. GPT-5.4 mini is the fast-casual version: quicker, cheaper, good enough for most everyday questions. GPT-5.4 nano is even lighter, like a food truck setup. And GPT-5.4 pro is the version that takes extra time to think through the really hard problems, like a chef who slow-cooks instead of microwaving.&lt;/p&gt;

&lt;p&gt;The key difference: free users don’t get the full kitchen. They get routed to whichever option is fastest and cheapest at that moment. That version &lt;em&gt;can&lt;/em&gt; answer a car wash question correctly, but it’s also more likely to give inconsistent results on anything with nuance. Paying users get reliable access to the better models.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/2026/gpt5-family.svg&quot; alt=&quot;The GPT-5 model family&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So when someone says “ChatGPT told me X” and someone else says “ChatGPT told me Y,” they may have been talking to completely different models, without either of them knowing it. That’s not a gotcha. That’s just what happens when you don’t have the vocabulary to describe what you’re actually using.&lt;/p&gt;

&lt;p&gt;This is why vocabulary matters. Not to be pedantic about terminology, but because the words give you handles on things you can actually change.&lt;/p&gt;

&lt;p&gt;Here are the terms that help close that gap.&lt;/p&gt;

&lt;h2 id=&quot;what-ai-is&quot;&gt;What AI Is&lt;/h2&gt;

&lt;p&gt;Three words that get used interchangeably. They shouldn’t be.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Artificial intelligence&lt;/em&gt; is the broad category. Any system performing tasks we’d normally associate with human reasoning, recognizing images, detecting fraud, recommending what to watch next. LLMs are one kind of AI. The algorithm shaping your social media feed is another kind entirely. Think of AI as “transportation.” It’s the whole category. LLMs are like cars specifically, while recommendation algorithms (for example, what shows to watch next) are like trains.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A large language model&lt;/em&gt;, or LLM, is AI trained specifically on enormous amounts of text. It works with words, reading, predicting, generating. GPT-5.4, Claude, Gemini, Llama: all LLMs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A model&lt;/em&gt; is the specific trained artifact underneath the product. When someone asks “which model are you using,” they’re not asking about the company. They want the exact version, because different models in the same family behave differently, cost differently, and have different knowledge cutoffs. This is like asking whether you’re driving a 2024 Civic or a 2026 Accord. They might be the same manufacturer, but very different capabilities.&lt;/p&gt;

&lt;p&gt;These nest. AI contains LLMs. LLMs come in specific models. They are not synonyms.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/2026/ai-llms-model.svg&quot; alt=&quot;AI, LLMs, and models as nested categories&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-the-model-thinks&quot;&gt;How the Model Thinks&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Token.&lt;/strong&gt; The LLM doesn’t read words the way you do. It reads tokens: chunks of text that might be a full word, part of a word, a punctuation mark, or a space. Everything about LLM capacity and pricing is measured in tokens, not words or characters. Think of tokens like syllables in speech. Sometimes they’re a whole word (“cat”), sometimes they’re a fragment (“un-break-able”).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context window.&lt;/strong&gt; The total amount of text, in tokens, the model can hold in working memory at once. Your prompt, the conversation history, any documents you’ve passed in, the response being generated: all of it counts. When the window fills, older content gets dropped. This is why long conversations sometimes feel like the AI forgot something from earlier. It didn’t forget. It ran out of room. Imagine a whiteboard where you can only write so much before you have to start erasing from the top to make space at the bottom.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/2026/context_window.svg&quot; alt=&quot;Diagram showing context window filling up over a conversation&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hallucination.&lt;/strong&gt; When the model generates text that is confident, fluent, and wrong. Not lying: it has no concept of truth or intent to deceive. It’s pattern-matching on what a plausible response looks like, and sometimes that leads somewhere inaccurate. Hallucinations range from small factual errors to completely fabricated citations. Knowing this term means you can stop calling everything you distrust a “hallucination” and start distinguishing between “the model reasoned badly” versus “the model stated something false with full confidence.” It’s like when you confidently give someone directions to a restaurant that closed three years ago. It’s not malicious, just working from outdated information.&lt;/p&gt;

&lt;h2 id=&quot;how-you-work-with-it&quot;&gt;How You Work With It&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prompt.&lt;/strong&gt; Your instruction to the model. Everything it receives before it starts generating. Prompt quality is one of the highest-leverage variables in any AI system. Vague prompts don’t just produce vague outputs: they produce unpredictable ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent.&lt;/strong&gt; An AI system that can take actions, not just generate text. It has access to tools, search, email, databases, APIs, and decides which to use and in what order. The defining characteristic is that it can affect the world outside the conversation. If an LLM is like a consultant who gives advice, an agent is like an assistant who can actually book your flight, send the email, and update the spreadsheet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Harness.&lt;/strong&gt; The scaffolding you build around an LLM to make it useful in a specific context. System prompt, retrieval logic, error handling, tool connections: all of it together. The model is the engine. The harness is everything that makes it go where you want. Think of a Formula 1 car: the engine is powerful, but useless without the steering wheel, brakes, suspension, and chassis that let you actually control it.&lt;/p&gt;

&lt;h3 id=&quot;more-advanced-terms-if-youre-building-with-ai&quot;&gt;More Advanced Terms If You’re Building With AI&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;API (Application Programming Interface).&lt;/strong&gt; The formal connection point between two pieces of software. This isn’t AI-specific. It’s how all modern software connects, from weather apps to payment processors. But it’s essential vocabulary for AI because almost every AI tool you use is either calling an API (to get the model’s response) or offering one (so other tools can connect to it). When tools say they “integrate,” they almost always mean they share an API connection. Think of it like the electrical outlet in your wall. It’s a standardized interface that lets different appliances plug in and get power without rewiring your house each time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP (Model Context Protocol).&lt;/strong&gt; A way to let AI access your stuff: files, calendar, email. It’s trying to make these connections easier, but it’s early days and each company still does it a bit differently. You might see tools advertising MCP support. Just know it means the tool is trying to play nice with AI, even if the setup isn’t always smooth yet.&lt;/p&gt;

&lt;h2 id=&quot;the-real-lesson-from-the-car-wash&quot;&gt;The Real Lesson from the Car Wash&lt;/h2&gt;

&lt;p&gt;The conversation around that test wasn’t really about whether AI could reason through a simple question. It was about people evaluating something they couldn’t fully name.&lt;/p&gt;

&lt;p&gt;If you know the difference between a model and a model family, you ask “which version were they using?” instead of “is AI smart or dumb?” If you understand context windows, you stop blaming the AI when it forgets something from earlier in a long conversation. If you know what hallucination actually means, you stop using it as a catch-all for every output you don’t trust.&lt;/p&gt;

&lt;p&gt;That’s what vocabulary does. It turns vague frustration into specific, solvable problems.&lt;/p&gt;

</description>
        <pubDate>Wed, 18 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//AI-Vocabulary-101</link>
        <guid isPermaLink="true">https://bekahhw.com//AI-Vocabulary-101</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Beginner</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>AI Has Entered the AI Development Loop</title>
        <description>&lt;p&gt;It feels like we crossed a recursive threshold in February and the internet yawned.&lt;/p&gt;

&lt;p&gt;In February 2026, OpenAI published this in &lt;a href=&quot;https://openai.com/index/introducing-gpt-5-3-codex/&quot;&gt;their blog&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“GPT-5.3-Codex is our first model that was instrumental in creating itself… our team was blown away by how much Codex was able to accelerate its own development.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That line matters more than most of the benchmarks that followed.&lt;/p&gt;

&lt;p&gt;It doesn’t mean the model designed itself or trained itself. Humans still ran the research program. But it does mean something new: a model helping debug the experiments, analyze the results, and build the internal tools used to develop the next model.&lt;/p&gt;

&lt;p&gt;In other words, AI has started participating in the process that improves AI. Not designing itself. Not training itself. But participating directly in the development loop.&lt;/p&gt;

&lt;p&gt;It’s a subtle shift, but it changes the development loop in ways people haven’t fully processed yet.&lt;/p&gt;

&lt;h2 id=&quot;what-actually-happened-with-codex&quot;&gt;What Actually Happened with Codex&lt;/h2&gt;

&lt;p&gt;Early versions of Codex were used by the team to debug and monitor their own training runs, track patterns, propose fixes, and build custom apps for researchers to compare behaviors against prior models. The model managed deployment work, fixed bugs, handled cache issues, and scaled dynamically during traffic surges. It built data pipelines, visualized thousands of data points, and summarized insights in minutes.&lt;/p&gt;

&lt;p&gt;Humans still set the goals and approved the changes. But the feedback loop was tight enough that the team described themselves as “blown away” by how much it accelerated their workflow.&lt;/p&gt;

&lt;p&gt;The important part isn’t that the model “built itself.” It didn’t.&lt;/p&gt;

&lt;p&gt;The important part is that AI is now participating in the same engineering process that produces the next generation of AI.&lt;/p&gt;

&lt;p&gt;For decades researchers have talked about recursive improvement — systems that help design or improve their successors. Until recently that mostly lived in theory or narrow experiments like AutoML and evolutionary optimization.&lt;/p&gt;

&lt;p&gt;What’s different here is that the loop has moved from theory into the practical mechanics of AI development.&lt;/p&gt;

&lt;p&gt;A model helping run experiments.&lt;br /&gt;
A model helping debug infrastructure.&lt;br /&gt;
A model helping analyze results that feed into the next model.&lt;/p&gt;

&lt;p&gt;That shortens the distance between building an AI system and improving it.&lt;/p&gt;

&lt;p&gt;And once that loop tightens enough, the limiting factor on progress starts to shift.&lt;/p&gt;

&lt;h2 id=&quot;the-near-term-is-already-here&quot;&gt;The Near-Term Is Already Here&lt;/h2&gt;

&lt;p&gt;Inside major AI labs, development workflows are already changing.&lt;/p&gt;

&lt;p&gt;Leadership comments and internal reports suggest that a large share of internal code is now AI-assisted. Engineers increasingly describe their role less as writing every line of code and more as supervising systems that generate, test, and iterate on it.&lt;/p&gt;

&lt;p&gt;GPT-5.3-Codex is also the first OpenAI model rated “High capability” under their Preparedness Framework specifically for identifying software vulnerabilities. That’s one reason they launched a $10M API credit program aimed at security researchers the same week.&lt;/p&gt;

&lt;p&gt;But the more important shift is development velocity.&lt;/p&gt;

&lt;p&gt;When a model helps build the tools, pipelines, and analyses that support AI research, the iteration cycle compresses. Experiments run faster. Failures get diagnosed quicker. Teams can test more ideas in the same amount of time.&lt;/p&gt;

&lt;p&gt;That’s not a new pattern to software engineering. Compilers eventually compile themselves. Build systems generate other build systems. Tooling improves the tooling that follows it.&lt;/p&gt;

&lt;p&gt;What’s new is the intelligence now sitting inside that loop. That matters because progress in AI has often been limited less by ideas than by how quickly researchers can run experiments, interpret results, and try again.&lt;/p&gt;

&lt;h3 id=&quot;the-research-velocity-bottleneck&quot;&gt;The Research Velocity Bottleneck&lt;/h3&gt;

&lt;p&gt;What makes this significant is research velocity. Progress in AI has often been limited less by ideas than by how quickly researchers can run experiments, interpret results, and try again. Training runs take time. Infrastructure breaks. Data pipelines fail. Evaluations produce thousands of signals that humans have to sift through before the next iteration begins.&lt;/p&gt;

&lt;p&gt;When a model starts helping with those steps — debugging experiments, summarizing outcomes, generating analysis tools — the iteration cycle compresses. More experiments can run in the same amount of time. More hypotheses get tested. The frontier moves not because any single model is dramatically smarter, but because the feedback loop around improvement gets faster.&lt;/p&gt;

&lt;p&gt;AI development has historically been limited by compute, data, and human research time. If part of that research loop becomes automated, the bottleneck shifts again.&lt;/p&gt;

&lt;p&gt;This pattern shows up repeatedly in technological progress. Semiconductor advances accelerated when fabrication and testing cycles became automated. Software development accelerated when continuous integration systems started running builds and tests automatically. In both cases, the breakthrough was both better ideas and shortening the loop between trying something and learning whether it worked.&lt;/p&gt;

&lt;p&gt;AI entering its own development loop looks similar. When the systems being improved start helping run the improvement process, iteration speeds up. And when iteration speeds up, progress compounds.&lt;/p&gt;

&lt;p&gt;The question now isn’t whether a single model is dramatically smarter than the last one. It’s how quickly the next iteration can happen.&lt;/p&gt;

&lt;h2 id=&quot;the-medium-term-is-where-it-gets-uncomfortable&quot;&gt;The Medium-Term Is Where It Gets Uncomfortable&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://x.com/sama/status/1983584366547829073?lang=en&quot;&gt;Sam Altman has publicly said they have a goal of an “AI research intern” capability by September 2026 and “true automated AI researcher” by March 2028&lt;/a&gt;. As the loop tightens,  the cost of pushing the frontier drops. This will mean that either more companies can compete or the leaders pull further ahead because their iteration cycles compound faster. Meanwhile, parts of the engineering stack are already shifting.&lt;/p&gt;

&lt;p&gt;That transition isn’t happening slowly. As we’ve seen repeatedly with technological shifts, organizations often adapt under competitive pressure rather than through careful planning which tends to produce messy transitions and uneven outcomes. And the ripple effects won’t stop at tech. Any field built around complex, repeatable knowledge work will feel some version of the same pressure.&lt;/p&gt;

&lt;p&gt;What felt like a 5–10 year horizon for broad disruption is now measured in 1–3 years for many industries. This is why the anxiety feels bigger than “just devs.” It’s not isolated; it’s systemic acceleration.&lt;/p&gt;

&lt;h2 id=&quot;the-long-term-is-the-part-nobody-wants-to-say-out-loud&quot;&gt;The Long-Term Is the Part Nobody Wants to Say Out Loud&lt;/h2&gt;

&lt;p&gt;If AI systems eventually assist with the full research loop the feedback cycle tightens further. Hypothesis generation, experiment design, training runs, evaluation, all of it. That doesn’t automatically mean runaway intelligence. Capabilities could compound in ways that are genuinely hard to reason about in advance. But it does mean the systems advancing AI become partially automated themselves.&lt;/p&gt;

&lt;p&gt;That has implications people don’t fully understand yet.&lt;/p&gt;

&lt;p&gt;Neither path is guaranteed. What’s not up for debate is that when AI writes the code that trains the next AI, auditing gets harder. Tiny undetected biases, optimization pressures, and specification gaming can propagate across iterations.&lt;/p&gt;

&lt;p&gt;OpenAI and others have safeguards in place. The real question is whether those safeguards scale as quickly as the systems themselves.&lt;/p&gt;

&lt;p&gt;That’s not a rhetorical question. It’s an open one.&lt;/p&gt;

&lt;h2 id=&quot;why-you-should-care-now&quot;&gt;Why You Should Care Now&lt;/h2&gt;

&lt;p&gt;My instinct is usually to frame these shifts in ways that feel manageable, maybe even exciting. And some of it is exciting. But preparing people for what’s actually coming means being honest that the timeline is compressed, the impacts are uneven, and the people least prepared for the disruption will feel it most.&lt;/p&gt;

&lt;p&gt;The anxiety you might feel reading this isn’t irrational. It’s information. The question is what you do with it.&lt;/p&gt;

&lt;p&gt;The roles that will matter most aren’t necessarily the ones that write the most code. They’re the ones that can evaluate what AI produces critically, catch what automated systems miss, and understand enough about the systems they’re building on to ask the right questions. That’s worth investing in now, not when the next wave lands.&lt;/p&gt;

&lt;p&gt;Machines are now helping build the machines that come after them.&lt;/p&gt;

&lt;p&gt;That’s not the future. That’s February 2026.&lt;/p&gt;
</description>
        <pubDate>Wed, 04 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//ai-in-the-ai-development-loop</link>
        <guid isPermaLink="true">https://bekahhw.com//ai-in-the-ai-development-loop</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>Why Capable AI Keeps Getting Blocked</title>
        <description>&lt;p&gt;Amazon bans Claude Code internally. Enterprises quietly block Copilot. Security teams flag agentic workflows before they ever make it to production. SDK usage restrictions start showing up in internal policy docs that nobody announced out loud.&lt;/p&gt;

&lt;p&gt;Different companies and reasons, but the same underlying instinct.&lt;/p&gt;

&lt;p&gt;When something feels uncontrollable, the first response is rarely “let’s understand it better.” It’s “let’s shut it down.” When elevators became were first introduced, people refused to ride them alone. Building operators had to hire elevator attendants because people needed a human present to feel safe (keeping the human in the loop). The technology worked. The trust infrastructure didn’t exist yet.&lt;/p&gt;

&lt;p&gt;It’s not a failure of vision yet. It’s a pretty rational response to a real problem, but it’s where things go from here that matters. The question isn’t “why are companies banning AI tools?” The question is “what would have to be true for those tools to not need banning in the first place?”&lt;/p&gt;

&lt;h2 id=&quot;the-problem-isnt-the-tools&quot;&gt;The Problem isn’t the Tools&lt;/h2&gt;

&lt;p&gt;The last two years focused almost entirely on capability.&lt;/p&gt;

&lt;p&gt;Bigger models.&lt;br /&gt;
Autonomous agents.&lt;br /&gt;
Sophisticated chaining.&lt;/p&gt;

&lt;p&gt;Those bets paid off, and the systems are genuinely powerful.&lt;/p&gt;

&lt;p&gt;But capability without visibility is risk with a good PR story.&lt;/p&gt;

&lt;p&gt;We already learned this lesson in distributed systems. You don’t deploy a microservice without logs. You don’t scale a database without monitoring. You don’t run Kubernetes without observability. Those systems became trusted not because they were powerful, but because operators could see what they were doing.&lt;/p&gt;

&lt;p&gt;AI agents haven’t reached that level of maturity.&lt;/p&gt;

&lt;p&gt;An agent can:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Modify dozens of files&lt;/li&gt;
  &lt;li&gt;Call external APIs&lt;/li&gt;
  &lt;li&gt;Chain multiple model decisions&lt;/li&gt;
  &lt;li&gt;Execute tools across a session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And when the session ends, most of that reasoning disappears.&lt;/p&gt;

&lt;p&gt;If something goes wrong:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Can you replay the exact decision path?&lt;/li&gt;
  &lt;li&gt;Can you inspect intermediate model outputs?&lt;/li&gt;
  &lt;li&gt;Can you produce a structured audit trail for security?&lt;/li&gt;
  &lt;li&gt;Can you deterministically reproduce the outcome?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In many environments, the answer is no.&lt;/p&gt;

&lt;p&gt;So institutions respond the way institutions always do when power outruns accountability: they restrict access. That’s institutions doing what institutions do when power outruns accountability.&lt;/p&gt;

&lt;h2 id=&quot;the-next-phase-of-ai-maturity&quot;&gt;The Next Phase of AI Maturity&lt;/h2&gt;

&lt;p&gt;The bans aren’t the story. They’re a signal that we’ve entered a new phase of AI maturity, one where the capability questions are largely settled and the infrastructure questions are just getting started. Brian Douglas wrote more about this shift in his post &lt;a href=&quot;https://papercompute.com/blog/push-the-code-era-is-over/&quot;&gt;The Push Code Era is Over&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What needs to exist isn’t another wrapper or another interface. It’s the same thing every distributed system eventually needed: operator-grade tooling. Full request and response recording. Durable execution trails. Deterministic replay. The primitives that let you run powerful systems with confidence instead of just running them with hope.&lt;/p&gt;

&lt;p&gt;It’s not just about more capable agents. It’s about agents that are actually safe to operate at scale, ones that security teams can audit, that legal teams can defend, and that developers can trust with real work.&lt;/p&gt;

&lt;p&gt;The question worth asking right now isn’t which tools are going to get banned next. It’s what would have to be true for those tools to not need banning in the first place.&lt;/p&gt;

</description>
        <pubDate>Thu, 26 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//Why-AI-is-getting-Blocked</link>
        <guid isPermaLink="true">https://bekahhw.com//Why-AI-is-getting-Blocked</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>AI Ate the Homework: What Communities Are Actually For Now</title>
        <description>&lt;p&gt;When I was learning to code, one of the things that motivated me most was the sense of community. I found a ton of value in the Twitter community, where people answered questions, shared resources, and celebrated each other’s wins. I also found incredible support in online coding communities. A huge part of this was the ability to ask questions and get help from others who had been where I was. They brought empathy and experience in a way that documentation and tutorials couldn’t, and made me feel like I could do it even when I didn’t believe that.&lt;/p&gt;

&lt;p&gt;A huge part of Virtual Coffee’s early growth was people finding each other to ask questions, get help, and learn together. It was a safe space to say “I don’t know how to do this” or “Is this interview experience ‘normal’?” and have someone patiently walk you through it.&lt;/p&gt;

&lt;p&gt;Not only did having your question answered give you the information you needed, it gave you validation. You weren’t alone. You were struggling with something that other people struggled with too. But. it also felt good to help. And in a lot of ways, you experienced growth and it felt tangible when you were able to answer someone else’s question. Successful communities saw collective knowledge sharing, mutual aid, opportunities to learn together.&lt;/p&gt;

&lt;p&gt;By 2024, something had fundamentally shifted.&lt;/p&gt;

&lt;p&gt;ChatGPT could answer your JavaScript question in three seconds. Claude could debug your code and explain why. The questions that used to fill Discord and Slack, “how do I center a div?” or “what’s the difference between let and const?” or “why isn’t my API call working?” suddenly had a faster, always-available answer. And now, you prompt your LLM and get code that works, explanations that make sense, and debugging help without needing to wait for someone to see your question and respond.&lt;/p&gt;

&lt;p&gt;And with that shift came a new tension nobody quite knew how to name: the growing frustration when someone asks a question that AI could have answered, and the growing anxiety about asking questions when you’re not sure if you’ve “done enough work first.”&lt;/p&gt;

&lt;p&gt;The bar rose.&lt;/p&gt;

&lt;h2 id=&quot;the-numbers-tell-the-story&quot;&gt;The Numbers Tell the Story&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://developers.slashdot.org/story/25/01/10/1729248/stackoverflow-usage-plummets-as-ai-chatbots-rise&quot;&gt;Stack Overflow traffic dropped 14% month-over-month from March to April 2023, right after GPT-4 launched. By December 2024, new questions had dropped 60% year-over-year. The volume of questions is down 75% from its 2017 peak and 76% since ChatGPT’s launch in November 2022.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developers weren’t being difficult. They were being rational.&lt;/p&gt;

&lt;p&gt;Why post a question on Stack Overflow and wait for someone to answer when ChatGPT gives you working code in seconds? Why search through Discord message history when Claude can explain the concept in plain English, tailored to your specific context? Why ask a community and risk judgment and assholes on the internet when AI is always available, non-judgmental, and fast?&lt;/p&gt;

&lt;p&gt;AI could now handle most of the questions communities used to.&lt;/p&gt;

&lt;h2 id=&quot;the-unspoken-contract-changed&quot;&gt;The Unspoken Contract Changed&lt;/h2&gt;

&lt;p&gt;Here’s what this shift did to the implicit contract of online communities:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In 2020-2021:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;You asked questions, even basic ones, and people were happy to help&lt;/li&gt;
  &lt;li&gt;The community was the primary resource for learning and problem-solving&lt;/li&gt;
  &lt;li&gt;At Virtual Coffee, we embraced horizontal mentrship—everyone could ask and everyone could answer&lt;/li&gt;
  &lt;li&gt;Asking for help was normal and expected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In 2025-2026:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;You’re expected to try AI first before “wasting” people’s time&lt;/li&gt;
  &lt;li&gt;The community is for questions AI &lt;em&gt;can’t&lt;/em&gt; answer&lt;/li&gt;
  &lt;li&gt;There’s an unspoken frustration at questions ChatGPT could handle&lt;/li&gt;
  &lt;li&gt;Asking for help requires demonstrating you’ve done your homework&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We started to see that community members who were tired of answering the same basic questions when AI could do it faster.&lt;/p&gt;

&lt;h2 id=&quot;what-communities-are-actually-for-now&quot;&gt;What Communities Are Actually For Now&lt;/h2&gt;

&lt;p&gt;So if AI handles basic questions, what are communities actually &lt;em&gt;for&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;The answer should be: judgment, experience, connection, and the questions AI can’t answer.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“Should I take this job or stay at my current role?”&lt;/li&gt;
  &lt;li&gt;“How do you actually work with this technology in production?”&lt;/li&gt;
  &lt;li&gt;“What’s the culture like at {company}?”&lt;/li&gt;
  &lt;li&gt;“I’m burned out. How did you work through it?”&lt;/li&gt;
  &lt;li&gt;“Here’s this cool thing I built and I think it could help others. What do you think?”&lt;/li&gt;
  &lt;li&gt;“How do you navigate sick kids and a feature launch???”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are inherently human questions requiring human judgment, lived experience, and contextual understanding. They’re the questions that make communities valuable. They’re the questions that foster connection and belonging. They’re the questions that create shared understanding and collective wisdom.&lt;/p&gt;

&lt;p&gt;But here’s the problem: many communities haven’t consciously made this shift. They’re still structured around Q&amp;amp;A patterns that AI now handles better. They’re still trying to be “the place developers get answers” when that race is lost.&lt;/p&gt;

&lt;p&gt;Product communities are particularly stuck. They’re trying to serve two populations:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Drive-by users&lt;/strong&gt; who just need their build to work and will never engage beyond that&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Community seekers&lt;/strong&gt; who want connection, depth, and belonging&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These need different things. The drive-by user benefits from AI-first + good docs. The community seeker needs human connection. Trying to serve both with the same strategy doesn’t work.&lt;/p&gt;

&lt;h2 id=&quot;the-sustainability-crisis&quot;&gt;The Sustainability Crisis&lt;/h2&gt;

&lt;p&gt;This creates a sustainability problem that’s quietly breaking communities:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For community builders:&lt;/strong&gt;
You’re caught between welcoming everyone and managing finite volunteer energy. When someone asks a question ChatGPT could answer in 3 seconds, do you answer it (and enable learned helplessness) or redirect them (and risk seeming unwelcoming)? There’s no good answer, and the constant navigation is exhausting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For community members:&lt;/strong&gt;
You’re navigating unwritten rules about what’s “appropriate” to ask. You feel guilty asking for help because maybe you didn’t try hard enough. You see others get redirected to AI and worry you’ll be next. The psychological safety that made communities work is eroding.&lt;/p&gt;

&lt;h2 id=&quot;the-uncomfortable-questions&quot;&gt;The Uncomfortable Questions&lt;/h2&gt;

&lt;p&gt;Where does this leave us? With some hard questions we need to actually ask:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;About AI expectations:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;How do we honor that AI makes many questions obsolete without making people feel unwelcome?&lt;/li&gt;
  &lt;li&gt;What’s our responsibility when not everyone has the same AI access?&lt;/li&gt;
  &lt;li&gt;How do we shift from “Q&amp;amp;A community” to “judgment and experience community”?&lt;/li&gt;
  &lt;li&gt;What questions actually need humans now?&lt;/li&gt;
  &lt;li&gt;Is “try ChatGPT first” gatekeeping or reasonable boundary?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;About community purpose:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Are we trying to be everything when we should be something specific?&lt;/li&gt;
  &lt;li&gt;Can drive-by Q&amp;amp;A and deep connection coexist in one space?&lt;/li&gt;
  &lt;li&gt;What happens when 80% of your community just wants fast answers?&lt;/li&gt;
  &lt;li&gt;How do we serve people who need basic help without burning out the helpers?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;About sustainability:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Can volunteer-run communities survive when the “easy” questions (that felt good to answer) are gone?&lt;/li&gt;
  &lt;li&gt;How do we make helping feel rewarding again when all that’s left are hard questions?&lt;/li&gt;
  &lt;li&gt;What’s the minimum viable community when AI handles the basics?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-actually-works-now&quot;&gt;What Actually Works Now&lt;/h2&gt;

&lt;p&gt;The communities thriving in 2026 aren’t the ones fighting AI or pretending it doesn’t exist. They’re the ones that:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accepted the shift in purpose.&lt;/strong&gt; They’re not trying to be Stack Overflow. They’re spaces for nuanced discussion, career advice, lived experience, and human judgment calls. They’ve made peace with AI handling the basics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stay welcoming while having boundaries.&lt;/strong&gt; “Hey, ChatGPT might be faster for this!” is fine. “Why are you wasting our time?” is not. There’s a way to redirect to AI tools while maintaining psychological safety.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separate transaction from connection.&lt;/strong&gt; Some spaces are for quick help (and that’s fine). Some spaces are for deeper belonging (and that’s different). Trying to be both creates friction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accepted different participation levels.&lt;/strong&gt; Drive-by questions are fine. People who only show up when they need something are fine. The always-engaged ideal is dead, and that’s okay.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built for the people who actually need them now.&lt;/strong&gt; People navigating complex career decisions. People working with niche technologies where AI training is thin. People who need human judgment, not just answers. People without AI access. Not &lt;em&gt;everyone&lt;/em&gt;, because not everyone needs human community for Q&amp;amp;A anymore.&lt;/p&gt;

&lt;p&gt;The bar that nobody asked for—AI capability—did change what communities are for. But it didn’t eliminate the need for community. It just clarified it.&lt;/p&gt;

&lt;p&gt;We don’t need communities to answer “how do I center a div?” anymore. We need them for “should I take this job?” and “how do I not burn out?” and “what’s it actually like to work there?”&lt;/p&gt;

&lt;p&gt;And honestly? Those are better questions. They just require us to be more human, not less.&lt;/p&gt;
</description>
        <pubDate>Mon, 24 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//ai-impact-on-community</link>
        <guid isPermaLink="true">https://bekahhw.com//ai-impact-on-community</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Community</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>The Invisible Load: How AI Workflows Can Replace Your Team&apos;s &apos;Glue Person&apos;</title>
        <description>&lt;p&gt;Every team has one, and, tbh, a lot of relationships have one. The person who remembers. For teams, it might be the person who remembers to update the changelog. Who posts the weekly standup summary. Who follows up on that GitHub issue from three weeks ago. Who makes sure the docs match the latest release. Who bridges the gap between what engineering ships and what the rest of the company knows about.&lt;/p&gt;

&lt;p&gt;We call this “glue work,” and research shows it disproportionately falls on women in teams, and mothers in relationships. It’s the invisible labor that keeps everything running smoothly, but rarely shows up in performance reviews or promotion discussions.&lt;/p&gt;

&lt;p&gt;The problem is that glue work is essential, but it shouldn’t be someone’s primary job. And it definitely shouldn’t be the reason talented people get passed over for advancement.&lt;/p&gt;

&lt;p&gt;But what if AI workflows could be the glue instead?&lt;/p&gt;

&lt;h2 id=&quot;the-glue-work-problem&quot;&gt;The Glue Work Problem&lt;/h2&gt;

&lt;p&gt;Tanya Reilly’s essay &lt;a href=&quot;https://www.noidea.dog/glue/&quot;&gt;“Being Glue”&lt;/a&gt; describes how critical but undervalued work like coordinating between teams, translating technical concepts, maintaining documentation, ensuring follow-through often becomes invisible. The people who do it often make everything seem easy. But there’s a cost, and it’s compounding in the background.&lt;/p&gt;

&lt;p&gt;If you have one teammate who’s spending hours each week:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Updating tickets after standups&lt;/li&gt;
  &lt;li&gt;Posting release summaries to Slack&lt;/li&gt;
  &lt;li&gt;Making sure customer support knows about new features&lt;/li&gt;
  &lt;li&gt;Chasing down PR reviews&lt;/li&gt;
  &lt;li&gt;Updating documentation after merges&lt;/li&gt;
  &lt;li&gt;Following up on blocked issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;when none of this is their actual job, then they may be your “glue.” All of it is necessary. But when they stop doing it, things fall apart.&lt;/p&gt;

&lt;p&gt;Maybe it doesn’t seem that bad right now, but coordination work compounds as teams grow.&lt;/p&gt;

&lt;h2 id=&quot;what-if-workflows-could-be-the-glue&quot;&gt;What If Workflows Could Be the Glue?&lt;/h2&gt;

&lt;p&gt;This is where composed AI workflows change everything. Not because they eliminate coordination work, but because they automate it at the seams between tasks.&lt;/p&gt;

&lt;p&gt;In his post on &lt;a href=&quot;https://www.linkedin.com/pulse/individual-workflows-scale-linearly-composed-compound-chad-metcalf-x7fyc&quot;&gt;composed workflows&lt;/a&gt;, Continue CEO Chad Metcalf makes an important distinction: a single workflow saves time, but composed workflows compound. When the output of one workflow can trigger the next, you’re doing more than just automating individual tasks. You’re automating the entire coordination system.&lt;/p&gt;

&lt;p&gt;Let’s look at what this actually means.&lt;/p&gt;

&lt;h3 id=&quot;example-1-the-release-communication-burden&quot;&gt;Example 1: The Release Communication Burden&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Current state:&lt;/strong&gt; After every release, someone (usually the same someone) needs to:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Draft changelog entries&lt;/li&gt;
  &lt;li&gt;Update product documentation&lt;/li&gt;
  &lt;li&gt;Post to company Slack&lt;/li&gt;
  &lt;li&gt;Update customer-facing docs&lt;/li&gt;
  &lt;li&gt;Create support team briefing&lt;/li&gt;
  &lt;li&gt;Close related Linear issues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That “someone” spends 2-3 hours per release on coordination work. Not working on more impactful work. Just making sure everyone knows what shipped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With composed workflows:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Merge to main 
  → Extract changes from PR descriptions 
  → Draft changelog entry 
  → Update technical docs 
  → Generate customer-facing summary 
  → Post to internal Slack 
  → Update support knowledge base 
  → Close related issues
  → Post completion summary
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The entire coordination chain runs automatically. The output of one workflow triggers the next. No one spends their afternoon being glue. Instead, they become the human in the loop who reviews and improves the process.&lt;/p&gt;

&lt;h3 id=&quot;example-2-the-follow-up-tax&quot;&gt;Example 2: The Follow-Up Tax&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Current state:&lt;/strong&gt; You’re in standup. Someone mentions they’re blocked on a security review. Everyone nods. The meeting ends.&lt;/p&gt;

&lt;p&gt;Three days later, nothing’s happened because nobody remembered to:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Create a ticket&lt;/li&gt;
  &lt;li&gt;Tag the security team&lt;/li&gt;
  &lt;li&gt;Follow up when there’s no response&lt;/li&gt;
  &lt;li&gt;Update the original ticket&lt;/li&gt;
  &lt;li&gt;Let the blocked person know it’s unblocked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Guess who remembers? The glue person, who now spends their time tracking other people’s blockers instead of writing code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With composed workflows:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;Blocked on X&quot; detected in standup notes 
  → Create Linear issue with context 
  → Tag relevant team 
  → Set reminder for 2 days 
  → Follow up if no response 
  → Update original ticket when resolved 
  → Notify blocked person
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The follow-through happens automatically. Nobody has to be the memory keeper.&lt;/p&gt;

&lt;h3 id=&quot;example-3-the-support-handoff&quot;&gt;Example 3: The Support Handoff&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Current state:&lt;/strong&gt; Customer reports a bug in Slack. Engineering fixes it. But somehow:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Support never gets notified the fix is live&lt;/li&gt;
  &lt;li&gt;Customer still thinks it’s broken&lt;/li&gt;
  &lt;li&gt;Docs don’t reflect the fix&lt;/li&gt;
  &lt;li&gt;The original Slack thread is forgotten&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Someone (the glue person) ends up manually connecting all these dots. Every. Single. Time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With composed workflows:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Bug report in Slack 
  → Create Linear issue 
  → PR created and merged 
  → Update documentation 
  → Generate fix summary 
  → Post to support channel 
  → Reply to original Slack thread 
  → Close Linear issue with summary
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The entire loop closes itself. From report to fix to notification to documentation to closure. No human glue required.&lt;/p&gt;

&lt;h2 id=&quot;why-this-works-where-other-solutions-dont&quot;&gt;Why This Works Where Other Solutions Don’t&lt;/h2&gt;

&lt;h3 id=&quot;its-not-about-replacing-people&quot;&gt;It’s Not About Replacing People&lt;/h3&gt;

&lt;p&gt;AI workflows aren’t replacing the glue person’s judgment or expertise. They’re replacing the repetitive coordination tasks that shouldn’t require judgment.&lt;/p&gt;

&lt;p&gt;When a PR merges, updating the changelog doesn’t need human insight. Following up on a blocked issue after two days doesn’t require strategic thinking. Posting a deployment summary to Slack isn’t creative work.&lt;/p&gt;

&lt;p&gt;These are mechanical transitions between tasks. Perfect candidates for automation.&lt;/p&gt;

&lt;h3 id=&quot;it-compounds-over-time&quot;&gt;It Compounds Over Time&lt;/h3&gt;

&lt;p&gt;Here’s what makes this different from other automation attempts: composition creates compounding value.&lt;/p&gt;

&lt;p&gt;Each workflow you add doesn’t just save time on that specific task. It amplifies the value of workflows already running. The deployment workflow outputs information the changelog workflow needs. The Linear sync workflow triggers the documentation update workflow. The customer support workflow feeds the product insights workflow.&lt;/p&gt;

&lt;p&gt;You’re not just automating individual tasks. You’re automating the entire coordination system.&lt;/p&gt;

&lt;h3 id=&quot;it-preserves-the-actual-value-of-glue&quot;&gt;It Preserves the Actual Value of “Glue”&lt;/h3&gt;

&lt;p&gt;The valuable part of glue work isn’t the mechanical coordination. It’s the strategic connection-making, the pattern recognition, the ability to see across teams and translate context.&lt;/p&gt;

&lt;p&gt;When AI workflows handle the mechanical parts, the humans who were doing glue work can focus on the strategic parts.&lt;/p&gt;

&lt;p&gt;They can spend time:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Identifying patterns across customer feedback&lt;/li&gt;
  &lt;li&gt;Improving team processes&lt;/li&gt;
  &lt;li&gt;Mentoring junior developers&lt;/li&gt;
  &lt;li&gt;Solving actually complex problems&lt;/li&gt;
  &lt;li&gt;Advancing their technical skills&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The things that actually deserve their expertise.&lt;/p&gt;

&lt;h2 id=&quot;the-composition-advantage&quot;&gt;The Composition Advantage&lt;/h2&gt;

&lt;p&gt;Individual workflows are helpful. Composed workflows are transformative.&lt;/p&gt;

&lt;p&gt;As Chad Metcalf writes in his post on composed workflows: “Individual workflows give linear improvements. Composed workflows compound.” This distinction is crucial when thinking about how to replace organizational glue work.&lt;/p&gt;

&lt;p&gt;Because here’s what happens when workflows compose: the coordination work stops being a burden on any individual. Instead, it becomes part of the system itself.&lt;/p&gt;

&lt;p&gt;You’re not asking someone to remember to update the docs after deployment. The deployment workflow triggers the documentation workflow automatically. You’re not relying on someone to follow up on blocked issues. The standup workflow creates follow-up workflows with built-in reminders.&lt;/p&gt;

&lt;p&gt;This is infrastructure that scales with your team. As you grow, the glue work compounds. But with composed workflows, the automation compounds instead.&lt;/p&gt;

&lt;h2 id=&quot;real-team-impact-beyond-time-savings&quot;&gt;Real Team Impact: Beyond Time Savings&lt;/h2&gt;

&lt;p&gt;Let’s talk about what this actually means for teams.&lt;/p&gt;

&lt;h3 id=&quot;no-more-that-person&quot;&gt;No More “That Person”&lt;/h3&gt;

&lt;p&gt;When coordination work is automated, it stops being concentrated on one or two people. The person who used to spend 10 hours a week on glue work can spend those hours on actual engineering. Or product work. Or whatever they were actually hired to do.&lt;/p&gt;

&lt;p&gt;More importantly: they stop being the bottleneck. When knowledge and coordination flows through automated systems rather than through specific people, teams become more resilient. People can take vacation without everything falling apart. New team members can onboard without needing to know who to ask for everything.&lt;/p&gt;

&lt;h3 id=&quot;career-equity&quot;&gt;Career Equity&lt;/h3&gt;

&lt;p&gt;Glue work is often invisible during performance reviews. “Sarah keeps everything running smoothly” doesn’t translate to promotion decisions the way “shipped three major features” does.&lt;/p&gt;

&lt;p&gt;When AI workflows handle coordination, engineers can focus on work that’s more visible and valued. This has disproportionate impact on people—often women and mothers—who tend to take on more glue work.&lt;/p&gt;

&lt;h3 id=&quot;team-velocity-at-scale&quot;&gt;Team Velocity at Scale&lt;/h3&gt;

&lt;p&gt;Small teams can coordinate informally. “Hey, remember to update the docs” works when you’re five people.&lt;/p&gt;

&lt;p&gt;At 20 people? 50? Informal coordination breaks down. You need systems. The question is: will those systems be human-dependent, automated, or composed with a human in the loop?&lt;/p&gt;

&lt;p&gt;Composed workflows scale. Human coordination doesn’t.&lt;/p&gt;

&lt;h2 id=&quot;how-to-actually-do-this&quot;&gt;How to Actually Do This&lt;/h2&gt;

&lt;p&gt;Don’t start by trying to automate everything. Start with the most repetitive, predictable coordination work on your team.&lt;/p&gt;

&lt;h3 id=&quot;step-1-identify-your-glue-work&quot;&gt;Step 1: Identify Your Glue Work&lt;/h3&gt;

&lt;p&gt;Have an honest conversation. Ask:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;What coordination tasks happen after every release?&lt;/li&gt;
  &lt;li&gt;What follow-ups consistently fall through the cracks?&lt;/li&gt;
  &lt;li&gt;Where does information get stuck between teams?&lt;/li&gt;
  &lt;li&gt;Who’s spending time on mechanical updates vs. strategic work?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write it down. You’re looking for patterns, not one-off tasks.&lt;/p&gt;

&lt;h3 id=&quot;step-2-build-one-workflow&quot;&gt;Step 2: Build One Workflow&lt;/h3&gt;

&lt;p&gt;Pick the most painful coordination task. The one that happens constantly and requires zero judgment.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Changelog updates after merges&lt;/li&gt;
  &lt;li&gt;Standup note distribution&lt;/li&gt;
  &lt;li&gt;PR review reminders&lt;/li&gt;
  &lt;li&gt;Linear ticket status syncing&lt;/li&gt;
  &lt;li&gt;Documentation updates post-deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Build a workflow that handles it end-to-end. Run it for a week. Measure intervention rate—how often does it need human correction?&lt;/p&gt;

&lt;p&gt;Get that intervention rate below 5%. Then move to step 3.&lt;/p&gt;

&lt;h3 id=&quot;step-3-compose&quot;&gt;Step 3: Compose&lt;/h3&gt;

&lt;p&gt;Look at the output of your first workflow. What happens next in the coordination chain?&lt;/p&gt;

&lt;p&gt;If your workflow posts deployment notes to Slack, what normally happens after that? Maybe documentation gets updated. Maybe customer support gets briefed. Maybe Linear tickets get closed.&lt;/p&gt;

&lt;p&gt;Build workflows for those next steps. Connect them to your first workflow’s output.&lt;/p&gt;

&lt;p&gt;Now you have composition. One workflow’s completion triggers the next. The coordination chain runs automatically.&lt;/p&gt;

&lt;h3 id=&quot;step-4-keep-going&quot;&gt;Step 4: Keep Going&lt;/h3&gt;

&lt;p&gt;Each new workflow amplifies the ones before it. The deployment workflow feeds the documentation workflow. The documentation workflow triggers the changelog workflow. The changelog workflow posts to Slack, which triggers the customer communication workflow.&lt;/p&gt;

&lt;p&gt;You’re not just saving time on individual tasks. You’re building a system where coordination happens automatically at every transition point.&lt;/p&gt;

&lt;h2 id=&quot;the-bigger-picture&quot;&gt;The Bigger Picture&lt;/h2&gt;

&lt;p&gt;This isn’t just about efficiency. It’s about equity.&lt;/p&gt;

&lt;p&gt;When essential coordination work is visible and automated, nobody gets stuck being the invisible glue. Everyone can focus on the work they’re actually good at, the work that gets recognized and rewarded.&lt;/p&gt;

&lt;p&gt;Teams that build composed AI workflows aren’t just shipping faster. They’re redistributing the coordination burden from people to systems. They’re making space for everyone to do their best work.&lt;/p&gt;

&lt;p&gt;Look at your team. Who’s the glue person? What would they be working on if they weren’t constantly coordinating?&lt;/p&gt;

&lt;p&gt;That’s the real value of composition.&lt;/p&gt;

</description>
        <pubDate>Thu, 06 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//AI-Workflows-Can-Be-The-Glue</link>
        <guid isPermaLink="true">https://bekahhw.com//AI-Workflows-Can-Be-The-Glue</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        <category>Career</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>When We Became What We Do: The Identity Crisis That Companies Mistook for Opportunity</title>
        <description>&lt;p&gt;In March 2020, a &lt;em&gt;weird&lt;/em&gt; thing happened to how we answered the question “Who are you?”&lt;/p&gt;

&lt;p&gt;Before the pandemic, most of us had multifaceted identities. I was the person who went to the gym and lifted weights 6x a week, who took my kids to the park all the time, who volunteered at the school, attended the occasional book club, and who took a break by going grocery shopping on Saturday mornings. For many of us, our sense of self was distributed across multiple domains, including social, familial, recreational, and professional.&lt;/p&gt;

&lt;h2 id=&quot;the-great-identity-consolidation&quot;&gt;The Great Identity Consolidation&lt;/h2&gt;

&lt;p&gt;Lockdown stripped most of those identities away in a matter of weeks or even days. Even family gatherings and Sunday dinners and holiday traditions moved to Zoom calls or stopped entirely.&lt;/p&gt;

&lt;p&gt;Every space where we’d embody our various identities closed. I couldn’t be “the person who deadlifted on Tuesdays” when there was no weightroom open. You can’t be “the parent who knows everyone at school” when school is a URL. You can’t be “the person who always hosts game night” when gathering is prohibited.&lt;/p&gt;

&lt;p&gt;Our professional identity didn’t just persist. It intensified, because work didn’t stop. In actuality, for a lot of us it intensified or became the one thing we could control. I lost my job, but I could look for another. For many people, work-from-home meant &lt;em&gt;more&lt;/em&gt; hours. Slack channels kept pinging. Standups kept happening. Deadlines didn’t pause for a pandemic.&lt;/p&gt;

&lt;p&gt;Suddenly, “developer” or “designer” or “product manager” wasn’t just what we &lt;em&gt;did&lt;/em&gt;. It became almost the entirety of who we &lt;em&gt;were&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Not by choice. By elimination.&lt;/p&gt;

&lt;p&gt;Remote work intensified what researchers called “identity blur” or the breakdown of boundaries between personal and professional life. Not to mention that an entire generation of early-career professionals were doing their identity formation almost exclusively through the professional lens.&lt;/p&gt;

&lt;h2 id=&quot;why-tech-communities-exploded&quot;&gt;Why Tech Communities Exploded&lt;/h2&gt;

&lt;p&gt;This identity shift created fertile ground for professional communities to thrive in unprecedented ways.&lt;/p&gt;

&lt;p&gt;Developer communities, in particular, saw explosive growth. The community infrastructure was already there: Slack, Discord, forums, virtual meetups. But suddenly, these weren’t just places to ask technical questions or network for jobs. They became primary social spaces.&lt;/p&gt;

&lt;p&gt;When I started Virtual Coffee in March of 2020, I was &lt;em&gt;desperately&lt;/em&gt; looking for &lt;em&gt;people&lt;/em&gt; after I lost my first developer job. It wasn’t supplementing my social life because it &lt;em&gt;was&lt;/em&gt; my social life. The Tuesday meetups became my weekly social anchor.&lt;/p&gt;

&lt;p&gt;And I wasn’t alone. Across the tech ecosystem, professional communities became all-purpose gathering spaces. The hallway track at conferences had always been valuable, but now people were craving the hallway track without the conference. They wanted the coffee shop where everyone was a developer. They wanted to belong somewhere, and professional identity was one of the few identities still accessible.&lt;/p&gt;

&lt;h2 id=&quot;the-numbers-that-told-a-story&quot;&gt;The Numbers That Told a Story&lt;/h2&gt;

&lt;p&gt;By 2021, the indicators were everywhere:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Community engagement increased&lt;/li&gt;
  &lt;li&gt;Community programs saw increased recognition of their value&lt;/li&gt;
  &lt;li&gt;Having an online community became more important in 2020&lt;/li&gt;
  &lt;li&gt;Time on social and community platforms jumped dramatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But here’s what the numbers &lt;em&gt;weren’t&lt;/em&gt; saying: they weren’t showing that people had discovered a permanent need for professional community. They were showing that professional community was filling a vacuum left by every &lt;em&gt;other&lt;/em&gt; kind of community disappearing.&lt;/p&gt;

&lt;p&gt;Professional community wasn’t competing with other professional communities. It was competing with—and replacing—gyms, coffee shops, happy hours, hobby groups, neighborhood connections, and casual friendships.&lt;/p&gt;

&lt;h2 id=&quot;the-company-gold-rush&quot;&gt;The Company Gold Rush&lt;/h2&gt;

&lt;p&gt;Companies looked at those engagement numbers and saw opportunity.&lt;/p&gt;

&lt;p&gt;If you were a tech company in 2020-2021 watching developers flock to online communities, the conclusion seemed obvious: we need a community. If you were hiring and saw that developer engagement was at all-time highs, you might think: we need a community manager. I became a technical community manager because tech was primed to invest in community roles.&lt;/p&gt;

&lt;p&gt;The role that was previously a nice-to-have became a strategic imperative.&lt;/p&gt;

&lt;p&gt;Companies launched Slacks, Discord servers, forums, and user groups. They hired community managers, developer advocates, and DevRel teams. They built content strategies around community engagement. They measured success by the metrics they were seeing everywhere: member counts, daily active users, message volume.&lt;/p&gt;

&lt;p&gt;The logic seemed on track:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;People are engaging with online communities at unprecedented levels&lt;/li&gt;
  &lt;li&gt;Our competitors are building communities&lt;/li&gt;
  &lt;li&gt;Community drives product adoption and loyalty&lt;/li&gt;
  &lt;li&gt;Therefore, we need to invest in community&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But this logic missed &lt;em&gt;context&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-substitution-effect-nobody-acknowledged&quot;&gt;The Substitution Effect Nobody Acknowledged&lt;/h2&gt;

&lt;p&gt;What companies were observing wasn’t a permanent shift in how people want to engage with brands or products. It was a temporary substitution driven by extraordinary circumstances.&lt;/p&gt;

&lt;p&gt;In 2020-2021, professional communities were standing in for:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Local social connections (because we couldn’t gather)&lt;/li&gt;
  &lt;li&gt;Recreational identities (because hobbies were paused)&lt;/li&gt;
  &lt;li&gt;Casual professional networking (because conferences were canceled)&lt;/li&gt;
  &lt;li&gt;Workspace camaraderie (because offices were closed)&lt;/li&gt;
  &lt;li&gt;General human connection (because isolation was mandatory)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The engagement wasn’t high because people suddenly valued brand communities more. It was high because professional community was the &lt;em&gt;only&lt;/em&gt; community many people had access to.&lt;/p&gt;

&lt;p&gt;Think about it this way: if you’re working from home, can’t go to the gym, can’t meet friends for coffee, and can’t attend local meetups, where do you find people? If your identity as a weight lifter is on hold because gyms are closed, and your identity as a parent is strained because you’re homeschooling, what’s left? Your professional identity. And where do professionals gather? Online, in communities organized around their work.&lt;/p&gt;

&lt;h2 id=&quot;what-success-really-looked-like&quot;&gt;What Success Really Looked Like&lt;/h2&gt;

&lt;p&gt;Companies celebrated metrics that looked like success:&lt;/p&gt;

&lt;p&gt;“Our Discord hit 10,000 members!”
“Daily active users up 300%!”
“Community engagement is our highest ever!”&lt;/p&gt;

&lt;p&gt;But a lot of them were ignoring the fact that people weren’t necessarily there because your product was so compelling that they wanted to be part of your brand community. They were there because they were lonely, isolated, and craving connection, and your professional community was one of the only options available.&lt;/p&gt;

&lt;p&gt;This isn’t to diminish the genuine connections people made or the real value these communities provided. Virtual Coffee meant–and still means–the world to me. The developer communities that emerged during this time saved people’s mental health and careers.&lt;/p&gt;

&lt;p&gt;But the &lt;em&gt;reason&lt;/em&gt; for that value was specific to the moment. We were all in crisis, and professional community became a lifeline not because it was uniquely better than before, but because everything else was gone.&lt;/p&gt;

&lt;h2 id=&quot;belonging-doesnt-scale-the-way-companies-hoped&quot;&gt;Belonging Doesn’t Scale the Way Companies Hoped&lt;/h2&gt;

&lt;p&gt;But you can’t manufacture the conditions that created pandemic-era engagement.&lt;/p&gt;

&lt;p&gt;You can’t make someone lonely enough to spend three hours a day in your Discord.&lt;/p&gt;

&lt;p&gt;You can’t make someone isolated enough to treat your Slack like their primary social group.&lt;/p&gt;

&lt;p&gt;You can’t make someone identity-starved enough to build their sense of self around your brand community.&lt;/p&gt;

&lt;p&gt;And you most definitely should not want to.&lt;/p&gt;

&lt;p&gt;As the world reopened, people’s identities re-diversified. The parent identity came back with in-person school. The athlete identity returned with reopened gyms. The friend identity flourished with in-person coffee dates. The hobbyist identity resumed with craft groups and sports leagues.&lt;/p&gt;

&lt;p&gt;Professional identity didn’t disappear, but it was &lt;em&gt;one of many&lt;/em&gt; identities, not the primary or only identity.&lt;/p&gt;

&lt;p&gt;But companies didn’t anticipate: people wanted to keep both.&lt;/p&gt;

&lt;p&gt;The connections made during the pandemic weren’t casual networking. They were trauma bonds. We didn’t just share technical knowledge in those slacks and Zoom rooms. We &lt;em&gt;survived&lt;/em&gt; isolation together, processed fear together, figured out how to keep going together. We saw each other at our worst: unmuted kids screaming, laundry piles stacked and thrown across the floor, tears with lost jobs. We celebrated new babies through screens. We mourned miscarriages together in the #heavy channel. We watched marriages fall apart in real-time as people processed isolation and stress.&lt;/p&gt;

&lt;p&gt;And we lost people.&lt;/p&gt;

&lt;p&gt;And when that happened, we couldn’t gather. We couldn’t hug each other. We couldn’t sit together at a funeral. We watched memorial services on Zoom, crying alone in our homes, typing condolences in chat windows, wishing desperately we could just &lt;em&gt;be there&lt;/em&gt; together in person.&lt;/p&gt;

&lt;p&gt;The grief was compounded by the medium. These were people who’d kept us sane, who we’d talked to nearly every day, who felt like lifelines. And when they were gone, we had to process that loss the same way we’d built the relationship, through screens, at a distance, without the physical comfort that humans need in grief.&lt;/p&gt;

&lt;p&gt;These weren’t casual professional connections. These were people who’d seen us completely, who’d held space for our fear and loneliness, who’d shared their own vulnerability in ways that rarely happen in professional contexts. The bonds formed under those conditions of shared trauma, radical vulnerability, mutual survival, don’t just dissolve when offices reopen.&lt;/p&gt;

&lt;p&gt;This wasn’t like moving to a new city and losing touch with old friends, or kids graduating so you stop seeing other parents at pickup. Those transitions are natural drift. This was different. People wanted to maintain these deep connections while returning to physical community.&lt;/p&gt;

&lt;p&gt;But time is finite. You can’t spend three hours a day in the Virtual Coffee co-working room when you’re back at an actual office. You can’t attend every virtual event when you’re back at the gym, at your kid’s school, at in-person meetups.&lt;/p&gt;

&lt;p&gt;The decline in engagement wasn’t people abandoning communities they didn’t care about. It was people being pulled between communities they cared about deeply and being forced to choose.&lt;/p&gt;

&lt;p&gt;Some people stayed in their pandemic communities because those bonds meant everything. Some drifted away despite wanting to stay connected. Many tried to maintain both and felt guilty about not being as present online.&lt;/p&gt;

&lt;p&gt;Professional identity didn’t disappear, but it returned to being one of many identities, not the primary or only identity. And with finite time and attention, something had to give.&lt;/p&gt;

&lt;h2 id=&quot;the-misread-that-shaped-a-strategy&quot;&gt;The Misread That Shaped a Strategy&lt;/h2&gt;

&lt;p&gt;Companies saw the engagement decline and treated it like a problem to solve rather than a natural consequence of changed circumstances.
The mistake wasn’t that companies built communities. Many of those communities genuinely serve people who need them, and many of those pandemic-era bonds are real and lasting.&lt;/p&gt;

&lt;p&gt;The mistake was thinking they could recreate or sustain trauma-bond-level engagement without the trauma.&lt;/p&gt;

&lt;p&gt;They thought the pandemic-era engagement levels were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Sustainable (Actually, many required conditions no one should want to recreate)&lt;/li&gt;
  &lt;li&gt;Universal (Actually, many were born of collective crisis)&lt;/li&gt;
  &lt;li&gt;Reproducible (Actually, many were trauma bonds form under specific circumstances)&lt;/li&gt;
  &lt;li&gt;Transferable (Actually, you can’t manufacture that depth of connection on command)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Companies built community strategies around peak crisis participation and crisis-level bonding. They staffed for engagement that made sense when professional community was substituting for all community and people were processing collective trauma together. They created expectations for involvement that assumed people’s entire social lives would continue to flow through professional channels with that same intensity.&lt;/p&gt;

&lt;p&gt;When engagement inevitably declined, it wasn’t because the communities failed. People’s lives and needs changed, and then companies panicked. They hired more community managers. They added more features. They pushed harder for participation.&lt;/p&gt;

&lt;p&gt;But you can’t solve for the absence of shared crisis with better Slack integrations.&lt;/p&gt;

&lt;p&gt;And with that shift, professional communities changed in character, not just size.&lt;/p&gt;

&lt;p&gt;Many became transactional. People drop in, ask a question, get an answer, leave. They need the &lt;em&gt;resource&lt;/em&gt;, the collective knowledge, the troubleshooting help, the documentation links. But they don’t want or need the &lt;em&gt;connection&lt;/em&gt;. They’re not looking for the coffee shop vibe anymore. They’re looking for Stack Overflow with a pulse.&lt;/p&gt;

&lt;p&gt;This isn’t everyone. Remote workers still exist. Niche specialists still need their people. Global collaborators still benefit from async communication across time zones. People for whom online professional community isn’t a substitute for anything, because it’s genuinely where their professional community exists.&lt;/p&gt;

&lt;p&gt;But even within those groups, the engagement looks different. It’s purposeful, not ambient. It’s “I’m here when I need something” rather than “this is where I hang out.”&lt;/p&gt;

&lt;p&gt;And then there are the community builders caught in the middle, trying to recreate that pandemic-era connection and intimacy in product-focused communities where most people just want help with their API integration. They’re hosting office hours that get three attendees. They’re planning social events that get polite “maybe” responses. They’re fighting to build connection in spaces where the majority of members are perfectly content with drive-by interactions.&lt;/p&gt;

&lt;p&gt;It’s not that these community builders are doing it wrong. &lt;em&gt;They’re trying to create depth in spaces where most people want efficiency.&lt;/em&gt; They’re optimizing for belonging when most users are optimizing for answers.&lt;/p&gt;

&lt;p&gt;The communities that thrived on trauma bonds and shared vulnerability can’t be replicated in a product community where people just need their build to work. And expecting them to is setting community builders up to burn out trying to recreate something that only existed under very specific, unrepeatable conditions.&lt;/p&gt;

&lt;h2 id=&quot;what-job-is-this-community-actually-doing&quot;&gt;What job is this community actually doing?&lt;/h2&gt;

&lt;p&gt;In 2020-2021, professional communities were doing the job of: general social connection, professional development, casual friendship, identity formation, and mental health support.&lt;/p&gt;

&lt;p&gt;In 2025, they should be doing the job of: professional knowledge sharing, specific technical support, collaboration, and professional networking.&lt;/p&gt;

&lt;p&gt;Those are different jobs requiring different strategies, different staffing, and different success metrics.&lt;/p&gt;

&lt;p&gt;Communities that thrive post-pandemic aren’t trying to be everything to everyone. They’re specific about who they serve and why. They’re intentional about the value they provide. They recognize that lower engagement isn’t failure. It’s actually right-sizing.&lt;/p&gt;

&lt;h2 id=&quot;the-uncomfortable-truth&quot;&gt;The Uncomfortable Truth&lt;/h2&gt;

&lt;p&gt;Not every company needs a community.&lt;/p&gt;

&lt;p&gt;Even if you needed one in 2020, you might not need one now.&lt;/p&gt;

&lt;p&gt;Even if your competitors have one, that doesn’t mean you should too.&lt;/p&gt;

&lt;p&gt;Even if engagement was high during the pandemic, that doesn’t mean it should be high now.&lt;/p&gt;

&lt;p&gt;The companies that will succeed with community in 2025 and beyond are the ones willing to ask: “Is this actually serving a real need, or are we chasing ghosts of pandemic-era metrics?”&lt;/p&gt;

&lt;p&gt;Because belonging doesn’t scale the way we hoped. Identity doesn’t consolidate because we want it to. And crisis-driven engagement isn’t a sustainable business strategy.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;This is the second in a series exploring how our understanding of community has changed from 2020 to 2025. Next: How AI and changing expectations are breaking the communities that remain.&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 02 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//The-Community-Identity-Crisis</link>
        <guid isPermaLink="true">https://bekahhw.com//The-Community-Identity-Crisis</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>Community</category>
        
        <category>Opinion</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>When &apos;Local&apos; Went Global: The Pandemic Era of International Communities</title>
        <description>&lt;p&gt;During the pandemic, I occupied the same space—a Zoom room-with members of the Virtual Coffee community from all over the world. We’ve had members across the US, Canada, South America, Europe, Australia, and Asia. We saw each other whether in an official Virtual Coffee even or eventually in our virtual co-working room that stayed open 24/7. Sometimes we’d chat. Sometimes, we’d just… exist together.&lt;/p&gt;

&lt;p&gt;It was the digital equivalent of running into someone in the dairy aisle, except the dairy aisle was a Zoom room, and the “someone” could be in Jakarta, São Paulo, Manchester, or Kansas City.&lt;/p&gt;

&lt;p&gt;For a brief window in modern history, “local” stopped meaning geography and started meaning something else entirely.&lt;/p&gt;

&lt;h2 id=&quot;the-collapse-of-default-community&quot;&gt;The Collapse of Default Community&lt;/h2&gt;

&lt;p&gt;Before March 2020, most of us didn’t have to think much about what “community” meant. It was simply the people you saw regularly: coworkers, neighbors, your kid’s soccer team parents, the familiar faces at church or the gym. Community was embedded in the infrastructure of daily life and was predictable, physical, and largely determined by proximity.&lt;/p&gt;

&lt;p&gt;Then proximity disappeared.&lt;/p&gt;

&lt;p&gt;When lockdowns began, the familiar networks evaporated overnight.&lt;/p&gt;

&lt;p&gt;The impact was immediate and profound. &lt;a href=&quot;https://connect2affect.org/wp-content/uploads/2020/10/The-Pandemic-Effect-A-Social-Isolation-Report-AARP-Foundation.pdf&quot;&gt;Two-thirds of adults reported experiencing social isolation during the pandemic&lt;/a&gt;. For younger adults, &lt;a href=&quot;https://mcc.gse.harvard.edu/reports/loneliness-in-america&quot;&gt;61% of young felt “serious loneliness” during this period&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We didn’t lose our desire for community. We lost the infrastructure that had been quietly supporting it all along.&lt;/p&gt;

&lt;h2 id=&quot;the-great-virtualization&quot;&gt;The Great Virtualization&lt;/h2&gt;

&lt;p&gt;What happened next wasn’t entirely new. People had been building online communities for years. But the scale and speed were unprecedented. Suddenly, everyone needed to figure out how to find belonging through a screen. When the physical infrastructure disappeared, we rebuilt it digitally.&lt;/p&gt;

&lt;p&gt;From massive pandemic hackathons to new Slack and Discord communities, people everywhere began re-creating local-belonging at scale.&lt;/p&gt;

&lt;p&gt;I started Virtual Coffee with weekly Tuesday meetings that were regular, predictable, and rhythmic. In a lot of ways, therapeutic. Then, the co-working room that transformed it into something that felt genuinely “local.” That room was open all the time. You could drop in whenever. You’d see who else was around. Sometimes you’d end up in a spontaneous conversation about your project, or someone’s career transition, or absolutely nothing at all.
We added a virtual book club, CodeWars challenges, and another day of coffee chats. Interintellect salons hosted three-hour events where people from diverse backgrounds came together for intellectually stimulating conversation, bridging tech and non-tech interests through Discord.&lt;/p&gt;

&lt;p&gt;The magic was in the serendipity. The unplanned encounters. The way you’d sign on to get work done and end up chatting with someone from Nigeria about their startup idea, or find yourself in a breakout room with a developer from Russia who was working through the same frustrating bug you’d just solved.&lt;/p&gt;

&lt;p&gt;We were strangers from different continents creating something that felt remarkably like what a neighborhood coffee shop might have provided. Except our “neighborhood” spanned time zones, and our “coffee shop” never closed.&lt;/p&gt;

&lt;h2 id=&quot;what-made-it-work&quot;&gt;What Made It Work&lt;/h2&gt;

&lt;p&gt;Looking back, I think the pandemic-era virtual communities that thrived shared a few key characteristics:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Regularity without rigidity. You knew when things were happening, but you weren’t required to show up. The co-working room was always there. The Tuesday meetings happened every Tuesday. This created rhythm, a temporal equivalent of “I know I’ll see you at the grocery store on Saturday mornings.”&lt;/li&gt;
  &lt;li&gt;Space for the unplanned. I still believe that the most meaningful connections don’t happen during structured programming. They happened in the margins: before the official meeting start, in the co-working room at odd hours, in side channels where someone posted a random question and three people end up in a deep conversation.&lt;/li&gt;
  &lt;li&gt;Low barriers, high humanity. The fact that events moved online opened communities up to people who might have been too uncomfortable to attend an in-person event due to anxiety, financial constraints, or something else, allowing for realtime conversations over Slack or Discord instead of struggling with in-person social time. Nobody cared about ring lights or professional setups–ok, maybe once I learned about those things, I did invest some money to upgrade a little bit. But we still showed up in our kitchens, with kids screaming in the background, with laundry visible behind us. The bar for participation was simply: be present, be kind, be human.&lt;/li&gt;
  &lt;li&gt;Shared vulnerability. We were all figuring it out together. Nobody had their shit completely sorted. That leveled the playing field in a way that’s rare in professional communities. In other words, the senior engineer and the bootcamp student/grad (ie, &lt;em&gt;me&lt;/em&gt;) were equally disoriented by the moment we were living through.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-shift-back&quot;&gt;The Shift Back&lt;/h2&gt;

&lt;p&gt;Then, gradually, the physical world opened back up.&lt;/p&gt;

&lt;p&gt;People returned to offices, or to coffee shops, gyms, schools, or co-working spaces again. The default infrastructure of community came back in-person.&lt;/p&gt;

&lt;p&gt;And the international local communities… shifted.&lt;/p&gt;

&lt;p&gt;The co-working room got quieter. The Tuesday meetings still happen, but attendance has thinned. Not because people stopped caring, but because they could now get some of those needs met in physical space again. Time—everyone’s most finite resource—got redistributed back to the in-person world.&lt;/p&gt;

&lt;p&gt;Before the pandemic, people spent the bulk of their social time at work, and remote work led to loneliness and feeling disconnected. The shared physical space offered opportunities to network, mentor others, and build community that were hard to recreate in a scattered, virtual workforce.&lt;/p&gt;

&lt;p&gt;This wasn’t a failure. It was just the natural consequence of changed circumstances.&lt;/p&gt;

&lt;p&gt;But it left a lot of questions unanswered.&lt;/p&gt;

&lt;h2 id=&quot;where-we-are-now&quot;&gt;Where We Are Now&lt;/h2&gt;

&lt;p&gt;We’re in a strange liminal space. Virtual communities haven’t disappeared, but they’re not serving the same function they did in 2020-2022. The urgency is gone. Community programs saw an increased recognition of their value during the pandemic, but that recognition was tied to a specific moment in time—a moment that has passed.&lt;/p&gt;

&lt;p&gt;People are negotiating between physical and digital belonging in ways we haven’t fully figured out yet.&lt;/p&gt;

&lt;p&gt;And meanwhile, companies are asking: “Why isn’t our community as engaged as it was during the pandemic?”&lt;/p&gt;

&lt;p&gt;But that’s the wrong question.&lt;/p&gt;

&lt;p&gt;The right question is: &lt;em&gt;“Who actually needs this community now, and what are we building it for?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;During the pandemic, virtual communities weren’t just filling a professional need. They were filling all our social needs. Professional community became a substitute for general community because it was all we had. The developer slack was my coffee shop, my gym, my after-work happy hour, my weekend hangout.&lt;/p&gt;

&lt;p&gt;Now that general social needs can be met locally again for many people, the population who needs online-as-local has shifted back to who it always was:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fully remote workers who’ve left physical proximity to colleagues behind entirely&lt;/li&gt;
  &lt;li&gt;Developers who want casual peer conversation without the overhead of professional networking events&lt;/li&gt;
  &lt;li&gt;People who want the hallway track experience (those serendipitous conversations that happen between sessions)&lt;/li&gt;
  &lt;li&gt;Specialists in niche areas where their “local” doesn’t have anyone else working on their specific stack or problem domain&lt;/li&gt;
  &lt;li&gt;Disabled folks, caretakers, and others for whom physical gatherings have always been inaccessible&lt;/li&gt;
  &lt;li&gt;Global collaborators building projects across continents and time zones&lt;/li&gt;
  &lt;li&gt;People who want the coffee shop, but the coffee shop is all technies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These communities still matter deeply. They’re still someone’s local. The mistake isn’t that these communities exist—it’s that companies think everyone needs this, all the time.&lt;/p&gt;

&lt;p&gt;The coffee shop didn’t disappear; it just got quieter.&lt;/p&gt;

&lt;h2 id=&quot;redefining-local-again&quot;&gt;Redefining Local, Again&lt;/h2&gt;

&lt;p&gt;The always-on, drop-in, developer coffee shop model didn’t stop working. It just stopped being universal.&lt;/p&gt;

&lt;p&gt;In 2020-2022, everyone needed it because everyone was isolated. In 2025, it serves a specific population: people whose physical environment doesn’t provide the technical community they need. This isn’t new. This population always existed. The pandemic just temporarily made everyone part of it.&lt;/p&gt;

&lt;p&gt;The confusion comes from companies who saw engagement numbers during lockdown and thought, “This is what community looks like now.” They built strategies around peak-crisis participation and are now wondering why engagement dropped when the crisis ended.&lt;/p&gt;

&lt;p&gt;But for the people who are fully remote, who do work in niche areas, who actually need virtual-as-local? The future of virtual community isn’t choosing between “always-on” and “seasonal engagement.” It’s recognizing that different models serve different needs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Always-on spaces for people who need virtual-as-local (remote workers, niche specialists, global teams)&lt;/li&gt;
  &lt;li&gt;Event-driven communities for people who have local networks but want to expand them occasionally&lt;/li&gt;
  &lt;li&gt;Project-based cohorts for people collaborating on specific initiatives&lt;/li&gt;
  &lt;li&gt;Hybrid models that acknowledge some members need daily presence while others drop in monthly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The brief era when local went global taught us something important about what community actually requires. Not geography. Not even, proximity.&lt;/p&gt;

&lt;p&gt;Rhythm, serendipity, and the willingness to show up wherever you are and be &lt;em&gt;human&lt;/em&gt; together.&lt;/p&gt;

&lt;p&gt;Those needs haven’t disappeared. But the population experiencing them has returned to its pre-pandemic size—still significant, still vital, just less universal.&lt;/p&gt;

&lt;p&gt;The question now is: can we build sustainable models for the people who actually need virtual-as-local, without expecting everyone to need it all the time?&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This is the first in a series exploring how our understanding of community has changed from 2020 to 2025. Next: Why companies misread the moment and built communities for everyone when they should have built for someone. When the world redefined community, companies thought they could scale it. But belonging doesn’t scale, at least, not the way they hoped.&lt;/p&gt;
</description>
        <pubDate>Thu, 30 Oct 2025 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//when-local-community-went-global</link>
        <guid isPermaLink="true">https://bekahhw.com//when-local-community-went-global</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        
        
        
        
      </item>
    
      <item>
        <title>A Developer’s Guide to Choosing an AI Coding Assistant That Boosts Productivity Without Overwhelming Your Workflow</title>
        <description>&lt;p&gt;&lt;em&gt;Finding the assistant that fits just right.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At &lt;a href=&quot;http://virtualcoffee.io/&quot;&gt;Virtual Coffee&lt;/a&gt; over the last year, we’ve been talking about our experiences with different AI Coding Assistants.  Some of the things I’ve heard include, “It felt like I was constantly being interrupted,” “I barely notice it’s there until I need it,” “Sometimes it feels like it’s micromanaging me, so I turn it off.” A lot of times, it’s the same tool with different experiences.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://dev.to/bekahhw/series/32242&quot;&gt;Over the last couple of weeks, I’ve been writing about my journey to find the &lt;em&gt;right&lt;/em&gt; coding assistant&lt;/a&gt;, but I thought it would be useful to distill what I’ve learned so far into a simple guide.&lt;/p&gt;

&lt;p&gt;This is what I’m calling this “The Goldilocks Problem.” Some AI coding assistants are too intrusive, some are too passive, and some are just right. But that sweet spot depends entirely on you.&lt;/p&gt;

&lt;p&gt;This guide is designed to help you find an AI assistant that enhances your workflow without hijacking it.&lt;/p&gt;

&lt;h2 id=&quot;step-1-understand-the-types-of-ai-assistant-behavior&quot;&gt;Step 1: Understand the Types of AI Assistant Behavior&lt;/h2&gt;

&lt;p&gt;AI tools fall along a spectrum based on how actively they interact with you:&lt;/p&gt;

&lt;h3 id=&quot;1-the-background-helper-minimal-intrusion&quot;&gt;1. The Background Helper (Minimal Intrusion)&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Quiet until called upon&lt;/li&gt;
  &lt;li&gt;Great for deep-focus devs&lt;/li&gt;
  &lt;li&gt;Acts like autocomplete on demand&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-the-proactive-partner-moderate-intrusion&quot;&gt;2. The Proactive Partner (Moderate Intrusion)&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Offers smart suggestions as you type&lt;/li&gt;
  &lt;li&gt;Balances guidance with control&lt;/li&gt;
  &lt;li&gt;Ideal for those who like nudges but not noise&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-the-active-collaborator-high-intrusion&quot;&gt;3. The Active Collaborator (High Intrusion)&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Suggests proactively, refactors on its own&lt;/li&gt;
  &lt;li&gt;Sometimes takes initiative beyond what you asked&lt;/li&gt;
  &lt;li&gt;Best for devs who want maximum AI assistance.&lt;/li&gt;
  &lt;li&gt;Can be fun for vibe coding.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;step-2-audit-your-workflow-style&quot;&gt;Step 2: Audit Your Workflow Style&lt;/h3&gt;

&lt;p&gt;The right assistant depends on how you work.&lt;/p&gt;

&lt;h4 id=&quot;what-kind-of-coder-are-you&quot;&gt;What kind of coder are you?&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Flow-state coder&lt;/strong&gt;: You need focus and minimal interruptions&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Burst coder&lt;/strong&gt;: You are energized by context-switching and quick input&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;what-breaks-your-concentration&quot;&gt;What breaks your concentration?&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Are popups or suggestions distracting?&lt;/li&gt;
  &lt;li&gt;Do you lose focus without a prompt?&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;how-do-you-prefer-to-learn&quot;&gt;How do you prefer to learn?&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Learn-by-doing&lt;/strong&gt;: Prefer code patterns and examples&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Learn-by-understanding&lt;/strong&gt;: Need deep explanations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;step-3-match-assistant-style-to-your-workflow&quot;&gt;Step 3: Match Assistant Style to Your Workflow&lt;/h2&gt;

&lt;p&gt;Once you know how you work, you can align that with the assistant type.&lt;/p&gt;

&lt;h3 id=&quot;option-1-invisible-until-needed&quot;&gt;Option 1: Invisible Until Needed&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Experienced devs who want help with boilerplate, syntax, and docs&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;what-assistant-features-to-look-for&quot;&gt;What Assistant Features to Look for&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Autocomplete only for common patterns&lt;/li&gt;
  &lt;li&gt;Context-aware suggestions that activate on pause&lt;/li&gt;
  &lt;li&gt;On-demand doc lookup&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;tools-to-try&quot;&gt;Tools to try&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://continue.dev/&quot;&gt;Continue.dev&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/features/copilot&quot;&gt;GitHub Copilot&lt;/a&gt; (with conservative settings)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;option-2-gentle-guidance&quot;&gt;Option 2: Gentle Guidance&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Developers who want AI help while staying in control&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;what-assistant-features-to-look-for-1&quot;&gt;What Assistant Features to Look for&lt;/h4&gt;
&lt;p&gt;Inline suggestions that feel natural
Code completion that adapts to your style
Suggestions that teach, not just do&lt;/p&gt;

&lt;h4 id=&quot;tools-to-try-1&quot;&gt;Tools to try&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Most assistants with moderate config&lt;/li&gt;
  &lt;li&gt;Continue’s philosophy is to put the developer in control&lt;/li&gt;
  &lt;li&gt;Copilot with smart prompt tuning&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;option-3-active-partnership&quot;&gt;Option 3: Active Partnership&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Complex projects and devs ready to shift their workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;what-assistant-features-to-look-for-2&quot;&gt;What Assistant Features to Look for&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Full-project understanding&lt;/li&gt;
  &lt;li&gt;Multi-file suggestions&lt;/li&gt;
  &lt;li&gt;Proactive refactors and implementations&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;tools-to-try-2&quot;&gt;Tools to Try&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cursor.com/&quot;&gt;Cursor&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Continue.dev (advanced mode)&lt;/li&gt;
  &lt;li&gt;GithHub Copilot&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;step-4-run-a-workflow-integration-test&quot;&gt;Step 4: Run a Workflow Integration Test&lt;/h2&gt;

&lt;p&gt;Before committing, test tools with these 5 workflow scenarios:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The Morning Startup Test
Does the AI help you pick up where you left off, or get in the way?&lt;/li&gt;
  &lt;li&gt;The Deep Focus Test
Can you stay in flow, or does it interrupt too much?&lt;/li&gt;
  &lt;li&gt;The Context Switch Test
Does it keep up when jumping between files and tasks?&lt;/li&gt;
  &lt;li&gt;The Learning Moment Test
When you hit something unfamiliar, does it help you understand?&lt;/li&gt;
  &lt;li&gt;The Cleanup Test
Can you read and modify the AI’s code later?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;step-5-signs-an-ai-assistant-is-helping-or-hurting-your-workflow&quot;&gt;Step 5: Signs an AI Assistant Is Helping Or Hurting Your Workflow&lt;/h2&gt;

&lt;h3 id=&quot;red-flags-its-disrupting-your-workflow&quot;&gt;Red Flags (It’s disrupting your workflow)&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Constantly fighting the suggestions&lt;/li&gt;
  &lt;li&gt;Code quality or clarity drops&lt;/li&gt;
  &lt;li&gt;You rely on it so much that you can’t code solo&lt;/li&gt;
  &lt;li&gt;You feel anxious when it’s off. (Maybe it’s time to see a therapist too :joy: )&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;green-flags-its-enhancing-your-workflow&quot;&gt;Green Flags (It’s enhancing your workflow)&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;You forget it’s there until you need it&lt;/li&gt;
  &lt;li&gt;You’re learning new patterns&lt;/li&gt;
  &lt;li&gt;You feel more confident and productive&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;tldr-finding-the-right-fit-ai-coding-assistant&quot;&gt;TL;DR: Finding the Right-Fit AI Coding Assistant&lt;/h2&gt;

&lt;p&gt;If you’re looking for an AI assistant that boosts productivity without overwhelming your workflow try GitHub Copilot or Continue.dev if you prefer minimal interruption.&lt;/p&gt;

&lt;p&gt;Choose tools with gentle, context-aware prompts if you want help but not takeover. Explore Cursor or advanced Continue setups for high-involvement AI assistance.&lt;/p&gt;
</description>
        <pubDate>Wed, 09 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//Boost-Productivity-with-AI</link>
        <guid isPermaLink="true">https://bekahhw.com//Boost-Productivity-with-AI</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>Pros and Cons of the Top AI Code Assistants: Continue.dev, GitHub Copilot, and Cursor (With a Hero’s Twist)</title>
        <description>&lt;p&gt;Every great hero needs the right weapon. Captain America has his shield, Aragorn wields Andúril, and David brought down Goliath with nothing but a slingshot and unshakeable faith.&lt;/p&gt;

&lt;p&gt;As developers, facing the giants of legacy code, impossible challenges, and the eternal question, “Can you just add one small feature?”, having the right “weapon” can mean the difference in how successful we are. The AI coding assistant landscape is about finding your legendary weapon. It’s about choosing our superhero origin story.&lt;/p&gt;

&lt;h2 id=&quot;choosing-your-coding-weapon-a-heros-guide-to-ai-assistants&quot;&gt;Choosing Your Coding Weapon: A Hero’s Guide to AI Assistants&lt;/h2&gt;

&lt;h2 id=&quot;continuedev-pros-cons-and-best-use-cases-&quot;&gt;Continue.dev: Pros, Cons, and Best Use Cases 🪃&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Hero Archetype:&lt;/strong&gt; The resourceful underdog who’s powers lie in adaptability and cleverness.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“For the battles aren’t won by size, but by skill and choosing your shot”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;the-metaphor-davids-slingshot&quot;&gt;The Metaphor: David’s Slingshot&lt;/h3&gt;
&lt;p&gt;Everyone expected David to suit up in Saul’s armor, but he looked at that heavy gear and said, “Nah, I’m good with my slingshot.” That’s Continue.dev.&lt;/p&gt;

&lt;p&gt;While other tools come loaded with corporate armor and preset strategies, Continue says, “Here’s your slingshot. You choose the stones.”&lt;/p&gt;

&lt;h3 id=&quot;pros&quot;&gt;Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Shape-shifting: Works with any AI model you choose (GPT-4, Claude, etc.)&lt;/li&gt;
  &lt;li&gt;Stealth mode: Can run everything locally&lt;/li&gt;
  &lt;li&gt;Weapon crafting: Custom assistant creation&lt;/li&gt;
  &lt;li&gt;Open source: Driven by community improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons&quot;&gt;Cons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Slight learning curve for setup and workflows&lt;/li&gt;
  &lt;li&gt;Less polished UI than commercial tools&lt;/li&gt;
  &lt;li&gt;Requires some config to reach full power&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;best-for&quot;&gt;Best For:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Developers who’ve been burned by vendor lock-in&lt;/li&gt;
  &lt;li&gt;Power users who want full control&lt;/li&gt;
  &lt;li&gt;Anyone building their own coding workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;github-copilot-pros-cons-and-best-use-cases-️&quot;&gt;GitHub Copilot: Pros, Cons, and Best Use Cases 🛡️&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hero Archetype:&lt;/strong&gt; The steadfast leader who inspires confidence through consistency.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“I can do this all day.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;the-metaphor-captain-americas-shield&quot;&gt;The Metaphor: Captain America’s Shield&lt;/h3&gt;

&lt;p&gt;The first Avenger, the one who established what it means to be an AI coding assistant. Steve Rogers’ shield isn’t flashy. It doesn’t shoot lasers. But it’s reliable, trusted by the team, and always ready.&lt;/p&gt;

&lt;p&gt;That’s GitHub Copilot.&lt;/p&gt;

&lt;h3 id=&quot;pros-1&quot;&gt;Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Unbreakable consistency: Works the same way every time&lt;/li&gt;
  &lt;li&gt;Team integration: Easy to roll out across orgs&lt;/li&gt;
  &lt;li&gt;Battle-tested: Millions of developers rely on it&lt;/li&gt;
  &lt;li&gt;Seamless with VS Code and GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons-1&quot;&gt;Cons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Occasionally hallucinates or misinterprets intentions&lt;/li&gt;
  &lt;li&gt;Offers limited insight into &lt;em&gt;why&lt;/em&gt; things break&lt;/li&gt;
  &lt;li&gt;Not ideal for deeper refactoring or debugging scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;best-for-1&quot;&gt;Best For:&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Developers who want plug-and-play completion&lt;/li&gt;
  &lt;li&gt;Teams looking for low-friction onboarding&lt;/li&gt;
  &lt;li&gt;Fast-paced shipping of small features or fixes&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;cursor-pros-cons-and-best-use-cases-️&quot;&gt;Cursor: Pros, Cons, and Best Use Cases ⚔️&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hero Archetype:&lt;/strong&gt; The chosen one destined for greatness if you’re willing to pay the price.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Reforged from the shards of what came before”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;the-metaphor-aragorns-andúril&quot;&gt;The Metaphor: Aragorn’s Andúril&lt;/h3&gt;

&lt;p&gt;Reforged from the shards of what came before, Cursor is VS Code reborn and transformed into something powerful.&lt;/p&gt;

&lt;h3 id=&quot;pros-2&quot;&gt;Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Royal bloodline: Built on VS Code’s foundation&lt;/li&gt;
  &lt;li&gt;AI-first vision: UI centered around AI workflows&lt;/li&gt;
  &lt;li&gt;Multi-realm mastery: Understands and edits your whole codebase&lt;/li&gt;
  &lt;li&gt;Composer magic: Suggests multi-file implementations intelligently&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons-2&quot;&gt;Cons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Premium pricing tiers&lt;/li&gt;
  &lt;li&gt;Can make sweeping changes outside of scope&lt;/li&gt;
  &lt;li&gt;Might be overwhelming for newer devs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;best-for-2&quot;&gt;Best For:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Developers who want deep AI collaboration&lt;/li&gt;
  &lt;li&gt;Projects involving large-scale refactors&lt;/li&gt;
  &lt;li&gt;Those ready to go “all in” on an AI-native IDE&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;tldr-pros--cons-of-top-ai-code-assistants&quot;&gt;TL;DR: Pros &amp;amp; Cons of Top AI Code Assistants&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Tool&lt;/th&gt;
      &lt;th&gt;Pros&lt;/th&gt;
      &lt;th&gt;Cons&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Continue.dev&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Open source, model-agnostic, runs locally, educational modes&lt;/td&gt;
      &lt;td&gt;Not as beginner-friendly, more setup required&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Fast completions, trusted by teams, easy to use in VS Code&lt;/td&gt;
      &lt;td&gt;Can hallucinate, struggles with context-aware fixes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;AI-native IDE, great for refactoring and large changes, smart UI&lt;/td&gt;
      &lt;td&gt;Expensive, can overreach and change more than intended&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
</description>
        <pubDate>Mon, 07 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//Pros-and-Cons-of-AI-Code-Assistants</link>
        <guid isPermaLink="true">https://bekahhw.com//Pros-and-Cons-of-AI-Code-Assistants</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        
        
        
        
      </item>
    
      <item>
        <title>Debugging Mobile Navigation Bugs with AI Code Assistants: Continue vs Copilot vs Cursor</title>
        <description>&lt;p&gt;&lt;em&gt;A follow-up to “Which Code Assistant Actually Helps Developers Grow?” This time, testing how AI assistants handle debugging existing code problems.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Last week, I &lt;a href=&quot;https://bekahhw.com/Which-Code-Assistant-Helps-Developers-Grow&quot;&gt;tested three AI coding assistants on building a new feature&lt;/a&gt;. This time, I wanted to see how they handle something most developers deal with daily: debugging existing code problems.&lt;/p&gt;

&lt;p&gt;I was debugging a mobile responsiveness issue on my Astro + Tailwind site (see the &lt;a href=&quot;https://github.com/BekahHW/siblings-write/&quot;&gt;GitHub Project here&lt;/a&gt;). The navbar wasn’t collapsing on mobile, causing layout issues. Instead of a full navigation bar cramming into mobile view, I needed a proper hamburger menu. Instead of manually rewriting it, I tested how three AI code assistants—Continue, Copilot, and Cursor—would solve it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/240b8dcxjht9ly0hg9v1.gif&quot; alt=&quot;gif showing the responsive layout issue on mobile is fixed when deleting the nav bar&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here’s what I told each assistant:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“There’s an issue with mobile view on the site. I think the main problem is with the navbar. But I don’t think it makes sense to have a nav bar for a mobile site. We should make the site responsive and add a sticky nav bar with a hamburger menu instead of the full navigation bar once the site hits mobile-sized screens.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: I tested Continue, GitHub Copilot, and Cursor to debug a broken mobile navbar in an Astro-based site. Continue offered the best explanations and teaching moments, Cursor was fast but made extra assumptions, and Copilot was fast but error-prone. If you’re debugging UI bugs, Continue’s Chat mode helps you understand why things break, not just how to fix them.&lt;/p&gt;

&lt;h2 id=&quot;can-continue-debug-a-responsive-nav-issue-in-astro&quot;&gt;Can Continue Debug a Responsive Nav Issue in Astro?&lt;/h2&gt;

&lt;p&gt;I used &lt;a href=&quot;https://continue.dev/&quot;&gt;Continue&lt;/a&gt; in &lt;a href=&quot;https://docs.continue.dev/agent/how-to-use-it&quot;&gt;Agent mode&lt;/a&gt;, giving it context from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Header.astro&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nav.astro&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseLayout.astro&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bg21110n6vfs19es00l5.png&quot; alt=&quot;Continue.dev suggesting hamburger menu fixes in Astro project&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-good&quot;&gt;The Good&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Created a dedicated hamburger menu component&lt;/li&gt;
  &lt;li&gt;Asked for permission between file changes&lt;/li&gt;
  &lt;li&gt;When I got a transparency issue with the menu panel, it fixed it in one go&lt;/li&gt;
  &lt;li&gt;It added comments to understand the steps it was taking in the code and debug logs in the code to help me see what was working and when&lt;/li&gt;
  &lt;li&gt;Everything worked within 12 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;the-learning-experience&quot;&gt;The Learning Experience&lt;/h3&gt;

&lt;p&gt;When I tested the same fix using Continue’s &lt;a href=&quot;https://docs.continue.dev/chat/how-to-use-it&quot;&gt;Chat mode&lt;/a&gt; instead of Agent mode, it took longer but provided much more thorough explanations. The conversation was more educational, walking me through the reasoning behind each change.&lt;/p&gt;

&lt;h3 id=&quot;verdict&quot;&gt;Verdict&lt;/h3&gt;

&lt;p&gt;Continue balances efficiency with learning. Agent mode got me working code fast, while Chat mode taught me the “why” behind the solutions.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ss3rdoqhm59mkjjqxbl.png&quot; alt=&quot;Copilot output showing approach to fixing broken layout with overlapping nav menu&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-copilot-handles-responsive-navbar-bugs&quot;&gt;How Copilot Handles Responsive Navbar Bugs&lt;/h2&gt;

&lt;p&gt;Copilot started by unnecessarily converting a Svelte component, then immediately threw a TypeScript error:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Argument of type &apos;EventTarget&apos; is not assignable to parameter of type &apos;Node&apos;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I’m not sure why it decided that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ThemeToggleButton&lt;/code&gt; needed to be converted. At the very least, that’s outside of the scope of this PR, in my opinion.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fi883ls0s34e83ux1zra.png&quot; alt=&quot;Image description&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It was able to solve the problem pretty quickly when I used the “Fix with Copilot” function, explaining, “You should cast e.target to Node when passing it to .contains() to resolve the type error.”&lt;/p&gt;

&lt;h3 id=&quot;the-real-problem&quot;&gt;The Real Problem&lt;/h3&gt;

&lt;p&gt;The hamburger menu initially didn’t appear at all. The responsiveness was “fixed” because the navigation disappeared, but users couldn’t access any menu items.&lt;/p&gt;

&lt;p&gt;After back-and-forth debugging, Copilot resorted to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!important&lt;/code&gt; declarations (not ideal) and the old “turn the background red” debugging trick. Even when the menu became visible, clicking it did nothing.&lt;/p&gt;

&lt;p&gt;Eventually, we identified JavaScript as the culprit. Copilot fixed it, but then the menu links appeared directly over the page content without any background container. More back-and-forth with questionable styling decisions followed.&lt;/p&gt;

&lt;p&gt;It was to the point where I definitely could fix this faster than having a back-and-forth with Copilot, so I called it. After that, I also realized there was a bug where, after expanding the hamburger menu on mobile and then switching to desktop view, the mobile menu remained open on top of the restored navigation bar.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvvd7pmfl9gm2usc0k1w.png&quot; alt=&quot;nav panel on top of page text&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time&lt;/strong&gt;: About 20 minutes, with me ultimately fixing the styles myself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning Value&lt;/strong&gt;: Minimal. Copilot told me what it was doing, but didn’t really explain its approach or help me understand the underlying problem.&lt;/p&gt;

&lt;h2 id=&quot;cursor-fixes-more-than-you-askhelpful-or-harmful&quot;&gt;Cursor Fixes More Than You Ask—Helpful or Harmful?&lt;/h2&gt;

&lt;p&gt;Cursor’s response was immediate and organized:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vx5vt6fdw9b2utz4gre.png&quot; alt=&quot;Cursor&apos;s initial message detailing what needed to be done to implement the hamburger menu&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-process&quot;&gt;The Process&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Automatically read the global CSS&lt;/li&gt;
  &lt;li&gt;Outlined exactly what needed to change and why&lt;/li&gt;
  &lt;li&gt;Provided all necessary file updates&lt;/li&gt;
  &lt;li&gt;Hit the same cross-page JavaScript issue as Copilot&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;the-interesting-part&quot;&gt;The Interesting Part&lt;/h3&gt;

&lt;p&gt;Cursor went beyond my request, automatically improving mobile styles across the site that I hadn’t asked for. This raises an interesting question: should AI assistants make assumptions about what you “really” need?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time&lt;/strong&gt;: About 15 minutes to complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning Value&lt;/strong&gt;: Good explanations of changes. I appreciate that it gives more information on why errors were happening in the context of using Astro.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vsk81fkbeau7jkmdtafh.png&quot; alt=&quot;showing the issue and how it understands and corrects it&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;context-switching-costs&quot;&gt;Context Switching Costs&lt;/h2&gt;

&lt;p&gt;Here’s something I noticed that none of the assistants addressed: familiarity bias. Cursor and GitHub Copilot felt nearly identical to use, so I moved faster with them. Continue required slightly more of a learning curve, which actually slowed me down initially but provided better educational value.&lt;/p&gt;

&lt;p&gt;This isn’t a knock against Continue. It’s a reminder that switching tools comes with costs, even when the new tool might be better in the long term.&lt;/p&gt;

&lt;h2 id=&quot;debugging-vs-building-different-skills-required&quot;&gt;Debugging vs. Building: Different Skills Required&lt;/h2&gt;

&lt;p&gt;This debugging scenario revealed something my first test missed, that building new features and fixing existing problems require different AI assistance approaches.&lt;/p&gt;

&lt;h3 id=&quot;building-new-features&quot;&gt;Building New Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Clear requirements&lt;/li&gt;
  &lt;li&gt;Blank slate approach&lt;/li&gt;
  &lt;li&gt;Focus on “what should this do?”&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;debugging-existing-code&quot;&gt;Debugging Existing Code&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Understanding legacy decisions&lt;/li&gt;
  &lt;li&gt;Identifying root causes&lt;/li&gt;
  &lt;li&gt;Focusing on “why isn’t this working?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Continue did well with the debugging mindset, asking permission before changes and explaining the reasoning. Copilot and Cursor were more aggressive about “fixing” things, sometimes creating new problems in the process.&lt;/p&gt;

&lt;h3 id=&quot;which-ai-coding-assistant-wins-for-debugging&quot;&gt;Which AI Coding Assistant Wins for Debugging?&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;For Learning&lt;/strong&gt;: Continue, especially in Chat mode. It helped me understand not just what was broken, but why the original approach failed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Speed&lt;/strong&gt;: Cursor, if you don’t mind AI making assumptions about improvements you didn’t request.&lt;/p&gt;

&lt;h2 id=&quot;the-bigger-picture&quot;&gt;The Bigger Picture&lt;/h2&gt;

&lt;p&gt;This comparison reinforced something I mentioned in my first post: the tool is only part of the equation. Each assistant performed differently not just because of their capabilities, but because of how they approached the problem-solving process.&lt;/p&gt;

&lt;p&gt;Continue treated debugging as a learning opportunity. Copilot treated it as a code completion task. Cursor treated it as a comprehensive redesign project.&lt;/p&gt;

&lt;p&gt;If you want to know which coding assistant helps developers grow when you’re debugging, try this: Before asking for a fix, ask the AI to help you understand why the original code failed. The debugging skills you develop will be more valuable than any individual fix.&lt;/p&gt;

</description>
        <pubDate>Mon, 30 Jun 2025 00:00:00 +0000</pubDate>
        <link>https://bekahhw.com//Which-Code-Assistant-Fix-Real-Problems-Best</link>
        <guid isPermaLink="true">https://bekahhw.com//Which-Code-Assistant-Fix-Real-Problems-Best</guid>
        
        <author>rhawrot@gmail.com (Bekah)</author>
        
        
        
        <category>AI</category>
        
        
        
        
        
      </item>
    
  </channel>
</rss>

