<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wahib EL KHADIRI</title>
    <description>The latest articles on DEV Community by Wahib EL KHADIRI (@wahib_el_khadiri_0).</description>
    <link>https://dev.to/wahib_el_khadiri_0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4040823%2Fdc1c7aa7-603d-4f87-a82b-07c20c473251.png</url>
      <title>DEV Community: Wahib EL KHADIRI</title>
      <link>https://dev.to/wahib_el_khadiri_0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wahib_el_khadiri_0"/>
    <language>en</language>
    <item>
      <title>I Taught an Open-Source SEO Tool to Check Whether Your Site Is Readable by AI Agents</title>
      <dc:creator>Wahib EL KHADIRI</dc:creator>
      <pubDate>Tue, 21 Jul 2026 23:08:35 +0000</pubDate>
      <link>https://dev.to/wahib_el_khadiri_0/i-taught-an-open-source-seo-tool-to-check-whether-your-site-is-readable-by-ai-agents-15i3</link>
      <guid>https://dev.to/wahib_el_khadiri_0/i-taught-an-open-source-seo-tool-to-check-whether-your-site-is-readable-by-ai-agents-15i3</guid>
      <description>&lt;p&gt;Most SEO audit tools still ask the questions search engines cared about ten years ago: is your title tag the right length, do your images have alt text, is your sitemap valid. Those still matter. But a growing chunk of how people find content now goes through an AI assistant instead of a search results page, and almost no audit tool checks whether your site is even &lt;em&gt;reachable&lt;/em&gt; by one.&lt;/p&gt;

&lt;p&gt;I picked up an open issue on &lt;a href="https://github.com/every-app/open-seo" rel="noopener noreferrer"&gt;open-seo&lt;/a&gt; (an open-source Semrush/Ahrefs alternative) to close that gap, and it turned into a good lesson in scoping a feature for someone else's codebase instead of your own.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual question
&lt;/h2&gt;

&lt;p&gt;"Is this site AI-readable?" breaks down into concrete, checkable things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does &lt;code&gt;robots.txt&lt;/code&gt; block the crawlers that build AI search indexes and answer live user requests?&lt;/li&gt;
&lt;li&gt;Does the site have an &lt;code&gt;llms.txt&lt;/code&gt; — the emerging convention that gives an AI assistant a clean map of your important pages?&lt;/li&gt;
&lt;li&gt;Does the site advertise a Markdown alternate for its pages, so an assistant can read clean content instead of parsing full HTML?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Straightforward to state. The interesting part was not flagging noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1: not every robots.txt block is a signal
&lt;/h2&gt;

&lt;p&gt;A site with &lt;code&gt;Disallow: /&lt;/code&gt; for every crawler made a deliberate, site-wide choice. Reporting "GPTBot is blocked!" on a site that blocks &lt;em&gt;everything&lt;/em&gt; isn't useful information — it's noise dressed up as an insight. So the check only flags an AI agent when it's treated &lt;strong&gt;worse than the generic rules&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;robots&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isAllowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rootUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GENERIC_PROBE_AGENT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// whole site is closed — not an AI-specific signal&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I also grouped agents by &lt;em&gt;why they visit&lt;/em&gt; instead of firing one issue per bot. &lt;code&gt;GPTBot&lt;/code&gt; and &lt;code&gt;ClaudeBot&lt;/code&gt; are training crawlers; blocking them is often an intentional content policy and barely worth a heads-up. &lt;code&gt;ChatGPT-User&lt;/code&gt; and &lt;code&gt;Claude-User&lt;/code&gt; fetch a page live because an actual human asked an assistant about it right now — blocking those is a much bigger deal, because you're breaking a request in progress, not opting out of a training set. Same signal, completely different severity, so they're separate issue types with separate default severities instead of one generic "AI crawler blocked" bucket.&lt;/p&gt;
&lt;h2&gt;
  
  
  Lesson 2: absence isn't always an error
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; and Markdown alternates are both new enough that almost nobody has them yet. If the check flagged every single audited site for "missing Markdown alternates," it would train users to ignore the audit tool's warnings entirely — the boy-who-cried-wolf failure mode of any linter. Both checks are &lt;code&gt;info&lt;/code&gt; severity with copy that says, explicitly, "this is common, not an error." The one genuinely broken state — a site that &lt;em&gt;serves&lt;/em&gt; &lt;code&gt;llms.txt&lt;/code&gt; but violates its one hard structural requirement (starts with an H1) — is the only case that gets bumped to &lt;code&gt;warning&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Lesson 3: match the codebase's own constraints, not your own instincts
&lt;/h2&gt;

&lt;p&gt;My first instinct for "does this page have a Markdown alternate" was to persist a new boolean column on the crawled-pages table. Then I actually looked at how the project's crawl pipeline works: full page data lives in a database table, but only a &lt;em&gt;slim summary&lt;/em&gt; (title, status code, a few other fields) survives between crawl phases as durable workflow state — link lists and everything else deliberately get dropped to keep memory bounded on 10,000-page crawls.&lt;/p&gt;

&lt;p&gt;Adding a persisted column meant a schema migration, which meant touching both the SQLite and Postgres schema paths this project supports side by side — a much bigger, riskier diff for a feature that doesn't actually need to survive past the audit run. So instead the flag rides through the same transient summary object the pipeline already carries between phases, and the &lt;em&gt;finding&lt;/em&gt; — not the raw per-page flag — is the only thing that gets persisted, as a single site-level issue row. Same pattern the project already used for the file-based &lt;code&gt;llms.txt&lt;/code&gt; check; I just extended it instead of inventing a new one.&lt;/p&gt;
&lt;h2&gt;
  
  
  Lesson 4: extend the open PR, don't fragment the review
&lt;/h2&gt;

&lt;p&gt;I'd already opened a PR for the robots.txt and &lt;code&gt;llms.txt&lt;/code&gt; checks. Before anyone had reviewed it, I built the Markdown-alternates check too — and instead of opening a third PR, I pushed a second commit onto the same branch. The maintainer hasn't looked at any of it yet, so there was no in-flight review to disrupt, and one PR that closes three-quarters of the original issue is easier to review than three PRs that each close a quarter of it and reference each other.&lt;/p&gt;
&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;19 unit tests, no schema changes, no new external API calls beyond one extra fetch for &lt;code&gt;llms.txt&lt;/code&gt;. The PR's open here if you want to see the actual diff: &lt;a href="https://github.com/every-app/open-seo/pull/122" rel="noopener noreferrer"&gt;every-app/open-seo#122&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/every-app" rel="noopener noreferrer"&gt;
        every-app
      &lt;/a&gt; / &lt;a href="https://github.com/every-app/open-seo" rel="noopener noreferrer"&gt;
        open-seo
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Open source alternative to Semrush and Ahrefs
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;OpenSEO&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Open source alternative to Semrush and Ahrefs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OpenSEO is an SEO tool for &lt;em&gt;the people&lt;/em&gt;. If tools like Semrush or Ahrefs are too expensive or bloated, OpenSEO is a pay-as-you-go alternative that you actually control.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All-in-one SEO tool for you and your AI agent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Connect with any agent like Claude Code, OpenClaw or Hermes. We have pre-built skills, but you can build your own to tailor OpenSEO to your needs.&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/44480372/601812447-fd208249-44ea-4849-bb4b-5fc896aeab73.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODQ2Nzc2ODMsIm5iZiI6MTc4NDY3NzM4MywicGF0aCI6Ii80NDQ4MDM3Mi82MDE4MTI0NDctZmQyMDgyNDktNDRlYS00ODQ5LWJiNGItNWZjODk2YWVhYjczLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA3MjElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNzIxVDIzNDMwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTJlMDkxOWE1OWNjZTQ1MzUxMDYyNTcyODM5Njc5OWE2ZmFjOWFhNDRmY2RiMzAyZDk2OWI2ZjhmZWE3YmJlOWUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.VkWCv9-miJDBZ0FrZnG5r0SpkeEot-wCVqRRDzyQouM"&gt;&lt;img width="1385" height="794" alt="Image" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F44480372%2F601812447-fd208249-44ea-4849-bb4b-5fc896aeab73.png%3Fjwt%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODQ2Nzc2ODMsIm5iZiI6MTc4NDY3NzM4MywicGF0aCI6Ii80NDQ4MDM3Mi82MDE4MTI0NDctZmQyMDgyNDktNDRlYS00ODQ5LWJiNGItNWZjODk2YWVhYjczLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA3MjElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNzIxVDIzNDMwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTJlMDkxOWE1OWNjZTQ1MzUxMDYyNTcyODM5Njc5OWE2ZmFjOWFhNDRmY2RiMzAyZDk2OWI2ZjhmZWE3YmJlOWUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.VkWCv9-miJDBZ0FrZnG5r0SpkeEot-wCVqRRDzyQouM" class="js-gh-image-fallback"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Hosted Version&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Try OpenSEO for free on our website. If you want to support the project, a hosted subscription is $10/month.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://openseo.so" rel="nofollow noopener noreferrer"&gt;openseo.so&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why use OpenSEO?&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Best in class MCP and AI Skills.&lt;/li&gt;
&lt;li&gt;Modern, simple UI.
&lt;ul&gt;
&lt;li&gt;Focused workflows instead of a bloated, complex SEO suite.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;No subscriptions.

&lt;ul&gt;
&lt;li&gt;Bring your own DataForSEO API key and pay only for what you use.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Fork and vibe code your own custom tool.&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Main SEO Workflows&lt;/h2&gt;

&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;Keyword research&lt;/li&gt;

&lt;li&gt;Rank tracking&lt;/li&gt;

&lt;li&gt;Competitor Insights&lt;/li&gt;

&lt;li&gt;Backlinks&lt;/li&gt;

&lt;li&gt;Site…&lt;/li&gt;

&lt;/ul&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/every-app/open-seo" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;The code itself was the easy part. The actual work was reading how someone else already solved similar problems in their codebase before writing a single line — the "how do I avoid noise" and "how do I fit this project's existing shape" questions mattered more than the crawler-detection logic itself.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Shipped My First Rust Release, and CI Turned Red Twice in 20 Minutes</title>
      <dc:creator>Wahib EL KHADIRI</dc:creator>
      <pubDate>Tue, 21 Jul 2026 22:43:39 +0000</pubDate>
      <link>https://dev.to/wahib_el_khadiri_0/i-shipped-my-first-rust-release-and-ci-turned-red-twice-in-20-minutes-31hp</link>
      <guid>https://dev.to/wahib_el_khadiri_0/i-shipped-my-first-rust-release-and-ci-turned-red-twice-in-20-minutes-31hp</guid>
      <description>&lt;p&gt;I shipped the first public release of my Rust project last night. Within about twenty minutes, CI turned red twice. Here's what broke, how I found it, and the two calls I made under a bit of time pressure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The project
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/WAHIB-EL-KHADIRI/AgentOS" rel="noopener noreferrer"&gt;AgentOS&lt;/a&gt; is a runtime layer for AI agents — the infrastructure &lt;em&gt;around&lt;/em&gt; an agent, not the agent logic itself: supervised lifecycle, a gRPC message bus, a health endpoint, an SSE event stream, a secrets vault, and deterministic time-travel replay (every LLM/tool exchange gets journaled, so a run can be replayed offline with no API cost, and forked into alternate timelines from any checkpoint).&lt;/p&gt;

&lt;p&gt;It's a 10-crate Rust workspace, MIT/Apache-2.0. I'd been building it privately for a while. Last night I flipped the repo to public and tagged the first alpha release. That's when things got interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure #1: a clippy lint that didn't exist last month
&lt;/h2&gt;

&lt;p&gt;The repo had been private, so CI hadn't run against a fresh &lt;code&gt;clippy&lt;/code&gt; in a while. The moment I pushed a commit after going public, this showed up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;seem&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;iterate&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nv"&gt;'s&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;
   &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;crates&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;631&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="mi"&gt;631&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_agent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;senders&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subs&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;^^^^^^^^^^^&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;corresponding&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;
&lt;span class="mi"&gt;631&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_agent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;senders&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subs&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="mi"&gt;631&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;senders&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subs&lt;/span&gt;&lt;span class="nf"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;clippy::for_kv_map&lt;/code&gt;, denied by &lt;code&gt;-D warnings&lt;/code&gt; in CI. Fair catch — the code was iterating a &lt;code&gt;HashMap&lt;/code&gt; and discarding the key on every iteration, which is exactly what &lt;code&gt;.values()&lt;/code&gt; is for. One-line fix:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// before&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_agent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;senders&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subs&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="c1"&gt;// after&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;senders&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subs&lt;/span&gt;&lt;span class="nf"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Pushed, CI green again. This one was boring, which is the best kind of bug to have.&lt;/p&gt;
&lt;h2&gt;
  
  
  Failure #2: the release matrix, at 12:33am
&lt;/h2&gt;

&lt;p&gt;The bigger one showed up when I tagged &lt;code&gt;v0.1.0-alpha&lt;/code&gt;. The release workflow builds five targets in parallel — Linux x64, Linux arm64, macOS Intel, macOS Apple Silicon, Windows — and packages each into a binary release with checksums.&lt;/p&gt;

&lt;p&gt;Four went green. Linux arm64 died with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error: failed to run custom build command for `openssl-sys v0.9.116`
...
Could not find directory of OpenSSL installation
$HOST = x86_64-unknown-linux-gnu
$TARGET = aarch64-unknown-linux-gnu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;openssl-sys&lt;/code&gt; needs a real OpenSSL installation (headers + libs) for the &lt;em&gt;target&lt;/em&gt; architecture to link against, and cross-compiling from an x86_64 GitHub Actions runner to arm64 doesn't have that available without extra setup. Not a code bug — a missing piece of cross-compilation infrastructure.&lt;/p&gt;

&lt;p&gt;I had three honest options at that point:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Block the whole release until arm64 cross-compiling was solved properly&lt;/li&gt;
&lt;li&gt;Vendor OpenSSL and wire up a cross-linker for the arm64 target under time pressure, late at night, for a release I hadn't tested that way before&lt;/li&gt;
&lt;li&gt;Ship the four targets that work, drop arm64 from &lt;em&gt;this&lt;/em&gt; release, and track the real fix as its own issue&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I went with option 3. Four platforms is still a real alpha release that covers the overwhelming majority of contributors trying it out. Blocking on a cross-compilation edge case for a Linux architecture almost nobody in the alpha audience runs felt like optimizing for the wrong thing at midnight. And silently vendoring a rushed fix into a security-relevant dependency (TLS) is exactly the kind of shortcut that comes back to bite you.&lt;/p&gt;

&lt;p&gt;So: pulled the target from the matrix, re-tagged, watched the four remaining builds go green, and &lt;a href="https://github.com/WAHIB-EL-KHADIRI/AgentOS/issues/38" rel="noopener noreferrer"&gt;filed the real fix as its own issue&lt;/a&gt; with three candidate approaches laid out (the best one is probably migrating off &lt;code&gt;openssl-sys&lt;/code&gt; to &lt;code&gt;rustls&lt;/code&gt; entirely, which would remove the system OpenSSL dependency for &lt;em&gt;every&lt;/em&gt; target, not just arm64 — cross-compilation problems like this are usually a sign the dependency choice needs revisiting, not just the CI config).&lt;/p&gt;
&lt;h2&gt;
  
  
  The one check I'm glad I ran before either of this
&lt;/h2&gt;

&lt;p&gt;Before any of the above, I'd actually run the README's own quickstart end to end — &lt;code&gt;cargo build --workspace&lt;/code&gt;, then run the example agent — specifically to catch the gap between "the README claims this works" and "this actually works." It did, and the real terminal output (supervisor spawning the agent, health server on &lt;code&gt;:8080&lt;/code&gt;, gRPC bus on &lt;code&gt;:50051&lt;/code&gt;, an SSE stream on &lt;code&gt;:8081&lt;/code&gt;) is now in the README instead of a hypothetical example. I also downloaded the actual released Windows binary afterward and ran &lt;code&gt;agentOS.exe --version&lt;/code&gt; against it — small thing, but it's the difference between "the release workflow exited 0" and "a stranger who downloads this file gets a working program."&lt;/p&gt;

&lt;p&gt;Neither bug was catastrophic. Both were the kind of thing that's mildly stressful in the moment and completely mundane in hindsight — which is most of what real engineering work actually looks like, release-day war stories included.&lt;/p&gt;

&lt;p&gt;If you want to poke at it, the repo's here: &lt;strong&gt;&lt;a href="https://github.com/WAHIB-EL-KHADIRI/AgentOS" rel="noopener noreferrer"&gt;github.com/WAHIB-EL-KHADIRI/AgentOS&lt;/a&gt;&lt;/strong&gt;. There are a handful of labeled &lt;code&gt;good first issue&lt;/code&gt;s if anyone wants to dig into a self-contained piece of it — I'm around to answer questions on any of them.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/WAHIB-EL-KHADIRI" rel="noopener noreferrer"&gt;
        WAHIB-EL-KHADIRI
      &lt;/a&gt; / &lt;a href="https://github.com/WAHIB-EL-KHADIRI/AgentOS" rel="noopener noreferrer"&gt;
        AgentOS
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Runtime infrastructure for AI agents — lifecycle, supervision, secrets, and deterministic time-travel replay. Built in Rust.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;AgentOS - Runtime Infrastructure for AI Agents&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.rust-lang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5bfae72232b83a4d4178c88542d70400585d892a0daf6077c9f3f385b9293f82/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f527573742d312e39342532422d6f72616e6765" alt="Rust"&gt;&lt;/a&gt;
&lt;a href="https://github.com/WAHIB-EL-KHADIRI/AgentOS#license" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/19e546f568d501b01caf5f8c4e7116e2df532b762bb3d2de68ecf1f4f0b2e0c6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542532304f522532304170616368652d2d322e302d626c7565" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/WAHIB-EL-KHADIRI/agentOS/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/WAHIB-EL-KHADIRI/agentOS/actions/workflows/ci.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/WAHIB-EL-KHADIRI/AgentOS/scripts/check.ps1" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/60b7735e3302f07a0ee15ef29d63e76b806bf7d95b809274afe48625225df06b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f77696e646f77732d737570706f727465642d626c7565" alt="Windows"&gt;&lt;/a&gt;
&lt;a href="https://github.com/WAHIB-EL-KHADIRI/AgentOS/docs/" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7386e7990576f21a5320b5f4e5a0e54bc941305dd1498b29d8e8709bbb4d38dd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d617661696c61626c652d626c7565" alt="Docs"&gt;&lt;/a&gt;
&lt;a href="https://github.com/WAHIB-EL-KHADIRI/AgentOS#quick-start" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/97bf57002f6627adc71a5e403cee8fb6d67ac48676e7a46c841d919dc3d92723/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f696e7374616c6c2d6f6e652d2d6c696e65722d73756363657373" alt="Install"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;AgentOS is an open-source runtime layer for AI agents. It focuses on the
infrastructure around agents: lifecycle, supervision, messaging, state, secrets
observability, and trace replay.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Created by &lt;a href="https://github.com/WAHIB-EL-KHADIRI" rel="noopener noreferrer"&gt;WAHIB EL KHADIRI&lt;/a&gt;&lt;/strong&gt; — founder and architect.&lt;/p&gt;
&lt;p&gt;Most agent frameworks help you build an agent workflow. AgentOS focuses on what
happens after that workflow needs to run as a long-lived process, fail clearly
restart carefully, and be inspected after the fact.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See it run&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Real output from a fresh clone — no API key required to bring the runtime up:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;$ cargo run -p agentos-cli -- run --agent examples/simple_agent.toml
INFO agentos_kernel::supervisor: agent spawned and running agent_id=agent_simple_agent state=Running name=simple-agent
INFO agentos_kernel::agent: agent loop started agent_id=agent_simple_agent
INFO agentos_kernel::events: system event emitted event=agent.spawned seq=0
INFO agentOS::run: AgentOS runtime started agent_id=agent_simple_agent host=127.0.0.1 http_port=8080 grpc_port=50051 sse_port=8081
INFO agentos_kernel::health: health server listening on 127.0.0.1:8080
INFO agentos_bus::grpc: gRPC bus server listening on 127.0.0.1:50051&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/WAHIB-EL-KHADIRI/AgentOS" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>rust</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
