<?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: Rodrigo Giuliani</title>
    <description>The latest articles on DEV Community by Rodrigo Giuliani (@giulianiregspec).</description>
    <link>https://dev.to/giulianiregspec</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%2F3914393%2Fe4bf6de5-cb4d-4bad-9a5b-d169a7634487.jpg</url>
      <title>DEV Community: Rodrigo Giuliani</title>
      <link>https://dev.to/giulianiregspec</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/giulianiregspec"/>
    <language>en</language>
    <item>
      <title>Home Assistant Already Talks to Your Devices. So What Would DoSync Add?</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Tue, 16 Jun 2026 03:00:49 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/home-assistant-already-talks-to-your-devices-so-what-would-dosync-add-1iei</link>
      <guid>https://dev.to/giulianiregspec/home-assistant-already-talks-to-your-devices-so-what-would-dosync-add-1iei</guid>
      <description>&lt;p&gt;If you run Home Assistant, you've already solved the hardest problem in the smart home: talking to three thousand kinds of device. Lights, locks, sensors, vacuums, obscure Zigbee gadgets from a brand that no longer exists — HA speaks to all of them. And since 2025 it ships an MCP server, so an AI assistant can already reach in and control them.&lt;br&gt;
So when a project like DoSync shows up describing itself as a protocol between AI and physical devices, the fair question from anyone in the HA community is: why would I need that? I already have HA, and now AI can talk to HA directly.&lt;br&gt;
That's the right question, and I want to answer it honestly — including the part where the answer is "you probably don't."&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Home Assistant is, precisely&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;HA does three jobs: it integrates with devices, it runs automations, and it gives you a UI. The first job is the one that matters here, and it's genuinely excellent. HA is the richest device-integration layer that exists. Nothing should try to replace that, and DoSync doesn't — it reads devices from HA through a bridge that's already in the repo.&lt;br&gt;
But notice what HA's model is, underneath: it's still commands. "Turn on light.living_room." "Set climate.bedroom to 21." The HA MCP server exposes those same commands to an AI. The intelligence about what to do — what should happen when there's an emergency, when nobody's home, when a sensor reads something strange — lives either in an automation you wrote in advance, or in the AI sending the commands. HA executes; it doesn't decide.&lt;br&gt;
That's not a criticism. It's just the layer HA operates at: it aggregates devices and gives you a uniform way to command them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Where a different layer might sit&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DoSync operates one layer up, and only does one thing: it turns a semantic intent into a coordinated, auditable set of actions.&lt;br&gt;
You don't tell it "turn on these ten lights, unlock that door, send this SMS." You express a goal — ensure_safety, away_mode — and a resolver decides which devices are relevant based on what they've declared they can do, executes the actions, and writes every one of them to a tamper-evident SHA-256 audit log. The devices can come from HA, or from a direct adapter (WiZ over UDP, GPIO on a Pi, BLE, MQTT). HA is one source of "bodies," not the center.&lt;br&gt;
Three things distinguish that from sending commands through the HA MCP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Intents, not commands. The AI says what it wants to achieve; the resolver works out the rest from declared device capabilities. Add a device and it participates automatically — no automation to rewrite.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An audit log built for accountability. Every action and the reason it fired, in a SHA-256 hash chain: each entry includes the hash of the previous one, so editing or deleting a past entry breaks the chain and is detectable on verification. To be precise about what that buys you — it protects against undetected after-the-fact modification of the history, not against an attacker with root on the hub (who could rewrite the whole chain). HA's recorder and logbook give you a searchable history, which is great for "what happened"; the hash chain adds "and you can show it wasn't altered" — which matters when an auditor, an insurer, or an incident review needs a record they can trust, and matters not at all for everyday automation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple sources under one contract. DoSync coordinates devices from HA and from other adapters under a single semantic model with policies and certification. HA is one especially rich source among several.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;And here's the part most projects won't say&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For the vast majority of what people use Home Assistant for — "turn on the porch light when I get home," "set the thermostat back at night" — you do not need DoSync. HA's own automations and its MCP server cover that completely. Adding a coordination layer would be extra infrastructure earning you nothing.&lt;br&gt;
DoSync earns its place only when two things are true at once: coordination matters (one goal has to fan out across many devices, reliably, possibly in an emergency) and traceability matters (you need an auditable record of what acted and why).&lt;br&gt;
A concrete home example: an elderly parent lives alone, and you've built a fall-response setup — a sensor trips and the home should unlock the door for paramedics, turn every light to full, and message the family, all at once, and you need to be able to say afterward exactly what fired and when. That's coordination plus traceability in a house, not a factory. Outside cases like that — most of what HA does day to day — the extra layer earns you nothing.&lt;br&gt;
If that's not your situation, stay with HA and enjoy it. That's not me being modest; it's me not wanting to sell you a layer you won't use.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How they actually fit together&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The honest picture isn't DoSync versus Home Assistant. It's DoSync using Home Assistant — treating HA as one of the best places to source devices, and adding a semantic, auditable coordination layer above it for the narrow set of cases that need one. HA keeps owning its integrations. The connecting AI stays where the intelligence belongs — outside, expressing intent. DoSync is just the nervous system in between.&lt;br&gt;
If you're in that narrow set of cases, it's worth a look. If you're not, you already have what you need — and if you're genuinely not sure which side of the line you're on, open an issue describing your setup and I'll tell you straight whether it's worth the trouble.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;https://github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;br&gt;
Web: &lt;a href="https://dosync.dev/" rel="noopener noreferrer"&gt;https://dosync.dev/&lt;/a&gt;&lt;br&gt;
License: Apache 2.0&lt;/p&gt;

</description>
      <category>homeassistant</category>
      <category>ai</category>
      <category>opensource</category>
      <category>iot</category>
    </item>
    <item>
      <title>When Automatic Failover Is More Dangerous Than No Failover</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Sun, 14 Jun 2026 15:25:07 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/when-automatic-failover-is-more-dangerous-than-no-failover-2c9o</link>
      <guid>https://dev.to/giulianiregspec/when-automatic-failover-is-more-dangerous-than-no-failover-2c9o</guid>
      <description>&lt;p&gt;Here's a counterintuitive thing I ran into building redundancy for DoSync, an open protocol that lets AI agents act on physical devices: the obvious failover design can hurt you more than having no failover at all.&lt;br&gt;
Let me show you why.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The setup&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DoSync runs a hub — the process that turns a semantic intent ("there's an emergency") into coordinated device actions, and writes every action to an audit log. That log is a SHA-256 hash chain: each entry includes the hash of the previous one, so any edit to history breaks the chain and is detectable. It's the part of the system that lets you answer "what happened, and when?" with confidence.&lt;br&gt;
One hub is a single point of failure. So the natural move is to add a standby that takes over when the primary dies. The naive design writes itself: the standby pings the primary every few seconds, and after N missed heartbeats it promotes itself to primary.&lt;br&gt;
It works perfectly in a demo. It's dangerous in a house.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The trap: split-brain&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Picture two hubs on your LAN. The network partitions — not the primary crashing, just the link between the two going away. The primary is alive and well, still serving its devices. But the standby can't see it.&lt;br&gt;
So the standby promotes itself. Now you have two primaries, both convinced they're in charge, both writing to the audit log. The hash chain that made that log tamper-evident diverges into two incompatible histories. The one guarantee the whole system is built on — you can always reconstruct what happened — is gone.&lt;br&gt;
A missed heartbeat doesn't tell you "the primary is dead." It tells you "I can't reach the primary." Those are very different statements, and the naive design treats them as the same.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The fix is mostly about honesty&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The real solution to split-brain is a quorum — three nodes voting, à la Raft. But for a home or a small building, that's overkill, and you usually don't have a third node anyway.&lt;br&gt;
So I went with something simpler and more honest: assisted failover. Two changes.&lt;br&gt;
First, before the standby concludes anything, it runs a second probe against an independent target on the LAN (the gateway):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;primary unreachable + gateway reachable  → primary is probably down
primary unreachable + gateway also down  → *I* am probably the problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That one extra check separates two failure modes the naive design conflates. It is not a substitute for quorum — it doesn't help in every partition (if both hubs can still see the gateway but not each other, the probe tells you nothing). What it cheaply catches is the most common home case: the standby itself losing its network. When that happens, the standby enters an UNCERTAIN state and refuses to act.&lt;br&gt;
Second — even when it does think the primary is down, it doesn't promote itself. It proposes promotion to a human. A person can glance at the situation and see whether the primary is actually alive. A 5-second heartbeat timeout cannot.&lt;br&gt;
(To be clear, this whole multi-hub layer is opt-in. A single hub runs exactly as before — redundancy is for people who want it, not a requirement.)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Testing it on real hardware&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I ran this on two real machines — a Raspberry Pi (primary) and a laptop (standby) — because this is exactly the kind of behavior that only shows up with real network conditions, not in unit tests.&lt;br&gt;
Killing the primary process: standby detected it, gateway probe still succeeded, proposed promotion. Good.&lt;br&gt;
Pulling the standby's network while the primary stayed up: standby saw both targets go dark, went UNCERTAIN, and stayed quiet. In that test, the only difference between "propose promotion" and "stay quiet" was the gateway probe — one bit of extra information deciding between a safe outcome and a corrupted log.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The takeaway&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Availability features have a failure mode of their own. An automatic action taken on bad information can be worse than no action plus a clear signal to a human. For anything writing to physical state — locks, alarms, logs you can't afford to corrupt — "fail loudly and ask" is often a better default than "fail over silently," at least until you have real consensus to back automatic promotion.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;DoSync&lt;/em&gt; is open source (Apache 2.0). If you want to poke holes in this design — and I'd genuinely like that — it's at &lt;a href="//dosync.dev"&gt;dosync.dev&lt;/a&gt;. The failover logic is a small, dependency-free state machine; criticism welcome.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why your smart home breaks the moment you add an AI agent</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Wed, 03 Jun 2026 01:27:33 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/why-your-smart-home-breaks-the-moment-you-add-an-ai-agent-3i4e</link>
      <guid>https://dev.to/giulianiregspec/why-your-smart-home-breaks-the-moment-you-add-an-ai-agent-3i4e</guid>
      <description>&lt;p&gt;You add a new smoke detector to your home network. It registers with the hub. Thirty seconds later, when someone fires an &lt;code&gt;ensure_safety&lt;/code&gt; intent, the detector is part of the response — no automation written, no rule updated, no developer intervention.&lt;br&gt;
How is that possible?&lt;br&gt;
The answer is capability abstraction. And it's the design decision that separates systems that work with AI from systems that merely tolerate it.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The device that knows its own role&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Every existing smart home protocol treats a device as a passive endpoint. The device waits. Something external — an app, a rule engine, a developer's script — decides when to call it and what to tell it. The device's only job is to execute.&lt;br&gt;
This model has a hidden assumption: that someone, somewhere, anticipated every scenario the device would be relevant for. They wrote the rule. They tested it. They kept it updated as new devices joined the network.&lt;br&gt;
That assumption holds when humans are in the loop. It breaks the moment an AI agent enters the picture — because the AI doesn't have the rulebook. It has a goal. And the gap between "I have a goal" and "I know which devices to activate" is exactly the integration problem that makes AI-IoT systems fragile.&lt;br&gt;
The fix is to move the knowledge of when a device is relevant from the rulebook into the device itself.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The Capability Manifest — a declaration, not an API&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In DoSync, every device publishes a Capability Manifest when it joins the network. Here's a real one from the production deployment — a Philips WiZ bulb running on a Raspberry Pi 5:&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="err"&gt;json&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"device_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wiz-living1-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"device_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;"Living Room — Bulb 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"manufacturer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Philips"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WiZ RGBW Tunable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"firmware"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.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;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"actuator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&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;"light"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"climate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"smart-plug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"emergency"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wiz"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actuators"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wiz-living1-01-turn_on"&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;"turn_on"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Turn on"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wiz-living1-01-turn_off"&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;"turn_off"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Turn off"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wiz-living1-01-set_brightness"&lt;/span&gt;&lt;span class="p"&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;"set_brightness"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Set brightness 0-100%"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wiz-living1-01-set_color"&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;"set_color"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Set RGB color"&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;"sensors"&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;"emergency_capable"&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="nl"&gt;"adapter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wiz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"adapter_config"&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;"ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"192.168.100.28"&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 isn't an API specification. It's a declaration of identity and relevance. The device is answering three questions at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What can I do? — turn on, turn off, set brightness, set color&lt;/li&gt;
&lt;li&gt;Where do I fit? — I'm a light, I'm a smart plug, I'm an &lt;code&gt;emergency&lt;/code&gt; device&lt;/li&gt;
&lt;li&gt;When do I matter? — I'm emergency-capable; include me when safety is at stake&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI agent never needs to know the device's native protocol. It fires:&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="err"&gt;json&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ensure_safety"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"urgency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"emergency"&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 resolver reads every registered manifest, scores each device for relevance — weighting tag overlap, location context, emergency bonus, and actuator match — and builds the action plan. The bulb is included because of its &lt;code&gt;emergency&lt;/code&gt; tag and &lt;code&gt;emergency_capable&lt;/code&gt;: true — not because anyone hardcoded it. Add ten more bulbs tomorrow with the same manifest structure, and they participate immediately in every emergency response.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;emergency_capable&lt;/code&gt; is a contract, not a flag&lt;br&gt;
This boolean deserves more attention than it usually gets.&lt;br&gt;
When a device declares emergency_capable: true, it's not filling in a form field. It's making a commitment to the protocol:&lt;br&gt;
&lt;em&gt;I will respond to emergency intents without confirmation. I accept being included in the audit trail as a critical actor. I understand that my actions in emergencies will be logged with a tamper-evident SHA-256 chain.&lt;/em&gt;&lt;br&gt;
The protocol enforces this contract. Emergency-capable devices bypass the normal policy evaluation flow. They're always included as candidates in emergency intent resolution, regardless of tag overlap. And every action they take is logged — precisely because actions taken during emergencies are consequential enough to require a verifiable record.&lt;br&gt;
This is the correct place for a safety guarantee to live. Not in a rule written by a developer who may or may not have anticipated the edge case. In the device's own declaration, verified and enforced by the protocol at runtime.&lt;br&gt;
Compare the two designs:&lt;br&gt;
Rule-based:  developer writes "if emergency, unlock frontdoor-01"&lt;br&gt;
             → breaks when frontdoor-01 is replaced&lt;br&gt;
             → breaks when a second entrance is added&lt;br&gt;
             → breaks when the emergency scenario changes&lt;/p&gt;

&lt;p&gt;Capability:  device declares emergency_capable: true&lt;br&gt;
             → protocol enforces the contract&lt;br&gt;
             → survives device replacement, new entrances, new scenarios&lt;br&gt;
             → audit trail is automatic&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why this is different from OpenAPI, MCP, and service registries&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Capability abstraction is an old pattern. OpenAPI schemas describe what an HTTP service can do. MCP tool descriptions tell an LLM which tools are available and when to use them. Service registries in microservices architectures let services announce themselves at runtime.&lt;br&gt;
DoSync's Capability Manifest is in this family. But there's a specific difference that matters for physical systems.&lt;br&gt;
OpenAPI and MCP describe interfaces — the exact shape of inputs and outputs. They're precise but context-free. An OpenAPI schema for a door lock tells you the &lt;code&gt;/unlock&lt;/code&gt; endpoint accepts a &lt;code&gt;duration_seconds&lt;/code&gt; integer. It doesn't tell you that this lock is at the main entrance, that it's relevant in emergencies, or that it should be included in a safety response but not an energy-saving routine.&lt;br&gt;
The Capability Manifest adds semantic context on top of interface description. The &lt;code&gt;tags&lt;/code&gt; field isn't a type system — it's a declaration of relevance across scenarios. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;["door-lock", "entrance", "emergency"]&lt;/code&gt;&lt;br&gt;
 tells the resolver three things that no API schema can express: what the device is, where it lives, and when it matters.&lt;br&gt;
This distinction exists because AI agents reason at the semantic level, not the API level. An LLM detecting an emergency thinks "there's a safety situation" — not "send a PUT request to /api/v1/lock/frontdoor-01/state with body &lt;code&gt;{locked: false, duration: 300}"&lt;/code&gt;. The abstraction layer has to meet the AI where it operates — at the level of meaning, not syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The device as a participant&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here's the shift capability abstraction enables, stated plainly:&lt;br&gt;
In the command model, adding a device means updating your automations. The device is inert until a human decides it should participate in something.&lt;br&gt;
In the capability model, adding a device is the integration. The manifest is the contract. From the moment it registers, the device participates in every scenario it declared itself relevant for.&lt;br&gt;
Before:  new device → engineer writes automation → device participates in scenario A&lt;br&gt;
         new scenario B → engineer writes automation → device participates in scenario B&lt;/p&gt;

&lt;p&gt;After:   new device registers manifest → device participates in all relevant scenarios&lt;br&gt;
         new scenario added to protocol → device participates automatically&lt;br&gt;
This is not a small operational difference. In a home with 40+ devices, maintaining the "before" model means hundreds of automation rules, each one a potential failure point when a device changes or a scenario is updated. The "after" model has one integration surface per device — the manifest — and it never needs to be updated when scenarios change.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What the manifest teaches manufacturers&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you're building a device that will coexist with AI agents, the Capability Manifest is the interface that matters more than your API documentation.&lt;br&gt;
A well-designed manifest answers the questions AI systems actually ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Will this device respond in an emergency? → &lt;code&gt;emergency_capable&lt;/code&gt;: &lt;code&gt;true/false&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;What kind of device is this? → &lt;code&gt;category&lt;/code&gt; + semantic &lt;code&gt;tags&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;What can it physically do? → &lt;code&gt;actuators&lt;/code&gt; with meaningful type names&lt;/li&gt;
&lt;li&gt;What can it sense? → &lt;code&gt;sensors&lt;/code&gt; with type and unit&lt;/li&gt;
&lt;li&gt;How does the protocol talk to it? → &lt;code&gt;adapter&lt;/code&gt; + &lt;code&gt;adapter_config&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A poorly designed manifest — missing location tags, wrong &lt;code&gt;emergency_capable&lt;/code&gt; value, generic actuator types — means the device is invisible to the AI in exactly the scenarios where it should matter most. The resolver can only work with what the device declares.&lt;br&gt;
Tag your devices correctly. The rest is automatic.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The idea worth keeping&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Five posts ago, we started with a simple observation: AI agents express goals, not commands. Every post since then has been an answer to the same question — what does a system have to look like, at each layer, to bridge that gap?&lt;br&gt;
Semantic intent replaced commands. Policies replaced rules. Events were separated from intents. And now capability abstraction replaces the developer who used to be the translator between device APIs and AI goals.&lt;br&gt;
The translator was always the fragile part. Every time a device changed, the translator broke. Every time a new scenario appeared, the translator had to be updated. Every time an AI agent expressed something that wasn't anticipated, the translator failed silently.&lt;br&gt;
Capability abstraction removes the translator. The device speaks for itself. The AI listens. The protocol enforces the contracts between them.&lt;br&gt;
That's not a smart home feature. That's the infrastructure for any physical environment where AI needs to act reliably.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GitHub: &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;https://github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;br&gt;
Website: &lt;a href="https://dosync.dev" rel="noopener noreferrer"&gt;https://dosync.dev&lt;/a&gt;&lt;br&gt;
License: Apache 2.0&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>iot</category>
      <category>architecture</category>
      <category>dosync</category>
    </item>
    <item>
      <title>Rules Aren't Enough Once an AI Is in the Loop</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Sat, 30 May 2026 03:06:15 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/rules-arent-enough-once-an-ai-is-in-the-loop-5cdg</link>
      <guid>https://dev.to/giulianiregspec/rules-arent-enough-once-an-ai-is-in-the-loop-5cdg</guid>
      <description>&lt;p&gt;Picture this: it's 03:00. A camera detects that an elderly person has fallen in the bedroom. The AI agent fires &lt;code&gt;ensure_safety [emergency]&lt;/code&gt;. The action plan includes unlocking the front door so emergency services can get in.&lt;br&gt;
But someone wrote a rule three months ago: never unlock after midnight.&lt;br&gt;
The rule wins. The door stays locked. The paramedics arrive and can't get in.&lt;br&gt;
This is not a bug in the AI. It's not a bug in the rule — in any other context, locking the door at night is exactly right. It's a design problem — and it's the exact problem that appears when you build physical AI systems on top of automation logic that was never designed for an AI to act on.&lt;br&gt;
The difference between a rule and a policy looks small from a distance. Both constrain behavior. Both say "don't do X in situation Y." But they operate at different levels of the system — and getting this distinction wrong in a physical environment has real consequences.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What a rule is&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A rule is a static, pre-written instruction that maps a condition to an action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;motion_detected&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;away_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;alarm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;turn_on&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rules live in the automation layer. They're written by a human, at configuration time, for a specific scenario that was anticipated in advance. They're deterministic in the right circumstances: given the same input, they always produce the same output.&lt;br&gt;
Rules work well when the world is predictable, the device set is stable, and a human is always the one deciding what to do. They've been the foundation of home automation for fifteen years for exactly this reason. Nothing in this article argues that rules are wrong or should be replaced — they're the right tool for scheduling, thresholds, and simple automations that a human configured deliberately. A rule that turns on the porch light at sunset doesn't need a policy — it has no safety implications, no edge cases, and no AI acting on it. Rules fail not because they're a bad idea, but because they were never designed to compose with an autonomous agent that can fire arbitrary intents at arbitrary times.&lt;br&gt;
But rules have a structural weakness: they can only respond to situations that were anticipated when they were written. And when an AI agent starts firing intents, the space of possible situations grows faster than anyone can write rules for.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What breaks when AI enters the picture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;An AI agent doesn't write rules. It fires intents.&lt;br&gt;
When a vision model detects someone who has fallen, it doesn't execute alarm.activate() and phone.call("911") — it fires ensure_safety [emergency]. When a model infers that nobody is home, it doesn't iterate through a list of devices and turn them off one by one — it fires save_energy [info].&lt;br&gt;
The intent expresses a goal. The protocol figures out how to achieve it.&lt;br&gt;
But here's the problem: once you have an AI agent firing intents, you need a way to constrain what it can and can't do — without writing a rule for every possible scenario. You need something that can evaluate intent against context at runtime, not something that was pre-written for a specific situation.&lt;br&gt;
You need a policy engine.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The difference that matters&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A rule answers: &lt;em&gt;what should happen when X occurs?&lt;/em&gt;&lt;br&gt;
A policy answers: &lt;em&gt;is this action permitted, given who's asking, what they want to do, and when?&lt;/em&gt;&lt;br&gt;
The distinction is not cosmetic. It changes the entire structure of how you think about safety in a physical system.&lt;br&gt;
Consider a front door lock. With rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Rule 1: lock at midnight
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Rule 2: unlock for delivery window
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;delivery_expected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unlock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These rules handle the scenarios they were written for. But what happens when an AI agent fires &lt;code&gt;control_access [emergency]&lt;/code&gt; at 03:00 because it detected an intruder? What happens when a different AI agent fires &lt;code&gt;away_mode&lt;/code&gt; which includes an unlock action? What happens when two intents fire simultaneously and both want to act on the lock?&lt;br&gt;
Rules don't compose. Each rule was written in isolation, without knowledge of the others. In a system where an AI can fire arbitrary intents at arbitrary times, the rule surface grows unbounded — and the gaps between rules are exactly where accidents happen.&lt;br&gt;
A policy is different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;pythonNeverAfterHoursPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;actuator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unlock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;device_ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lock-frontdoor-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;blocked_hours&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;      &lt;span class="c1"&gt;# never unlock 00:00–06:00
&lt;/span&gt;    &lt;span class="n"&gt;except_urgency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;emergency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;# unless it's an emergency
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This policy applies to every intent that would unlock the front door, regardless of which AI fired it, regardless of what scenario triggered it. It's declared once. It evaluates at runtime. It composes with other policies automatically.&lt;br&gt;
And it has an explicit emergency exception — because in a physical system, the rule "never unlock after midnight" has to be breakable in genuine emergencies. Rules can't express that nuance cleanly. Policies can.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What a policy engine actually does&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In DoSync, every intent passes through the PolicyEngine before execution. The engine evaluates the action plan against all configured policies and returns one of four verdicts:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ALLOW&lt;/code&gt; — proceed as planned&lt;br&gt;
&lt;code&gt;BLOCK&lt;/code&gt; — reject the intent entirely&lt;br&gt;
&lt;code&gt;CONFIRM&lt;/code&gt; — hold execution and request human confirmation&lt;br&gt;
&lt;code&gt;MODIFY&lt;/code&gt; — allow execution but remove or adjust specific actions&lt;/p&gt;

&lt;p&gt;This happens between the resolver (which decides what to do) and the executor (which actually does it). The AI never bypasses this layer — not even for emergency intents, which bypass policy constraints at the urgency level, not by circumventing the engine entirely.&lt;br&gt;
In DoSync, this looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="c1"&gt;# An AI fires save_energy at 02:00
&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;IntentClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SAVE_ENERGY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;urgency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Urgency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;trigger&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;occupancy_inferred_empty&lt;/span&gt;&lt;span class="sh"&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;# The resolver builds an action plan:
# → turn_off: wiz-living-01..10
# → turn_off: wiz-hallway-01       ← this one is excluded by policy
# → set_temperature: thermostat-01
&lt;/span&gt;
&lt;span class="c1"&gt;# The PolicyEngine evaluates:
# DeviceExclusionPolicy: hallway light excluded from save_energy → MODIFY
# ContextualWeightingPolicy: 02:00 on a weekday → weight reduced but ALLOW
&lt;/span&gt;
&lt;span class="c1"&gt;# The executor receives the modified plan:
# → turn_off: wiz-living-01..10
# → set_temperature: thermostat-01
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI expressed a goal. The protocol decided how to achieve it. The policy engine ensured the result was safe — without the AI needing to know anything about the hallway light policy, or the time-based weighting, or which devices are excluded from which intents.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why this matters beyond the home&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The rule/policy distinction becomes critical at scale and in regulated environments.&lt;br&gt;
In a hotel, a rule that says "turn off lights when nobody is in the room" works until a guest leaves their laptop charging and the system decides the room is empty. A policy that says "never cut power to outlet circuits in occupied rooms regardless of occupancy inference" handles the edge case — without needing a rule for every possible device state.&lt;br&gt;
In a hospital, a rule that says "lock all doors at 22:00" breaks the moment a crash cart needs to move between floors. A policy that says "door locks revert to unlocked state on emergency_capable override, regardless of schedule" is robust to the scenario that matters most — the one nobody wanted to think about at configuration time.&lt;br&gt;
In a factory, a rule that says "shut down line B if temperature exceeds threshold" doesn't compose with the rule that says "never shut down line B during a shift change handover." A ConflictResolutionPolicy that assigns priorities to intents and resolves contention explicitly is the right abstraction — not an ever-growing set of conditional rules that interact in unpredictable ways.&lt;br&gt;
The pattern is always the same: rules break at the boundaries between anticipated scenarios. Policies compose across all of them.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The audit implication&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There's one more difference that matters in regulated environments: auditability.&lt;br&gt;
A rule that fires an action leaves a trace, but the reasoning is implicit — buried in the automation logic that evaluated the condition. If something goes wrong, you can see what happened, but reconstructing why requires reading the rule code.&lt;br&gt;
A policy verdict is explicit. Every intent execution in DoSync's audit log records what happened, what the resolver decided, and what the executor did — in a tamper-evident SHA-256 chained record. The reasoning is in the system's configuration (which policies are active, with what parameters), not buried in conditional logic that has to be reverse-engineered after the fact.&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="err"&gt;json&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;"intent_executed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"intent"&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_energy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"urgency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"failed"&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;"success"&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="nl"&gt;"hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a3f7..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prev_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9c12..."&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 matters for post-incident analysis. It matters for regulatory compliance. And it matters for the fundamental accountability question in any AI-augmented physical system: when something goes wrong, can you reconstruct exactly what the system decided and why?&lt;br&gt;
With rules, the answer is usually "mostly." With policies, the answer is "yes, completely."&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The deeper point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Rules encode what to do. Policies encode what's permitted.&lt;br&gt;
When a human is always in the loop, rules are enough — the human's judgment fills the gap between what the rules say and what should actually happen. When an AI agent is in the loop, that judgment gap has to be filled by the infrastructure.&lt;br&gt;
That's what a policy engine is for. Not to constrain the AI arbitrarily, but to make the system's safety model explicit, configurable, and auditable — so that the AI can act autonomously within a boundary that a human defined deliberately.&lt;br&gt;
The AI expresses goals. The protocol executes them. The policy engine ensures the result is safe.&lt;br&gt;
That's the contract a physical AI system needs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;DoSync Protocol: &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;https://github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;br&gt;
License: Apache 2.0&lt;/em&gt;&lt;/p&gt;

</description>
      <category>iot</category>
      <category>ai</category>
      <category>architecture</category>
      <category>security</category>
    </item>
    <item>
      <title>How I Used GitHub Copilot to Turn a Half-Finished Protocol Into a Certified Standard published</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Wed, 27 May 2026 02:23:47 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/how-i-used-github-copilot-to-turn-a-half-finished-protocol-into-a-certified-standardpublished-20cd</link>
      <guid>https://dev.to/giulianiregspec/how-i-used-github-copilot-to-turn-a-half-finished-protocol-into-a-certified-standardpublished-20cd</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;DoSync Protocol is an open-source communication protocol (Apache 2.0) that lets AI agents control physical devices using semantic intentions instead of commands. Instead of lock.unlock(), an AI agent says ensure_safety — and every registered device figures out its own role automatically.&lt;br&gt;
The Python reference implementation was running in production on a Raspberry Pi 5. But a protocol with only one implementation isn't a standard — it's a library. The unfinished piece: a second independent Node.js implementation that could pass the DoSync certification suite.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;https://github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcq0t78qi7je8xbvprrfx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcq0t78qi7je8xbvprrfx.png" alt="VS Code with GitHub Copilot Chat suggesting the GET /v1/status endpoint on the right, and the terminal showing DoSync Standard certification passing 11/11 on the left" width="800" height="424"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;── Tier BASIC ─────────────────────────────────────────────
  ✓  Hub reachable — version 0.1.0
  ✓  Protocol version declared — dosync/0.1
  ✓  Device can register — registered
  ✓  Device appears in registry — 1 device registered
  ✓  Hub returns device detail — status=200
  ✓  Capability manifest has all required fields — all present
── Tier STANDARD — Intents and events ─────────────────────
  ✓  Hub accepts notify_family intent — 4 actions executed
  ✓  Intent resolves correctly — 4 actions processed
  ✓  Device can send event — received
  ✓  Hub rejects unknown intents with 422 — status=422
  ✓  Hub rejects unregistered device events with 404 — status=404
── Result ──────────────────────────────────────────────────
  Tests passed: 11
  Tests failed: 0
  ✓ CERTIFIED — DoSync STANDARD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;Before: The Node.js implementation (implementations/dosync-node) passed Basic certification (6/6 tests) — it could register devices and handle simple queries. But Standard tier was failing at test 1 because the server was missing GET /v1/status, the endpoint the certification suite uses to verify hub identity and protocol version.&lt;br&gt;
Additionally, the certification CLI (certify.py) only supported HTTP — but the production hub runs on HTTPS with a local PKI. Running Standard tests against real infrastructure was impossible.&lt;br&gt;
What changed:&lt;br&gt;
certify.py — fixed to support real deployments:&lt;/p&gt;

&lt;p&gt;HTTPS support with CA certificate validation via DOSYNC_CA_CERT&lt;br&gt;
Bearer token injection via DOSYNC_TOKEN&lt;br&gt;
Localhost detection: HTTP for local dev, HTTPS for remote&lt;br&gt;
Connectivity test fixed to use /v1/status instead of / (which returns the HTML dashboard)&lt;/p&gt;

&lt;p&gt;dosync-node — the missing endpoint, added with Copilot:&lt;/p&gt;

&lt;p&gt;GET /v1/status — the single endpoint that unlocked Standard certification&lt;/p&gt;

&lt;p&gt;After: dosync-node passes DoSync Standard certification (11/11). Two independent implementations in different languages, same protocol, same certification suite — the minimum criterion for an open standard.&lt;/p&gt;
&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;Copilot contributed in two ways during this session.&lt;br&gt;
Inline suggestions while editing certify.py. As I was modifying the HTTP helper to support HTTPS and token injection, Copilot's inline suggestions consistently anticipated the next line — the SSL context setup, the os.environ.get() calls, the exception handling pattern. It didn't write the logic, but it reduced the friction of writing boilerplate correctly on the first pass.&lt;br&gt;
The endpoint that closed the gap. Once I identified that GET /v1/status was the missing piece, I asked Copilot Chat:&lt;/p&gt;

&lt;p&gt;"I'm implementing the DoSync Protocol in Node.js. The certification suite requires a GET /v1/status endpoint that returns name, version, protocol, status, devices count, and audit_entries count. The existing code uses Fastify. Please add this endpoint following the same patterns already in the file."&lt;/p&gt;

&lt;p&gt;Copilot read the existing file, identified the right variable names (registry, auditLog, VERSION, PROTOCOL), and generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javascript// GET /v1/status
app.get('/v1/status', async () =&amp;gt; ({
  name:          'DoSync Hub',
  version:       VERSION,
  protocol:      PROTOCOL,
  status:        'running',
  devices:       registry.size,
  audit_entries: auditLog.length,
}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Correct variable names. Correct Fastify pattern. No hallucinations. The key was giving Copilot the right context: the spec requirement, the existing code pattern, and the constraint. It didn't need to invent — it needed to synthesize what was already there.&lt;br&gt;
After accepting the suggestion, the certification run went from 0/11 to 11/11. GitHub Copilot helped close the gap between "protocol with one implementation" and "protocol with a certified standard."&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;https://github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;br&gt;
License: Apache 2.0&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
    </item>
    <item>
      <title>Why AI Agents and IoT Protocols Speak Different Languages</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Tue, 26 May 2026 13:21:13 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/why-ai-agents-and-iot-protocols-speak-different-languages-831</link>
      <guid>https://dev.to/giulianiregspec/why-ai-agents-and-iot-protocols-speak-different-languages-831</guid>
      <description>&lt;p&gt;There's a distinction that comes up constantly when designing systems that connect AI to physical environments, and it's one that most protocols blur or ignore entirely.&lt;br&gt;
The distinction is between an event and an intent.&lt;br&gt;
They look similar on the surface. Both are messages. Both carry information about the world. But they describe fundamentally different things — and building a system that confuses them leads to brittleness, fragility, and automation that breaks exactly when it matters most.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What an event is&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;An event is a description of something that happened.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;json{
  "device": "pir-sensor-01",
  "type": "motion_detected",
  "timestamp": 1748000000,
  "location": "entrance"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An event is past tense. It's factual. It carries no opinion about what should happen next. The PIR sensor doesn't know whether this motion means "the kids just got home" or "there's an intruder" or "the cat walked by again." It just observed something and reported it asynchronously — fire and forget.&lt;br&gt;
Events are the raw material of a physical system. Sensors generate them constantly — temperature readings, contact closures, power measurements, motion pulses. They are objective and dumb, in the best possible sense.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What an intent is&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;An intent is a description of something that needs to happen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;json{
  "intent": "children_arrived_home",
  "urgency": "info",
  "context": {
    "trigger": "motion_detected",
    "time": "18:45",
    "day": "monday"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An intent is future tense. It carries meaning. It encodes a goal — what the system should achieve — without specifying how to achieve it. The intent doesn't say "turn on lights 3, 7, and 9 at 80% brightness." It says "the kids are home." The infrastructure figures out the rest.&lt;/p&gt;

&lt;p&gt;The leap from event to intent requires reasoning. Something has to look at the motion event, consider the time, the day, the history, and decide: this event means the kids just arrived. That reasoning is exactly what AI agents are good at.&lt;/p&gt;

&lt;p&gt;Concretely, that transition 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;[PIR fires motion_detected at 18:45 on Monday]
        ↓
  AI agent reasons:
  - time: 18:45 → within arrival window
  - day: Monday → weekday
  - location: entrance → consistent with arrival
        ↓
  fires: children_arrived_home [info]
        ↓
  hub resolves against device registry:
  → 5 lights turn on
  → SMS sent to parents
  → audit log updated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent handled the meaning. The protocol handled the coordination.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why conflating the two breaks systems&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Most smart home platforms today — Home Assistant automations, Matter scenes, Zigbee rules — are built on a hidden assumption: that the translation from event to action is a simple, static mapping.&lt;br&gt;
IF motion_detected AND time &amp;gt; 18:00 AND day IN [Mon, Tue, Wed, Thu, Fri]&lt;br&gt;
THEN turn_on(light_1), turn_on(light_2), send_sms("kids home")&lt;br&gt;
This works until it doesn't. Add a new light and the rule doesn't know about it. Change the schedule and you rewrite rules. Move to a new home with different devices and you start over. The rule hardcodes both the reasoning ("this motion means the kids arrived") and the execution ("these specific lights, this specific message").&lt;br&gt;
Separating events from intents breaks this coupling.&lt;br&gt;
The AI agent handles the reasoning layer: event → intent. It observes the motion, considers the context, and decides what's happening. That reasoning can be as simple or as sophisticated as needed — a time-based rule, a learned pattern, or a full LLM inference.&lt;br&gt;
The protocol handles the execution layer: intent → actions. Once the intent is declared, every device that registered as relevant participates automatically. Add a new light and it joins the response. Remove a device and the system adapts. No rules to rewrite.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why this matters beyond the home&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The event/intent separation is not a smart home concept. It's an architectural pattern for any system where AI needs to act on physical infrastructure.&lt;br&gt;
&lt;strong&gt;In a factory:&lt;/strong&gt; a temperature sensor fires threshold_exceeded on a critical component — that's an event. The AI reasons about it: abnormal reading, production line active, no scheduled maintenance — and determines execute_safe_shutdown. That's an intent. The execution is then coordinated automatically across the line: equipment powers down in sequence, the supervisor is paged, a maintenance request is logged, cooling activates. None of those responses were hardcoded for that specific sensor reading. Each system declared what it could do, and the protocol assembled the response.&lt;br&gt;
The pattern is always the same: the AI reasons about meaning, the infrastructure handles coordination. The temperature sensor does not know about the cooling system. The cooling system does not know about the sensor. The protocol coordinates both.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How DoSync implements this separation&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In DoSync, the separation is structural. Events flow in from sensors and adapters — raw, factual, carrying no prescription. Intents flow out from AI agents — meaningful, goal-oriented, carrying no implementation.&lt;br&gt;
The hub sits in between: it receives intents, resolves them against every device's declared Capability Manifest, and builds an action plan at runtime. The resolver never sees the original event. The sensor never sees the resulting actions. The layers are cleanly decoupled.&lt;br&gt;
That decoupling is what makes the system extensible by design. A new device joins the network, declares its capabilities, and automatically participates in every relevant intent — without any rule being written, without any configuration being changed.&lt;br&gt;
That's the architectural difference that matters.&lt;/p&gt;

&lt;p&gt;DoSync Protocol: &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;https://github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;br&gt;
License: Apache 2.0&lt;/p&gt;

</description>
      <category>iot</category>
      <category>ai</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Why AI Agents Like Hermes Need a Semantic Execution Layer for the Physical World</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Sat, 23 May 2026 16:20:14 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/why-ai-agents-like-hermes-need-a-semantic-execution-layer-for-the-physical-world-1985</link>
      <guid>https://dev.to/giulianiregspec/why-ai-agents-like-hermes-need-a-semantic-execution-layer-for-the-physical-world-1985</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;: Write About Hermes Agent&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Most AI agents interact with the world through APIs, databases, and web services. The feedback loop is fast and forgiving — if something goes wrong, you retry.&lt;br&gt;
Physical environments are different. A light that turns on twice isn't a problem. A door that unlocks at the wrong time is. An agent operating in the physical world needs not just reasoning capability, but a clear contract between what it decides and what actually executes.&lt;br&gt;
This post is about that contract — and why Hermes Agent's architecture makes it a natural fit for physical systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes Hermes Agent relevant here&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hermes Agent has three characteristics that matter specifically for physical environments:&lt;br&gt;
Native MCP support. Hermes connects to external systems via Model Context Protocol natively. Any hub or device layer that exposes an MCP server becomes immediately accessible — no custom integrations, no bridges.&lt;br&gt;
Multi-step tool use with context. Hermes doesn't just call tools — it reasons about which tool to call, in what order, based on context. For physical systems where the right action depends on time, location, and state, this matters.&lt;br&gt;
Open weights and local execution. Physical environments often have strict privacy requirements. A system that can run fully local — without sending home sensor data to a cloud provider — is architecturally different from one that can't.&lt;br&gt;
These three properties together describe an agent that can act on physical systems in a way that's both capable and auditable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gap it needs to cross&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every physical device protocol was designed around one assumption: a human decides what to do, and a device executes it. The protocols speak in commands — lock.unlock(), light.set_brightness(100).&lt;br&gt;
An AI agent doesn't produce commands. It produces understanding. "The kids just arrived home" is not a command. The translation from that understanding to the right set of device actions — for the specific devices available, in the right context — still has to be written by someone, in advance.&lt;br&gt;
This is where most physical AI integrations break down. The agent reasons correctly and the devices exist, but the translation layer between them is a pile of hardcoded rules that grows more fragile with every new device.&lt;br&gt;
A semantic execution layer inverts this. Instead of the agent knowing how to act, devices declare what they can do and when they're relevant. The agent expresses goals. The infrastructure handles translation at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An experiment: Hermes + DoSync&lt;/strong&gt;&lt;br&gt;
I tested this with DoSync Protocol, an open-source hub (Apache 2.0) that implements this semantic layer. Devices register with a capability manifest. The hub exposes a native MCP server.&lt;br&gt;
Connecting Hermes to DoSync required three lines in &lt;code&gt;~/.hermes/config.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;yaml&lt;/span&gt;
&lt;span class="na"&gt;mcp_servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dosync&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;/path/to/dosync/mcp_server.py&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;DOSYNC_HUB_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:47200&lt;/span&gt;
      &lt;span class="na"&gt;DOSYNC_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;token&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I gave Hermes a single prompt:&lt;br&gt;
&lt;em&gt;It's 18:45 on a Monday. The PIR sensor at the entrance just detected motion.&lt;/em&gt;&lt;br&gt;
What does the system do?&lt;/p&gt;

&lt;p&gt;Hermes queried the hub state, reasoned about the time and day, identified the appropriate semantic intent (children_arrived_home), and fired it once. Five physical lights turned on. An SMS was sent to the family. The audit log updated with two new SHA-256 chained entries.&lt;br&gt;
What Hermes didn't need to know: which specific bulbs to address, the SMS provider, or the schedule policy restricting this intent to weekday evenings. That knowledge lived in the hub. Hermes expressed a goal — the infrastructure handled execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The open question&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This experiment raises a boundary question that physical AI deployments will have to answer: where does agent reasoning end and infrastructure policy begin?&lt;br&gt;
Should Hermes decide which intent to fire, or should context mapping be pre-configured? When an agent acts in a physical environment with real consequences, how much autonomy is appropriate before a human needs to confirm?&lt;br&gt;
Hermes Agent's transparency — open weights, observable tool calls, local execution — makes it the right kind of system to explore these questions. You can see exactly what it reasoned and why. In physical environments, that auditability isn't a nice-to-have. It's a requirement.&lt;/p&gt;

&lt;p&gt;DoSync Protocol (open source): &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;https://github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;br&gt;
Hermes Agent: &lt;a href="https://hermes-agent.nousresearch.com" rel="noopener noreferrer"&gt;https://hermes-agent.nousresearch.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
      <category>ai</category>
    </item>
    <item>
      <title>Why Hardcoded Automations Fail AI Agents</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Fri, 22 May 2026 12:39:00 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/why-hardcoded-automations-fail-ai-agents-3b00</link>
      <guid>https://dev.to/giulianiregspec/why-hardcoded-automations-fail-ai-agents-3b00</guid>
      <description>&lt;p&gt;DoSync Concepts — Part 2 of 5&lt;/p&gt;

&lt;p&gt;There's a rule every smart home developer has written at least once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;motion_detected&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;turn_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hallway_light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works. It's simple. And it's the foundation of how every major home automation platform thinks about intelligence today.&lt;br&gt;
The problem isn't that the rule is wrong. The problem is what happens when you add an AI agent to the system — and why rules, no matter how many you write, are the wrong abstraction for that job.&lt;/p&gt;

&lt;p&gt;The rule-writing problem&lt;br&gt;
Rules are commands in disguise. "If X happens, do Y" is just a delayed command — the human still decided what Y should be, they just decided it in advance.&lt;br&gt;
That works perfectly when you can anticipate every scenario, your device set never changes, and the AI's job is simply to trigger pre-approved responses. None of those assumptions hold in a real AI-augmented environment.&lt;br&gt;
Consider what happens when you add a new device. A smart lock arrives. You register it with your platform. Now you have to go back through every relevant rule and add the lock. Miss one and the system silently does nothing in exactly the scenario where you needed it most.&lt;br&gt;
Or consider an AI that detects unusual temperature patterns in the kitchen — a sensor reading that might mean the fridge compressor is failing. The AI knows something is wrong. But there's no rule for "fridge compressor anomaly," because nobody wrote one. The system does nothing.&lt;br&gt;
This is the brittleness problem: hardcoded automations only respond to situations that were anticipated when the rule was written.&lt;/p&gt;

&lt;p&gt;Why AI agents make this worse, not better&lt;br&gt;
The intuitive solution is to write more rules, or smarter rules. Use the AI to generate them. Inspect logs and auto-suggest new automations.&lt;br&gt;
But this misses the architectural problem.&lt;br&gt;
An AI agent doesn't produce rules. It produces understanding. When a vision model detects a fall, it doesn't know it needs to call phone.call("911") and lock.unlock() and alarm.activate("emergency"). It knows there's an emergency. The translation from understanding to commands still has to be written somewhere — by someone — in advance.&lt;br&gt;
The more capable the AI, the more situations it can detect. And every new situation the AI can detect is a new set of rules that needs to be written to respond to it. The rule surface grows faster than anyone can maintain it.&lt;/p&gt;

&lt;p&gt;What capability-based discovery changes&lt;br&gt;
The alternative is to shift where the knowledge lives.&lt;br&gt;
Instead of centralizing the response logic in rules, distribute it to the devices themselves. Each device declares what it can do and in what contexts it's appropriate to act:&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="err"&gt;json&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"device_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lock-frontdoor-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&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;"door-lock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"entrance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"emergency"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actuators"&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;"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;"unlock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"emergency_capable"&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;"emergency_capable"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This manifest is not a rule. It's a declaration. The device is saying: I can unlock. I'm relevant in emergencies. I'm at the entrance.&lt;br&gt;
When the AI fires a semantic intent — ensure_safety / emergency — the resolver reads every registered manifest and asks: which devices declared themselves relevant to this situation? It builds the response at runtime, from what's actually available.&lt;br&gt;
ensure_safety [emergency]&lt;br&gt;
  → lock-frontdoor-01    unlock   (emergency_capable, entrance tag)&lt;br&gt;
  → alarm-main-01        activate (emergency_capable)&lt;br&gt;
  → wiz-living-01..10    turn_on  (light tag, full brightness)&lt;br&gt;
  → notifier-sms-01      notify   (communication tag)&lt;br&gt;
All in parallel. No rules written for this scenario.&lt;br&gt;
Add the smart lock tomorrow — it participates automatically in every relevant scenario. No rule rewriting. No code changes. The device brought its own knowledge.&lt;/p&gt;

&lt;p&gt;The difference that matters&lt;br&gt;
Hardcoded automations are fragile because they encode knowledge in a central place that can't keep up with change. Every new device, every new scenario, every new AI capability requires human intervention to update the rules.&lt;br&gt;
Capability-based discovery distributes that knowledge to the edges. Devices own their context. The system is resilient to change because adding new capabilities is additive, not a rewrite.&lt;br&gt;
For AI agents specifically, this is the difference between a system that only responds to situations you anticipated and a system that responds to situations the AI can detect — whether you anticipated them or not.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;https://github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;br&gt;
License: Apache 2.0&lt;/p&gt;

&lt;p&gt;DoSync Concepts is a series exploring the ideas behind the DoSync Protocol — the semantic layer between AI agents and physical systems.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>ai</category>
      <category>opensource</category>
      <category>architecture</category>
    </item>
    <item>
      <title>What is Semantic Intent? And Why It's Not the Same as a Command</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Sun, 17 May 2026 16:34:48 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/what-is-semantic-intent-and-why-its-not-the-same-as-a-command-1ggb</link>
      <guid>https://dev.to/giulianiregspec/what-is-semantic-intent-and-why-its-not-the-same-as-a-command-1ggb</guid>
      <description>&lt;p&gt;DoSync Concepts — Part 1 of 5&lt;/p&gt;

&lt;p&gt;There's a word that keeps appearing in conversations about AI and the physical world: intent.&lt;br&gt;
We say things like "the AI understood my intent" or "I want the system to infer my intent from context." But when you actually sit down to build something — a smart home, a hospital room, a hotel — you quickly discover that most protocols don't have a concept of intent at all.&lt;br&gt;
They have commands.&lt;br&gt;
And that difference, small as it sounds, is architectural. It changes everything about how you build systems that are supposed to work with AI.&lt;/p&gt;

&lt;p&gt;The command model&lt;br&gt;
Every smart home protocol in existence today was designed around one assumption: a human decides what to do, an app translates that decision into a specific instruction, and a device executes it.&lt;br&gt;
Human → App → Command → Device&lt;br&gt;
lock.unlock()&lt;br&gt;
light.set_brightness(80)&lt;br&gt;
thermostat.set_temperature(21)&lt;br&gt;
This is the command model. It works beautifully when the human is in the loop — when someone taps a button, sets a schedule, or writes a rule. The intent is implicit in the human's action. The app just needs to translate it correctly.&lt;br&gt;
The problem starts when you remove the human.&lt;/p&gt;

&lt;p&gt;What an AI agent actually produces&lt;br&gt;
When an AI system observes the world — a camera detecting a fall, a sensor registering unusual temperature, a model inferring that nobody is home — it doesn't produce a command. It produces an understanding of a situation.&lt;br&gt;
"There is an emergency."&lt;br&gt;
"The person who lives here has arrived."&lt;br&gt;
"Something is wrong with the refrigerator."&lt;br&gt;
These are not commands. They're semantic descriptions of a state of the world. They describe what is happening or what needs to happen, not how to make it happen.&lt;br&gt;
To translate this into device commands, someone has to write that translation — manually, in advance, for every possible situation, for every device combination. Miss one edge case and the system does nothing. Add a new device and you rewrite the rules.&lt;br&gt;
This is the command gap. And it only becomes visible when you try to add AI to a physical system.&lt;/p&gt;

&lt;p&gt;Semantic intent: a different contract&lt;br&gt;
A semantic intent is a structured expression of a goal — what needs to be achieved — without specifying how to achieve it.&lt;br&gt;
Compare:&lt;br&gt;
json// Command (existing protocols)&lt;br&gt;
{&lt;br&gt;
  "device": "lock-frontdoor-01",&lt;br&gt;
  "command": "unlock",&lt;br&gt;
  "duration": 300&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Semantic Intent (DoSync)&lt;br&gt;
{&lt;br&gt;
  "intent": "ensure_safety",&lt;br&gt;
  "urgency": "emergency",&lt;br&gt;
  "context": {&lt;br&gt;
    "trigger": "fall_detected",&lt;br&gt;
    "location": "bedroom"&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
The command says: unlock this specific lock for 5 minutes.&lt;br&gt;
The intent says: there is a safety emergency in the bedroom.&lt;br&gt;
The difference isn't just syntactic. It's about who holds the knowledge.&lt;br&gt;
In the command model, the knowledge of which devices to activate and how lives in the app, or in the rules engine, or in the code a developer wrote last year. That knowledge is static. It can't adapt to new devices, new scenarios, or new contexts.&lt;br&gt;
In the intent model, that knowledge lives in the devices themselves — in their Capability Manifests. Each device declares what it can do and when it's appropriate to act. The system assembles the response at runtime, based on what's available.&lt;/p&gt;

&lt;p&gt;How DoSync implements this&lt;br&gt;
In DoSync, every device publishes a Capability Manifest when it joins the network:&lt;br&gt;
json{&lt;br&gt;
  "device_id": "lock-frontdoor-01",&lt;br&gt;
  "tags": ["door-lock", "entrance", "emergency"],&lt;br&gt;
  "actuators": [&lt;br&gt;
    { "type": "unlock", "description": "Unlock for emergency access" },&lt;br&gt;
    { "type": "lock" }&lt;br&gt;
  ],&lt;br&gt;
  "emergency_capable": true&lt;br&gt;
}&lt;br&gt;
This manifest is not a command interface. It's a declaration of capability and context. The device is saying: I can unlock. I am relevant in emergencies. I am at the entrance.&lt;br&gt;
When an AI agent fires an intent:&lt;br&gt;
json{&lt;br&gt;
  "intent": "ensure_safety",&lt;br&gt;
  "urgency": "emergency"&lt;br&gt;
}&lt;br&gt;
The DoSync semantic resolver reads every registered manifest and asks: which devices are relevant to this intent, given their declared capabilities and tags? It builds an action plan automatically — no rules written, no pre-configuration required.&lt;br&gt;
ensure_safety [emergency]&lt;br&gt;
  → lock-frontdoor-01    unlock  (emergency_capable, entrance tag)&lt;br&gt;
  → alarm-main-01        alarm   (emergency_capable)&lt;br&gt;
  → phone-family-01      call    (communication tag)&lt;br&gt;
  → wiz-living-01..10    turn_on (light tag, full brightness)&lt;br&gt;
All in parallel. Under 100ms. No internet. No cloud.&lt;br&gt;
Add a new device tomorrow — a smart siren, a second lock, a notification relay — and it participates automatically in every relevant scenario. No rule rewriting. No code changes.&lt;/p&gt;

&lt;p&gt;Why this matters beyond the home&lt;br&gt;
The command gap isn't unique to smart homes. It's structural — it appears anywhere an AI system needs to coordinate physical devices in response to real-world events.&lt;br&gt;
A hospital AI detects a deteriorating patient. It knows there's urgency. But it doesn't know which room equipment to prepare, which staff to page, which doors to unlock for the crash cart. With command-based protocols, an engineer had to anticipate that exact scenario in advance. With semantic intent, each device declares its relevance and the system responds.&lt;br&gt;
A factory line detects an anomaly on a critical component. The AI knows something is wrong. With commands, someone pre-wrote the response. With intent, the devices coordinate a safe shutdown based on their declared capabilities — and the audit log captures every action with a tamper-evident chain.&lt;br&gt;
The protocol is domain-agnostic. The insight is not.&lt;/p&gt;

&lt;p&gt;The deeper shift&lt;br&gt;
Here's what semantic intent actually changes, at a philosophical level:&lt;br&gt;
In the command model, the AI is a remote control. It knows the exact sequence of buttons to press. It breaks when a device changes, when a new device appears, or when a scenario wasn't anticipated.&lt;br&gt;
In the intent model, the AI is a coordinator. It expresses what needs to happen. The devices figure out their role. The system is resilient to change because the knowledge is distributed — each device owns its own context.&lt;br&gt;
This is not a small difference. It's the difference between building a system that works today and building a system that can grow.&lt;/p&gt;

&lt;p&gt;What comes next&lt;br&gt;
This is the first post in a series exploring the concepts behind DoSync — an open protocol (Apache 2.0) for semantic intent-based communication between AI and physical devices.&lt;br&gt;
In the next post: Why hardcoded automations fail AI agents — and what a system designed from first principles for AI actually looks like.&lt;br&gt;
GitHub: &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;https://github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;br&gt;
License: Apache 2.0&lt;/p&gt;

&lt;p&gt;DoSync Concepts is a series exploring the ideas behind the DoSync Protocol — the semantic layer between AI agents and physical systems.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>ai</category>
      <category>opensource</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The Missing Layer Between AI Agents and Physical Systems</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Fri, 15 May 2026 17:56:57 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/the-missing-layer-between-ai-agents-and-physical-systems-4c4</link>
      <guid>https://dev.to/giulianiregspec/the-missing-layer-between-ai-agents-and-physical-systems-4c4</guid>
      <description>&lt;p&gt;There's a fundamental mismatch at the heart of every smart home today, and most people building in this space haven't fully articulated what it is.&lt;/p&gt;

&lt;p&gt;It's not a hardware problem. The sensors, locks, cameras, and thermostats we have today are genuinely capable. It's not a connectivity problem — Matter, Zigbee, and Z-Wave do a perfectly good job of letting apps talk to devices. The problem is architectural, and it only becomes visible when you try to add AI to the picture.&lt;/p&gt;

&lt;p&gt;Let me show you what I mean.&lt;/p&gt;




&lt;h2&gt;
  
  
  The command gap
&lt;/h2&gt;

&lt;p&gt;Every smart home protocol in existence was designed around a fundamental assumption: &lt;strong&gt;a human decides what to do, an app translates that decision into a command, and a device executes it.&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;Human decision → App → Command → Device
lock.unlock()
light.set_brightness(100)
thermostat.set_temperature(21)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works perfectly for app-controlled scenarios. Matter is an excellent solution to the problem of letting different brands' apps control different brands' devices. Zigbee and Z-Wave solve real problems in mesh networking and low-power communication.&lt;/p&gt;

&lt;p&gt;But AI systems don't think in commands. They think in goals.&lt;/p&gt;

&lt;p&gt;When an AI detects a fall, it doesn't know it needs to call &lt;code&gt;lock.unlock()&lt;/code&gt; and &lt;code&gt;phone.call("911")&lt;/code&gt; and &lt;code&gt;alarm.activate("emergency")&lt;/code&gt;. It knows there's an emergency. The translation from "there's an emergency" to the specific sequence of device commands has to be written by a human, device by device, scenario by scenario, in advance.&lt;/p&gt;

&lt;p&gt;That translation layer is fragile. It breaks when you add a new device. It fails to anticipate scenarios. And in emergencies — where the system should be most reliable — it's exactly the layer most likely to have a gap.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters now
&lt;/h2&gt;

&lt;p&gt;For the last decade, this wasn't a real problem. Smart home automation was primarily rule-based: "if motion sensor triggers after 10pm, turn on the hallway light." Rules are commands. The mapping was trivial.&lt;/p&gt;

&lt;p&gt;But the emergence of capable AI agents changes the equation entirely. We now have systems that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detect that an elderly person has fallen from camera footage&lt;/li&gt;
&lt;li&gt;Infer from sensor data that a fridge compressor has failed&lt;/li&gt;
&lt;li&gt;Understand from context that "nobody is home" without a button press&lt;/li&gt;
&lt;li&gt;React to a smoke detector with a phased evacuation response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are &lt;strong&gt;goal-oriented&lt;/strong&gt; events, not command-oriented ones. And every existing protocol forces you to pre-write the translation between "goal" and "command" yourself. There is no standard interface for saying "ensure her safety" and having the home figure out the rest.&lt;/p&gt;

&lt;p&gt;This problem isn't limited to the home. Consider a manufacturing line: a temperature sensor detects an abnormal reading on a critical component. The AI system knows there's an anomaly — but it doesn't know whether to stop the line, alert the supervisor, activate cooling, trigger a maintenance request, or all of the above. With existing protocols, an engineer had to anticipate this scenario and write that rule in advance. Miss one edge case and the system does nothing. With a semantic protocol, each device declares its capabilities and the resolver determines the appropriate response based on urgency and context — without any pre-written rules for that specific failure mode.&lt;/p&gt;

&lt;p&gt;The same architectural gap exists in hospitals, hotels, smart buildings, and anywhere an AI needs to coordinate physical systems in response to real-world events.&lt;/p&gt;




&lt;h2&gt;
  
  
  What a semantic protocol actually needs
&lt;/h2&gt;

&lt;p&gt;I've been working on this problem for several months, and the design space is clearer than it looks. A protocol that can bridge AI goals and physical devices needs a few specific things:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Capability-based device registration
&lt;/h3&gt;

&lt;p&gt;Instead of a device waiting to receive commands, it announces what it can do when it joins the network:&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;"device_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lock-frontdoor-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&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;"door-lock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"entrance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"emergency"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actuators"&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;"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;"unlock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"emergency_capable"&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;"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;"lock"&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;"emergency_capable"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This manifest lets the system discover what's available without any pre-configuration. Add a new device and it participates automatically in every relevant scenario.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Semantic intent, not commands
&lt;/h3&gt;

&lt;p&gt;The AI layer submits an intent — what it wants to achieve — not a specific sequence of commands:&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;"intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ensure_safety"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"urgency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"emergency"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"context"&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;"trigger"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fall_detected"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bedroom"&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;A semantic resolver then matches this intent against the registered device manifests, determines which devices are relevant, and builds an action plan. The AI doesn't need to know what devices exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Emergency override without confirmation
&lt;/h3&gt;

&lt;p&gt;For urgent situations, the system must be able to act immediately. This means &lt;code&gt;emergency_capable&lt;/code&gt; devices bypass the normal confirmation flow. Every action is logged with a tamper-evident chain — but the action executes without waiting.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Transport agnosticism
&lt;/h3&gt;

&lt;p&gt;A semantic protocol should be independent of the physical layer. Whether devices communicate over WiFi, Zigbee, Z-Wave, BLE, or Thread should be an implementation detail, not an architectural constraint.&lt;/p&gt;




&lt;h2&gt;
  
  
  DoSync: a working implementation
&lt;/h2&gt;

&lt;p&gt;I built a reference implementation of these ideas called &lt;strong&gt;DoSync Protocol&lt;/strong&gt; (Apache 2.0). It's not a theoretical spec — there's a running hub, a web dashboard, a certification CLI, and hardware adapters.&lt;/p&gt;

&lt;p&gt;Here's what happens when the system receives an emergency intent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PIR sensor detects motion → gpio_adapter fires ensure_safety [emergency]
    → Semantic resolver scores all 23 registered devices
        → 10 Philips WiZ bulbs: turn_on at full brightness (WiZ UDP adapter)
        → HA lock: unlock for 5 minutes (Home Assistant adapter)  
        → Alarm: activate emergency pattern (simulated)
        → SMS: sent to emergency contact (Twilio)
        → Audit log: SHA-256 chain updated
All in under 100ms. No rules written. No pre-configuration.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current hardware setup runs autonomously on a Raspberry Pi 5 with a PIR motion sensor and DHT22 temperature sensor. The hub survives reboots via systemd. Any LLM with MCP support (Claude, ChatGPT, etc.) can control the hub through a native MCP server.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this doesn't solve
&lt;/h2&gt;

&lt;p&gt;I want to be honest about the limitations, because I think intellectual honesty is what makes a protocol worth taking seriously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DoSync is a protocol of application layer, not transport.&lt;/strong&gt; It runs over HTTP/WebSocket today. It doesn't replace Zigbee or Z-Wave at the radio level — it sits above them and abstracts them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The semantic resolver is simple.&lt;/strong&gt; Today it's a capability matching algorithm that scores devices by tags, urgency, and &lt;code&gt;emergency_capable&lt;/code&gt; flag. It works well for the scenarios we have, but a production-grade resolver needs to go further.&lt;/p&gt;

&lt;p&gt;The current algorithm asks: &lt;em&gt;which devices have the right tags and capabilities for this intent?&lt;/em&gt; A mature resolver would also ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Device state awareness&lt;/strong&gt; — don't unlock a door that's already unlocked, don't turn on a light that's already at full brightness&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competing priorities&lt;/strong&gt; — if two intents fire simultaneously (morning routine + motion detected), which takes precedence and how do they compose?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextual weighting&lt;/strong&gt; — a motion sensor in a bedroom at 3am carries different weight than the same sensor at 3pm&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learned patterns&lt;/strong&gt; — over time, the resolver should know that in &lt;em&gt;this&lt;/em&gt; home, "save energy" means turning off the living room lights but never the hallway&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resolver interface is already decoupled from the rest of the protocol — you can implement a more sophisticated one without touching the adapter layer or the audit system. The spec defines what a resolver must do, not how. That's intentional. I plan to document this interface formally in v0.2 so that third-party resolver implementations can be dropped in. A production deployment might use a small local LLM as the resolver itself — the protocol is designed to support that path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is no hardware certification process yet.&lt;/strong&gt; The CLI generates a signed JSON report, but there's no third-party review. That's the right long-term model — it's just not there yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's one person's implementation.&lt;/strong&gt; A protocol needs multiple independent implementations to become a standard. That's the next milestone.&lt;/p&gt;




&lt;h2&gt;
  
  
  The broader point
&lt;/h2&gt;

&lt;p&gt;Smart home AI is arriving whether the protocol layer is ready or not. Home Assistant added MCP support in 2025. Claude and ChatGPT can already control devices via tool calls. The question isn't whether AI will be integrated into physical environments — it's whether the integration will be done well or badly.&lt;/p&gt;

&lt;p&gt;Done badly: AI systems that call device APIs directly, with hardcoded rules, fragile integrations, no audit trail, and no standard for what "emergency capable" even means.&lt;/p&gt;

&lt;p&gt;Done well: a semantic layer where devices declare what they can do, AI expresses what it wants to achieve, and the home figures out the rest — with full auditability and a clear certification model for safety-critical scenarios.&lt;/p&gt;

&lt;p&gt;The hardware is ready. The AI is ready. The missing piece is a protocol designed from first principles for this use case.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/giulianireg-spec/dosync-protocol
&lt;span class="nb"&gt;cd &lt;/span&gt;dosync-protocol
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
pip &lt;span class="nb"&gt;install &lt;/span&gt;fastapi uvicorn websockets pywizlight aiohttp

&lt;span class="nv"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; uvicorn server:app &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; 47200 &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;span class="c"&gt;# Open http://localhost:47200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dashboard shows registered devices, live events, and the audit log in real time. The certification CLI runs 16 tests across three tiers. The MCP server lets any compatible LLM control the hub directly.&lt;/p&gt;

&lt;p&gt;Feedback, contributions, and adapter implementations are welcome. The RFC process is open.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; github.com/giulianireg-spec/dosync-protocol&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; Apache 2.0&lt;br&gt;
&lt;strong&gt;Contact:&lt;/strong&gt; &lt;a href="mailto:giulianireg@gmail.com"&gt;giulianireg@gmail.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;DoSync Protocol v0.1 — building the semantic layer between AI and physical systems.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>iot</category>
      <category>ai</category>
      <category>opensource</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Why Your Smart Home AI Can't Open the Door in an Emergency (And How to Fix It)</title>
      <dc:creator>Rodrigo Giuliani</dc:creator>
      <pubDate>Tue, 05 May 2026 16:57:07 +0000</pubDate>
      <link>https://dev.to/giulianiregspec/why-your-smart-home-ai-cant-open-the-door-in-an-emergency-and-how-to-fix-it-5d5i</link>
      <guid>https://dev.to/giulianiregspec/why-your-smart-home-ai-cant-open-the-door-in-an-emergency-and-how-to-fix-it-5d5i</guid>
      <description>&lt;p&gt;A practical story about the missing protocol between AI and physical devices — and the open-source project building it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scenario that started everything
&lt;/h2&gt;

&lt;p&gt;Imagine your grandmother lives with your family. One afternoon, no one is home. She falls in the bedroom and can't get up.&lt;/p&gt;

&lt;p&gt;Your home has a smart lock, a camera with AI fall detection, a connected phone hub, and an alarm system. All of them are online. All of them are certified Matter devices. And none of them can coordinate a response — because no standard exists that lets an AI say &lt;em&gt;"ensure her safety"&lt;/em&gt; and have every device figure out its role automatically.&lt;/p&gt;

&lt;p&gt;The camera can detect the fall. But it can't tell the lock to open. The lock can open, but it doesn't know there's an emergency. The phone hub can call 911, but it doesn't know when to. Each device speaks its own command language, and the AI speaks in goals.&lt;/p&gt;

&lt;p&gt;That gap — between AI intent and physical action — is what DoSync is built to close.&lt;/p&gt;




&lt;h2&gt;
  
  
  The core problem with existing protocols
&lt;/h2&gt;

&lt;p&gt;Matter, Zigbee, and Z-Wave are excellent at what they do: letting apps control devices. They define command clusters like &lt;code&gt;OnOff&lt;/code&gt;, &lt;code&gt;LevelControl&lt;/code&gt;, and &lt;code&gt;Lock&lt;/code&gt; that work across manufacturers. That's genuinely valuable.&lt;/p&gt;

&lt;p&gt;But they were designed for &lt;em&gt;human-initiated&lt;/em&gt; control via apps. When an AI enters the picture, these protocols become a bottleneck:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# What existing protocols understand
&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unlock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;thermostat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_temperature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# What an AI actually thinks in
&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ensure the safety of the person who fell&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prepare the home for bedtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nobody is home — save energy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Someone has to translate. Today, that translation is custom code written per-device, per-platform, per-scenario. It doesn't scale. It breaks when you add a new device. And it completely fails in emergencies where milliseconds matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing DoSync
&lt;/h2&gt;

&lt;p&gt;DoSync is an open communication protocol (Apache 2.0) that lets AI systems interact with physical home devices using &lt;strong&gt;semantic intent&lt;/strong&gt; — expressing &lt;em&gt;what they want to achieve&lt;/em&gt;, not &lt;em&gt;how to achieve it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The key insight: instead of the AI issuing commands, devices declare their &lt;strong&gt;capabilities&lt;/strong&gt;, and a semantic resolver matches intent to capability automatically.&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;device&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;announces&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;what&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;can&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(Capability&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Manifest)&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;"device_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lock-frontdoor-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&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;"door-lock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"entrance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"emergency"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actuators"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unlock"&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;"unlock"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lock"&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;"lock"&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;"emergency_capable"&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;AI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;intent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;command&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;"intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ensure_safety"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"urgency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"emergency"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"context"&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;"trigger"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fall_detected"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bedroom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"emergency_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"911"&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;DoSync&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;resolves&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;automatically&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;lock-frontdoor&lt;/span&gt;&lt;span class="mi"&gt;-01&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;unlock&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(emergency_capable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;phone-hub&lt;/span&gt;&lt;span class="mi"&gt;-01&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;911&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;alarm&lt;/span&gt;&lt;span class="mi"&gt;-01&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;activate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;emergency&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;pattern&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;family&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;phones:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;notification&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;All&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;parallel.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;hardcoded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;rules.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The 5-layer architecture
&lt;/h2&gt;

&lt;p&gt;DoSync is organized in 5 layers, similar to OSI but designed for AI-to-device communication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Layer 5 — Intent        AI expresses goals in natural language or JSON
Layer 4 — Semantic      Intent → device action mapping via capability matching  
Layer 3 — Registry      Devices self-declare capabilities on network join
Layer 2 — Secure ch.    mTLS, local PKI, zero-trust — no internet required
Layer 1 — Transport     WiFi · BLE · Zigbee · Z-Wave · Thread · Ethernet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The transport-agnostic HAL (Hardware Abstraction Layer) means the same protocol runs over any physical medium. A manufacturer implements DoSync once and supports any AI system.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's built today
&lt;/h2&gt;

&lt;p&gt;The protocol is not theoretical. There's a working reference implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/giulianireg-spec/dosync-protocol
&lt;span class="nb"&gt;cd &lt;/span&gt;dosync-protocol
pip &lt;span class="nb"&gt;install &lt;/span&gt;fastapi uvicorn

&lt;span class="c"&gt;# Start the hub&lt;/span&gt;
&lt;span class="nv"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; uvicorn server:app &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; 47200 &lt;span class="nt"&gt;--reload&lt;/span&gt;

&lt;span class="c"&gt;# Run the full demo — 7 scenarios&lt;/span&gt;
&lt;span class="nv"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; python3 examples/demo_full.py

&lt;span class="c"&gt;# Run the certification suite&lt;/span&gt;
python3 certify.py &lt;span class="nt"&gt;--host&lt;/span&gt; localhost &lt;span class="nt"&gt;--port&lt;/span&gt; 47200 &lt;span class="nt"&gt;--tier&lt;/span&gt; emergency
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The demo output looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;══════════════════════════════════════════════════════════════
  Scenario 1 — Fall detected · Emergency
══════════════════════════════════════════════════════════════
  ▶  Camera emits event: fall_detected [EMERGENCY]
  ▶  AI resolves intent: ensure_safety [EMERGENCY]
  ✓  [lock-frontdoor-01] unlock  → {"status": "unlocked", "duration_seconds": 300}
  ✓  [alarm-main-01] alarm       → {"status": "activated", "pattern": "emergency"}
  ✓  [phone-family-01] call      → {"status": "calling", "number": "911"}
  ✓ SUCCESS  — 7 parallel actions in &amp;lt; 100ms
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the certification CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;── Tier EMERGENCY — Override and audit log ─────────────
  ✓  Emergency intent executes without confirmation
  ✓  Emergency-capable devices participate in response
  ✓  Audit log exists and has entries
  ✓  SHA-256 chain integrity verified
  ✓  Emergency event recorded in audit log
── Result ──────────────────────────────────────────────
  Tests passed: 16  ·  Tests failed: 0
  ✓ CERTIFIED — DoSync EMERGENCY
  Fingerprint: fb083f5740978b9a38c448bdc4fe3090…
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The 7 working scenarios
&lt;/h2&gt;

&lt;p&gt;The demo covers situations that no existing protocol handles automatically:&lt;/p&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;Trigger&lt;/th&gt;
&lt;th&gt;DoSync response&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fall detected&lt;/td&gt;
&lt;td&gt;Camera AI&lt;/td&gt;
&lt;td&gt;911 called · Door unlocked · Alarm · Family notified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Smoke / CO&lt;/td&gt;
&lt;td&gt;Detector over threshold&lt;/td&gt;
&lt;td&gt;3 phases: Alert → Evacuate → Unlock for responders&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fridge failure&lt;/td&gt;
&lt;td&gt;Compressor off, temp rising&lt;/td&gt;
&lt;td&gt;Family SMS before food spoils&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nobody home&lt;/td&gt;
&lt;td&gt;Phone WiFi + power meter&lt;/td&gt;
&lt;td&gt;Lights off · Thermostat eco · Alarm armed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Laundry done&lt;/td&gt;
&lt;td&gt;Appliance cycle complete&lt;/td&gt;
&lt;td&gt;Remind family before clothes wrinkle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good morning&lt;/td&gt;
&lt;td&gt;First motion of the day&lt;/td&gt;
&lt;td&gt;Blinds 80% · Coffee on · Weather shown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bedtime&lt;/td&gt;
&lt;td&gt;Scheduler at 21:30&lt;/td&gt;
&lt;td&gt;Lights dim to 10% · Blinds close&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The smoke scenario is worth highlighting because it introduces &lt;strong&gt;phased execution&lt;/strong&gt; — unlike the others that run in parallel, a fire evacuation needs a specific order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;PhasedActionPlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phases&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nc"&gt;Phase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ALERT — immediate notification&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delay_after_ms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;PhaseAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alarm-main-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alarm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pattern&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fire&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="nc"&gt;PhaseAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone-family-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;call&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="nc"&gt;PhaseAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone-family-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;notify&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;urgency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;emergency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="nc"&gt;Phase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EVACUATION — visual guidance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delay_after_ms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;PhaseAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lights-main-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;set_brightness&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;brightness&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="nc"&gt;PhaseAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lock-backdoor-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unlock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;duration_seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="nc"&gt;Phase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ACCESS — entry for responders&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;PhaseAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lock-frontdoor-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unlock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;duration_seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="nc"&gt;PhaseAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;camera-exterior-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;record&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fire_emergency&lt;/span&gt;&lt;span class="sh"&gt;"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Presence inference — not detection
&lt;/h2&gt;

&lt;p&gt;One of the less obvious design decisions: DoSync doesn't treat presence as a binary sensor. It uses an &lt;strong&gt;OccupancyEngine&lt;/strong&gt; that aggregates weighted signals from multiple context providers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Phone leaves WiFi network (weight: 0.7)
&lt;/span&gt;&lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_presence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PresenceSignal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;device_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone-rodrigo-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;signal_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ContextSignalType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PRESENCE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;present&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;confidence&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Hub infers: occupied=False | confidence=100% | signals=1
&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_occupancy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a smartwatch is added, its GPS signal (weight 0.9) combines with the phone WiFi signal for a more robust inference. If the phone battery died but the smartwatch is home, the system correctly infers someone is still there. The AI learns patterns over time — this is the bridge to FamilyOS, the generational AI project that DoSync is designed to power.&lt;/p&gt;




&lt;h2&gt;
  
  
  The certification model
&lt;/h2&gt;

&lt;p&gt;Following the Matter approach, DoSync uses self-certification with three tiers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Requirements&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Basic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Connects, authenticates, publishes capability manifest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Standard&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Responds to intents, sends events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Emergency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Emergency override + tamper-evident SHA-256 audit log&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The CLI generates a signed &lt;code&gt;dosync-cert.json&lt;/code&gt; report. No manual approval needed for Basic and Standard. Emergency tier requires human review.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dosync-certify &lt;span class="nt"&gt;--host&lt;/span&gt; 192.168.1.50 &lt;span class="nt"&gt;--tier&lt;/span&gt; standard &lt;span class="nt"&gt;--output&lt;/span&gt; cert.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tamper-evident audit log is worth a separate mention: every action chains to the previous one with SHA-256, similar to blockchain. If someone modifies any historical entry, the entire chain breaks and the system detects it immediately.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's different from Matter, Zigbee, and Home Assistant
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Matter&lt;/strong&gt; solves device interoperability for app-controlled scenarios. It has no semantic layer, no emergency override, and no concept of AI intent. DoSync doesn't replace Matter — a device can be Matter-certified for app control and DoSync-certified for AI interaction simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Home Assistant&lt;/strong&gt; is a platform, not a protocol. It recently added MCP support for natural language, which is directionally similar, but it's adapting an existing command-based system rather than designing from first principles for AI communication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DoSync&lt;/strong&gt; is the only open protocol designed specifically for AI-to-device semantic communication, with transport agnosticism, emergency override, capability-based discovery, and a certifiable standard that any manufacturer can implement.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The Raspberry Pi hardware kit is on order. The next milestone is a physical demo: a real door lock opening in response to a semantic emergency intent. That demo, combined with the working certification CLI, is the artifact we're taking to hardware manufacturers and IoT investors.&lt;/p&gt;

&lt;p&gt;The roadmap:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Already shipped:&lt;/strong&gt; SQLite persistence · 7 working scenarios · REST API · Certification CLI 16/16&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Q2 2026&lt;/strong&gt; — GPIO adapter for Raspberry Pi · Physical door lock demo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Q3 2026&lt;/strong&gt; — Home Assistant bridge · BLE transport adapter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Q4 2026&lt;/strong&gt; — 3 certified partner devices · First manufacturer outreach&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2027+&lt;/strong&gt; — FamilyOS integration · Generational AI memory layer&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try it now
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/giulianireg-spec/dosync-protocol
&lt;span class="nb"&gt;cd &lt;/span&gt;dosync-protocol
pip &lt;span class="nb"&gt;install &lt;/span&gt;fastapi uvicorn
&lt;span class="nv"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; uvicorn server:app &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; 47200 &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;span class="c"&gt;# Open http://localhost:47200/docs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interactive API docs let you register devices, fire intents, and see the semantic resolver work in real time — no hardware required.&lt;/p&gt;

&lt;p&gt;If you're building IoT firmware, smart home devices, or AI home assistants, I'd love to hear your feedback. The RFC process is open and transport adapter contributions are welcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/giulianireg-spec/dosync-protocol" rel="noopener noreferrer"&gt;github.com/giulianireg-spec/dosync-protocol&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; Apache 2.0&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Contact:&lt;/strong&gt; &lt;a href="mailto:giulianireg@gmail.com"&gt;giulianireg@gmail.com&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Update — May 2026
&lt;/h2&gt;

&lt;p&gt;Since this post was published, DoSync has moved from theory to working hardware.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Physical demo live:&lt;/strong&gt; 10 Philips WiZ bulbs responding to semantic intents &lt;br&gt;
via UDP — no cloud, no intermediary. A natural language conversation with &lt;br&gt;
Claude Desktop controls real lights in real time.&lt;/p&gt;

&lt;p&gt;📹 Watch the demo: &lt;a href="https://youtu.be/2czAqoIrd08" rel="noopener noreferrer"&gt;https://youtu.be/2czAqoIrd08&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What shipped since this post:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WebSocket endpoint — real-time event broadcasting to all connected clients&lt;/li&gt;
&lt;li&gt;Web dashboard at &lt;code&gt;http://localhost:47200&lt;/code&gt; — live feed, intent launcher, audit log&lt;/li&gt;
&lt;li&gt;API key authentication with SHA-256 hashing&lt;/li&gt;
&lt;li&gt;Native MCP server — any LLM with MCP support can control the hub directly&lt;/li&gt;
&lt;li&gt;Home Assistant bridge — imports devices from HA automatically (10 domains)&lt;/li&gt;
&lt;li&gt;Automatic device discovery via UDP broadcast&lt;/li&gt;
&lt;li&gt;WiZ adapter — direct UDP control of Philips WiZ bulbs&lt;/li&gt;
&lt;li&gt;Full device management CLI (&lt;code&gt;manage.py&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Raspberry Pi kit arrived — GPIO adapter in progress&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The MCP integration deserves a mention:&lt;/strong&gt; with the DoSync MCP server &lt;br&gt;
configured in Claude Desktop, you can type "there's an emergency at home" &lt;br&gt;
and physical lights respond immediately. No app. No command. Just intent.&lt;/p&gt;

&lt;p&gt;The door lock demo (the scenario this project was built for) is coming &lt;br&gt;
as soon as the physical lock hardware arrives.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;DoSync is part of a larger project: FamilyOS — a private, local, generational AI for the home. The best inheritance we can leave our children is knowledge. DoSync is the protocol that lets the home itself become part of that inheritance.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>iot</category>
      <category>opensource</category>
      <category>python</category>
      <category>smarthome</category>
    </item>
  </channel>
</rss>
