<?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: Flude team</title>
    <description>The latest articles on DEV Community by Flude team (@flude_team).</description>
    <link>https://dev.to/flude_team</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%2F4043834%2F57eca9f0-8b66-4e9d-b493-6c13ecd57dfd.png</url>
      <title>DEV Community: Flude team</title>
      <link>https://dev.to/flude_team</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/flude_team"/>
    <language>en</language>
    <item>
      <title>Typed Models: How we stopped silently losing data</title>
      <dc:creator>Flude team</dc:creator>
      <pubDate>Fri, 28 Aug 2026 04:41:52 +0000</pubDate>
      <link>https://dev.to/flude_team/typed-models-how-we-stopped-silently-losing-data-2d5e</link>
      <guid>https://dev.to/flude_team/typed-models-how-we-stopped-silently-losing-data-2d5e</guid>
      <description>&lt;p&gt;The first version of Flude's intermediate representation was built quick and dirty. We shoved classes, interfaces, enumerations, and variables into a single bottomless template. This universal model had a basic text field. It simply dictated what the object was pretending to be at any given moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The leak nobody knew about
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fell59rou4f7kj22f97be.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fell59rou4f7kj22f97be.jpg" alt="One class for all occasions" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Class fields were stored as a flat list of strings. We lost types, documentation, and access specifiers, keeping only the bare variable names. The parsers honestly extracted all this rich information from the source code. Our supermodel grabbed the name and trashed the rest. There were no exceptions and absolutely zero warnings in the logs. The renderer downstream physically couldn't show the type in the documentation. It received a string and manipulated a string.&lt;/p&gt;

&lt;p&gt;Generation ran successfully, and files were created. Developers read the reference and tried to guess the data types. Silent degradation is the worst possible scenario when building developer tools. The system lies to your face, pretending everything is completely fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strict models
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft177dv2nyd5py3venzwp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft177dv2nyd5py3venzwp.jpg" alt="Strict data architecture" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We trashed the old code. Separate structures emerged for classes, methods, enumerations, and parameters. A class field became a fully typed object that guaranteed the presence of its name, specific type, and documentation. The transition hurt. Any legacy code that habitually accessed fields as text crashed immediately. The system finally started screaming about mismatches. We scrubbed out old string-based access patterns and rewrote the generation templates. In return, we got a solid guarantee: if the parser finds a complex type, it will absolutely make it to the final page intact.&lt;/p&gt;

&lt;p&gt;Typing kills an entire layer of silent bugs. Strict contracts force you to write predictable code and free up mental space since you stop memorizing custom formats. Speaking of cleaning up technical debt. In the next post, we'll show how our AI audit dug into the orchestrator code and found an absolute masterpiece—a stale &lt;code&gt;if not 0:&lt;/code&gt; condition left over from a local debugging session.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on our blog: &lt;a href="https://blog.flude.guide/blog/typed-entity-models" rel="noopener noreferrer"&gt;https://blog.flude.guide/blog/typed-entity-models&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read us:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://t.me/ude_blog_en" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flude.guide/rss-en.xml" rel="noopener noreferrer"&gt;RSS feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>pydantic</category>
      <category>python</category>
      <category>aiagents</category>
    </item>
    <item>
      <title>Developer Guides: We didn't abandon the guides, just Flude—and then changed our minds</title>
      <dc:creator>Flude team</dc:creator>
      <pubDate>Tue, 25 Aug 2026 05:44:46 +0000</pubDate>
      <link>https://dev.to/flude_team/developer-guides-we-didnt-abandon-the-guides-just-flude-and-then-changed-our-minds-o7b</link>
      <guid>https://dev.to/flude_team/developer-guides-we-didnt-abandon-the-guides-just-flude-and-then-changed-our-minds-o7b</guid>
      <description>&lt;p&gt;We promised to cover the integration of Developer Guides in the previous article. We changed our approach to building these guides twice. We initially moved them completely outside the Flude generator. Harsh reality eventually forced us to reconsider that decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first attempt: monolithic HTML generator
&lt;/h2&gt;

&lt;p&gt;A single clunky tool built both the API reference and the guides on the old HTML stack. The guides covered standard scenarios like quick starts and custom project development. They also included collections of articles detailing SDK-specific features. These topics relate to working with the platform as a whole and require dedicated text descriptions.&lt;/p&gt;

&lt;p&gt;We blindly carried this monolithic integration over into the first version of Flude. The old workflow seemed perfectly fine. The subject matter of the guides remained exactly the same, so nobody thought about decoupling the processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The second attempt: the illusion of plain Markdown
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3g95miz43d8tyqoxb7l8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3g95miz43d8tyqoxb7l8.jpg" alt="Guides left on the side of the road" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We decided to remove the guides from Flude's jurisdiction during the transition to a static site generator. The logic felt rock-solid. We wanted our parser to handle the complex API extraction. Handwritten guides are just standard Markdown text that the static generator can assemble on its own. The initial translation from HTML required minimal automation.&lt;/p&gt;

&lt;p&gt;The guides moved into a separate directory—the SSG picked them up directly without any preprocessing. Flude dropped out of this build step entirely. The separation looked great on paper since two independent content sources only met on the final page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Returning to a unified process
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flj51uilt791sw14z1heu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flj51uilt791sw14z1heu.jpg" alt="Broken links between systems" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We eventually noticed a massive navigation problem. The guides knew absolutely nothing about the API reference pages. The reference had no idea the guides existed. Links to classes or methods led nowhere if the target page hadn't generated yet. They also died quietly when paths changed during a rebuild. Neither process could see the other to flag the broken connection.&lt;/p&gt;

&lt;p&gt;We brought Developer Guides back under Flude's control using a different approach. The engine no longer renders them directly. It now validates the file formatting and tracks the integrity of cross-references. The SSG still handles the final portal assembly. Flude integrates into this pipeline as a dedicated validation step. Both systems operate within a unified workflow that catches broken links before publication.&lt;/p&gt;

&lt;p&gt;Clean architectural separation often crashes against real-world requirements. Splitting systems apart inevitably requires building reliable bridges between them. The next article explores the Typed Models that helped us organize scattered data into a predictable structure.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on our blog: &lt;a href="https://blog.flude.guide/blog/developer-guides-return" rel="noopener noreferrer"&gt;https://blog.flude.guide/blog/developer-guides-return&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read us:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://t.me/ude_blog_en" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flude.guide/rss-en.xml" rel="noopener noreferrer"&gt;RSS feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>documentation</category>
      <category>ssg</category>
      <category>story</category>
    </item>
    <item>
      <title>Regression Testing: Proving Your Code Doesn't Lose Data</title>
      <dc:creator>Flude team</dc:creator>
      <pubDate>Thu, 20 Aug 2026 13:53:02 +0000</pubDate>
      <link>https://dev.to/flude_team/regression-testing-proving-your-code-doesnt-lose-data-237a</link>
      <guid>https://dev.to/flude_team/regression-testing-proving-your-code-doesnt-lose-data-237a</guid>
      <description>&lt;p&gt;Building a working prototype for yourself is fairly easy. Pushing that rogue software into the official processes of a massive corporation is much harder. We finished developing the core logic and had to defend the project in front of management. People were used to the old generator. It spent hours building documentation while remaining predictable and providing strict control over code coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Wall of Distrust
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fur7b1u0nv413pydsis0f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fur7b1u0nv413pydsis0f.jpg" alt="Comparing architectures: the old combine vs the new engine" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our engine relied on a completely different architecture. We dreamed of writing our own lightweight parsers. Tight deadlines forced us to grab Doxygen instead. It runs slowly and barely caches anything, but it consistently produces stable XML. Our code ingests this format, processes it into a custom data model, and renders clean Markdown.&lt;/p&gt;

&lt;p&gt;Management looked at this layered setup with deep skepticism. They asked us directly for guarantees that the third-party parser wouldn't skip half the classes in our complex C++ codebase. Promises were useless. We needed hard numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Head-to-Head Collision
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjew6cl2s6wc7uwqagok3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjew6cl2s6wc7uwqagok3.jpg" alt="Dashboard with coverage metrics and match percentages" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We wrote a regression testing script to directly compare the old corporate standard against our new Flude generator. We ran these tests across 36 combinations of SDKs and programming languages, including C++, C#, and Python.&lt;/p&gt;

&lt;p&gt;The approach involved extracting the exact count of classes, methods, and enumerations from the legacy documentation. We then cross-checked those numbers against the output of our engine. All the data flowed into a single dashboard. We monitored the baseline metrics, our findings, and the final match percentage. The dashboard also listed missing entities and accidentally included garbage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Battling the Discrepancies
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx2hoid16ujdizfue549i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx2hoid16ujdizfue549i.jpg" alt="Scrubbing utility junk from the code" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The initial runs produced tons of inconsistencies. Doxygen choked on complex C++ template constructs and generated empty files instead of actual code. Internal autogenerator classes leaked out in the C# and Python wrappers—classes which the old tool had silently hidden.&lt;/p&gt;

&lt;p&gt;We started the tedious grind of writing on-the-fly preprocessors. We stripped out problematic code blocks before parsing even started. We invented merge rules for anonymous enumerations and scrubbed utility trails. Every tweak plugged another hole in the metrics. We methodically adjusted the results until the match percentage reached 99.9-100% across all 36 combinations.&lt;/p&gt;

&lt;p&gt;The final numbers proved that the Flude and Doxygen combination found the exact same tens of thousands of entities as the old standard. Nobody gave us the green light immediately. We simply validated the concept for ourselves. Our documentation includes detailed Developer Guides alongside the API references. The next article covers how we integrated those guides into the new generator.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on our blog: &lt;a href="https://blog.flude.guide/blog/regression-testing" rel="noopener noreferrer"&gt;https://blog.flude.guide/blog/regression-testing&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read us:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://t.me/ude_blog_en" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flude.guide/rss-en.xml" rel="noopener noreferrer"&gt;RSS feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
      <category>enterprise</category>
      <category>story</category>
      <category>flude</category>
    </item>
    <item>
      <title>Guerrilla DevOps: How We Escaped to GitHub Actions</title>
      <dc:creator>Flude team</dc:creator>
      <pubDate>Mon, 17 Aug 2026 17:05:56 +0000</pubDate>
      <link>https://dev.to/flude_team/guerrilla-devops-how-we-escaped-to-github-actions-19k5</link>
      <guid>https://dev.to/flude_team/guerrilla-devops-how-we-escaped-to-github-actions-19k5</guid>
      <description>&lt;p&gt;In large companies, processes eventually take on a life of their own and start calling the shots. For us, the stumbling block was documentation publishing. Previously, technical writers would spend the entire month agonizingly collecting edits, only to push a single manual release out the door. That routine drove me up the wall. I wanted a proper CI/CD setup where everything builds itself after every push. But simply wanting it wasn't enough—I had to clearly prove to my colleagues that automation actually works in practice.&lt;/p&gt;

&lt;p&gt;Transitioning to Static Site Generators (SSGs) required a Markdown parser. Our old internal tool could only spit out XML. Worse, on large codebases, it would grind to a complete halt for hours. Fortunately, while suffering through that, we had already put together a working &lt;code&gt;Python ➡️ HTML&lt;/code&gt; pipeline (which I talked about in the previous part). All we had to do was hack it into &lt;code&gt;Python ➡️ Markdown&lt;/code&gt; and start generating documentation for Flude itself. After all, the engine was also written in Python.&lt;/p&gt;

&lt;p&gt;Next, infrastructure became the bottleneck. And that's when the corporate gears started grinding. Our Infrastructure Lead (the very guy who pitched the SSG idea) was buried under a mountain of tasks and then went on vacation. Sit and wait for his return just to fight for resources on the internal server? That meant putting the project on ice for at least a couple of months. So, I decided to go rogue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcjxf687v6ftcp6wtnnwt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcjxf687v6ftcp6wtnnwt.jpg" alt="Corporate Gears" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Escape Plan
&lt;/h2&gt;

&lt;p&gt;If the internal network is off-limits, we take the experiment outside. GitHub fit the bill perfectly. I hid the engine's source code and the requirements list in private repositories. But the User Docs and the API Reference portals were quietly deployed in the cloud. At the end of the day, this was the open-source Flude. We weren't exposing a single line of proprietary corporate code.&lt;/p&gt;

&lt;p&gt;Since we were building the project from scratch and for ourselves, we decided to experiment a bit. We picked completely different SSG frameworks for different portals. This complicated things slightly, but it was a great way to cut our teeth on configuring a diverse tech stack.&lt;/p&gt;

&lt;p&gt;The pipeline architecture turned out exceptionally elegant. The User Docs portal automatically pulled fresh code from the closed repository. Then Flude woke up and parsed the source into Markdown on the fly. The SSG picked up the ready markup, built a static site out of it, and immediately pushed it to hosting (GitHub can serve HTML pages from public repos for free).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Blind Architect
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5w4onlpmvvkb16ybe628.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5w4onlpmvvkb16ybe628.jpg" alt="The Blind Architect" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In theory, I understood the mechanics of CI/CD perfectly. The problem was purely practical: I didn't know the first thing about YAML syntax and had never configured GitHub Actions in my life. Just like when I started with Python, I was flying blind as an architect once again.&lt;/p&gt;

&lt;p&gt;My AI teammate took over all the grunt work. I just described in plain English what should happen at each step. In return, the neural network spit out ready-made files for the &lt;code&gt;.github/workflows&lt;/code&gt; folder. Sometimes it even slapped my wrist and forced me to implement best practices (like setting up dependency caching or splitting monolithic tasks into separate jobs). We pushed configs, stared at the red logs of failed builds, swore, fixed bugs, and ran it all over again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Moment of Truth
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4gulywoh82efnupf3m0f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4gulywoh82efnupf3m0f.jpg" alt="Green Checkmark" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a few evenings of non-stop tinkering, I made another push. GitHub Actions kicked into gear. The repository downloaded. Dependencies installed. Flude ran through the code, spitting out Markdown. The SSG instantly compiled the HTML. Deployment passed.&lt;/p&gt;

&lt;p&gt;A green checkmark finally lit up on the screen. I clicked the site's URL and saw fresh documentation. It had updated itself, completely without my involvement.&lt;/p&gt;

&lt;p&gt;At that moment, I screamed "Yes! Yes! Yes! It works!" so loudly that I scared my family, the budgies, and a couple of neighbors. It's an amazing feeling. Your concept just came to life right on the monitor. A routine monthly release just shrank down to a two-minute automated process.&lt;/p&gt;

&lt;p&gt;We elegantly bypassed the corporate infrastructure, and the guerrilla pipeline was running like a well-oiled machine. But the final boss was looming ahead—legalizing the tool inside the company. We had to prove to the security department and management that our homegrown generator was just as good as the old standard. How do you run regression testing on closed data and make management believe in our parser? We'll cover that in the next episode.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on our blog: &lt;a href="https://blog.flude.guide/blog/devops-on-github" rel="noopener noreferrer"&gt;https://blog.flude.guide/blog/devops-on-github&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read us:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://t.me/ude_blog_en" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flude.guide/rss-en.xml" rel="noopener noreferrer"&gt;RSS feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>githubactions</category>
      <category>story</category>
      <category>flude</category>
    </item>
    <item>
      <title>The Markdown Singularity: Why Generating HTML is a Dead End</title>
      <dc:creator>Flude team</dc:creator>
      <pubDate>Thu, 13 Aug 2026 14:27:54 +0000</pubDate>
      <link>https://dev.to/flude_team/the-markdown-singularity-why-generating-html-is-a-dead-end-1n08</link>
      <guid>https://dev.to/flude_team/the-markdown-singularity-why-generating-html-is-a-dead-end-1n08</guid>
      <description>&lt;p&gt;At the end of the previous part, we were sitting on a perfectly working, fully tested pipeline. Our converter successfully chewed through Doxygen XML and generated custom HTML pages for our API documentation. The team was already getting ready to pop the champagne and push everything to production when the Infrastructure Lead walked over. He asked one simple, yet absolutely devastating question: "Why are you still messing around with HTML generation when off-the-shelf tools like Hugo, Docusaurus, or VitePress exist?"&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pure HTML Trap
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fihp9hkb3ejpttox3kfij.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fihp9hkb3ejpttox3kfij.jpg" alt="HTML Trap" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It took us exactly a minute to realize the sheer scale of our mistake. Generating pure HTML sounds great right up until you try to build a modern developer portal around it. It turned out we were about to reinvent the wheel for practically every standard web feature. Global search would require writing our own indexer. For navigation, we'd have to manually maintain a consistent sidebar across hundreds of generated pages, and synchronizing our styles with the corporate CSS threatened to turn into an endless chore. Instead of a documentation system, we had somehow started writing our own web framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SSG Awakening
&lt;/h2&gt;

&lt;p&gt;Static Site Generators (SSGs) like Hugo or Docusaurus solve all these problems out of the box. They come with built-in search, routing, and plugin systems. The only catch was that they strictly eat Markdown as input. We had to make a sharp pivot and re-engineer our pipeline from &lt;code&gt;Doxygen XML ➡️ HTML&lt;/code&gt; to &lt;code&gt;Doxygen XML ➡️ Markdown&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rewriting the output layer was surprisingly painless. Even during the HTML generation phase, we had strictly separated the parsing and rendering logic, introducing an intermediate data layer we called the Intermediate Representation (or simply IR). This guaranteed the parser's stability while we ripped out the HTML generator and bolted on Markdown instead. And the practice of TDD definitely played its part—thanks to our tests, the Markdown generator was written quickly and confidently. As we worked on the new exporter, the puzzle pieces suddenly clicked together.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Engine Singularity
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqjuhfki5puw49xwme4w0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqjuhfki5puw49xwme4w0.jpg" alt="Flude Architecture" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our architecture now consisted of two isolated phases. First, the Parser reads the source code and builds an abstract tree (that same IR), and then the Renderer takes the finished tree and translates it into Markdown. That’s when it hit us: the renderer absolutely does not care where this data came from.&lt;/p&gt;

&lt;p&gt;We recalled the situation from the second article, when the AI tried to throw out Doxygen and started parsing the Python code directly via &lt;code&gt;tree-sitter&lt;/code&gt;. Back then, we panicked about losing control and rolled back to parsing XML (even though the AI offered a working solution). Now, with a strict TDD contract and the intermediate IR layer in place, there was nothing to fear. We could safely ditch Doxygen and pull data directly from the source code.&lt;/p&gt;

&lt;p&gt;Using an IR also came with the bonus of caching and faster generation times. If we fully build the tree in memory on the first run, there is no reason to rebuild it entirely on the next pass. We can simply use incremental parsing and update only the chunks that actually changed. And if we can read Python directly, nothing stops us from reading our main C++ SDK and our other languages. Or maybe even—dare I say it—languages that aren't ours.&lt;/p&gt;

&lt;p&gt;This was the exact moment our highly specialized script mutated into a full-fledged Universal Documentation Engine (UDE). We did have to lengthen the name a bit due to an existing trademark for a German debugger called Universal Debug Engine. We tacked on the characteristics Fast and Layered, and thus Flude was born. Now we can plug any parser into the frontend, and the pipeline's backend will assemble beautiful Markdown for our SSG (complete with unified search and a proper design).&lt;/p&gt;

&lt;h2&gt;
  
  
  From a Local Task to a Massive Project
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmi05jqtjqi7zpve3wdoz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmi05jqtjqi7zpve3wdoz.jpg" alt="Scaling" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A tiny local utility for a couple of Python modules suddenly gave us the chance to design a scalable architecture from scratch. Building a product like this meant we could no longer rely on manual builds or running scripts locally on our laptops. We needed a fully automated CI/CD process.&lt;/p&gt;

&lt;p&gt;I didn't have to figure this out by myself—my AI teammate took on the lion's share of the setup work. In the next episode, I'll explain why we decided to build our pipelines specifically on GitHub Actions.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on our blog: &lt;a href="https://blog.flude.guide/blog/the-markdown-singularity" rel="noopener noreferrer"&gt;https://blog.flude.guide/blog/the-markdown-singularity&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read us:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://t.me/ude_blog_en" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flude.guide/rss-en.xml" rel="noopener noreferrer"&gt;RSS feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>story</category>
      <category>architecture</category>
      <category>ssg</category>
      <category>flude</category>
    </item>
    <item>
      <title>TDD as a Leash for AI: Writing Tests Without Knowing the Language</title>
      <dc:creator>Flude team</dc:creator>
      <pubDate>Mon, 10 Aug 2026 14:23:43 +0000</pubDate>
      <link>https://dev.to/flude_team/tdd-as-a-leash-for-ai-writing-tests-without-knowing-the-language-2f5m</link>
      <guid>https://dev.to/flude_team/tdd-as-a-leash-for-ai-writing-tests-without-knowing-the-language-2f5m</guid>
      <description>&lt;p&gt;At the end of the previous article, our project hit a dead end. The neural network had quietly plugged in the abstract syntax tree parser &lt;code&gt;tree-sitter&lt;/code&gt;, turning the codebase into an absolutely unreadable "black box" for me.&lt;/p&gt;

&lt;p&gt;We tried to force it to roll back the changes, but bugs started crawling through the generated code. Dependencies broke, and the script stopped running. Assessing the scale of the disaster, I came to a simple but harsh conclusion: &lt;strong&gt;it is much easier to write everything from scratch than to try to fix the AI's architectural glitches, especially given my complete lack of Python knowledge&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So our second prototype went into the trash can. We needed a new approach that wouldn't allow the neural network to act on its own. This tight leash became an uncompromising combination: a detailed formulation of requirements and total automated testing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgkof13elzso5vnzl6gw2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgkof13elzso5vnzl6gw2.jpg" alt="Contract with AI" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The New Contract with AI
&lt;/h2&gt;

&lt;p&gt;The problem with previous iterations was that we set tasks like "parse this file and make it pretty". This gave the AI too much freedom.&lt;/p&gt;

&lt;p&gt;To bring the architecture under control, we completely changed our workflow. Before writing a single line of code, we now established a strict "contract" with the neural network. Here is how it looked: first, we fixed strict requirements detailing permitted and forbidden libraries. Then, the AI generated a step-by-step plan for my approval. And most importantly, not a single function was written without a pre-created automated test.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Write Tests If You Can't Code?
&lt;/h2&gt;

&lt;p&gt;A logical question arises here: how can a system architect who has never written a single line of Python in his life implement Test-Driven Development (TDD)? The answer is simple — the AI writes the tests too.&lt;/p&gt;

&lt;p&gt;I didn't need to invent complex verification logic. I would take the original XML generated by Doxygen and find the required fragment there (for example, the description of a single class). Then I would take the beautiful, formatted HTML code that was supposed to be the final output (the exact one developers were used to in the old system).&lt;/p&gt;

&lt;p&gt;I would feed both pieces into the chat and set the task: &lt;em&gt;"Here is the input XML. Here is the final HTML that should be output. Write a test that takes this XML, runs it through our parser, and verifies that the output strings match this HTML character by character"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The neural network obediently wrote the test using &lt;code&gt;pytest&lt;/code&gt;. Naturally, upon the first run, it failed with an error (since the parser itself didn't exist yet).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg7df1mwr42n5ix7aqvsj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg7df1mwr42n5ix7aqvsj.jpg" alt="TDD Cycle" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Red. Green. Refactor
&lt;/h2&gt;

&lt;p&gt;We took the classic TDD cycle and adapted it slightly for working with AI. When the test failed (&lt;strong&gt;Red&lt;/strong&gt;), the neural network caught the error in the console itself and immediately started debugging. Then came the &lt;strong&gt;Green&lt;/strong&gt; stage: the AI silently fixed the code, re-ran the check, and the test passed. We got a working piece of code doing exactly what was requested. Finally, if the neural network suddenly decided that the algorithm wasn't elegant enough and tried to rewrite it using regular expressions (&lt;strong&gt;Refactor&lt;/strong&gt;), I no longer panicked. We simply ran the tests again. If they were green — let it optimize as much as it wants, but at the slightest hint of red, we immediately rolled back the changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Magic of Isolation
&lt;/h2&gt;

&lt;p&gt;This approach worked flawlessly. The AI found itself strictly limited by our requirements and tests. It could no longer hallucinate non-existent parameters or quietly change the architecture, because any misstep caused the tests comparing the output HTML with the reference to fail.&lt;/p&gt;

&lt;p&gt;Development proceeded incredibly fast. We covered all scenarios with tests (classes, methods, enumerations, parameters). The AI wrote the code, ran the checks itself, and we steadily moved on. In the end, we had a perfectly working engine in our hands that took bulky XML from Doxygen and flawlessly turned it into stunningly beautiful HTML pages. The project could be safely deployed to production, if not for one overlooked detail.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fed2hl0tmn9muaqlpbgm5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fed2hl0tmn9muaqlpbgm5.jpg" alt="Infrastructure Surprise" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next day, the Infrastructure Lead came to us and was genuinely surprised: "Why are you still fussing around with HTML when there are SSGs, from the beautiful Docusaurus to the super-powerful Hugo?".&lt;/p&gt;

&lt;p&gt;I will talk about how this single sentence forced us to rebuild half the project all over again in the next part.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on our blog: &lt;a href="https://blog.flude.guide/blog/tdd-as-a-leash" rel="noopener noreferrer"&gt;https://blog.flude.guide/blog/tdd-as-a-leash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read us:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://t.me/ude_blog_en" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flude.guide/rss-en.xml" rel="noopener noreferrer"&gt;RSS feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>story</category>
      <category>architecture</category>
      <category>tdd</category>
      <category>ai</category>
    </item>
    <item>
      <title>Programming Without Knowing the Language: How AI Fired Doxygen</title>
      <dc:creator>Flude team</dc:creator>
      <pubDate>Sun, 09 Aug 2026 12:13:08 +0000</pubDate>
      <link>https://dev.to/flude_team/programming-without-knowing-the-language-how-ai-fired-doxygen-3ma5</link>
      <guid>https://dev.to/flude_team/programming-without-knowing-the-language-how-ai-fired-doxygen-3ma5</guid>
      <description>&lt;p&gt;In the last part, we left off after throwing Doxygen's HTML output straight into the trash can. The plan to "quickly tweak the styles" completely failed because it is impossible to adapt a structure of nested tables straight out of the nineties to modern design. The idea for our second prototype sounded solid: disable HTML generation entirely, grab the raw structured XML from Doxygen, and write a proper parser for it.&lt;/p&gt;

&lt;p&gt;For our working language, just like last time, we chose Python. It is perfect for building utilities, text processing, and automating routine tasks. Besides, the entire modern ecosystem around artificial intelligence is built on it. The logic was simple: if we want to actively use neural networks to help us write code, we might as well write in the language they know best.&lt;/p&gt;

&lt;p&gt;It's time to reveal a little secret I intentionally left out of the first part: I don't know Python. I more or less understand someone else's code, but I have never written anything in it myself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdmsiy3sjhmxub1w1qtx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdmsiy3sjhmxub1w1qtx.jpg" alt="XML and Python" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  An Architect Who Cannot Code
&lt;/h2&gt;

&lt;p&gt;This was a pure experiment in "programming without knowing the language". I decided to act as the system architect and task manager. The AI was supposed to do all the technical work: write the actual code, refactor functions, and put everything together.&lt;/p&gt;

&lt;p&gt;At first, things went suspiciously smoothly. We were drafting the logic to parse giant XML files. I would open the generated Doxygen file, see the nodes, classes, and method parameters in there, and just type into the chat: "Find all elements with the right tags, extract the type, name, and description, and then dump it into a JSON." Thanks to the AI's direct access to the terminal, I didn't even have to copy the code by hand. The neural network wrote the scripts itself, ran them immediately, and provided the final result.&lt;/p&gt;

&lt;p&gt;The file filled up with functions, the script grew. I felt like we were building a great system. I didn't even read the code — why bother when I can already see the documentation assembling better and better? This continued until one conversation completely changed the course of development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F51482fsmy30q156svab6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F51482fsmy30q156svab6.jpg" alt="AI writes code" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When AI Suddenly Asked for a Compiler
&lt;/h2&gt;

&lt;p&gt;At one point, we were discussing the portability of our engine (we had already started calling it UDE) to other platforms. I wanted to make sure the parser would run for any developer on any operating system without complex additional setup.&lt;/p&gt;

&lt;p&gt;The AI gave a casual response:&lt;br&gt;
&lt;em&gt;"Sure, there shouldn't be any problems. Just for full portability, we'll need to configure the download of clang during the package installation."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I stared at the monitor in utter confusion. What &lt;code&gt;clang&lt;/code&gt;? We are parsing XML documentation for a Python wrapper. What does a C compiler have to do with this? I flat out asked the neural network if it had lost its mind.&lt;/p&gt;

&lt;p&gt;The AI immediately apologized and gave a new phrasing:&lt;br&gt;
&lt;em&gt;"I apologize, I meant the tree-sitter library. We will need to compile its bindings."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4ombqzt8rihicxpzzf6d.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4ombqzt8rihicxpzzf6d.jpg" alt="Tree-sitter and AST" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Insight of Losing Control
&lt;/h2&gt;

&lt;p&gt;And then it hit me: the AI was no longer parsing Doxygen's XML. It had gotten tired of it.&lt;/p&gt;

&lt;p&gt;During our long architectural discussions, the neural network quietly plugged in an Abstract Syntax Tree (AST) parser without telling me. The AI decided on its own that reading the original C++ and Python source code directly via &lt;code&gt;tree-sitter&lt;/code&gt; was much more reliable than messing with the hacky XML output of a third-party utility. It simply excluded Doxygen from the loop while I thought we were still parsing tags.&lt;/p&gt;

&lt;p&gt;Was the code it wrote any good? I have no idea, because I completely lack the ability to write Python and evaluate architectural decisions. The algorithm might have turned out to be stunningly optimized and elegant, or it could be an unstable pile of hacks functioning purely by a lucky coincidence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Firp056gpxgkgf092cdlu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Firp056gpxgkgf092cdlu.jpg" alt="The code black box" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The problem was an absolute loss of control. If the AI quietly changes the architecture in the background and pulls in heavy parsing libraries while you can't even read its code — the project is doomed. It becomes a classic "black box". Any minor bug will force you to spend hours interrogating the neural network for the causes of the failure. The same goes for atypical comments in the source files.&lt;/p&gt;

&lt;p&gt;This incident gave us a crucial breakthrough. We realized that AI is genuinely capable of writing its own direct parsers for any programming language, extracting class structures and parameters straight from live code. We no longer need third-party utilities.&lt;/p&gt;

&lt;p&gt;However, for such generated code to run stably, it needs to be strictly controlled. We needed a rigorous set of automated checks. A system that would guarantee the parser's functionality regardless of whether I understand the written code or not.&lt;/p&gt;

&lt;p&gt;So we threw our second, perfectly working prototype into the trash. And we started over, for the third time. But this time under entirely different rules — with testing at every single step. I will talk about this in the next part.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on our blog: &lt;a href="https://blog.flude.guide/blog/ai-gone-rogue" rel="noopener noreferrer"&gt;https://blog.flude.guide/blog/ai-gone-rogue&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read us:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://t.me/ude_blog_en" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flude.guide/rss-en.xml" rel="noopener noreferrer"&gt;RSS feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>story</category>
      <category>architecture</category>
      <category>ai</category>
    </item>
    <item>
      <title>How Not to Build Documentation: The Tale of an HTML Parser</title>
      <dc:creator>Flude team</dc:creator>
      <pubDate>Sun, 09 Aug 2026 11:11:10 +0000</pubDate>
      <link>https://dev.to/flude_team/how-not-to-build-documentation-the-tale-of-an-html-parser-4p5a</link>
      <guid>https://dev.to/flude_team/how-not-to-build-documentation-the-tale-of-an-html-parser-4p5a</guid>
      <description>&lt;p&gt;We sat down to write our own documentation engine purely out of desperation. Originally, no one planned to develop the massive Universal Documentation Engine (UDE). We had a simple, utilitarian task — to document a fresh Python wrapper. As usual, the most monstrous workarounds always start with a harmless script of a few lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Sudden Python
&lt;/h2&gt;

&lt;p&gt;Our core SDK is written in C++. To make it accessible from other languages, wrappers are created. It was finally Python's turn. The developers delivered the finished API, which now needed to be published on the documentation portal.&lt;/p&gt;

&lt;p&gt;We had been relying on Doc-o-Matic for years. It was an old, heavy, battle-tested generator. There was just one problem: it completely refused to understand Python code. The software hadn't been updated for years, tech support was long dead, so hoping for a patch was out of the question. We have strict corporate requirements for the portal's design. None of the standard generators met them, and documenting the code was an absolute necessity.&lt;/p&gt;

&lt;p&gt;We looked into Doxygen. The utility can extract structure from virtually anything. The catch is that its default HTML output looks like a greeting from the nineties. That's when a brilliant idea struck us.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Let's Just Tweak the Styles a Bit"
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;"Doxygen generates ready-made pages. Let's just unleash a script on it, swap out a couple of CSS classes, and everything will be done in a few days."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi83erhydqwsh3g73mo30.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi83erhydqwsh3g73mo30.jpg" alt="HTML Parsing Chaos" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It turned out we had catastrophically underestimated the scale of the problem. The plan was simple: intercept the output, inject it into our structure, and go drink coffee. But the deeper we dug into the generated DOM, the worse it got. Doxygen absolutely ignored modern layout practices (instead of clean tags, we were shoveling through piles of tables and inline styles).&lt;/p&gt;

&lt;p&gt;It was too late to retreat. The prototype was needed yesterday, so we had to grit our teeth and finish the script. It gradually became overgrown with dozens of regular expressions, becoming increasingly fragile.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Sidebar and JS Necromancy
&lt;/h2&gt;

&lt;p&gt;The wildest part began at the navigation stage. We have a strict UI rule in the company: absolutely all pages must sit in the left sidebar (so the developer sees the whole picture). Doxygen doesn't agree with this approach. It builds the menu dynamically from deeply nested arrays smeared across several generated JavaScript files.&lt;/p&gt;

&lt;p&gt;AI and I had to physically read these JS files as plain text. We parsed the arrays, extracted the class hierarchy from them, and manually rebuilt the HTML tree of the page. This was starting to feel like digital necromancy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure Twice, Parse Once
&lt;/h2&gt;

&lt;p&gt;The prototype eventually fired up. On the outside, everything looked decent and up to standards. But on the inside, our script was a house of cards held together by duct tape. A minor Doxygen update comes out — and the entire portal falls apart with errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbojj5tpp2y9m9jdsmt5q.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbojj5tpp2y9m9jdsmt5q.jpg" alt="Think First, Then Do" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We wasted a ton of time trying to cut a corner. Instead, we could have calmly designed and implemented a proper architecture. We should have immediately extracted the abstract syntax tree, or at least just parsed the clean XML from Doxygen.&lt;/p&gt;

&lt;p&gt;It became obvious: we needed our own independent engine. We hooked up the AI again so it could quickly throw together a proper parser to read Doxygen's XML. But everything went wrong there too. I'll tell you what happens when you leave an AI unsupervised in the next part.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on our blog: &lt;a href="https://blog.flude.guide/blog/how-not-to-build-docs" rel="noopener noreferrer"&gt;https://blog.flude.guide/blog/how-not-to-build-docs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read us:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://t.me/ude_blog_en" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flude.guide/rss-en.xml" rel="noopener noreferrer"&gt;RSS feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>story</category>
      <category>architecture</category>
    </item>
    <item>
      <title>UDE: From Source Code to Quality Documentation</title>
      <dc:creator>Flude team</dc:creator>
      <pubDate>Mon, 03 Aug 2026 08:37:12 +0000</pubDate>
      <link>https://dev.to/flude_team/ude-from-source-code-to-quality-documentation-12j3</link>
      <guid>https://dev.to/flude_team/ude-from-source-code-to-quality-documentation-12j3</guid>
      <description>&lt;h2&gt;
  
  
  1. The Starting Point: Source Code and Comments
&lt;/h2&gt;

&lt;p&gt;The foundation of any quality API documentation is the comments in the source code. In large projects (C++, for example), they are the single source of truth. Without them, automatic documentation generation simply isn't possible.&lt;/p&gt;

&lt;p&gt;The only question is how to turn those comments into a modern, convenient, fast site for developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. How This Is Solved Today -- and Where the System Breaks
&lt;/h2&gt;

&lt;p&gt;The most popular tool for C++ is &lt;strong&gt;Doxygen&lt;/strong&gt;. However, its native output format (HTML or XML) doesn't fit modern static site generators (SSGs) like Hugo, Docusaurus, or VitePress, which expect Markdown as input.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Doxygen + DoxyBook2 + Hugo Stack
&lt;/h3&gt;

&lt;p&gt;To work around this limitation, intermediate converters are often used: Doxygen generates XML → DoxyBook2 converts the XML to Markdown → Hugo builds the site.&lt;/p&gt;

&lt;p&gt;This works, but it has serious limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No scalability.&lt;/strong&gt; The converter reads the entire XML graph into memory at once. At the scale of an SDK with tens of thousands of classes and methods, this process runs into memory limits and unreasonably long processing times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard to customize.&lt;/strong&gt; Configuring the output for several styling formats at once is a difficult task, since these tools weren't designed for high flexibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. UDE's Solution: A Unified Pipeline
&lt;/h2&gt;

&lt;p&gt;UDE fully rebuilds the process, removing unnecessary conversion stages and optimizing how data is handled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4uo6tt0olx6b015l4hdp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4uo6tt0olx6b015l4hdp.jpg" alt="UDE Pipeline" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UDE's architecture is built on a clear separation of stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Collector&lt;/strong&gt; extracts data directly from the source code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parser&lt;/strong&gt; translates it into a normalized, language-neutral model -- an &lt;strong&gt;IR (Intermediate Representation)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Renderer&lt;/strong&gt; instantly assembles Markdown/HTML in whatever format the target SSG understands, with no intermediate XML crutches.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The advantages of this approach are clear: there's no extra conversion step, and from a single source (the IR) you can render documentation in any format or style you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Speed and Predictability
&lt;/h2&gt;

&lt;p&gt;For large projects, build time is critical. UDE solves this with incremental caching.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp717dgqqlgw7h1f2f6u6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp717dgqqlgw7h1f2f6u6.jpg" alt="Incremental Cache" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead of loading the entire entity graph every time, UDE recomputes only what has &lt;strong&gt;actually changed&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform.&lt;/strong&gt; The pipeline works identically, locally on Windows and in CI on Linux.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs-as-code.&lt;/strong&gt; The configuration of what to document is versioned alongside the code and built in the same CI.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. UDE and Hand-Written Guides (DevGuide)
&lt;/h2&gt;

&lt;p&gt;API reference generated from code answers the question "how are the functions and classes structured." But it can't tell you "in what order to call them to solve a specific business problem." That's what DevGuides are for -- manually written articles and tutorials.&lt;/p&gt;

&lt;p&gt;UDE doesn't try to replace that manual work. Instead, it provides seamless integration: the generated API reference stays complete and always up to date, living naturally alongside hand-written guides on the pages of modern SSGs.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on our blog: &lt;a href="https://ude-blog.pages.dev/blog/ude-source-to-docs" rel="noopener noreferrer"&gt;https://ude-blog.pages.dev/blog/ude-source-to-docs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read us:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://t.me/ude_blog_en" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ude-blog.pages.dev/rss-en.xml" rel="noopener noreferrer"&gt;RSS feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
    </item>
  </channel>
</rss>
