<?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: Tobi Lekan Adeosun</title>
    <description>The latest articles on DEV Community by Tobi Lekan Adeosun (@tflux2011).</description>
    <link>https://dev.to/tflux2011</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3736286%2F955e019a-972d-4ddd-94e0-731d9bdd9326.jpeg</url>
      <title>DEV Community: Tobi Lekan Adeosun</title>
      <link>https://dev.to/tflux2011</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tflux2011"/>
    <language>en</language>
    <item>
      <title>Your services already know why they broke. You just delete that knowledge at deploy time.</title>
      <dc:creator>Tobi Lekan Adeosun</dc:creator>
      <pubDate>Fri, 17 Jul 2026 03:14:31 +0000</pubDate>
      <link>https://dev.to/tflux2011/your-services-already-know-why-they-broke-you-just-delete-that-knowledge-at-deploy-time-5c23</link>
      <guid>https://dev.to/tflux2011/your-services-already-know-why-they-broke-you-just-delete-that-knowledge-at-deploy-time-5c23</guid>
      <description>&lt;p&gt;I want to start with a moment most of us have lived through.&lt;/p&gt;

&lt;p&gt;It's 3 a.m. A dashboard is red. You're eight terminals deep in &lt;code&gt;grep&lt;/code&gt;, trying to work out which service actually fell over and why. And the whole time there's this nagging feeling that you're doing archaeology on a system you wrote last month.&lt;/p&gt;

&lt;p&gt;Here's what got under my skin about it. The answer was never actually lost. Back in the source code it said, in plain terms, that the payment service talks to Postgres through a connection pool. That this retry backs off three times. That this particular dependency is external and you must never, ever try to "just restart it." That was all right there at build time. Then we packaged everything up, deployed, threw that structure in the bin, and asked a sleep-deprived human to reconstruct it from log lines.&lt;/p&gt;

&lt;p&gt;That gap bugged me enough that I spent a while building something around it. This post is about that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Autoscaling is good at the wrong problem
&lt;/h2&gt;

&lt;p&gt;We've gotten genuinely good at reacting to resource pressure. Traffic climbs, a box gets slow, CPU pins, and the autoscaler adds capacity or sheds load. No complaints there, it's kept things running for years.&lt;/p&gt;

&lt;p&gt;The problem is it has no idea what your app is &lt;em&gt;for&lt;/em&gt;. It can't tell a service that's slow because it's healthy and hammered from a service that's fast because it's quietly writing garbage to the database. It never had a model of the application in the first place.&lt;/p&gt;

&lt;p&gt;So a whole category of failures just sails right past it. A connection pool getting drained by something downstream. A poison message kicking off a retry storm. A schema change that breaks one code path and leaves the other one looking perfectly fine. Infrastructure that only thinks in CPU and memory is blind to all of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "throw an LLM at it" era
&lt;/h2&gt;

&lt;p&gt;The going answer right now is to bolt a large language model onto your observability stack. Fire hose all the logs, traces, and metrics at a big central model and ask it what happened.&lt;/p&gt;

&lt;p&gt;I get why. I also think it's the wrong shape, and I keep coming back to three things.&lt;/p&gt;

&lt;p&gt;It's expensive in a way that doesn't survive a finance review. Frontier models bill per token, telemetry is enormous, and you're proposing to push all of it through the priciest thing in your stack.&lt;/p&gt;

&lt;p&gt;It's centralized, so you've built yourself a single brain that now needs its own babysitting and happens to sit a long way from the failure it's supposed to understand.&lt;/p&gt;

&lt;p&gt;And the part I actually find frustrating: it hallucinates architecture. We hand the model a heap of logs and ask it to &lt;em&gt;infer&lt;/em&gt; who calls who, what a retry means here, what's safe to restart. That information wasn't fuzzy or missing. It was sitting in the code, exact and unambiguous, until we deleted it at deploy time and then paid a model to guess it back, usually worse.&lt;/p&gt;

&lt;p&gt;Which made me stop asking "how do we read logs better" and start asking a different question: why can't the application just reason about itself?&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ended up building
&lt;/h2&gt;

&lt;p&gt;The thing I built, the Cognitive Autonomic Framework, does four things. I'll be honest that none of the individual pieces are new. The bet is on how they fit together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The self-model comes out of the code.&lt;/strong&gt; At build time a compiler walks the AST and pulls out what I call a Runtime Semantic Topology, or RST. It's a small, dense graph: who depends on who, failure domains, retry policies, latency budgets, and the closed list of repairs an agent is even permitted to try on each node. A whole microservice graph fits in a few kilobytes, so it just rides along inside the container. When something breaks, nothing has to guess the system's shape. It reads it.&lt;/p&gt;

&lt;p&gt;A node in that graph is roughly this:&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;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"depends_on"&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;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"failure_domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"billing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"criticality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"retry_policy"&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;"max_attempts"&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="nl"&gt;"backoff"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"exponential"&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;"external_dependencies"&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;"stripe"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permitted_repairs"&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;"restart_pool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shed_load"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"open_circuit"&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;The bit I care about is &lt;code&gt;permitted_repairs&lt;/code&gt;, and the fact that it's a closed list. The agent is allowed to restart the pool. It is not allowed to restart &lt;code&gt;stripe&lt;/code&gt;, because the model flatly says that's an external dependency. The safety lives in the structure, not in whether the model happened to be in a good mood.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reasoning stays near the failure.&lt;/strong&gt; Every service gets a small local agent, and they sit in three tiers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tier 0   reflex        circuit breakers, timeouts       ~ms      free
Tier 1   node-local    reads evidence + self-model      ~100ms   cheap
Tier 2   global        frontier model, off to the side  rare     expensive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most incidents never leave Tier 0, where boring, dependable machinery handles them. Tier 1 reads the local evidence, checks the self-model, and tries a bounded fix. The big expensive model at Tier 2 only gets pulled in for the genuinely nasty stuff, and even then it's off the critical path, not sitting in the middle of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nodes gossip beliefs, not heartbeats.&lt;/strong&gt; Usually gossip is health and counters. Here nodes gossip hunches: "I think the billing pool is saturated, confidence 0.9, here's my evidence." If neighbors independently land on the same thing, confidence climbs and you've got a systemic fault. If nobody else sees it, it's isolated, and the node can heal it locally. Telling "my problem" apart from "everyone's problem," with no central coordinator making the call, turns out to be the useful trick.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autonomy is fenced in on purpose.&lt;/strong&gt; This is the part I won't wave away. An agent can never run an arbitrary command. It picks from the closed set the model declared for that node, and any repair it proposes has to clear verification in a shadow environment before it's allowed anywhere near production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;proposes  -&amp;gt;  in permitted_repairs?  -&amp;gt;  passes shadow check?  -&amp;gt;  ships to prod
                   | no                       | no
                   v                          v
                reject                     reject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model suggests, the pipeline decides. I wanted safety to be a property of the plumbing, not a thing you hope the model gets right.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I can actually stand behind
&lt;/h2&gt;

&lt;p&gt;There's a running implementation, not a diagram. Six real services, each in its own container, agents gossiping beliefs over actual TCP, and a diagnostic reasoner that's deterministic out of the box but swaps out for a hosted model if you want one. It's public, and every number in the paper came off that running system. Nothing's simulated.&lt;/p&gt;

&lt;p&gt;What it showed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Giving the reasoner its self-model roughly doubled how often it found the real root cause.&lt;/li&gt;
&lt;li&gt;That came from the structure, not the model size. &lt;code&gt;gpt-4o-mini&lt;/code&gt; and &lt;code&gt;gpt-4o&lt;/code&gt; scored the same.&lt;/li&gt;
&lt;li&gt;The safety boundary threw out every repair it wasn't allowed to make, including the ones where the model confidently pointed at the wrong thing.&lt;/li&gt;
&lt;li&gt;Per-node overhead stayed small.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And what I'm &lt;em&gt;not&lt;/em&gt; claiming, because it's easy to oversell this stuff: I haven't shown it holds at fleet scale, across a wide spread of fault types, over a long deployment. The economics pitch, that most incidents get handled cheaply and locally, is still something I'm measuring, not a result I get to wave around yet. The limitations section in the paper is written to be read, not skimmed past.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it might matter past DevOps
&lt;/h2&gt;

&lt;p&gt;The framing I actually care about isn't "AI for ops." It's software that carries an explicit model of itself and reasons over it. Reliability is just the first place that's obviously useful. The same fabric could just as easily carry adaptive routing, or intrusion detection, or a service that rewrites its own model as it changes.&lt;/p&gt;

&lt;p&gt;The whole thing boils down to one stubborn idea: an application should carry and reason over a model of itself, instead of handing that job to some outside observer that has to rebuild the picture from scratch every single time something goes wrong.&lt;/p&gt;

&lt;p&gt;If that lands for you, or if you can see exactly where it falls apart, I'd genuinely like to hear it.&lt;/p&gt;




&lt;p&gt;Listen: [&lt;a href="https://notebooklm.google.com/notebook/4779c275-9060-44bb-b0a9-bd2eb953592f?authuser=6" rel="noopener noreferrer"&gt;https://notebooklm.google.com/notebook/4779c275-9060-44bb-b0a9-bd2eb953592f?authuser=6&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Paper: &lt;a href="https://zenodo.org/records/21352597" rel="noopener noreferrer"&gt;zenodo.org/records/21352597&lt;/a&gt; (DOI &lt;a href="https://doi.org/10.5281/zenodo.21352597" rel="noopener noreferrer"&gt;10.5281/zenodo.21352597&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/tflux2011/caf-prototype" rel="noopener noreferrer"&gt;github.com/tflux2011/caf-prototype&lt;/a&gt; (archived at DOI &lt;a href="https://doi.org/10.5281/zenodo.21363579" rel="noopener noreferrer"&gt;10.5281/zenodo.21363579&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;I'm Tobi Adeosun, an independent researcher in Texas. You can reach me at &lt;a href="mailto:me@tadeosun.com"&gt;me@tadeosun.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>distributedsystems</category>
      <category>ai</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Why Merging AI Models Fails (And How a 'Gossip Handshake' Fixed It)</title>
      <dc:creator>Tobi Lekan Adeosun</dc:creator>
      <pubDate>Sat, 07 Mar 2026 06:54:38 +0000</pubDate>
      <link>https://dev.to/tflux2011/why-merging-ai-models-fails-and-how-a-gossip-handshake-fixed-it-3gef</link>
      <guid>https://dev.to/tflux2011/why-merging-ai-models-fails-and-how-a-gossip-handshake-fixed-it-3gef</guid>
      <description>&lt;p&gt;The Problem: AI is Too Centralized&lt;br&gt;
Right now, the "AI Arms Race" is happening in giant data centers. But what happens in a rural village in Africa, or a high-security office with no internet? These communities need to share knowledge between their local AI models without a central server.&lt;/p&gt;

&lt;p&gt;I spent the last few months researching Decentralized Knowledge Sharing. The goal: Could two different AI "experts"—say, an Agronomy Expert and a Veterinary Expert, combine their brains into one?&lt;/p&gt;

&lt;p&gt;The "Common Sense" Failure: Weight-Space Merging&lt;br&gt;
The current trend in AI is called Weight-Space Merging (like TIES-Merging). It basically tries to "average" the math of two models to create a single super-model.&lt;/p&gt;

&lt;p&gt;I tested this, and the results were catastrophic.&lt;/p&gt;

&lt;p&gt;When I merged a model that knew how to fix tractors with a model that knew how to treat cattle, the resulting "merged" model scored below random chance. It didn't just forget; it got confused. It tried to apply tractor repair logic to sick cows.&lt;/p&gt;

&lt;p&gt;I call this the Specialization Paradox: The smarter your individual AI models get, the harder they are to merge.&lt;/p&gt;

&lt;p&gt;The Solution: The Gossip Handshake Protocol&lt;br&gt;
Instead of trying to smash two brains together, I built the Gossip Handshake.&lt;/p&gt;

&lt;p&gt;Instead of merging weights, we:&lt;/p&gt;

&lt;p&gt;Gossip: Devices discover each other via Bluetooth (BLE) and swap tiny 50MB "LoRA adapters" (knowledge packets).&lt;/p&gt;

&lt;p&gt;Handshake: The device stores these adapters in a local library.&lt;/p&gt;

&lt;p&gt;Route: When you ask a question, a lightweight Semantic Router picks the right expert for the job.&lt;/p&gt;

&lt;p&gt;The Results: 13x Better Performance&lt;br&gt;
I ran this on Apple Silicon (M-series) using the Qwen2.5 model family (0.5B and 1.5B parameters).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;Agronomy&lt;/th&gt;
&lt;th&gt;Veterinary&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Overall Score&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Baseline&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Standalone Expert&lt;/td&gt;
&lt;td&gt;68.0%&lt;/td&gt;
&lt;td&gt;92.0%&lt;/td&gt;
&lt;td&gt;80.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Standard Merge&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;TIES-Merging (d=0.5)&lt;/td&gt;
&lt;td&gt;20.0%&lt;/td&gt;
&lt;td&gt;8.0%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;14.0%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Our Approach&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Gossip Handshake&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;64.0%&lt;/td&gt;
&lt;td&gt;92.0%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;78.0%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The gap is massive. By simply switching instead of merging, we achieved a 5.6x to 13x leap in performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Matters for Digital Sovereignty&lt;/strong&gt;&lt;br&gt;
This isn't just about better scores; it's about Sovereignty.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero Internet: This protocol works in "Zero-G" zones.&lt;/li&gt;
&lt;li&gt;Privacy: Your raw data never leaves your device. Only the "math" (the adapter) is shared.&lt;/li&gt;
&lt;li&gt;Scalable: You can add 100 experts to a single phone, and it only takes milliseconds to switch between them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it Yourself (Open Source)&lt;br&gt;
I've open-sourced the entire pipeline. You can generate the synthetic data, train the adapters, and run the Gossip Protocol on your own laptop.&lt;/p&gt;

&lt;p&gt;👉 GitHub Repository: &lt;a href="https://github.com/tflux2011/gossip-handshake" rel="noopener noreferrer"&gt;https://github.com/tflux2011/gossip-handshake&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;br&gt;
We need to stop trying to force AI into a "one size fits all" box. The future of AI is Modular, Decentralized, and Local.&lt;/p&gt;

&lt;p&gt;I’d love to hear from you: Have you tried merging LoRA adapters? What were your results? Let’s discuss in the comments!&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Stop Trusting Your AI Agents: How to Build a "Constitutional Sentinel"</title>
      <dc:creator>Tobi Lekan Adeosun</dc:creator>
      <pubDate>Sat, 21 Feb 2026 19:37:45 +0000</pubDate>
      <link>https://dev.to/tflux2011/stop-trusting-your-ai-agents-how-to-build-a-constitutional-sentinel-1kcg</link>
      <guid>https://dev.to/tflux2011/stop-trusting-your-ai-agents-how-to-build-a-constitutional-sentinel-1kcg</guid>
      <description>&lt;p&gt;In my last post, I wrote about why "Always-Online" AI agents fail in the real world and how to build an offline-first architecture.&lt;/p&gt;

&lt;p&gt;But solving the connectivity problem introduces a much scarier problem: Autonomous Risk. When an AI agent is operating offline or at the edge, it is making decisions without immediate human oversight. LLMs are notoriously "confident idiots", they will happily generate code that grants isAdmin=true to a guest user, or confidently drop a database table because it misunderstood a prompt.&lt;/p&gt;

&lt;p&gt;If you are building Agentic workflows, you cannot just hook an LLM directly to your execution environment. You need a middleman.&lt;/p&gt;

&lt;p&gt;In my Contextual Engineering framework, we call this the Constitutional Sentinel.&lt;/p&gt;

&lt;p&gt;What is a Constitutional Sentinel?&lt;br&gt;
A Sentinel is a deterministic safety layer (hardcoded logic) that wraps around your probabilistic AI agent. Before the agent is allowed to execute any tool_call or API request, the Sentinel intercepts the payload, evaluates it against a set of hard constraints (the "Constitution"), and decides whether to:&lt;/p&gt;

&lt;p&gt;Allow the execution.&lt;/p&gt;

&lt;p&gt;Block the execution and return an error to the agent to try again.&lt;/p&gt;

&lt;p&gt;Escalate to a Human-in-the-Loop (HITL).&lt;/p&gt;

&lt;p&gt;The Implementation (Python)&lt;br&gt;
Here is a simplified look at how to implement a Sentinel pattern to catch dangerous agent actions before they execute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ConstitutionalSentinel:
    def __init__(self):
        # Hardcoded constraints the AI is NEVER allowed to break
        self.banned_actions = ["drop_table", "delete_user", "grant_admin"]
        self.max_spending_limit = 50.00

    def evaluate_action(self, agent_proposed_action, payload):
        """
        Intercepts the agent's decision BEFORE execution.
        """
        print(f"🔍 Sentinel Intercept: Evaluating '{agent_proposed_action}'...")

        # 1. Check for universally banned actions
        if agent_proposed_action in self.banned_actions:
            return self._block(f"Action '{agent_proposed_action}' violates core safety constitution.")

        # 2. Check context-specific constraints (e.g., financial limits)
        if agent_proposed_action == "issue_refund":
            amount = payload.get("amount", 0)
            if amount &amp;gt; self.max_spending_limit:
                return self._escalate_to_human(agent_proposed_action, amount)

        # 3. If it passes all checks, allow execution
        return self._allow()

    def _block(self, reason):
        print(f"❌ BLOCKED: {reason}")
        # Return context back to the LLM so it can correct its mistake
        return {"status": "blocked", "feedback": reason}

    def _escalate_to_human(self, action, context):
        print(f"⚠️ ESCALATED: Human approval required for {action} ({context})")
        return {"status": "pending_human_review"}

    def _allow(self):
        print("✅ ALLOWED: Action passed constitutional checks.")
        return {"status": "approved"}


# --- Example Usage in your Agent Loop ---
sentinel = ConstitutionalSentinel()

# The AI Agent decides it wants to grant admin access based on a user prompt
proposed_action = "grant_admin"
payload = {"user_id": "9942"}

# The Sentinel intercepts it
decision = sentinel.evaluate_action(proposed_action, payload)

if decision["status"] == "approved":
    execute_tool(proposed_action, payload)
else:
    print("Execution halted. Agent must rethink or wait for human.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why "Green Checkmarks" Are Dangerous&lt;br&gt;
Without a Sentinel, your tests might pass because the AI successfully generated the correct JSON structure for the API call. But structurally correct doesn't mean logically safe.&lt;/p&gt;

&lt;p&gt;The Sentinel shifts your architecture from "Assuming the AI is right" to "Assuming the AI is a liability." It forces the system to prove its safety deterministically.&lt;/p&gt;

&lt;p&gt;The Full Blueprint&lt;br&gt;
The Constitutional Sentinel is just one piece of the Contextual Engineering architecture.&lt;/p&gt;

&lt;p&gt;If you want to see how this Sentinel integrates with the Sync-Later Queue and the Hybrid Router to build resilient, offline-first AI for low-resource environments, I’ve open-sourced the complete reference manuscript.&lt;/p&gt;

&lt;p&gt;You can download the full PDF on Zenodo for free (recently crossed 200+ downloads by other builders!):&lt;br&gt;
👉 &lt;a href="https://zenodo.org/records/18005435" rel="noopener noreferrer"&gt;https://zenodo.org/records/18005435&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s stop building agents that just "work," and start building agents we can actually trust.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>architecture</category>
      <category>security</category>
    </item>
    <item>
      <title>Building Offline-First AI Agents: Why "Always-Online" Architectures Fail in the Real World</title>
      <dc:creator>Tobi Lekan Adeosun</dc:creator>
      <pubDate>Wed, 28 Jan 2026 03:21:18 +0000</pubDate>
      <link>https://dev.to/tflux2011/building-offline-first-ai-agents-why-always-online-architectures-fail-in-the-real-world-2o87</link>
      <guid>https://dev.to/tflux2011/building-offline-first-ai-agents-why-always-online-architectures-fail-in-the-real-world-2o87</guid>
      <description>&lt;p&gt;The "Happy Path" Problem&lt;br&gt;
If you look at the documentation for most AI agent frameworks (LangChain, AutoGPT, CrewAI), they all share a dangerous assumption: Abundance Connectivity.&lt;/p&gt;

&lt;p&gt;They assume your API calls to OpenAI will always succeed. They assume your websocket will never drop. They assume your user has stable 5G.&lt;/p&gt;

&lt;p&gt;But I build software for Lagos, Nigeria. Here, power flickers, fiber cuts happen, and latency is a physical constraint, not an edge case. When I tried deploying standard agentic workflows here, they didn't just fail, they failed catastrophically. Users lost data, workflows hallucinated, and API credits were wasted on timeouts.&lt;/p&gt;

&lt;p&gt;I call this the "Agentic Gap", the massive divide between how AI works in a demo video in San Francisco and how it works in a resource-constrained environment.&lt;/p&gt;

&lt;p&gt;We Need "Contextual Engineering"I spent the last year re-architecting how we build these systems. I call the approach Contextual Engineering. It’s not about making models smarter; it’s about making the system around them resilient.&lt;/p&gt;

&lt;p&gt;Here are two architectural patterns I built to fix this, which you can use in your own Python projects today.&lt;/p&gt;

&lt;p&gt;Pattern 1: The "Sync-Later" Queue&lt;br&gt;
Most agents use a synchronous User -&amp;gt; LLM -&amp;gt; Response loop. If the network dies in the middle, the context is lost.&lt;/p&gt;

&lt;p&gt;Instead, we treat every user intent as a Transaction.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Serialize the Intent: When a user prompts the agent, we don't hit the API immediately. We serialize the request and store it in a local SQLite queue.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cryptographic Signing: We sign the request to ensure integrity.&lt;/p&gt;

&lt;p&gt;Opportunistic Sync: A background worker checks for connectivity (Ping/Heartbeat). Only when $N(t) = 1$ (network is available) do we flush the queue.&lt;/p&gt;

&lt;p&gt;The Python Implementation:Instead of a direct requests.post, we use a local buffer. Here is the logic from the open-source framework:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import sqlite3
import uuid

def queue_action(user_input, intent_type):
    # 1. Create a transaction ID
    tx_id = str(uuid.uuid4())

    # 2. Store locally first (Offline-First)
    conn = sqlite3.connect('agent_state.db')
    cursor = conn.cursor()
    cursor.execute(
        "INSERT INTO pending_actions (id, input, status) VALUES (?, ?, 'PENDING')",
        (tx_id, user_input)
    )
    conn.commit()

    # 3. Try to sync (if online)
    if check_connectivity():
        sync_manager.flush()
    else:
        print(f"Network down. Action {tx_id} queued for later.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures Zero Data Loss. The user can keep working, and the agent "catches up" when the internet comes back.&lt;/p&gt;

&lt;p&gt;Pattern 2: The Hybrid Inference Router&lt;br&gt;
Why route a simple "Hello" or "Summarize this text" to GPT-4? It’s slow, expensive, and requires a heavy internet connection.&lt;/p&gt;

&lt;p&gt;I implemented a Router Logic Gate that inspects the prompt before it leaves the device.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low Complexity? → Route to a local SLM (like Llama-3-8B or Phi-2) running on-device. (Cost: $0, Latency: Low).&lt;/li&gt;
&lt;li&gt;High Complexity? → Route to the Cloud (GPT-4o).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The decision function looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# The Routing Logic
if network_is_down() or complexity &amp;lt; threshold:
    model = "Local Llama-3 (8B)" # Free, Fast, Offline
else:
    model = "GPT-4o"             # Smart, Costly, Online
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple check saved us about 40-60% on API costs and made the application feel "instant" for basic tasks, even on 3G networks.&lt;/p&gt;

&lt;p&gt;The "Contextual Engineering" Framework&lt;br&gt;
These patterns aren't just hacks; they are part of a broader discipline I’m trying to formalize called Contextual Engineering. It’s about building AI that respects the Contextual Tuple (C = {I, K, R}): Infrastructure, Knowledge (Culture), and Regulation.&lt;/p&gt;

&lt;p&gt;I’ve open-sourced the entire reference architecture. It includes the routing logic, the SQLite queue wrappers, and the "Constitutional Sentinel" for safety.&lt;/p&gt;

&lt;p&gt;Where to find the code&lt;br&gt;
I want to see more engineers building specifically for the Global South. You can find the full Python implementation here:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/tflux2011/contextual-engineering-patterns" rel="noopener noreferrer"&gt;Star the GitHub Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Deep Dive (Free Book)&lt;br&gt;
For those who want the math and the full architectural theory, I also wrote a 90-page reference manuscript titled "Contextual Engineering: Architectural Patterns for Resilient AI." It covers the full "Agentic Gap" theory and detailed diagrams.&lt;/p&gt;

&lt;p&gt;📖 &lt;a href="https://zenodo.org/records/18005435" rel="noopener noreferrer"&gt;Download the PDF (Open Access)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know in the comments: How do you handle network flakes in your LLM apps?&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>systemdesign</category>
    </item>
  </channel>
</rss>
