<?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: Kanwal Oswal</title>
    <description>The latest articles on DEV Community by Kanwal Oswal (@kanwaloswal).</description>
    <link>https://dev.to/kanwaloswal</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3785573%2F4ab605a1-7a9d-4dbe-8bc4-9763af2eb094.png</url>
      <title>DEV Community: Kanwal Oswal</title>
      <link>https://dev.to/kanwaloswal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kanwaloswal"/>
    <language>en</language>
    <item>
      <title>The Return of the CLI: Faster for Humans, Native for AI</title>
      <dc:creator>Kanwal Oswal</dc:creator>
      <pubDate>Sat, 28 Mar 2026 14:07:09 +0000</pubDate>
      <link>https://dev.to/kanwaloswal/the-return-of-the-cli-faster-for-humans-native-for-ai-e4m</link>
      <guid>https://dev.to/kanwaloswal/the-return-of-the-cli-faster-for-humans-native-for-ai-e4m</guid>
      <description>&lt;p&gt;For a decade, we were told the "User Experience" lived in the browser. But as systems grew complex, dashboards became a clicking nightmare. Today, the CLI is back—not because we’re nostalgic or want to feel 'cool' and 'techie', but because it’s the most efficient interface for humans and the native language of AI agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why CLI? Why Now?
&lt;/h2&gt;

&lt;p&gt;In an era of &lt;strong&gt;Platform Engineering&lt;/strong&gt;, the CLI is the ultimate abstraction. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Composability:&lt;/strong&gt; You can’t &lt;code&gt;pipe&lt;/code&gt; a React button into a database migration script. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent-Readiness:&lt;/strong&gt; Large Language Models (LLMs) struggle with fluctuating DOM elements in a GUI but thrive on structured CLI output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Moving your hand to a mouse is a latency hit. For a senior dev, the terminal is a high-bandwidth low-latency connection to the machine.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Python: The Speed of Thought
&lt;/h2&gt;

&lt;p&gt;Python is the "gold standard" for CLIs because of its readability and the incredible library support. If you're still using &lt;code&gt;argparse&lt;/code&gt;, you're working too hard.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Modern Stack: Typer
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Typer&lt;/code&gt; (built on &lt;code&gt;Click&lt;/code&gt;) uses Python type hints to generate help screens and validations automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;typer&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;formal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;formal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;typer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Greetings, Distinguished Colleague &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;typer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hey &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;typer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Run this without and arg and see and then with the arg.&lt;br&gt;
&lt;strong&gt;Pro-Tip:&lt;/strong&gt; Use &lt;code&gt;Rich&lt;/code&gt; alongside Python CLIs to render beautiful tables and progress bars that make the terminal feel like a high-end dashboard.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Java: The Enterprise Workhorse
&lt;/h2&gt;

&lt;p&gt;Historically, Java was "too slow" to start for CLI tools. With &lt;strong&gt;GraalVM Native Image&lt;/strong&gt;, that’s over. You get the type safety of Java with the startup speed of C++.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Modern Stack: Picocli
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Picocli&lt;/code&gt; is tiny but mighty. It handles everything from ANSI colors to autocomplete.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Command&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"checksum"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mixinStandardHelpOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Checksum&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Callable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Parameters&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The file to check"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;fileContents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readAllBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toPath&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DigestUtils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;md5Hex&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileContents&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Architect's Note:&lt;/strong&gt; Use Picocli when building internal tools that need to tap into your existing Enterprise Spring Boot or Jakarta EE logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Windows and the CLI: No Longer a Second-Class Citizen
&lt;/h2&gt;

&lt;p&gt;The days of struggling with &lt;code&gt;cmd.exe&lt;/code&gt; are dead. The &lt;strong&gt;Windows Terminal&lt;/strong&gt; and &lt;strong&gt;PowerShell 7 (Core)&lt;/strong&gt; have unified the experience.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Object-Oriented Piping:&lt;/strong&gt; Unlike Bash (which passes strings), PowerShell passes &lt;em&gt;objects&lt;/em&gt;. 

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ls | where {$_.Length -gt 1mb}&lt;/code&gt; — This doesn't just parse text; it filters file objects.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Winget:&lt;/strong&gt; The Windows Package Manager has finally made environment setup scriptable. 

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;winget install JanDeDobbeleer.OhMyPosh&lt;/code&gt; — Use this to make your Windows prompt look as good as any macOS Zsh setup.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  The "Cool" Factor: More Than Just Text
&lt;/h2&gt;

&lt;p&gt;Modern terminals support &lt;strong&gt;TrueColor&lt;/strong&gt; and &lt;strong&gt;Unicode symbols&lt;/strong&gt;. You can create sophisticated visuals without a single pixel of CSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  ASCII &amp;amp; Rich Visuals
&lt;/h3&gt;

&lt;p&gt;Using tools like &lt;code&gt;Art&lt;/code&gt; in Python or simple Unicode characters, you can create "Status Dashboards" that live in the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  _________________ 
&amp;lt; CLI is the Future &amp;gt;
  ----------------- 
         \   ^__^
          \  (oo)\_______
             (__)\       )\/\
                 ||----w |
                 ||     ||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3 Practical Tips for Your Next CLI
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Idempotency is King:&lt;/strong&gt; A CLI command should be safe to run twice. Check state before acting.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Standard Out vs. Standard Error:&lt;/strong&gt; Send your logs to &lt;code&gt;stderr&lt;/code&gt; and your data to &lt;code&gt;stdout&lt;/code&gt;. This keeps your pipes clean.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;JSON Output Mode:&lt;/strong&gt; Always provide a &lt;code&gt;--json&lt;/code&gt; flag. This is how you make your tool "Agent-Friendly" so an AI or a script can consume the output without "regex-ing" your text.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;The CLI isn't a step backward; it's a pivot toward automation.&lt;/strong&gt; &lt;/p&gt;




&lt;p&gt;Here is the 'cowsay' generated code (Thanks Gemini)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;simple_cowsay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Calculate the bubble width
&lt;/span&gt;    &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Build the speech bubble
&lt;/span&gt;    &lt;span class="n"&gt;bubble&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;border&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. The Cow (using double backslashes to escape them)
&lt;/span&gt;    &lt;span class="n"&gt;cow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;         \   ^__^&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;          \  (oo)\_______&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;             (__)\       )\/\ &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;                 ||----w |&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;                 ||     ||&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Combine and print
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bubble&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cow&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nf"&gt;simple_cowsay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CLI is the Future&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cli</category>
      <category>ai</category>
      <category>shell</category>
    </item>
    <item>
      <title>Stop Asking LLMs “Does This Pass?” — Turn Policies Into Executable Rules Instead</title>
      <dc:creator>Kanwal Oswal</dc:creator>
      <pubDate>Thu, 19 Mar 2026 02:06:24 +0000</pubDate>
      <link>https://dev.to/kanwaloswal/stop-asking-llms-does-this-pass-turn-policies-into-executable-rules-instead-16of</link>
      <guid>https://dev.to/kanwaloswal/stop-asking-llms-does-this-pass-turn-policies-into-executable-rules-instead-16of</guid>
      <description>&lt;p&gt;If you’ve worked with LLMs in real systems, you’ve probably tried something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Here’s a policy document. Here’s some input data.&lt;br&gt;&lt;br&gt;
Does this meet the policy?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It works surprisingly well… at first.&lt;/p&gt;

&lt;p&gt;But as soon as you move beyond demos, a few problems start to show up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Results vary depending on phrasing or context
&lt;/li&gt;
&lt;li&gt;It’s hard to explain &lt;em&gt;why&lt;/em&gt; a decision was made
&lt;/li&gt;
&lt;li&gt;The only audit trail is prompt + response
&lt;/li&gt;
&lt;li&gt;Re-running the same input doesn’t always guarantee the same output
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This becomes a real issue in domains like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;financial services
&lt;/li&gt;
&lt;li&gt;compliance
&lt;/li&gt;
&lt;li&gt;eligibility systems
&lt;/li&gt;
&lt;li&gt;underwriting
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where decisions need to be &lt;strong&gt;consistent, explainable, and auditable&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Problem
&lt;/h2&gt;

&lt;p&gt;The issue isn’t that LLMs are bad.&lt;/p&gt;

&lt;p&gt;It’s that we’re using them for the wrong part of the workflow.&lt;/p&gt;

&lt;p&gt;We’re asking them to &lt;strong&gt;evaluate policies repeatedly at runtime&lt;/strong&gt;, instead of using them to &lt;strong&gt;extract structured logic once&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Different Approach
&lt;/h2&gt;

&lt;p&gt;Instead of:&lt;br&gt;
Policy Document + Input Data → LLM → Decision&lt;/p&gt;

&lt;p&gt;What if we did:&lt;br&gt;
Policy Document → LLM → Structured Rules&lt;br&gt;
↓&lt;br&gt;
Deterministic Engine&lt;br&gt;
↓&lt;br&gt;
Decision + Trace&lt;/p&gt;

&lt;p&gt;This is the idea behind &lt;strong&gt;AeroRule&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 GitHub: &lt;a href="https://github.com/kanwaloswal/AeroRule" rel="noopener noreferrer"&gt;https://github.com/kanwaloswal/AeroRule&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What is AeroRule?
&lt;/h2&gt;

&lt;p&gt;AeroRule is a lightweight rules engine designed around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JSON-based rule definitions&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CEL (Common Expression Language)&lt;/strong&gt; for conditions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;deterministic evaluation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;traceable outputs&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s built to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;safe for LLM-generated rules
&lt;/li&gt;
&lt;li&gt;easy to integrate (Java + Python)
&lt;/li&gt;
&lt;li&gt;suitable for audit-heavy environments
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to &lt;strong&gt;decouple business logic from code&lt;/strong&gt; while keeping it safe and explainable.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example Rule
&lt;/h2&gt;

&lt;p&gt;Here’s what a rule looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CREDIT-001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Minimum credit score requirement"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer.creditScore &amp;gt;= 680"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"onSuccess"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PASS"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"onFailure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DECLINE"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, readable, and structured.&lt;br&gt;
The condition is written in CEL, which is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;safe (non-Turing complete)&lt;/li&gt;
&lt;li&gt;fast&lt;/li&gt;
&lt;li&gt;easy to sandbox&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why Traceability Matters&lt;/p&gt;

&lt;p&gt;In many systems, it’s not enough to know what happened.&lt;/p&gt;

&lt;p&gt;You need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what inputs were used&lt;/li&gt;
&lt;li&gt;what condition was evaluated&lt;/li&gt;
&lt;li&gt;whether it matched&lt;/li&gt;
&lt;li&gt;what action was taken&lt;/li&gt;
&lt;li&gt;how long it took&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is critical for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;debugging&lt;/li&gt;
&lt;li&gt;audits&lt;/li&gt;
&lt;li&gt;compliance reviews&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rule Sets: Real Policies, Not Just Rules&lt;/p&gt;

&lt;p&gt;Real-world policies aren’t a single condition. They are a sequence of checks.&lt;/p&gt;

&lt;p&gt;AeroRule supports RuleSets, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"executionStrategy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GATED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer.creditScore &amp;gt;= 680"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer.annualIncome &amp;gt;= 40000"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With strategies like:&lt;br&gt;
ALL → evaluate everything&lt;br&gt;
GATED → stop on first failure&lt;/p&gt;

&lt;p&gt;This lets you model real decision flows like loan approvals.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where LLMs Fit In
&lt;/h2&gt;

&lt;p&gt;LLMs are still incredibly useful — just in a different role.&lt;/p&gt;

&lt;p&gt;Instead of evaluating decisions, they:&lt;/p&gt;

&lt;p&gt;👉 convert natural language → structured rules&lt;/p&gt;

&lt;p&gt;AeroRule includes a demo app that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;takes a policy document&lt;/li&gt;
&lt;li&gt;generates rules using an LLM&lt;/li&gt;
&lt;li&gt;links rules back to source text&lt;/li&gt;
&lt;li&gt;allows interactive evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a pipeline like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Human Policy → LLM → JSON Rules → Deterministic Engine → Traceable Decision&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re interested, check it out:&lt;br&gt;
👉 &lt;a href="https://github.com/kanwaloswal/AeroRule" rel="noopener noreferrer"&gt;https://github.com/kanwaloswal/AeroRule&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback, ideas, and contributions are welcome.&lt;/p&gt;

</description>
      <category>java</category>
      <category>businessrules</category>
      <category>python</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
