<?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: Osama Alghanmi</title>
    <description>The latest articles on DEV Community by Osama Alghanmi (@almadar).</description>
    <link>https://dev.to/almadar</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%2F3456458%2F39bb2840-7c87-4f5a-8ccd-ffcd979586a3.png</url>
      <title>DEV Community: Osama Alghanmi</title>
      <link>https://dev.to/almadar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/almadar"/>
    <language>en</language>
    <item>
      <title>You Learn Faster When You Tell AI What You Already Know</title>
      <dc:creator>Osama Alghanmi</dc:creator>
      <pubDate>Sat, 07 Mar 2026 03:17:32 +0000</pubDate>
      <link>https://dev.to/almadar/you-learn-faster-when-you-tell-ai-what-you-already-know-4leo</link>
      <guid>https://dev.to/almadar/you-learn-faster-when-you-tell-ai-what-you-already-know-4leo</guid>
      <description>&lt;p&gt;Most people ask AI to explain things. Fewer people ask AI to explain things &lt;em&gt;to them specifically&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every concept has a cousin
&lt;/h2&gt;

&lt;p&gt;State machines were confusing to me until I recognized I'd been building them manually for years, just without the name. Event sourcing clicked the moment someone described it as a git log for your data. These connections didn't happen by accident. Someone knew what I already understood and found the bridge.&lt;/p&gt;

&lt;p&gt;AI can do this reliably, but only if you tell it where to start.&lt;/p&gt;

&lt;p&gt;"Explain WebSockets" returns a definition. "Explain WebSockets to someone who understands HTTP request-response, specifically what breaks down when you need the server to push data without the client asking first," returns something you can actually use. The second question works because it gives AI a place to stand. It knows where you are. It doesn't have to guess.&lt;/p&gt;

&lt;p&gt;This is how learning has always worked. New information sticks when it attaches to something already in your head. AI is unusually good at finding that attachment point across domains you'd never encounter side by side otherwise. It can connect your SQL knowledge to MongoDB aggregation, your OOP background to functional programming, your REST intuition to the specific friction GraphQL was designed to solve. But it needs your reference point to know which connection to draw.&lt;/p&gt;

&lt;h2&gt;
  
  
  The instinct that works against you
&lt;/h2&gt;

&lt;p&gt;When learning something new, there's a pull toward beginner mode. You try to receive information fresh, as if your existing knowledge might contaminate it. Backend developers learning React sometimes treat state management as a new concept, rather than recognizing that they've been thinking about state for years in a different context.&lt;/p&gt;

&lt;p&gt;Your existing models aren't contaminated. They're the reason new explanations stick. A backend developer who says: "I understand data flow and separation of concerns; show me how React handles both" will outpace someone who starts from scratch and works through the basics without that anchor.&lt;/p&gt;

&lt;p&gt;Before asking AI to explain something, it's worth spending ten seconds on: what do I already know that this resembles? What problem does this thing solve that I've encountered before in a different form? The answer to either of those shapes a much better question.&lt;/p&gt;

&lt;h2&gt;
  
  
  It compounds
&lt;/h2&gt;

&lt;p&gt;Once you establish a reference point, each follow-up question builds on it. You're not accumulating disconnected facts. You're extending an existing map.&lt;/p&gt;

&lt;p&gt;People who seem to learn new technologies fast aren't processing information faster. They're anchoring better. Each new concept attaches to the previous one, which attaches to something before that. The reference point at the start of a learning session determines how much of the rest actually lands.&lt;/p&gt;

&lt;p&gt;AI accelerates this by traversing domains in a single conversation. You can go from "I understand X" to a working mental model of something three conceptual steps away, without having to read three textbooks first. The catch is that the conversation has to start somewhere concrete. It's best when you have a knowledge repository that the LLM can pull from and use as a reference point.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>learning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>We Need an Emission Test for AI</title>
      <dc:creator>Osama Alghanmi</dc:creator>
      <pubDate>Sun, 01 Mar 2026 10:58:23 +0000</pubDate>
      <link>https://dev.to/almadar/we-need-an-emission-test-for-ai-1pla</link>
      <guid>https://dev.to/almadar/we-need-an-emission-test-for-ai-1pla</guid>
      <description>&lt;p&gt;We test cars for emissions before they're allowed on the road. We rate appliances for energy efficiency. We slap labels on buildings telling you how much power they consume per square meter.&lt;/p&gt;

&lt;p&gt;AI agents get none of this. No one asks how many tokens a system burned to answer a yes-or-no question.&lt;/p&gt;

&lt;h2&gt;
  
  
  Invisible Waste
&lt;/h2&gt;

&lt;p&gt;Every token an LLM generates costs energy. Real electricity, real cooling, real hardware deprecation. A model that generates 2,000 tokens of preamble, caveats, and filler to deliver 40 tokens of actual information is producing waste. Physical, measurable, environmental waste.&lt;/p&gt;

&lt;p&gt;Nobody's measuring it. We're in the "leaded gasoline" era of AI. The technology works, people love it, and the externalities are completely unpriced.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Would This Look Like
&lt;/h2&gt;

&lt;p&gt;A standardized benchmark for &lt;strong&gt;efficiency&lt;/strong&gt;, not accuracy. Given a set of tasks with known correct answers, how many tokens does the system consume to get there?&lt;/p&gt;

&lt;p&gt;Four metrics:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Token Efficiency Ratio (TER)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TER = useful_output_tokens / total_tokens_generated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A system that generates 500 tokens but only 80 carry actual information has a TER of 0.16. That's an F rating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Task Completion Cost (TCC)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How many tokens (input + output) does the agent consume to complete a well-defined task? Summarize this document. Fix this bug. Answer this question. Two systems that both produce the correct answer are not equal if one uses 10x as many tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Retry and Exploration Overhead&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agentic systems are the worst offenders. An agent that tries 5 wrong approaches before stumbling on the right one might "work," but it consumes 5x as many resources as one that reasons the first time correctly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Conversation Waste Index&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In multi-turn interactions, how much of the conversation is the AI repeating itself, restating the question, or generating text that the user already knows? The equivalent of an engine idling in traffic. Burning fuel, going nowhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;p&gt;ChatGPT alone has 900 million weekly active users. Add Gemini, Claude, Copilot, and the rest, and the real number is well over a billion. If each interaction costs an average of 500 unnecessary tokens, that's 500 billion tokens wasted per week. At roughly 0.001 kWh per 1,000 tokens (a conservative estimate for inference), that's 500,000 kWh per week in pure waste. Enough to power about 50,000 homes&lt;/p&gt;

&lt;p&gt;Agentic AI will multiply this by orders of magnitude. Systems that run autonomously, calling tools, spawning sub-agents, looping through retries. An agent that runs for 10 minutes, burning tokens in a loop, wastes more than your money. It wastes shared atmosphere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the Analogy Holds and Where It Breaks
&lt;/h2&gt;

&lt;p&gt;Cars produce CO2 as a byproduct of moving you from A to B. AI tokens produce CO2 as a byproduct of answering your question. In both cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The useful work can be done with vastly different amounts of waste&lt;/li&gt;
&lt;li&gt;Consumers can't see the waste happening&lt;/li&gt;
&lt;li&gt;Market incentives alone won't fix it (bigger models are "better," just like bigger engines were "better")&lt;/li&gt;
&lt;li&gt;Regulation and labeling changed behavior (CAFE standards, Energy Star ratings)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's where it gets interesting: with cars, you can't make the engine &lt;em&gt;think harder&lt;/em&gt; about whether it needs to burn that fuel. With AI, you can. The system can reason about whether a 2,000-token response is warranted or whether 50 tokens would do. The waste is in the software, not the physics, which actually makes this a more solvable problem than automotive emissions ever were.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Would Change
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Efficiency becomes a competitive axis:&lt;/strong&gt; Right now, benchmarks reward accuracy. An emission benchmark would reward getting the same accuracy with fewer tokens. The model that scores 95% on 200 tokens is rated higher than the one that scores 96% on 2,000 tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent frameworks get pressure to optimize:&lt;/strong&gt; Today's agent architectures are shockingly wasteful. Retry loops, full-context re-reads, redundant tool calls. An emissions rating would push developers toward smarter planning, better caching, and more efficient use of tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Users get a basis for choosing:&lt;/strong&gt; People pick AI tools based on vibes and marketing. An emission label, like the kWh sticker on your fridge, lets them factor in efficiency. "This agent is A-rated: it completes coding tasks with 3x fewer tokens than average."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing reflects reality:&lt;/strong&gt; Token pricing today is a race to the bottom. If we internalize the environmental cost, wasteful systems become expensive, and efficient ones become cheap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Builds This
&lt;/h2&gt;

&lt;p&gt;No single company should own this, especially not the ones selling the tokens. It needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;An independent body&lt;/strong&gt; (like the EPA, or the EU's energy labeling system) that defines the benchmark tasks and scoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standardized test suites&lt;/strong&gt;: 100-500 diverse tasks with known optimal token budgets across coding, writing, reasoning, and agentic workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparent reporting&lt;/strong&gt;: providers publish emission scores alongside capability benchmarks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tiered ratings&lt;/strong&gt;: A through F, stars, whatever makes it readable to non-technical users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The EU is already moving in this direction with the AI Act's sustainability provisions. But "report your energy consumption" is too vague. We need a per-task efficiency metric that lets you compare systems directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Agents, One Task
&lt;/h2&gt;

&lt;p&gt;Same task: "Read this 200-line file and tell me if there's a SQL injection vulnerability."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent A&lt;/strong&gt; reads the file and responds in 120 tokens:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Yes. Line 47 passes &lt;code&gt;user_input&lt;/code&gt; directly into an f-string SQL query without parameterization. Use parameterized queries instead."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Agent B&lt;/strong&gt; reads the file, re-reads it, then generates 1,500 tokens: a summary of what SQL injection is, a history of the OWASP Top 10, three remediation strategies with code examples, notes about ORM interactions, and a disclaimer about completeness.&lt;/p&gt;

&lt;p&gt;Both correct. Agent B might even score higher on current benchmarks for being "thorough." But it burned 12x the tokens, and 90% of its output was unrequested padding.&lt;/p&gt;

&lt;p&gt;Agent A passes the emission test. Agent B is a gas guzzler.&lt;/p&gt;

&lt;h2&gt;
  
  
  So
&lt;/h2&gt;

&lt;p&gt;We don't let cars on the road without testing their emissions. We shouldn't let AI agents into production without testing theirs.&lt;/p&gt;

&lt;p&gt;As we scale these systems to billions of users and autonomous operation, we should probably figure out if we're building the computational equivalent of a 1970s muscle car: impressive, powerful, and catastrophically wasteful.&lt;/p&gt;

&lt;p&gt;The token is the new gallon.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'd like to hear from anyone working on AI sustainability, green computing, or model optimization. How would you design the benchmark?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>sustainability</category>
      <category>ethics</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Dream Framework: How Organized Thought Lets You Build Anything in the AI Age</title>
      <dc:creator>Osama Alghanmi</dc:creator>
      <pubDate>Wed, 25 Feb 2026 20:16:58 +0000</pubDate>
      <link>https://dev.to/almadar/the-thinking-framework-how-organized-thought-lets-you-build-anything-in-the-ai-age-7kh</link>
      <guid>https://dev.to/almadar/the-thinking-framework-how-organized-thought-lets-you-build-anything-in-the-ai-age-7kh</guid>
      <description>&lt;p&gt;AI doesn't fix messy thinking. It accelerates it.&lt;/p&gt;

&lt;p&gt;Give an LLM a vague idea and you get a vague response. Give it a well-structured document with clear terminology, scoped problems, and tracked gaps — and it becomes the most productive collaborator you've ever worked with.&lt;/p&gt;

&lt;p&gt;The bottleneck in 2026 isn't writing code. AI writes code fast. The bottleneck is &lt;strong&gt;knowing what to build&lt;/strong&gt; — and being able to articulate it clearly enough that both humans and AI can execute on it.&lt;/p&gt;

&lt;p&gt;This post introduces a framework for doing exactly that. It's not about AI tools. It's about how you organize your thoughts so that &lt;em&gt;any&lt;/em&gt; complex problem becomes approachable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Framework: 7 Phases
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dream → Concrete → Divide → Gaps → Fix → Realize → Share
  ↑                                                   |
  └───────────────── feedback loop ────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each phase transforms your thinking. Each one produces an artifact. Here's how they work.&lt;/p&gt;




&lt;h3&gt;
  
  
  Phase 1: Dream
&lt;/h3&gt;

&lt;p&gt;You have an idea. It's half-formed, ambitious, probably unrealistic in its current shape. That's fine.&lt;/p&gt;

&lt;p&gt;Prompt AI with whatever is in your head — even a single sentence — and let it generate a &lt;strong&gt;dream document&lt;/strong&gt;. This is aspirational, not precise. The point is to get the idea &lt;em&gt;out of your head and into a document&lt;/em&gt; where you can see it, react to it, and start shaping it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I want to build an AI-powered medical diagnosis platform
that helps doctors catch rare diseases earlier. A patient
describes symptoms, the system triages, suggests possible
diagnoses, and routes to the right specialist.

Generate a dream document with:
- The vision (what does this look like when it's done?)
- Current landscape (what exists today and what's missing?)
- Key concepts I'll need to define
- Open questions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What you get back:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A structured dream doc. Maybe 2-3 pages. It captures your intent, maps the landscape (UpToDate, Isabel Healthcare, Ada Health — what they do well, where they fall short), and surfaces questions you hadn't thought of yet. "What does 'catch earlier' mean? Faster triage? Better differential diagnosis? Flagging patterns across patient history?"&lt;/p&gt;

&lt;p&gt;You didn't need to organize your thoughts first — AI did the first pass. Now you have something to react to.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The dream document is not a plan. It's a compass. It tells you the direction, not the steps.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;dreams/ai-diagnosis-platform.md&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Phase 2: Concrete
&lt;/h3&gt;

&lt;p&gt;Now you take the dream and turn it into a &lt;strong&gt;concrete reference document&lt;/strong&gt;. This is structured, precise, and scoped. Define your terms. Draw your architecture. Specify what's in and what's out.&lt;/p&gt;

&lt;p&gt;This is where AI earns its keep. Feed it the dream doc:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Here's my dream doc: [paste].
Turn this into a concrete reference document with:
- Defined terms and concepts
- Architecture sections with clear boundaries
- Scope (what this covers, what it doesn't)
- Open questions marked as [GAP] placeholders
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example result:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What started as &lt;em&gt;"I want AI to help doctors catch rare diseases"&lt;/em&gt; becomes a reference document covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Symptom intake engine&lt;/strong&gt;: How patients describe symptoms, structured vs. free-text, multi-language support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagnosis model&lt;/strong&gt;: Differential diagnosis ranking, confidence scores, explainability requirements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specialist routing&lt;/strong&gt;: Matching diagnoses to specialties, urgency tiers, availability awareness&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Patient records&lt;/strong&gt;: EHR integration, data formats (FHIR/HL7), privacy boundaries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance layer&lt;/strong&gt;: HIPAA, FDA Software as Medical Device (SaMD), audit logging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clinical UI&lt;/strong&gt;: Doctor-facing dashboard, patient-facing intake, mobile vs. desktop&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope boundaries&lt;/strong&gt;: "V1 does NOT include: prescription management, insurance billing, lab ordering"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This document is now your &lt;strong&gt;single source of truth&lt;/strong&gt;. Not the code. Not chat history. Not someone's memory. The document.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;docs/Diagnosis_Platform.md&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Phase 3: Divide
&lt;/h3&gt;

&lt;p&gt;Your concrete doc is getting long. Some sections are 10 pages on their own. That's the signal to &lt;strong&gt;divide&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Break the concrete document into focused &lt;strong&gt;division documents&lt;/strong&gt;, each deep enough to stand alone but connected to the whole.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Here's my concrete doc: [paste].
Which sections are complex enough to deserve their own
focused document? For each, suggest a title and scope.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A medical diagnosis platform reference doc naturally divides into:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Division Doc&lt;/th&gt;
&lt;th&gt;Covers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Symptom_Engine.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Intake flow, symptom normalization, multi-language parsing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Diagnosis_Model.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Differential ranking, confidence thresholds, explainability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Specialist_Routing.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specialty matching, urgency tiers, referral workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Patient_Records.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;EHR integration, FHIR/HL7 formats, data retention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Compliance.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HIPAA controls, SaMD classification, audit trail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Clinical_UI.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Doctor dashboard, patient intake, mobile responsiveness&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These aren't just knowledge divisions — &lt;strong&gt;they're your code modules&lt;/strong&gt;. Each division doc maps directly to a real unit of code: a microservice, a package in a monorepo, a module in a monolith, or a bounded context in a domain-driven design. The doc describes what the module does, the code implements it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Division Doc          →  Code Module
─────────────────────────────────────────────
Symptom_Engine.md     →  packages/symptom-engine/
Diagnosis_Model.md    →  packages/diagnosis-model/
Specialist_Routing.md →  packages/specialist-routing/
Patient_Records.md    →  packages/patient-records/
Compliance.md         →  packages/compliance/
Clinical_UI.md        →  apps/clinical-dashboard/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once docs map to code, you create an &lt;strong&gt;index document&lt;/strong&gt; — a single file that sits at the root of your project and maps every doc to its code module. Think of it as the table of contents for your entire system. When an AI agent (or a new team member) needs to work on routing, they look at the index, find &lt;code&gt;Specialist_Routing.md → packages/specialist-routing/&lt;/code&gt;, and have full context before touching a line of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Project Index&lt;/span&gt;

| Working In | Primary Doc | Gaps |
|---|---|---|
| &lt;span class="sb"&gt;`packages/symptom-engine/`&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Symptom_Engine.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Symptom_Engine.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Symptom_Engine_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Symptom_Engine_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; |
| &lt;span class="sb"&gt;`packages/diagnosis-model/`&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Diagnosis_Model.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Diagnosis_Model.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Diagnosis_Model_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Diagnosis_Model_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; |
| &lt;span class="sb"&gt;`packages/specialist-routing/`&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Specialist_Routing.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Specialist_Routing.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Specialist_Routing_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Specialist_Routing_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; |
| &lt;span class="sb"&gt;`packages/patient-records/`&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Patient_Records.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Patient_Records.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Patient_Records_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Patient_Records_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; |
| &lt;span class="sb"&gt;`packages/compliance/`&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Compliance.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Compliance.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Compliance_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Compliance_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; |
| &lt;span class="sb"&gt;`apps/clinical-dashboard/`&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Clinical_UI.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Clinical_UI.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; | &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Clinical_UI_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;docs/Clinical_UI_Gaps.md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This index becomes the most important file in the repo. It's the bridge between organized thought and organized code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;docs/DX_Symptom_Engine.md&lt;/code&gt;, &lt;code&gt;docs/DX_Compliance.md&lt;/code&gt;, + root &lt;code&gt;CLAUDE.md&lt;/code&gt; index&lt;/p&gt;




&lt;h3&gt;
  
  
  Phase 4: Gaps
&lt;/h3&gt;

&lt;p&gt;Here's where the framework really works. Once you have concrete docs and division docs, &lt;strong&gt;you can see what's missing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Gaps aren't failures. They're the framework doing its job. You can't see what's missing until you've written what's there.&lt;/p&gt;

&lt;p&gt;Track gaps with &lt;strong&gt;gap codes&lt;/strong&gt; — short identifiers that make them searchable and referenceable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;### GAP-DX004: Model suggests diagnosis but doesn't explain reasoning&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Phase**&lt;/span&gt;: Diagnosis output
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Area**&lt;/span&gt;: Diagnosis model — result presentation layer
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Impact**&lt;/span&gt;: Doctor sees "Possible: Lupus (82% confidence)"
  but no explanation of which symptoms contributed or why
  alternatives were ruled out. Doctor can't trust or verify
  the suggestion. Useless in clinical practice.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Root Cause**&lt;/span&gt;: Model outputs a ranked list with scores
  but no reasoning chain. Explainability was never specified
  in the architecture — it was assumed to be a UI concern.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Fix**&lt;/span&gt;: Add an explainability module that maps each
  diagnosis to contributing symptoms, relevant patient
  history, and ruled-out alternatives. Display as
  "evidence for / evidence against" in the clinical UI.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Priority**&lt;/span&gt;: Critical
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Status**&lt;/span&gt;: Open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The gap code format gives you:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Searchable ID (GAP-DX004, GAP-C001) with category prefix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Phase&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When in the system this surfaces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Area&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Which module or concept is affected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Impact&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What users experience when this gap exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Why the gap exists — not symptoms, causes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fix&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Proposed solution (can be a phased plan)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Priority&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Critical / High / Medium / Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Open / In Progress / Fixed (with date)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Category prefixes keep gaps organized: &lt;code&gt;GAP-DX&lt;/code&gt; for diagnosis, &lt;code&gt;GAP-SE&lt;/code&gt; for symptom engine, &lt;code&gt;GAP-C&lt;/code&gt; for compliance, &lt;code&gt;GAP-UI&lt;/code&gt; for clinical interface. You'll develop your own categories as your project grows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;docs/DX_Diagnosis_Gaps.md&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Phase 5: Fix → Update
&lt;/h3&gt;

&lt;p&gt;Fix the gaps. But not all at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Always ask for a phased implementation plan.&lt;/strong&gt; Gaps have dependencies. Some are prerequisites for others. Trying to fix everything simultaneously creates chaos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Here are my open gaps: [paste gap doc].
Here's the main concrete doc for context: [paste relevant section].
Create a phased implementation plan:
- Phase 1: Critical gaps that unblock other work
- Phase 2: High-priority gaps
- Phase 3: Medium-priority improvements
For each phase, estimate scope and list dependencies.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a gap is fixed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update the gap doc&lt;/strong&gt; — mark status as &lt;code&gt;Fixed (2026-02-22)&lt;/code&gt;, note what was done&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update the main concrete doc&lt;/strong&gt; — the reference doc must reflect reality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Archive the old version&lt;/strong&gt; — move superseded docs to &lt;code&gt;archive/&lt;/code&gt;. Don't delete them. They're the history of your thinking&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The concrete document &lt;strong&gt;evolves&lt;/strong&gt;. Version 1 had 20 gaps. Version 2 closes 15 and discovers 5 new ones. Version 3 closes those and the doc stabilizes. This is convergence — each pass gets you closer to a complete, honest description of your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifact:&lt;/strong&gt; Updated &lt;code&gt;docs/Diagnosis_Platform.md&lt;/code&gt;, archived &lt;code&gt;archive/gaps/DX_Diagnosis_Gaps_v1.md&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Phase 6: Realize
&lt;/h3&gt;

&lt;p&gt;Build real things from your docs. &lt;strong&gt;Projects are proof that the framework works.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each project tests your framework against reality. When something breaks, the question is: &lt;em&gt;which doc is wrong?&lt;/em&gt; The issue traces back to a gap in docs, not just a bug in code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From one set of diagnosis platform docs, you build pilot deployments: one for an urgent care clinic (fast triage, high volume, common conditions), one for a rural hospital (limited specialists on-site, telemedicine routing), one for a pediatric practice (age-adjusted symptom interpretation, different reference ranges).&lt;/p&gt;

&lt;p&gt;Each deployment tests the docs against a different reality. When the rural hospital pilot revealed that the specialist routing assumed specialists were in-house — but rural hospitals route to remote telemedicine providers with different availability windows — you didn't just patch the code. You:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Created &lt;code&gt;GAP-SR002&lt;/code&gt; in the routing gaps doc&lt;/li&gt;
&lt;li&gt;Documented the root cause (routing model assumed same-building availability, not async telemedicine)&lt;/li&gt;
&lt;li&gt;Fixed it with a phased plan (Phase 1: add remote-provider availability model, Phase 2: async consultation workflow)&lt;/li&gt;
&lt;li&gt;Updated &lt;code&gt;Specialist_Routing.md&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now the urgent care and pediatric deployments automatically handle telemedicine routing. Every project makes the docs better. Every doc improvement makes future projects more reliable.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cross-module composition
&lt;/h4&gt;

&lt;p&gt;Here's where the divide phase pays compound interest. Because each module has its own self-contained doc, &lt;strong&gt;you can mix and match modules across entirely different projects.&lt;/strong&gt; Not every project needs every module. New projects are assembled by selecting which division docs to include.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;Modules Used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Urgent care triage kiosk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Symptom_Engine&lt;/code&gt; + &lt;code&gt;Clinical_UI&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rural telemedicine platform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Symptom_Engine&lt;/code&gt; + &lt;code&gt;Diagnosis_Model&lt;/code&gt; + &lt;code&gt;Specialist_Routing&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Clinical research tool&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Diagnosis_Model&lt;/code&gt; + &lt;code&gt;Patient_Records&lt;/code&gt; + &lt;code&gt;Compliance&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Patient self-check app&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Symptom_Engine&lt;/code&gt; + &lt;code&gt;Clinical_UI&lt;/code&gt; (patient-facing subset)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hospital compliance auditor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Compliance&lt;/code&gt; + &lt;code&gt;Patient_Records&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The urgent care kiosk doesn't need the full diagnosis model — it just needs fast symptom intake and a clean UI to hand off to the doctor. The research tool doesn't need specialist routing — it needs deep diagnosis data with compliant record access. Each project pulls the modules it needs, and the docs tell you exactly what you're getting.&lt;/p&gt;

&lt;p&gt;This is the same principle behind monorepo packages, microservice composition, or even Unix pipes — small, well-documented units that combine into larger systems. The difference is that here, the composition starts at the &lt;em&gt;documentation&lt;/em&gt; level. You decide what a project needs by reading docs, not by reading code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;projects/urgent-care-pilot/&lt;/code&gt;, &lt;code&gt;projects/rural-hospital-pilot/&lt;/code&gt;, etc.&lt;/p&gt;




&lt;h3&gt;
  
  
  Phase 7: Share
&lt;/h3&gt;

&lt;p&gt;Write about your process. Teaching forces you to understand what you actually did.&lt;/p&gt;

&lt;p&gt;Blog posts, READMEs, tutorials, internal docs — the medium doesn't matter. What matters is that you explain your framework to someone who doesn't have your context. This surfaces assumptions you didn't know you were making.&lt;/p&gt;

&lt;p&gt;Sharing also closes the loop. A blog post about your diagnosis explainability approach might inspire a reader to suggest symptom-graph visualization instead of flat evidence lists. That becomes a new dream. The cycle restarts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifact:&lt;/strong&gt; Blog posts, tutorials, public documentation&lt;/p&gt;




&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;The framework is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dream it → Write it down → Break it apart → Find what's missing → Fix it → Build it → Share it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the AI age, organized thought is the highest-leverage skill you can develop. Not prompt engineering. Not knowing which model to use. &lt;strong&gt;Clarity of thought&lt;/strong&gt; — the ability to take a messy idea and refine it into something precise enough that both humans and AI can execute on .&lt;/p&gt;




&lt;p&gt;&lt;em&gt;A note on maintenance: docs drift. Code changes, APIs shift, dependencies update. Treat drift as another gap — audit periodically, update docs when code changes, and archive old versions instead of deleting them. The history of your thinking is as valuable as the thinking itself.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>architecture</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Figure It Out As You Go: Designing Software in the Age of AI</title>
      <dc:creator>Osama Alghanmi</dc:creator>
      <pubDate>Sat, 21 Feb 2026 04:32:43 +0000</pubDate>
      <link>https://dev.to/almadar/figure-it-out-as-you-go-designing-software-in-the-age-of-ai-5aoh</link>
      <guid>https://dev.to/almadar/figure-it-out-as-you-go-designing-software-in-the-age-of-ai-5aoh</guid>
      <description>&lt;p&gt;You don't need a perfect design upfront. You need a direction and the willingness to keep refining until things converge.&lt;/p&gt;

&lt;p&gt;This is what I learned after building the same app a dozen times, burning it down, and rebuilding it, until the system taught me what it wanted to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Myth of the Perfect Upfront Design
&lt;/h2&gt;

&lt;p&gt;Every software project starts the same way: someone draws boxes on a whiteboard and declares, "This is the architecture." There's usually a lot of nodding. Sometimes there's a second whiteboard.&lt;/p&gt;

&lt;p&gt;Then you actually start building, and reality shows up uninvited.&lt;/p&gt;

&lt;p&gt;The boxes don't fit. The data flows the wrong way. That service you thought would be simple has seventeen edge cases. By week three, you're writing code that quietly apologizes to the whiteboard.&lt;/p&gt;

&lt;p&gt;The hard truth is: &lt;strong&gt;you cannot know the full shape of your system before you've built parts of it.&lt;/strong&gt; Requirements lie. Users surprise you. Scale reveals things that no diagram predicted.&lt;/p&gt;

&lt;p&gt;And that's fine. The problem isn't that your design was wrong. The problem is treating the original design as sacred.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eventual Consistency, But For Your Codebase
&lt;/h2&gt;

&lt;p&gt;If you've worked with distributed systems, you know the concept of &lt;em&gt;eventual consistency&lt;/em&gt;: different nodes in a system might have different views of the data at any given moment, but given enough time and communication, they all converge to the same state.&lt;/p&gt;

&lt;p&gt;Your software design works the same way.&lt;/p&gt;

&lt;p&gt;You start with incomplete information. Your architecture has gaps. Your understanding of the domain is partial. But if you keep iterating, each cycle making the design a little more honest, a little more aligned with reality, you converge toward something that actually fits.&lt;/p&gt;

&lt;p&gt;The goal isn't to get it right immediately. The goal is to &lt;em&gt;keep getting less wrong.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Call it &lt;strong&gt;Figure-It-Out-As-You-Go (FIAYG) Development&lt;/strong&gt;. Not as catchy as TDD or DDD, but considerably more honest about how software actually gets built.&lt;/p&gt;

&lt;p&gt;The key is: every time you learn something new, from a bug, from user feedback, from hitting a scaling wall, you encode that learning into the architecture. You don't just fix the symptom. You fix the system so the symptom can't recur.&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Built Almadar (Or: A Story of Productive Chaos)
&lt;/h2&gt;

&lt;p&gt;Almadar is a declarative framework that compiles state-machine schemas into full-stack apps. A single &lt;code&gt;.orb&lt;/code&gt; file describes your entities, behaviors, and UI, and the compiler generates a working React frontend, Express backend, and database models.&lt;/p&gt;

&lt;p&gt;That's what it is &lt;em&gt;now&lt;/em&gt;. Here's how we got there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 1: The Single Project
&lt;/h3&gt;

&lt;p&gt;It started simple. We had one project, a client that needed a CRUD-heavy business application. We hand-coded it the normal way: React components, Express routes, TypeORM entities. Boilerplate everywhere.&lt;/p&gt;

&lt;p&gt;We noticed we were writing the same patterns over and over: a table to list records, a modal to create them, a form to edit them, and a confirmation to delete them. Copy. Paste. Rename. Repeat.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There must be a better way.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So we tried something: what if we described the data and behavior in a JSON schema, and generated the boilerplate from that?&lt;/p&gt;

&lt;p&gt;It was rough. The schema was barely structured. The generator was a string template with &lt;code&gt;fs.writeFileSync&lt;/code&gt; calls. But it worked. The client was happy. We shipped faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we learned:&lt;/strong&gt; The 80% of every app that is boilerplate can be described declaratively. The 20% that's unique is what you actually want to spend time on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 2: The Second Client Breaks Everything
&lt;/h3&gt;

&lt;p&gt;The second client had different requirements. Our generator was too tightly coupled to the first client's patterns. We'd hardcoded assumptions everywhere: naming conventions, file structure, component hierarchy.&lt;/p&gt;

&lt;p&gt;We could have hacked it. Instead, we stopped and asked: &lt;em&gt;What would a general version of this look like?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is where the architecture started to crystallize. We introduced the concept of &lt;strong&gt;Orbitals&lt;/strong&gt;, self-contained feature modules that combine an entity (data shape), a trait (behavior as a finite-state machine), and a page (route). We separated the schema definition from the code generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we learned:&lt;/strong&gt; The moment you have a second use case, your abstractions reveal themselves. If it doesn't generalize, it wasn't an abstraction. It was a coincidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 3: The Monorepo and the Constraints
&lt;/h3&gt;

&lt;p&gt;As the project count grew, so did the chaos. Each client project had its own design system, its own component variations, its own idea of what a "button" looked like. We were maintaining ten flavors of the same component.&lt;/p&gt;

&lt;p&gt;So we restructured everything into a monorepo with explicit rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Core components live in &lt;code&gt;@almadar/ui&lt;/code&gt;, shared, versioned, never duplicated&lt;/li&gt;
&lt;li&gt;Client design systems live in &lt;code&gt;projects/{name}/design-system/&lt;/code&gt;, extending core, not replacing it&lt;/li&gt;
&lt;li&gt;The compiler is in &lt;code&gt;orbital-rust/&lt;/code&gt;, sacred, never modified without discussion&lt;/li&gt;
&lt;li&gt;Generated code goes in &lt;code&gt;projects/{name}/app/&lt;/code&gt;, never edited directly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More importantly, we added &lt;em&gt;constraints&lt;/em&gt;. Hard rules the team encodes in a &lt;code&gt;CLAUDE.md&lt;/code&gt; file that every developer (human and AI) must follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Never use raw HTML elements&lt;/strong&gt;, always use design system components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema first&lt;/strong&gt;, edit the &lt;code&gt;.orb&lt;/code&gt; file, recompile, never touch generated code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compiler is sacred&lt;/strong&gt;, adding a rule requires explicit approval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And we enforced those constraints with a &lt;strong&gt;custom ESLint plugin&lt;/strong&gt; (&lt;code&gt;@almadar/eslint&lt;/code&gt;). Not optional guidelines — actual errors that block the pre-commit hook. Zero warnings allowed. Some of the rules we built:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;What it catches&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;no-raw-dom-elements&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Blocks &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, etc. Use &lt;code&gt;VStack&lt;/code&gt;, &lt;code&gt;Typography&lt;/code&gt;, &lt;code&gt;Button&lt;/code&gt; instead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;no-as-any&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Blocks &lt;code&gt;as any&lt;/code&gt; type casts. Fix the actual type issue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;no-import-generated&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Blocks importing from &lt;code&gt;projects/*/app/&lt;/code&gt;. Generated code is not an API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;require-closed-circuit-props&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every component must accept &lt;code&gt;className&lt;/code&gt;, &lt;code&gt;isLoading&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;entity&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;require-event-bus&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Interactions must use &lt;code&gt;useEventBus()&lt;/code&gt;, not raw &lt;code&gt;onClick&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;require-display-name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every component must set &lt;code&gt;displayName&lt;/code&gt; for debugging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;require-stories&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every new component must ship with a &lt;code&gt;.stories.tsx&lt;/code&gt; file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;event-naming-convention&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;UI events must follow the &lt;code&gt;UI:EVENT_NAME&lt;/code&gt; pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-no-hooks&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Template components are pure. No &lt;code&gt;useState&lt;/code&gt;, no &lt;code&gt;useEffect&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-no-iteration&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Templates don't loop. The organism does the iteration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;organism-no-callback-props&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Organisms communicate through the event bus, not prop callbacks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pre-commit hook runs ESLint on every staged &lt;code&gt;.ts&lt;/code&gt;/&lt;code&gt;.tsx&lt;/code&gt; file. If any rule fires, the commit is blocked. No exceptions. Every rule is severity 2 (error), not a warning. Warnings are aspirational. Errors are architecture.&lt;/p&gt;

&lt;p&gt;The result: a new developer, human or AI, can't accidentally violate the design principles. The linter says no before the PR is even opened.&lt;/p&gt;

&lt;p&gt;Constraints sound limiting. They're actually liberating. When the rules are clear, decisions get faster, inconsistencies get caught earlier, and new team members can contribute without breaking things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we learned:&lt;/strong&gt; A monorepo without constraints is just a polite monolith. Constraints are the architecture, and linting is how you make them real.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 4: AI Changes the Rules
&lt;/h3&gt;

&lt;p&gt;Here's where it gets interesting.&lt;/p&gt;

&lt;p&gt;When AI coding assistants arrived, our constraint-based architecture proved to be &lt;em&gt;exactly&lt;/em&gt; what they needed to work well. An LLM with a clear schema to edit, a pattern registry to validate against, a linter that blocks bad patterns, and a compiler that says "no" to broken output? That's a productive AI agent.&lt;/p&gt;

&lt;p&gt;An LLM working in a free-form codebase with no rules? That's a very confident agent who confidently does the wrong thing.&lt;/p&gt;

&lt;p&gt;We formalized this: the AI gets the constraints in &lt;code&gt;CLAUDE.md&lt;/code&gt;, checks the pattern registry before adding components, runs ESLint on every file it changes, and validates the schema with the Orbital compiler before declaring anything done. The compiler is the AI's code reviewer, and it never gets tired, never misses a case, and runs in under 50ms.&lt;/p&gt;

&lt;p&gt;The architecture we stumbled into through iteration turned out to be the right architecture for AI-assisted development. We didn't plan that. We converged on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we learned:&lt;/strong&gt; AI amplifies whatever structure (or chaos) already exists in your codebase. Constraints aren't bureaucracy. They're the difference between an AI that helps and an AI that confidently breaks things.&lt;/p&gt;

&lt;h2&gt;
  
  
  The FIAYG Playbook
&lt;/h2&gt;

&lt;p&gt;If you're a beginner, here's how to apply this without building a framework from scratch:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Start simple. Embarrassingly simple.
&lt;/h3&gt;

&lt;p&gt;Your first version should do one thing. Not the thing, plus error handling, plus caching, plus a configuration system. Just the thing. You will learn more from shipping something small than from designing something large.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Notice repetition, it's a message
&lt;/h3&gt;

&lt;p&gt;When you write the same code for the third time, that's the codebase telling you something wants to be abstracted. Don't abstract on the first repetition (premature). Don't ignore the third (negligence). The second time is the signal, the third is the confirmation.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Encode your learnings as constraints
&lt;/h3&gt;

&lt;p&gt;When you find a bug pattern — like a modal that can get stuck open — don't just fix this one modal. Figure out what rule would prevent that class of bug entirely. Write it down. Enforce it. In Almadar's case, we turned "every modal must have a CANCEL transition" into a compiler validation rule, and "never use raw HTML elements" into a linting error. In your project, it might be a custom ESLint rule, a pre-commit hook, or a code review checklist. The medium doesn't matter. What matters is that the rule is &lt;em&gt;automatic&lt;/em&gt;. If it requires a human to remember it, it will eventually be forgotten.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Your architecture should get &lt;em&gt;smaller&lt;/em&gt; over time
&lt;/h3&gt;

&lt;p&gt;Every time you spot a pattern and generalize it, you should be writing less code to accomplish the same thing. If your codebase keeps growing at the same rate forever, you're accumulating complexity, not managing it. The goal is more functionality per line, not more lines.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Don't fear the pivot
&lt;/h3&gt;

&lt;p&gt;We renamed things. We deleted entire packages. We moved the design system twice. Every time we did, the system got cleaner, and the rules got clearer. A pivot isn't a failure. It's the evidence that your understanding has improved.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Convergence Looks Like
&lt;/h2&gt;

&lt;p&gt;After several years and many client projects, here's what we converged on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One schema file per project, the single source of truth&lt;/li&gt;
&lt;li&gt;One compiler, deterministic, validates 50+ rules, generates all boilerplate&lt;/li&gt;
&lt;li&gt;One design system with per-project extensions&lt;/li&gt;
&lt;li&gt;One custom ESLint plugin, 17 rules enforced on every commit&lt;/li&gt;
&lt;li&gt;One standard library of reusable behaviors (CRUD, wizards, master-detail, pagination)&lt;/li&gt;
&lt;li&gt;One constraint that every developer and AI agent follows&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;The best software architecture isn't the one you design before you start. It's the one that emerges from listening to what your system is trying to tell you, through bugs, through repetition, through the friction you feel when something is wrong.&lt;/p&gt;

&lt;p&gt;Figure it out as you go. Encode what you learn. Keep getting less wrong.&lt;/p&gt;

&lt;p&gt;Consistency is eventual. Ship anyway.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ai</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>JSON That Thinks: A Programming Language Inside JSON</title>
      <dc:creator>Osama Alghanmi</dc:creator>
      <pubDate>Thu, 19 Feb 2026 14:22:47 +0000</pubDate>
      <link>https://dev.to/almadar/json-that-thinks-how-we-built-a-turing-complete-language-inside-json-4n76</link>
      <guid>https://dev.to/almadar/json-that-thinks-how-we-built-a-turing-complete-language-inside-json-4n76</guid>
      <description>&lt;p&gt;What if JSON wasn't just a data format?&lt;/p&gt;

&lt;p&gt;What if it was a programming language?&lt;/p&gt;

&lt;p&gt;We built a &lt;strong&gt;Turing-complete language that is a strict subset of JSON&lt;/strong&gt;.&lt;br&gt;
No new syntax. No custom parser. Every program is valid JSON.&lt;/p&gt;

&lt;p&gt;This is Almadar.&lt;/p&gt;


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

&lt;p&gt;In 1958, John McCarthy introduced S-expressions in Lisp:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;"big"&lt;/span&gt; &lt;span class="s"&gt;"small"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;S-expressions are nested lists where the first element is the operator.&lt;/p&gt;

&lt;p&gt;JSON arrays are nested lists.&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="s2"&gt;"+"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&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="s2"&gt;"if"&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="s2"&gt;"&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"big"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"small"&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;That's it.&lt;/p&gt;

&lt;p&gt;S-expressions already fit perfectly inside JSON arrays.&lt;br&gt;
Instead of inventing new syntax, we interpret what JSON already expresses.&lt;/p&gt;


&lt;h2&gt;
  
  
  What an Almadar Program Looks Like
&lt;/h2&gt;

&lt;p&gt;An Almadar program is composed of &lt;strong&gt;Orbitals&lt;/strong&gt; — the basic building blocks of the system.&lt;/p&gt;

&lt;p&gt;Each Orbital encapsulates three core elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Entity&lt;/strong&gt; — the data model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trait&lt;/strong&gt; — the behavior&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Page&lt;/strong&gt; — the UI&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Entity — The Data Model
&lt;/h3&gt;

&lt;p&gt;The Entity defines the structure of data.&lt;br&gt;
It declares fields, types, and constraints.&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The schema&lt;/li&gt;
&lt;li&gt;The memory&lt;/li&gt;
&lt;li&gt;The state container&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It holds the data the system operates on.&lt;/p&gt;


&lt;h3&gt;
  
  
  Trait — The Behavior
&lt;/h3&gt;

&lt;p&gt;A Trait defines behavior.&lt;/p&gt;

&lt;p&gt;Technically, a Trait is a &lt;strong&gt;reusable state machine&lt;/strong&gt; linked to an Entity.&lt;/p&gt;

&lt;p&gt;It contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;States&lt;/li&gt;
&lt;li&gt;Transitions&lt;/li&gt;
&lt;li&gt;Guards (conditions written as S-expressions)&lt;/li&gt;
&lt;li&gt;Effects (actions like &lt;code&gt;set&lt;/code&gt;, &lt;code&gt;emit&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traits encapsulate logic and can be reused across orbitals.&lt;br&gt;
They are the computational core of the system.&lt;/p&gt;


&lt;h3&gt;
  
  
  Page — The UI
&lt;/h3&gt;

&lt;p&gt;A Page defines the user interface.&lt;/p&gt;

&lt;p&gt;It describes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Layout&lt;/li&gt;
&lt;li&gt;Components&lt;/li&gt;
&lt;li&gt;Bindings to entity fields&lt;/li&gt;
&lt;li&gt;Event triggers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pages react to entity state and dispatch events that drive Traits.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example
&lt;/h2&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ApprovalWorkflow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orbitals"&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;"entity"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fields"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"number"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"enum"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"values"&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="s2"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"approved"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rejected"&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="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"traits"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ApprovalTrait"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"linkedEntity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"stateMachine"&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;"states"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"isInitial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Approved"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rejected"&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;"transitions"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Approved"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"APPROVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"guard"&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="s2"&gt;"and"&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="s2"&gt;"&amp;gt;="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@user.roleLevel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&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="s2"&gt;"&amp;lt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@entity.amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10000&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;"effects"&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="s2"&gt;"set"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@entity.status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"approved"&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="s2"&gt;"emit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"REQUEST_APPROVED"&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="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="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;Structure is JSON.&lt;br&gt;
Logic is JSON arrays.&lt;br&gt;
Execution is deterministic and recursive.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Is a Guard?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;guard&lt;/strong&gt; is a conditional expression that determines whether a state transition is allowed to execute.&lt;/p&gt;

&lt;p&gt;A transition only fires if its guard evaluates to &lt;code&gt;true&lt;/code&gt;.&lt;br&gt;
If the guard evaluates to &lt;code&gt;false&lt;/code&gt;, the transition is blocked.&lt;/p&gt;

&lt;p&gt;Guards are pure expressions — they have &lt;strong&gt;no side effects&lt;/strong&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  Guard Example
&lt;/h3&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Approved"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"APPROVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"guard"&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="s2"&gt;"and"&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="s2"&gt;"&amp;gt;="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@user.roleLevel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&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="s2"&gt;"&amp;lt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@entity.amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10000&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;"effects"&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="s2"&gt;"set"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@entity.status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"approved"&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;This transition runs only if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user's role level is at least 3&lt;/li&gt;
&lt;li&gt;The request amount is less than 10,000&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If either condition fails, the transition does nothing.&lt;/p&gt;


&lt;h3&gt;
  
  
  Guard Evaluation
&lt;/h3&gt;

&lt;p&gt;Guards are evaluated recursively:&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="s2"&gt;"and"&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="s2"&gt;"&amp;gt;="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@user.roleLevel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&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="s2"&gt;"&amp;lt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@entity.amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10000&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;Evaluation steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Resolve bindings (&lt;code&gt;@user.roleLevel&lt;/code&gt;, &lt;code&gt;@entity.amount&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt; Evaluate inner expressions&lt;/li&gt;
&lt;li&gt; Evaluate the outer operator&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result must be a boolean.&lt;/p&gt;

&lt;p&gt;Guards can use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logical operators: &lt;code&gt;and&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, &lt;code&gt;not&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Comparisons: &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Arithmetic&lt;/li&gt;
&lt;li&gt;Nested expressions&lt;/li&gt;
&lt;li&gt;References to &lt;code&gt;@entity&lt;/code&gt;, &lt;code&gt;@user&lt;/code&gt;, or &lt;code&gt;@payload&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Conceptually, a guard is the equivalent of an &lt;code&gt;if&lt;/code&gt; condition for a transition.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Is a Programming Language
&lt;/h2&gt;

&lt;p&gt;Almadar is Turing-complete because it provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mutable state (entity fields)&lt;/li&gt;
&lt;li&gt;Deterministic state machines&lt;/li&gt;
&lt;li&gt;Conditional logic&lt;/li&gt;
&lt;li&gt;Effects (&lt;code&gt;set&lt;/code&gt;, &lt;code&gt;emit&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Self-transitions (loops)&lt;/li&gt;
&lt;li&gt;Event-driven communication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A self-transition with a guard and state updates is equivalent to a while loop:&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Computing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Computing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TICK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"guard"&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="s2"&gt;"&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@entity.counter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"effects"&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="s2"&gt;"set"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@entity.counter"&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="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@entity.counter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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="s2"&gt;"emit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TICK"&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;State = memory.&lt;br&gt;
Transitions = control flow.&lt;br&gt;
Expressions = computation.&lt;/p&gt;

&lt;p&gt;That's a complete computational model.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Proposal
&lt;/h2&gt;

&lt;p&gt;Almadar proposes a simple shift:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep JSON.&lt;/li&gt;
&lt;li&gt;Interpret arrays as S-expressions.&lt;/li&gt;
&lt;li&gt;Combine them with state machines for control flow.&lt;/li&gt;
&lt;li&gt;Treat structured data and executable logic as one system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No new grammar.&lt;br&gt;
No new syntax rules.&lt;br&gt;
Just structured computation inside the world's most universal data format.&lt;/p&gt;

&lt;p&gt;JSON already won.&lt;/p&gt;

&lt;p&gt;Now it can think.&lt;/p&gt;

</description>
      <category>json</category>
      <category>lisp</category>
      <category>languages</category>
      <category>programming</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Osama Alghanmi</dc:creator>
      <pubDate>Thu, 19 Feb 2026 13:54:43 +0000</pubDate>
      <link>https://dev.to/almadar/-3ph1</link>
      <guid>https://dev.to/almadar/-3ph1</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/modelin_409b9ef89fbc" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3781100%2F9e340ecb-6009-4cf6-8ee5-40e5e19b3d8d.png" alt="modelin_409b9ef89fbc"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/modelin_409b9ef89fbc/ai-agents-dont-scale-like-chatbots-25j5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;AI Agents Don’t Scale Like Chatbots&lt;/h2&gt;
      &lt;h3&gt;ModelIndex ・ Feb 19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#devops&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#machinelearning&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#rag&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>ai</category>
      <category>devops</category>
      <category>machinelearning</category>
      <category>rag</category>
    </item>
    <item>
      <title>Finite State Machines: The Most Underused Design Pattern in Frontend Development</title>
      <dc:creator>Osama Alghanmi</dc:creator>
      <pubDate>Thu, 19 Feb 2026 13:51:33 +0000</pubDate>
      <link>https://dev.to/almadar/finite-state-machines-the-most-underused-design-pattern-in-frontend-development-4dfp</link>
      <guid>https://dev.to/almadar/finite-state-machines-the-most-underused-design-pattern-in-frontend-development-4dfp</guid>
      <description>&lt;p&gt;If you're using &lt;code&gt;useState&lt;/code&gt; for complex UI, you're probably doing it wrong. There's a 50-year-old solution you're ignoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Boolean Flag Trap
&lt;/h2&gt;

&lt;p&gt;Here's a familiar pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isEditing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsEditing&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isSaving&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsSaving&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setErrorMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setIsSaving&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setIsError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;saveUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setIsEditing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setIsError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setErrorMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setIsSaving&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// What combinations are valid?&lt;/span&gt;
  &lt;span class="c1"&gt;// isLoading=true, isError=true?&lt;/span&gt;
  &lt;span class="c1"&gt;// isEditing=true, isSaving=true?&lt;/span&gt;
  &lt;span class="c1"&gt;// Who knows!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates &lt;strong&gt;2^n possible states&lt;/strong&gt; (32 combinations for 5 booleans). Most are invalid or nonsensical.&lt;/p&gt;

&lt;h2&gt;
  
  
  The State Machine Alternative
&lt;/h2&gt;

&lt;p&gt;What if you explicitly defined valid states?&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;"states"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"idle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"isInitial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"loading"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editing"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"saving"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&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;"events"&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="s2"&gt;"FETCH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EDIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SAVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUCCESS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ERROR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CANCEL"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transitions"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"idle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"loading"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FETCH"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"loading"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"idle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUCCESS"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"loading"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ERROR"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"idle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EDIT"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"saving"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SAVE"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"saving"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"idle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUCCESS"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"saving"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ERROR"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"idle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CANCEL"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"idle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CANCEL"&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;Now there are exactly &lt;strong&gt;5 states&lt;/strong&gt; and &lt;strong&gt;9 valid transitions&lt;/strong&gt;. No impossible combinations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visualizing the Difference
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Boolean Flags: Spaghetti State
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;         isLoading=true
        /             \
isError=true?      isEditing=true?
      /                 \
     ?                   ?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any combination is possible. Bugs arise from invalid states you didn't consider.&lt;/p&gt;

&lt;h3&gt;
  
  
  State Machine: Directed Graph
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ┌─────────┐
         ┌─────────►│  idle   │◄────────┐
         │          └────┬────┘         │
         │               │              │
    ERROR│          FETCH│         SUCCESS
         │               ▼              │
    ┌────┴───┐      ┌─────────┐        │
    │ error  │      │ loading │        │
    └───┬────┘      └────┬────┘        │
        ▲                │             │
        │           SUCCESS            │
        │                │             │
        │                ▼             │
        │           ┌─────────┐        │
        └───────────┤ editing ├────────┘
                    └────┬────┘
                         │ SAVE
                         ▼
                    ┌─────────┐
         ┌─────────│ saving  │─────────┐
         │         └─────────┘         │
    ERROR│                              │SUCCESS
         │                              │
         └──────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every path is explicit. Invalid transitions don't exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Example: Form Submission
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Boolean Way
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ContactForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFormData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isSubmitting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsSubmitting&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsSuccess&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setErrorMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setIsSubmitting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setIsError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setIsSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setIsSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setIsError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setErrorMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setIsSubmitting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Bug: What if isSuccess and isError are both true?&lt;/span&gt;
  &lt;span class="c1"&gt;// Bug: Can I submit again while isSubmitting?&lt;/span&gt;
  &lt;span class="c1"&gt;// Bug: What clears isSuccess?&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The State Machine Way
&lt;/h3&gt;

&lt;p&gt;Define explicit states and transitions:&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;"states"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"isInitial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"validating"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"submitting"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"isTerminal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&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;"events"&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="s2"&gt;"SUBMIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VALIDATED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUCCESS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FAILURE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RETRY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EDIT"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transitions"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"validating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUBMIT"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"validating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"submitting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VALIDATED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"guard"&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="s2"&gt;"="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@validation.valid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"validating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VALIDATED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"guard"&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="s2"&gt;"="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@validation.valid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"submitting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SUCCESS"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"submitting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FAILURE"&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;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RETRY"&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;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Can't submit while already submitting&lt;/li&gt;
&lt;li&gt;✅ Validation happens in its own state&lt;/li&gt;
&lt;li&gt;✅ Error and success are mutually exclusive&lt;/li&gt;
&lt;li&gt;✅ Clear paths for retry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're using XState, this maps directly. If you prefer a lighter approach, even a plain TypeScript discriminated union gets you most of the way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FormState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;editing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;validating&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submitting&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Developers Avoid State Machines
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Myth 1: "They're Too Complex"
&lt;/h3&gt;

&lt;p&gt;Reality: Boolean flags &lt;em&gt;seem&lt;/em&gt; simpler until you have 5+ of them. Then the interaction matrix becomes incomprehensible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Myth 2: "They're Only for Games"
&lt;/h3&gt;

&lt;p&gt;Reality: Game developers use FSMs because they &lt;strong&gt;work&lt;/strong&gt;. UI is just like a game: user actions trigger state changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Myth 3: "They're Hard to Change"
&lt;/h3&gt;

&lt;p&gt;Reality: Changing a state machine means adding a state or transition. Changing boolean flags means hunting through &lt;code&gt;useEffect&lt;/code&gt; chains.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use State Machines
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Boolean Flags&lt;/th&gt;
&lt;th&gt;State Machine&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2-3 simple states&lt;/td&gt;
&lt;td&gt;✅ Okay&lt;/td&gt;
&lt;td&gt;✅ Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Async operations&lt;/td&gt;
&lt;td&gt;❌ Buggy&lt;/td&gt;
&lt;td&gt;✅ Clear&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-step flows&lt;/td&gt;
&lt;td&gt;❌ Messy&lt;/td&gt;
&lt;td&gt;✅ Perfect&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex UI modes&lt;/td&gt;
&lt;td&gt;❌ Impossible&lt;/td&gt;
&lt;td&gt;✅ Ideal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Real-World Analogy: Traffic Lights
&lt;/h2&gt;

&lt;p&gt;Traffic lights are the canonical state machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Red → Green → Yellow → Red
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine if traffic lights used boolean flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isRed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsRed&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isGreen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsGreen&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isYellow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsYellow&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Bug: All could be true!&lt;/span&gt;
&lt;span class="c1"&gt;// Bug: All could be false!&lt;/span&gt;
&lt;span class="c1"&gt;// Bug: Green could turn directly to Red!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Traffic engineers use state machines because &lt;strong&gt;lives depend on predictable states&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Your users' sanity depends on it too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It: Convert a Boolean Mess
&lt;/h2&gt;

&lt;p&gt;Take this boolean-heavy component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Checkout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isCartOpen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsCartOpen&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isCheckingOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsCheckingOut&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isProcessing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsProcessing&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isComplete&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsComplete&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hasError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setHasError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// ... nightmare of useEffect&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Convert to explicit states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;states: browsing → cartOpen → checkoutForm → processing → complete
                                                        ↘ error → checkoutForm (retry)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The state machine version has &lt;strong&gt;6 explicit states&lt;/strong&gt; instead of &lt;strong&gt;32 possible boolean combinations&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;Finite state machines aren't academic exercises — they're &lt;strong&gt;practical tools&lt;/strong&gt; for managing complexity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2-3 booleans: Probably fine&lt;/li&gt;
&lt;li&gt;4+ booleans: Consider a state machine&lt;/li&gt;
&lt;li&gt;Async flows: Definitely use a state machine&lt;/li&gt;
&lt;li&gt;Multi-step UI: State machine or bust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Libraries like &lt;a href="https://xstate.js.org/" rel="noopener noreferrer"&gt;XState&lt;/a&gt; make this easy in any React/Vue/Svelte project.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
