<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://www.yellowduck.be/pretty-atom-feed-v3.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <link href="https://www.yellowduck.be" rel="alternate"/>
  <link href="https://www.yellowduck.be/posts/feed" rel="self"/>
  <author>
    <name>Pieter Claerhout</name>
    <email>pieter@yellowduck.be</email>
  </author>
  <id>https://www.yellowduck.be/posts/feed</id>
  <title>🐥 YellowDuck.be</title>
  <updated>2026-09-14T13:00:00Z</updated>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/waterfall-was-never-the-problem" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Spec-Driven Development is often dismissed as merely another form of waterfall. However, Simon Martinelli argues that misconceptions about the waterfall model stem from a lack of understanding of Winston Royce&apos;s original intentions. Royce didn’t advocate for the strict form people criticize; he pointed out the risks and proposed feedback loops for improvement. In practice, plan-driven models like waterfall work well in stable environments where changes are costly. The real issue lies with the handoff between teams, leading to delays and increased costs. With the advent of AI in Spec-Driven Development, the process has transformed. Specifications can be executable, reducing the time from concept to code to mere minutes, effectively lowering costs and challenges associated with late changes. Martinelli emphasizes that adopting these modern tools aligns with Royce&apos;s early vision, which many have overlooked.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://martinelli.ch/waterfall-was-never-the-problem/&quot;&gt;Continue reading on &lt;strong&gt;martinelli.ch&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-14T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/waterfall-was-never-the-problem</id>
    <title>🔗 Waterfall was never the problem</title>
    <updated>2026-09-14T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/the-cost-of-saying-yes-has-changed" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;The landscape of open source mentorship is shifting as AI brings new challenges. The article highlights how the increasing volume of contributions makes it harder to identify mentorship signals. It presents the 3 Cs framework which guide maintainers in mentoring more strategically, thereby preventing burnout. Additionally, it discusses developments in orchestrating AI agents within GitHub repositories, emphasizing collaborative and inspectable workflows. The focus is on empowering software engineers to leverage GitHub Copilot effectively, enhancing their coding practices and managing contributions more efficiently. With insights from experienced contributors, the article offers valuable strategies for navigating the evolving ecosystem created by AI in software development.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://github.blog/engineering/the-cost-of-saying-yes-has-changed/&quot;&gt;Continue reading on &lt;strong&gt;github.blog&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/github&quot;&gt;#github&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-14T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/the-cost-of-saying-yes-has-changed</id>
    <title>🔗 The cost of saying yes has changed</title>
    <updated>2026-09-14T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/why-go-is-an-ideal-language-for-ai-assisted-software-engineering" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;AI coding assistants are reshaping software engineering, but humans still need to review and verify generated code. Go, a language designed for collaboration, stands out as an ideal platform for this shift. Originally crafted for software engineering, not just programming, Go emphasizes maintainability and readability, catering perfectly to both human developers and AI.&lt;/p&gt;
&lt;p&gt;With built-in tools like &lt;code&gt;gofmt&lt;/code&gt; for code formatting and a strong static type system, Go helps streamline the coding process. Its structured approach and standard library reduce complexity, ensuring both developers and AI can work more efficiently. As AI takes on more coding tasks, Go’s commitment to simplicity and reliability becomes crucial. It promotes not only the production of code but also its long-term maintainability, making it a trusted choice for the future of software development.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://developers.googleblog.com/why-go-is-an-ideal-language-for-ai-assisted-software-engineering/&quot;&gt;Continue reading on &lt;strong&gt;developers.googleblog.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/golang&quot;&gt;#golang&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-13T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/why-go-is-an-ideal-language-for-ai-assisted-software-engineering</id>
    <title>🔗 Why Go is an ideal language for AI-assisted software engineering</title>
    <updated>2026-09-13T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/the-appwrite-cli-is-now-written-in-go" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;The Appwrite CLI&apos;s transition from TypeScript to Go is a game changer. It boasts a staggering 17-fold speed increase, with startup times plummeting from 207.6 ms to just 11.1 ms. Installation footprints shrink dramatically, bringing package dependencies down from 330 to just 2, which results in major reductions in memory usage from 283.5 MB to 28 MB during operations. The new CLI, now a single 14 MB binary, retains all user-facing flags, exit codes, and command outputs, ensuring existing workflows remain intact. This rewrite is backed by meticulous measurements and a solid reasoning process, focusing specifically on improving user experience without compromising essential features. The article provides insights into the systematic approach taken in the rewrite, including testing phases and a commitment to preserving interface consistency.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://appwrite.io/blog/post/rewriting-the-appwrite-cli-in-go?via=dailydev&quot;&gt;Continue reading on &lt;strong&gt;appwrite.io&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/golang&quot;&gt;#golang&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/tools&quot;&gt;#tools&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/devops&quot;&gt;#devops&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/announcement&quot;&gt;#announcement&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-13T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/the-appwrite-cli-is-now-written-in-go</id>
    <title>🔗 The Appwrite CLI is now written in Go</title>
    <updated>2026-09-13T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/dialog-api-vs-popover-api-which-one-should-you-actually-use" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;The choice between the Dialog API and Popover API is crucial for creating effective overlays in web applications. While both can display content above the page, they serve different functions that impact user interaction. The Dialog API is best used when a user&apos;s complete attention is required, such as in confirmation dialogs or login modals. In contrast, the Popover API is designed for non-disruptive overlays like tooltips or menus, allowing users to continue engaging with the page. Understanding the distinctions, accessibility implications, and interaction styles helps developers select the right API, ultimately leading to more user-friendly applications.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.syncfusion.com/blogs/post/dialog-api-vs-popover-api&quot;&gt;Continue reading on &lt;strong&gt;www.syncfusion.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/frontend&quot;&gt;#frontend&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/html&quot;&gt;#html&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-13T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/dialog-api-vs-popover-api-which-one-should-you-actually-use</id>
    <title>🔗 Dialog API vs Popover API: Which one should you actually use?</title>
    <updated>2026-09-13T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/undoing-a-pushed-merge-commit-without-losing-work" rel="alternate"/>
    <content type="html">&lt;p&gt;Sometimes you push a merge commit you didn&apos;t mean to, and notice it only after the fact. Here&apos;s how we handled it cleanly when that happened on a feature branch.&lt;/p&gt;
&lt;p&gt;My branch history looked like this:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;abc1234  Fix for the feature we were working on  ← latest commit, must keep
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;def5678  Merge branch &amp;#39;feature/my-branch&amp;#39; of ...  ← mistake
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;ghi9012  Previous commit
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;4&quot;&gt;jkl3456  Older commit
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The merge commit &lt;code&gt;def5678&lt;/code&gt; was already pushed to GitHub. The latest fix (&lt;code&gt;abc1234&lt;/code&gt;) sat on top of it, so a plain &lt;code&gt;git reset --hard HEAD~1&lt;/code&gt; would have taken the fix with it.&lt;/p&gt;
&lt;p&gt;I needed to drop exactly one commit from the middle of the history while keeping everything above it. &lt;code&gt;git rebase --onto&lt;/code&gt; is the right tool for this:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-bash&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;l-function-call&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;rebase&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;--onto&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;ghi9012&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;def5678&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;HEAD&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This tells Git: take all commits after &lt;code&gt;def5678&lt;/code&gt; up to &lt;code&gt;HEAD&lt;/code&gt;, and replay them directly onto &lt;code&gt;ghi9012&lt;/code&gt; — the commit before the bad merge. The merge commit is skipped entirely.&lt;/p&gt;
&lt;p&gt;The rebase left us in a detached HEAD state, so we updated the branch pointer and switched back:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-bash&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;l-function-call&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;branch&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;feature/my-branch&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;HEAD&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;&lt;span class=&quot;l-function-call&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;checkout&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;feature/my-branch&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The history was now clean:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;xyz7890  Fix for the feature we were working on
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;ghi9012  Previous commit
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;jkl3456  Older commit
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then a force-push to update the remote:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-bash&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;l-function-call&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;push&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;--force&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why not &lt;code&gt;git revert&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git revert -m 1 &lt;hash&gt;&lt;/code&gt; is the safer choice when multiple people have already pulled the branch, because it adds a new commit rather than rewriting history. In our case the branch was a personal feature branch with no other active collaborators, so rewriting was fine and kept the history cleaner.&lt;/p&gt;
&lt;p&gt;When in doubt on a shared branch, revert. On a solo feature branch, rebase is cleaner.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/terminal&quot;&gt;#terminal&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/git&quot;&gt;#git&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-12T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/undoing-a-pushed-merge-commit-without-losing-work</id>
    <title>🐥 Undoing a pushed merge commit without losing work</title>
    <updated>2026-09-12T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/why-we-dont-use-ai-rene-herse-cycles" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;A nice post from Rene Herse Cycles on why AI is not the answer to everything.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.renehersecycles.com/why-we-dont-use-ai/&quot;&gt;Continue reading on &lt;strong&gt;www.renehersecycles.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-12T15:00:00Z</published>
    <id>https://www.yellowduck.be/posts/why-we-dont-use-ai-rene-herse-cycles</id>
    <title>🔗 Why We Don’t Use AI @ Rene Herse Cycles</title>
    <updated>2026-09-12T15:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/linux-nameservers-and-dns-resolution" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;DNS resolution on Linux can lead to frustrating errors like “Temporary failure in resolving” when issues arise. This guide, written by Hayden James, explains how DNS resolution works on Linux systems, covering configuration for desktops, servers, and VPS setups. The article details the management of DNS settings via &lt;code&gt;/etc/nsswitch.conf&lt;/code&gt; and &lt;code&gt;/etc/resolv.conf&lt;/code&gt;, as well as the role of &lt;code&gt;systemd-resolved&lt;/code&gt; in modern distributions. Key tools such as &lt;code&gt;dig&lt;/code&gt;, &lt;code&gt;resolvectl&lt;/code&gt;, and &lt;code&gt;getent&lt;/code&gt; are discussed for diagnosing and troubleshooting DNS problems. Readers will learn how to configure DNS servers, flush caches, and resolve common DNS issues. Understanding these concepts is crucial for maintaining reliable network connectivity on Linux systems.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://linuxblog.io/linux-nameservers-dns-resolution/&quot;&gt;Continue reading on &lt;strong&gt;linuxblog.io&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/tools&quot;&gt;#tools&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/devops&quot;&gt;#devops&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/terminal&quot;&gt;#terminal&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/linux&quot;&gt;#linux&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/sysadmin&quot;&gt;#sysadmin&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-12T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/linux-nameservers-and-dns-resolution</id>
    <title>🔗 Linux nameservers and DNS resolution</title>
    <updated>2026-09-12T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/laravel-doctor-diagnose-your-app-with-one-artisan-command" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Laravel Doctor was announced at Laracon US 2026 in Boston, introducing an &lt;code&gt;artisan doctor&lt;/code&gt; command that performs health checks on Laravel applications. This command ensures essential configurations are correct, such as verifying the presence of the &lt;code&gt;.env&lt;/code&gt; file, checking the &lt;code&gt;APP_KEY&lt;/code&gt;, confirming PHP version compatibility, and making sure required extensions are installed. If issues are found, Doctor can automatically fix them where possible or clearly state what needs attention.&lt;/p&gt;
&lt;p&gt;Each diagnostic is grouped into classes handling specific checks—covering environment, Composer dependencies, configuration, database connectivity, and more. The command can be extended by packages that want to add custom diagnostics, making it a versatile tool for maintaining application health. With the ability to provide machine-readable reports, Laravel Doctor is designed not only for developers but also for CI environments and AI coding agents, ensuring robust application maintenance across various setups.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://laravel-news.com/laravel-doctor-first-party-diagnostics-for-your-application&quot;&gt;Continue reading on &lt;strong&gt;laravel-news.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/laravel&quot;&gt;#laravel&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/tools&quot;&gt;#tools&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-12T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/laravel-doctor-diagnose-your-app-with-one-artisan-command</id>
    <title>🔗 Laravel Doctor: Diagnose your app with one artisan command</title>
    <updated>2026-09-12T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/clickhouse-adapter-elixir" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Building an Ecto adapter for ClickHouse involved overcoming the limits of Postgres when handling aggregate data. The article describes how integrating ClickHouse&apos;s columnar storage improves query performance while preserving Ecto&apos;s familiar syntax and functions. The author shares insights on the development process, including utilizing a dependency-aware issue tracker called &lt;code&gt;beads&lt;/code&gt; and employing a language model for incremental task breakdowns. An important aspect of the project was establishing a native TCP driver to facilitate efficient communication. Key challenges included debugging a complex handshake protocol and implementing a custom compression method. Ultimately, the project produced a functional &lt;code&gt;clickhouse_adapter_ecto&lt;/code&gt;, enabling support for ClickHouse features while adapting them to Ecto&apos;s structure, proving the value of careful planning and incremental testing in software development.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://mfeckie.dev/blog/clickhouse-adapter-elixir&quot;&gt;Continue reading on &lt;strong&gt;mfeckie.dev&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/database&quot;&gt;#database&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/elixir&quot;&gt;#elixir&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-11T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/clickhouse-adapter-elixir</id>
    <title>🔗 ClickHouse adapter Elixir</title>
    <updated>2026-09-11T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/anti-antipatterns-in-elixir-library-guidelines" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;The Elixir Library Guidelines preach strict rules, but what if they&apos;re overlooking practical software engineering needs? This article dives into the nine declared &quot;anti-patterns&quot; from these guidelines, arguing why they aren&apos;t just permissible but essential in many scenarios. From the erroneous avoidance of application configuration to the drawbacks of strictly using tuples for control flow, the discussion reveals real-world use cases where breaking these prescribed rules can lead to better software design. The guidelines may be a helpful starting point, but understanding when and why to deviate from them empowers developers to make informed decisions tailored to their project&apos;s unique challenges. This piece invites readers to reconsider the rigidity of these guidelines, emphasizing the importance of context-driven development.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://rocket-science.ru/hacking/2026/08/09/anti-antipatterns-in-elixir-libraries&quot;&gt;Continue reading on &lt;strong&gt;rocket-science.ru&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/pattern&quot;&gt;#pattern&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/elixir&quot;&gt;#elixir&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-11T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/anti-antipatterns-in-elixir-library-guidelines</id>
    <title>🔗 Anti-antipatterns in Elixir library guidelines</title>
    <updated>2026-09-11T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/phoenix-version-adoption-security" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;The Phoenix ecosystem sees rapid patch adoption but slow migration between minor versions. Data shows that patch releases within the same minor version gain traction within two weeks, while the transition to a new minor version often takes seven to eight months to surpass a 50% adoption rate. This pattern highlights a connection between the minor series in use and the responsiveness to security releases.&lt;/p&gt;
&lt;p&gt;Currently, four minor versions of Phoenix receive official support. Adoption data indicates that teams using older versions experience delays in applying patches due to inertia. This not only elevates the risk of unpatched vulnerabilities but complicates upgrades as dependencies grow. When crucial security patches roll out, older versions lag in responsiveness, posing a significant security risk, especially when vulnerabilities require no authentication, rendering unpatched systems vulnerable to attacks. Staying current with Phoenix and LiveView releases is essential to maintaining application security and operational efficiency.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.praialabs.com/phoenix-version-adoption&quot;&gt;Continue reading on &lt;strong&gt;www.praialabs.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/phoenix&quot;&gt;#phoenix&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/devops&quot;&gt;#devops&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-11T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/phoenix-version-adoption-security</id>
    <title>🔗 Phoenix version adoption &amp; security</title>
    <updated>2026-09-11T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/genstage-demand-visualized" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Can visualizing demand in GenStage optimize your Elixir applications? Andrea Leopardi demonstrates how to craft informative visualizations that clarify backpressure in stream processing. By employing tools like &lt;code&gt;:observer&lt;/code&gt; and custom metrics, the article emphasizes the importance of understanding how demand fluctuates in real-time. Leopardi shares practical examples that help developers grasp how to balance producer and consumer relationships in GenStage for more resilient applications. He advocates for clear metrics and visual aids that can significantly enhance how systems operate, especially as complexity increases with more extensive data streams. Overall, it&apos;s a focused look at leveraging Elixir&apos;s capabilities to improve application performance through visual insights.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://out.reddit.com/t3_1vhxagp?app_name=ios&amp;token=AQAA0092avhip6BbqTwiqSMrplW2w8k1NqYRbiGqDdGqlMP12sli&amp;url=https%3A%2F%2Fandrealeopardi.com%2Fposts%2Fgenstage-demand-visualized%2F&quot;&gt;Continue reading on &lt;strong&gt;out.reddit.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/tools&quot;&gt;#tools&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/elixir&quot;&gt;#elixir&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-10T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/genstage-demand-visualized</id>
    <title>🔗 GenStage demand visualized</title>
    <updated>2026-09-10T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/github-actions-is-having-one-of-the-worst-days-in-its-history" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;GitHub Actions experienced a major outage on August 6, 2026, that lasted over seven hours, making it the second-longest outage in the service&apos;s history. The incident significantly impacted the ability to execute workflows, with GitHub processing only about 15% of webhook triggers at its peak. Many jobs failed to execute, and although there was an improvement later on, the overall performance remained poor. The outage contrasted sharply with GitHub&apos;s rapid growth in service demand, as reflected in past metrics that showed an increase from 500 million minutes a week in 2023 to over 2.1 billion minutes this spring. While GitHub has not yet disclosed the exact cause of this latest outage, it highlights the challenges that come with scaling services to meet increasing user demand.&lt;/p&gt;
&lt;p&gt;The final tally for this incident marked 7 hours and 26 minutes of total downtime, just shy of the record for the longest major outage set in May 2021. While there may be no immediate lessons learned, the community was left collectively waiting for updates as the situation unfolded.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://kernel.pryanic.com/posts/github-actions-is-having-one-of-the-worst-days-in-its-history&quot;&gt;Continue reading on &lt;strong&gt;kernel.pryanic.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/devops&quot;&gt;#devops&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/github&quot;&gt;#github&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/announcement&quot;&gt;#announcement&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-10T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/github-actions-is-having-one-of-the-worst-days-in-its-history</id>
    <title>🔗 GitHub Actions is having one of the worst days in its history</title>
    <updated>2026-09-10T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/the-distinct-in-your-count" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;The query &lt;code&gt;SELECT count(DISTINCT user_id) FROM events;&lt;/code&gt; might seem efficient, but it can lead to performance pitfalls. The keyword &lt;code&gt;DISTINCT&lt;/code&gt; disables parallel query execution in PostgreSQL, forcing the database to process all data serially. This occurs because the aggregate &lt;code&gt;COUNT(DISTINCT ...)&lt;/code&gt; requires a unique count, which cannot use parallel processing effectively due to the need for a specific order. Without parallel execution, queries on large tables become inefficient, often resulting in costly disk usage and longer processing times. The article offers a solution: rewriting the query to use a &lt;code&gt;GROUP BY&lt;/code&gt; clause instead. This approach allows for parallel processing, significantly improving query execution time with larger datasets while still achieving the desired unique count result.  This insight is crucial for developers optimizing analytics queries for better performance.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://boringsql.com/posts/distinct-in-your-count/&quot;&gt;Continue reading on &lt;strong&gt;boringsql.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/database&quot;&gt;#database&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/postgresql&quot;&gt;#postgresql&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/sql&quot;&gt;#sql&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-10T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/the-distinct-in-your-count</id>
    <title>🔗 The DISTINCT in your COUNT</title>
    <updated>2026-09-10T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/what-are-code-reviews-even-for" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;AI didn’t break code review; it highlighted existing issues. Brian Houck discusses how the surge of AI in code production has outpaced human review. At Meta, lines of code per diff increased by 106%, with diffs up 51% due to AI, while the timeliness of reviews has declined. Developers idealize spending only 7% of their time reviewing code, indicating we must rethink the purpose of code review itself. It&apos;s traditionally about more than just defect detection; it&apos;s a space for knowledge transfer and architectural understanding. Rethinking habits around code reviews before AI can be effective is crucial. Using AI wisely can enhance the process, but organizations risk eroded collective understanding by automating too much. Effective code review is about preserving knowledge and fostering collaboration, not just speeding up the process.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://newsletter.getdx.com/p/what-are-code-reviews-even-for&quot;&gt;Continue reading on &lt;strong&gt;newsletter.getdx.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-09T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/what-are-code-reviews-even-for</id>
    <title>🔗 What are code reviews even for?</title>
    <updated>2026-09-09T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/your-count-distinct-is-too-slow-approximations-and-sampling-in-postgresql" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Can you afford to wait for precise distinct counts in Postgres? Elizabeth Garrett Christensen reveals that exact counts can be prohibitively slow, especially with large datasets. She outlines various strategies for approximating unique counts using features like the built-in &lt;code&gt;TABLESAMPLE&lt;/code&gt; for random sampling, the HyperLogLog (HLL) for efficient distinct counting, and introduces Apache DataSketches for more complex scenarios. The article offers practical examples, including how to set up a sample &lt;code&gt;page_views&lt;/code&gt; table with 10 million rows, and examines the benchmarks of different methods to highlight performance differences. You&apos;ll learn how accurate data analysis can still be quick and accessible without sacrificing too much precision.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.snowflake.com/en/blog/engineering/postgres-count-distinct-approximation/&quot;&gt;Continue reading on &lt;strong&gt;www.snowflake.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/database&quot;&gt;#database&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/postgresql&quot;&gt;#postgresql&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-09T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/your-count-distinct-is-too-slow-approximations-and-sampling-in-postgresql</id>
    <title>🔗 Your COUNT(DISTINCT) is too slow: Approximations and sampling in PostgreSQL</title>
    <updated>2026-09-09T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/hybrid-search-patterns-with-postgresql-and-pgvector" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Most production vector queries aren&apos;t just about finding similar documents; they often involve specific criteria. The article explains hybrid search patterns, combining similarity ranking with scalar filters in PostgreSQL by utilizing &lt;code&gt;pgvector&lt;/code&gt; and hybrid Nearest Neighbor searches. The author showcases how to effectively integrate &lt;code&gt;WHERE&lt;/code&gt; clauses into vector queries, which can often lead to trade-offs between recall and performance. Techniques such as iterative index scans are discussed to refine these searches. The article thoroughly analyzes various querying strategies, including oversampling and caching responses to improve query efficiency. It offers practical insights on building indexes and optimizing performance for complex applications that require both speed and accuracy, making it an essential read for database administrators and developers working with vector data in PostgreSQL.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.crunchydata.com/blog/hybrid-vector-search&quot;&gt;Continue reading on &lt;strong&gt;www.crunchydata.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/database&quot;&gt;#database&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/postgresql&quot;&gt;#postgresql&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-09T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/hybrid-search-patterns-with-postgresql-and-pgvector</id>
    <title>🔗 Hybrid search patterns with PostgreSQL and pgvector</title>
    <updated>2026-09-09T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/image-dominant-color-and-heic-support-in-laravel-13-24" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Laravel 13.24 brings major improvements to its image API, including dominant color detection and support for HEIC files. With the new &lt;code&gt;dominantColor()&lt;/code&gt; method, developers can now easily retrieve the average color of an image, making it ideal for UI enhancements while loading images. This version also introduces the &lt;code&gt;modelKeys()&lt;/code&gt; method to Eloquent queries, streamlining primary key retrieval, along with a new &lt;code&gt;array_keys&lt;/code&gt; validation rule that reports unexpected keys directly. Importantly, it adds support for AVIF and HEIC image formats as both input and output, enhancing compatibility for images straight from devices like iPhones. Other fixes include performance improvements for wildcard validations on large arrays, among various other enhancements to the Laravel framework. This update reflects Laravel&apos;s ongoing commitment to improving developer experience and application performance.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://laravel-news.com/laravel-13-24-0&quot;&gt;Continue reading on &lt;strong&gt;laravel-news.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/laravel&quot;&gt;#laravel&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/eloquent&quot;&gt;#eloquent&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-08T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/image-dominant-color-and-heic-support-in-laravel-13-24</id>
    <title>🔗 Image dominant color and HEIC support in Laravel 13.24</title>
    <updated>2026-09-08T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/limited-output-is-a-feature" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;As startups increasingly leverage LLM agents for software tasks, a critical question arises: are they losing sight of meaningful product development? Johanna Larsson argues that many are racing to optimize for &quot;AI-enablement&quot; rather than focusing on user value. She highlights successful companies like Linear, which thrived by prioritizing core user experiences over excessive features. Instead of getting caught up in continuous output and feature requests, Larsson encourages a return to thoughtful product creation. Businesses should spend more time contemplating what truly matters—cutting out unnecessary complexity to reveal the essence of their products. This slower, more intentional approach not only enhances user satisfaction but also fosters innovation, advocating for fewer features that deliver greater value.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://jola.dev/posts/limited-output-is-a-feature&quot;&gt;Continue reading on &lt;strong&gt;jola.dev&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-08T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/limited-output-is-a-feature</id>
    <title>🔗 Limited output is a feature.</title>
    <updated>2026-09-08T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/whats-new-in-php-8-6" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;PHP 8.6, set to release on November 19, 2026, introduces several important features including partial function application (PFA) and a new polling API. PFA lets developers create references to closures with some parameters pre-defined, streamlining code when combined with the pipe operator. The new polling API improves the handling of asynchronous processes, although it doesn&apos;t bring built-in async capabilities.&lt;/p&gt;
&lt;p&gt;Another significant change is the allowance of default values for readonly properties, following the introduction of property hooks in PHP 8.4, and the addition of new functions and classes for enhanced functionality such as &lt;code&gt;Duration&lt;/code&gt; and &lt;code&gt;clamp()&lt;/code&gt;. Moreover, the security for session defaults is tightened with stricter ini settings, improving overall security for applications. These updates reflect an aim for better usability and performance in PHP development.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://stitcher.io/blog/new-in-php-86&quot;&gt;Continue reading on &lt;strong&gt;stitcher.io&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/php&quot;&gt;#php&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-08T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/whats-new-in-php-8-6</id>
    <title>🔗 What&apos;s new in PHP 8.6</title>
    <updated>2026-09-08T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/laravel-boost-best-practices-a-major-tone-shift-august-2026" rel="alternate"/>
    <content type="html">&lt;p&gt;Two commits landed in the &lt;a href=&quot;https://github.com/laravel/boost&quot;&gt;Laravel Boost&lt;/a&gt; repository on August 26, 2026 that significantly update the AI guidance rules baked into the package. The changes touch all 19 best-practice rule files and add a new section on controller resource design. Here is what changed and why it matters.&lt;/p&gt;
&lt;h1&gt;The big picture: from prescriptive to contextual&lt;/h1&gt;
&lt;p&gt;The first commit (&lt;a href=&quot;https://github.com/laravel/boost/commit/d165b9ea6086294a8f1999ac3dcf4e61da267b23&quot;&gt;&lt;code&gt;d165b9ea&lt;/code&gt;&lt;/a&gt;) touches 1,427 lines across every rule file. The headline change is not a new feature — it is a &lt;strong&gt;deliberate softening of absolute language&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Rules that previously said &lt;strong&gt;&quot;Incorrect&quot; / &quot;Correct&quot;&lt;/strong&gt; now use labels like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&quot;Manual lookup:&quot;&lt;/em&gt; / &lt;em&gt;&quot;Use route model binding:&quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&quot;Hidden dependency:&quot;&lt;/em&gt; / &lt;em&gt;&quot;Injected dependency:&quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&quot;Unsafe:&quot;&lt;/em&gt; / &lt;em&gt;&quot;Preferred:&quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&quot;Queued and durable:&quot;&lt;/em&gt; / &lt;em&gt;&quot;Deferred in the current process:&quot;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The intent is clear: the guidance now presents &lt;strong&gt;trade-offs and context&lt;/strong&gt; instead of moral verdicts. This matters because AI coding agents (and developers) following these rules were previously being trained to treat &quot;Incorrect&quot; examples as always wrong, even in situations where the pattern was actually fine.&lt;/p&gt;
&lt;h1&gt;Key Changes by Area&lt;/h1&gt;
&lt;h2&gt;Queries — &lt;code&gt;advanced-queries.md&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The old guidance said &lt;code&gt;whereHas()&lt;/code&gt; was flat-out wrong because it &quot;re-executes per row.&quot; The new version is more honest:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;whereHas()&lt;/code&gt; typically produces an &lt;code&gt;EXISTS&lt;/code&gt; subquery, while &lt;code&gt;whereIn()&lt;/code&gt; can express the same filter with an &lt;code&gt;IN&lt;/code&gt; subquery. Either form may be faster depending on the database engine, indexes, cardinality, and query plan. &lt;strong&gt;Measure both forms with representative data.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The section title changed from &lt;em&gt;&quot;Prefer &lt;code&gt;whereIn&lt;/code&gt; + Subquery Over &lt;code&gt;whereHas&lt;/code&gt;&quot;&lt;/em&gt; to &lt;em&gt;&quot;Compare &lt;code&gt;whereHas()&lt;/code&gt; with an &lt;code&gt;IN&lt;/code&gt; Subquery&quot;&lt;/em&gt;. Similarly, the compound index rule now says &lt;em&gt;&quot;verify the query plan&quot;&lt;/em&gt; rather than asserting a single correct approach.&lt;/p&gt;
&lt;p&gt;A technical fix also snuck in: the dynamic relationship example now correctly passes the foreign key to &lt;code&gt;belongsTo()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;&lt;span class=&quot;l-comment&quot;&gt;// Before (broken — missing the FK argument):&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;4&quot;&gt;&lt;span class=&quot;l-keyword-return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;l-variable-builtin&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;belongsTo&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-type&quot;&gt;Login&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;l-constant&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;6&quot;&gt;&lt;span class=&quot;l-comment&quot;&gt;// After (correct):&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;7&quot;&gt;&lt;span class=&quot;l-keyword-return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;l-variable-builtin&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;belongsTo&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-type&quot;&gt;Login&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;l-constant&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;l-string&quot;&gt;&amp;#39;last_login_id&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Architecture — &lt;code&gt;architecture.md&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Two notable shifts:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dependency injection&lt;/strong&gt;: The old rule said constructor injection was always correct and method injection was a code smell. The new rule aligns with how Laravel actually works:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Prefer constructor injection for dependencies required throughout an object&apos;s lifetime. &lt;strong&gt;Method injection is appropriate for dependencies needed by one controller action, listener, job handler, or other container-invoked method.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Default sort order&lt;/strong&gt;: Instead of &quot;always use &lt;code&gt;latest()&lt;/code&gt;&quot;, the guidance now recommends a stable two-column sort with a tie-breaker for reliable pagination:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;&lt;span class=&quot;l-type&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;l-function-call&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;4&quot;&gt;    &lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;orderByDesc&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-string&quot;&gt;&amp;#39;created_at&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;5&quot;&gt;    &lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;orderByDesc&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-string&quot;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;6&quot;&gt;    &lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;paginate&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Caching — &lt;code&gt;caching.md&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;Cache::remember()&lt;/code&gt; section now explicitly warns about the false-cache-miss bug:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The manual version below incorrectly treats valid falsy values, such as &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt;, as cache misses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It also adds an honest caveat: &lt;code&gt;Cache::remember()&lt;/code&gt; does not prevent concurrent requests from computing the same missing value — you still need &lt;code&gt;Cache::lock()&lt;/code&gt; for that.&lt;/p&gt;
&lt;h2&gt;Routing — &lt;code&gt;routing.md&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The &quot;Keep Controllers Thin&quot; rule (with its arbitrary &quot;under 10 lines&quot; target) is gone. In its place:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Controllers should coordinate HTTP input, authorization, validation, an application operation, and the response. &lt;strong&gt;Extract substantial or reusable business logic, but do not introduce an action or service merely to satisfy an arbitrary line limit.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Migrations — &lt;code&gt;migrations.md&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The file shrank significantly (78 → 24 deletions vs. 24 additions). Several overly prescriptive examples were removed. The foreign-key section now includes a practical note:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do not add a duplicate single-column index without checking the database driver&apos;s treatment of foreign-key indexes and the indexes already created by the migration.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Security — &lt;code&gt;security.md&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Two nuanced additions stand out:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;$guarded = []&lt;/code&gt; is no longer labeled universally &quot;Incorrect.&quot; The new text acknowledges that mass-assignment protection controls &lt;em&gt;which attributes can be set&lt;/em&gt;, not values or authorization — and that deliberate conventions using &lt;code&gt;$guarded&lt;/code&gt; are valid.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The SQL injection example now uses the fluent string helper properly:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;&lt;span class=&quot;l-type&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;l-function-call&quot;&gt;whereRaw&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-string&quot;&gt;&amp;#39;LOWER(name) = ?&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;l-punctuation-bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;l-variable&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-string&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;A new explicit note: &lt;em&gt;&quot;Public actions intentionally available to everyone do not need a redundant authorization check.&quot;&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Queues — &lt;code&gt;queue-jobs.md&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The Amazon SQS footnote is new and important:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Amazon Simple Queue Service uses its &lt;strong&gt;visibility timeout&lt;/strong&gt; instead of Laravel&apos;s &lt;code&gt;retry_after&lt;/code&gt;; configure that timeout at the queue level.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;code&gt;ShouldBeUnique&lt;/code&gt; section now notes that all dispatching processes must share a cache store that supports locks — a silent gotcha that has burned teams before.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;New section: organize controllers around resources&lt;/h1&gt;
&lt;p&gt;The second commit (&lt;a href=&quot;https://github.com/laravel/boost/commit/d165b9ea6086294a8f1999ac3dcf4e61da267b23&quot;&gt;&lt;code&gt;b19e98a8&lt;/code&gt;&lt;/a&gt;) adds a standalone section to &lt;code&gt;routing.md&lt;/code&gt; covering a pattern that often gets debated on Laravel teams.&lt;/p&gt;
&lt;p&gt;The guidance establishes a clear default: organize controllers around one resource using standard resource actions (&lt;code&gt;index&lt;/code&gt;, &lt;code&gt;show&lt;/code&gt;, &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;store&lt;/code&gt;, &lt;code&gt;edit&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;destroy&lt;/code&gt;). When a custom verb like &lt;code&gt;publish&lt;/code&gt;, &lt;code&gt;approve&lt;/code&gt;, or &lt;code&gt;archive&lt;/code&gt; appears, treat it as a &lt;strong&gt;design signal&lt;/strong&gt; — it might represent a separate resource.&lt;/p&gt;
&lt;p&gt;The canonical example models podcast publishing as a dedicated controller:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;&lt;span class=&quot;l-comment&quot;&gt;// Route&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;4&quot;&gt;&lt;span class=&quot;l-type&quot;&gt;Route&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;l-function-call&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-string&quot;&gt;&amp;#39;/published-podcasts/{podcast}&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;l-punctuation-bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;l-type&quot;&gt;PublishedPodcastController&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;l-constant&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;l-string&quot;&gt;&amp;#39;store&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;5&quot;&gt;    &lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-string&quot;&gt;&amp;#39;published-podcasts.store&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;6&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;7&quot;&gt;&lt;span class=&quot;l-type&quot;&gt;Route&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;l-function-call&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-string&quot;&gt;&amp;#39;/published-podcasts/{podcast}&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;l-punctuation-bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;l-type&quot;&gt;PublishedPodcastController&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;l-constant&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;l-string&quot;&gt;&amp;#39;destroy&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;8&quot;&gt;    &lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-string&quot;&gt;&amp;#39;published-podcasts.destroy&amp;#39;&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;9&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;10&quot;&gt;&lt;span class=&quot;l-comment&quot;&gt;// Controller&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;11&quot;&gt;&lt;span class=&quot;l-keyword-type&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;l-type&quot;&gt;PublishedPodcastController&lt;/span&gt; &lt;span class=&quot;l-keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;l-type&quot;&gt;Controller&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;12&quot;&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;13&quot;&gt;    &lt;span class=&quot;l-keyword-modifier&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;l-keyword-function&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;l-function-method&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-type&quot;&gt;Podcast&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;$podcast&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-type&quot;&gt;RedirectResponse&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;14&quot;&gt;    &lt;span class=&quot;l-punctuation-bracket&quot;&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;15&quot;&gt;        &lt;span class=&quot;l-variable&quot;&gt;$podcast&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;16&quot;&gt;        &lt;span class=&quot;l-keyword-return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;l-function-call&quot;&gt;back&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;17&quot;&gt;    &lt;span class=&quot;l-punctuation-bracket&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;18&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;19&quot;&gt;    &lt;span class=&quot;l-keyword-modifier&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;l-keyword-function&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;l-function-method&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-type&quot;&gt;Podcast&lt;/span&gt; &lt;span class=&quot;l-variable-parameter&quot;&gt;$podcast&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-type&quot;&gt;RedirectResponse&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;20&quot;&gt;    &lt;span class=&quot;l-punctuation-bracket&quot;&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;21&quot;&gt;        &lt;span class=&quot;l-variable&quot;&gt;$podcast&lt;/span&gt;&lt;span class=&quot;l-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;l-function-method-call&quot;&gt;unpublish&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;22&quot;&gt;        &lt;span class=&quot;l-keyword-return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;l-function-call&quot;&gt;back&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;l-punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;23&quot;&gt;    &lt;span class=&quot;l-punctuation-bracket&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;24&quot;&gt;&lt;span class=&quot;l-punctuation-bracket&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The guidance ends with an important escape hatch:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Treat a custom verb as a &lt;strong&gt;design signal, not proof&lt;/strong&gt; that another controller is required. Use query parameters for simple filtering, and keep an explicit action route when modeling the operation as a resource would obscure the domain or conflict with established project conventions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Why this matters for AI-assisted development&lt;/h2&gt;
&lt;p&gt;Laravel Boost feeds these rules directly to AI coding agents as context when generating code. Overly prescriptive &quot;always/never&quot; rules cause agents to reject valid patterns and to add unnecessary abstractions (action classes for trivial logic, for example). The new tone should lead to more pragmatic, context-aware suggestions — and fewer unnecessary &quot;Incorrect&quot; rewrites of perfectly reasonable code.&lt;/p&gt;
&lt;p&gt;The shift also signals a broader direction: good AI guidance reads like a &lt;strong&gt;senior developer explaining trade-offs&lt;/strong&gt;, not a linter listing violations.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/laravel&quot;&gt;#laravel&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-07T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/laravel-boost-best-practices-a-major-tone-shift-august-2026</id>
    <title>🐥 Laravel boost best practices: A major tone shift (August 2026)</title>
    <updated>2026-09-07T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/native-apps-should-be-avoided-whenever-possible" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;What if your smartphone is tracking you more than you think? A detailed article warns against using native apps, revealing their penchant for collecting vast amounts of data, often without users&apos; knowledge. It highlights the case of the recently launched White House app, which claimed zero data collection but was found to be tracking location continuously. The author emphasizes that native apps often inherit permissions from embedded third-party software, posing significant privacy risks. In contrast, websites restrict this level of access, making them a safer choice for most services. With governments and companies frequently buying users&apos; location data, the article advocates for minimizing app usage, reminding readers that many everyday tasks can be handled through web browsers instead. This shift could help protect personal data from prying eyes in an age when surveillance and data commodification are rampant.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://nooneshappy.com/article/native-apps-should-be-avoided-whenever-possible/&quot;&gt;Continue reading on &lt;strong&gt;nooneshappy.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/android&quot;&gt;#android&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-07T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/native-apps-should-be-avoided-whenever-possible</id>
    <title>🔗 Native apps should be avoided whenever possible</title>
    <updated>2026-09-07T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/ibm-i-os-400-the-database-operating-system" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;What if there’s an operating system that challenges traditional views on how systems should be designed? Kamil Pytliński’s article dives into IBM i, an often-overlooked platform that marries its integrated relational database, &lt;code&gt;Db2 for i&lt;/code&gt;, directly with its OS. This unique configuration treats all data as objects, leading to enhanced security and unprecedented performance in online transaction processing since its inception in 1988. With features such as Single Level Storage and the TIMI layer ensuring backward compatibility, IBM i stands as a testament to innovative design, offering capabilities still unmatched today, though access remains limited to high-end IBM hardware. The article showcases how this elite system continues to perform where others struggle, challenging the perception of legacy systems.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://osadmins.com/en/ibm-i-os-400-the-database-operating-system/&quot;&gt;Continue reading on &lt;strong&gt;osadmins.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/database&quot;&gt;#database&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/sysadmin&quot;&gt;#sysadmin&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-07T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/ibm-i-os-400-the-database-operating-system</id>
    <title>🔗 IBM i (OS/400) the database operating system</title>
    <updated>2026-09-07T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/the-schema-doctor-is-in" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;A migration adding a &lt;code&gt;user_id&lt;/code&gt; column can pass all reviews, but later lead to slow queries. This is a problem the new &lt;code&gt;truss:doctor&lt;/code&gt; feature of Truss 1.5 addresses. Designed to identify schema issues before deployment, it flags problems like tables missing primary keys, foreign keys without supporting indexes, and redundant indexes.&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;php artisan truss:doctor&lt;/code&gt; in your terminal checks for these issues deterministically, which is safe for CI pipelines. The results can also be viewed graphically in the dashboard, offering real-time feedback on database structure without querying actual data. This phase one release includes 13 distinct rules and plans for future enhancements are already in the pipeline, focusing on suppressions and additional checks. Truss has quickly gained traction in the Laravel community, making it a valuable tool for maintaining database integrity.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://albertoarena.it/posts/the-schema-doctor-is-in/&quot;&gt;Continue reading on &lt;strong&gt;albertoarena.it&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/laravel&quot;&gt;#laravel&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/database&quot;&gt;#database&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/tools&quot;&gt;#tools&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/devops&quot;&gt;#devops&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-09-06T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/the-schema-doctor-is-in</id>
    <title>🔗 The schema doctor is in</title>
    <updated>2026-09-06T17:00:00Z</updated>
  </entry>
</feed>