<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Phil Windley's Technometria]]></title><description><![CDATA[Digital identity and decentralized systems]]></description><link>https://www.technometria.com</link><image><url>https://substackcdn.com/image/fetch/$s_!899P!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5634e67-3a5e-4054-ad2f-e2bf981a9fd3_148x148.png</url><title>Phil Windley&apos;s Technometria</title><link>https://www.technometria.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 30 Oct 2026 20:18:20 GMT</lastBuildDate><atom:link href="https://www.technometria.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Phillip J. Windley]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[phil@windley.org]]></webMaster><itunes:owner><itunes:email><![CDATA[phil@windley.org]]></itunes:email><itunes:name><![CDATA[Phil Windley]]></itunes:name></itunes:owner><itunes:author><![CDATA[Phil Windley]]></itunes:author><googleplay:owner><![CDATA[phil@windley.org]]></googleplay:owner><googleplay:email><![CDATA[phil@windley.org]]></googleplay:email><googleplay:author><![CDATA[Phil Windley]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Identity Enables Autonomy]]></title><description><![CDATA[Summary: Moving a pico from one engine to another looks like a migration feature, but the point is autonomy.]]></description><link>https://www.technometria.com/p/identity-enables-autonomy</link><guid isPermaLink="false">https://www.technometria.com/p/identity-enables-autonomy</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Fri, 30 Oct 2026 14:03:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!niFT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>Moving a pico from one engine to another looks like a migration feature, but the point is autonomy. Most people will never run their own servers, so freedom online depends on apps and data that can move between hosts, and identity is what lets them move without breaking. This post lays out the argument behind my IIW demo.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!niFT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!niFT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!niFT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!niFT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!niFT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!niFT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A pico comes home to its owner&quot;,&quot;title&quot;:&quot;A pico comes home to its owner&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="A pico comes home to its owner" title="A pico comes home to its owner" srcset="https://substackcdn.com/image/fetch/$s_!niFT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!niFT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!niFT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!niFT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a72e570-22d1-4067-b734-ed005d68c025_1672x941.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>My session at <a href="https://internetidentityworkshop.com/">Internet Identity Workshop (IIW)</a> next week will show a pico moving from one engine to another. A bike club sells Gravel Bike #7 to a new owner, and the pico that represents the bike, along with the child pico for its bike computer, moves from the club&#8217;s mesh to the new owner&#8217;s mesh. Its identity comes along, and so do its relationships. I described the mechanics (with a video) in <a href="https://www.windley.com/archives/2026/10/moving_picos_from_mesh_to_mesh.shtml">Moving Picos from Mesh to Mesh</a>; here I want to explain why I think it matters.</p><p>It&#8217;s easy to see a demo like this as a migration feature, the kind of thing an operations team uses to shuffle workloads between data centers. That is not my primary goal. My aim is loftier: portability is how people keep control of their online lives without having to run the infrastructure themselves, and identity is what makes portability work. In other words, <em>identity enables autonomy</em>.</p><h2><strong>Freedom Requires Portability</strong></h2><p>Personal freedom online requires that we control our apps and our data. I&#8217;ve been making some version of that argument for decades. For example, in <a href="https://www.windley.com/archives/2014/04/the_compuserve_of_things.shtml">The CompuServe of Things</a>, I worried that the Internet of Things was being built as a collection of walled gardens, each with its own servers, accounts, and terms of service. If the company running the server decides your thermostat is no longer supported, the thermostat stops being yours in any meaningful sense. The same is true of the apps and data that run the rest of our lives.</p><p>The obvious answer is to run your own servers, but realistically, most people never will. That isn&#8217;t a failure of will or education; it&#8217;s the same reason most people don&#8217;t generate their own electricity. Hosting is a service, and people should be able to buy it the way they buy other services, so long as they can freely move to another service. A renter doesn&#8217;t own the apartment, but they own the furniture, and when they move, the furniture goes with them. Apps and data should be the same: hosted by someone, but not owned by them.</p><h2><strong>Spheres of Control</strong></h2><p>Every hosting arrangement comes down to a simple question: whose rules apply? In the physical world, we answer it without thinking. The things in your house are yours to use, lend, or rearrange; the things in a store belong to the store until you buy them, and the store sets the rules for handling them. Each of us has a <em>sphere of control</em>, the set of things we get to make decisions about, and we move through other people&#8217;s spheres all day long without confusing them with our own.</p><p>Online, those boundaries are much harder to discern. An app on your phone feels like yours, but in most cases the app&#8217;s logic and the data it collects live on someone else&#8217;s servers and follow someone else&#8217;s rules. You&#8217;re a visitor in the provider&#8217;s sphere of control, even when the subject is your own health, your car, or your bike. The important question isn&#8217;t who hosts the app; it&#8217;s whose sphere of control the app and its data belong to.</p><p>Figure 1 shows how most apps work today. The app and the data about you sit inside the provider&#8217;s sphere of control, and you reach both through the provider. You use the app, but the provider decides what it does, what happens to your data, and how long either one exists.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-1DG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-1DG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png 424w, https://substackcdn.com/image/fetch/$s_!-1DG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png 848w, https://substackcdn.com/image/fetch/$s_!-1DG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png 1272w, https://substackcdn.com/image/fetch/$s_!-1DG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!-1DG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png" width="1456" height="796" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98170bfb-f888-4194-ae24-56688a711593_1573x860.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:796,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The Provider's Sphere of Control&quot;,&quot;title&quot;:&quot;The Provider's Sphere of Control&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The Provider's Sphere of Control" title="The Provider's Sphere of Control" srcset="https://substackcdn.com/image/fetch/$s_!-1DG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png 424w, https://substackcdn.com/image/fetch/$s_!-1DG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png 848w, https://substackcdn.com/image/fetch/$s_!-1DG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png 1272w, https://substackcdn.com/image/fetch/$s_!-1DG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98170bfb-f888-4194-ae24-56688a711593_1573x860.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1: The Provider&#8217;s Sphere of Control (click to enlarge)</figcaption></figure></div><p>Figure 2 shows a better model. The app and the data sit inside <em>your sphere of control</em>, and the company that used to be the provider becomes a partner that works with your data on terms you set, labeled &#8220;<a href="https://myterms.info/">my terms</a>&#8220; in the figure. The components in the two figures are nearly identical. What changes is who&#8217;s in charge.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y3mA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y3mA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png 424w, https://substackcdn.com/image/fetch/$s_!Y3mA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png 848w, https://substackcdn.com/image/fetch/$s_!Y3mA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png 1272w, https://substackcdn.com/image/fetch/$s_!Y3mA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y3mA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png" width="1456" height="774" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:774,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Your Sphere of Control&quot;,&quot;title&quot;:&quot;Your Sphere of Control&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Your Sphere of Control" title="Your Sphere of Control" srcset="https://substackcdn.com/image/fetch/$s_!Y3mA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png 424w, https://substackcdn.com/image/fetch/$s_!Y3mA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png 848w, https://substackcdn.com/image/fetch/$s_!Y3mA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png 1272w, https://substackcdn.com/image/fetch/$s_!Y3mA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5e175f5-8ce7-4177-b261-f2f5f561972e_1608x855.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2: Your Sphere of Control (click to enlarge)</figcaption></figure></div><p>I first imagined the arrangement in Figure 2 in the area of IoT, where every connected thing could have its own app under its owner&#8217;s control rather than its manufacturer&#8217;s. That was hard to realize when every app had to be built and maintained by someone with a business reason to do it. AI changes the calculation. As I wrote in <a href="https://www.windley.com/archives/2026/09/theres_a_personal_app_for_that.shtml">There&#8217;s a Personal App for That</a>, building a custom app for a single person or organization is now a morning&#8217;s work. When apps are that cheap to make, software stops looking like a few products with millions of users and starts looking like a billion small markets. Those apps need somewhere to live that the person controls, and they need to be able to move.</p><h2><strong>Identity Is the Foundation</strong></h2><p>Portability sounds like a storage problem: export the data and import it somewhere else. The hard part is everything that points at the thing you moved. A pico does its work through relationships with other picos, and if moving it breaks every relationship that refers to its old address, the pico hasn&#8217;t really moved; it has been orphaned. Identity is what lets the rest of the world still recognize something that has moved.</p><p>That&#8217;s why some of the recent pico engine work focused on <a href="https://www.windley.com/archives/2026/08/pico-to-pico_identity_arrives.shtml">pico-to-pico identity</a>. Each pico carries two kinds of DIDs, and they do different jobs in a move. The <code>did:webvh</code> is the pico&#8217;s public identity, the passport it hands to strangers. Its self-certifying identifier (SCID) survives a move; only the host and path change, and anyone who resolves the DID finds the pico at its new location.</p><p>Relationships ride on something else. Each relationship is based on a pair of <code>did:peer</code>identifiers, private, point-to-point names with no engine address baked into them. The picos use them to exchange messages using DIDComm. After a move, the pico sends a rotation message to each of its peers, and each peer updates where it sends traffic for that relationship. Nothing has to be reintroduced; the <code>did:webvh</code> keeps the pico findable, and the peer DIDs keep its relationships intact. In the demo, four things move together:</p><ul><li><p><strong>The subtree</strong> &#8212; the bike pico and its children export as a portable blob and import on the new engine. This isn&#8217;t federation of whole engines; it&#8217;s one subtree changing hands.</p></li><li><p><strong>The identity</strong> &#8212; the SCID stays the same while the DID&#8217;s host and path follow the engine.</p></li><li><p><strong>The relationships</strong> &#8212; they&#8217;re kept whole, even when that means converting a local ECI-based relationship into a DID-based one.</p></li><li><p><strong>The app</strong> &#8212; the application and all its data move from one sphere of control to another.</p></li></ul><p>The last item is the point the demo is trying to make. The new owner doesn&#8217;t get a data export from the club&#8217;s system; they get the bike&#8217;s pico, with its functionality, history, and relationships, running in their own mesh.</p><h2><strong>Identity Enables Autonomy</strong></h2><p>A personal app needs more than code; it needs a place to keep its state, a way to talk with the people, devices, and services it works with, and an identity those parties can rely on. <a href="https://www.windley.com/archives/2026/10/closures_objects_actors_and_picos.shtml">Picos</a> package all of that together. The name itself is short for &#8220;persistent compute object&#8221; and that&#8217;s been the goal for as long as picos have existed.</p><p>Each pico persists its own logic and data, responds to events from anywhere on the internet, and carries its relationships with it. Because the whole package travels as a unit, moving a personal app from one host to another becomes an operation rather than a rewrite. The host provides a place to run; the pico is the app.</p><p>Selling a bike is one reason to move a pico, but there are many others:</p><ul><li><p><strong>Resilience</strong> &#8212; leave a host that fails, turns hostile, or censors.</p></li><li><p><strong>Economics</strong> &#8212; find cheaper compute or storage.</p></li><li><p><strong>Latency</strong> &#8212; get closer to the people, devices, and other picos it works with.</p></li><li><p><strong>Bandwidth</strong> &#8212; move toward the data instead of hauling it across the network.</p></li><li><p><strong>Jurisdiction</strong> &#8212; live on infrastructure with the right governance and data-handling rules.</p></li><li><p><strong>Ownership</strong> &#8212; follow a sale, or simply avoid lock-in.</p></li></ul><p>Today, a person or a program acting for them decides when a pico moves. And does the exporting and importing by hand. What I ultimately want is for a pico to move itself on command and, eventually, on its own judgment, weighing cost, latency, reliability, and trust to decide where it should live. Getting there takes more work. Moves need to be atomic, with rollback when something fails halfway and forwarding from the old location; the engine needs to transfer exports and clean up the donor rather than leaving those jobs to the operator; and we need far more testing against relationships that cross subtree boundaries and external systems that remember old addresses. I expect the sharp edges to show up as soon as people use this for something other than my demo.</p><p>Picos are persistent objects with their own identities and relationships, not session tokens issued by whatever app happens to host them. That distinction is what makes everything else possible. An app whose identity belongs to its host can only live where it&#8217;s told. A pico with its own identity can choose where it lives, just like the person it works for. <em>Identity enables autonomy</em>.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/10/pico_coming_home.png">A pico comes home to its owner</a> from ChatGPT (public domain)</p>]]></content:encoded></item><item><title><![CDATA[Pico Engine 1.8 Is for Builders]]></title><description><![CDATA[Summary: Smalltalk taught a generation of programmers what it felt like to build by conversing with a live system, and Alan Kay hoped it would turn users into builders.]]></description><link>https://www.technometria.com/p/pico-engine-18-is-for-builders</link><guid isPermaLink="false">https://www.technometria.com/p/pico-engine-18-is-for-builders</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Tue, 27 Oct 2026 17:59:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!XMJR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>Smalltalk taught a generation of programmers what it felt like to build by conversing with a live system, and Alan Kay hoped it would turn users into builders. Version 1.8 of the pico engine takes both ideas seriously: a better developer UI for people, an MCP surface for agents, and a schema underneath that makes both possible. This post describes the release and why the builders it serves don&#8217;t all have to be developers.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XMJR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XMJR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!XMJR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!XMJR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!XMJR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XMJR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Building in conversation with a pico&quot;,&quot;title&quot;:&quot;Building in conversation with a pico&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="Building in conversation with a pico" title="Building in conversation with a pico" srcset="https://substackcdn.com/image/fetch/$s_!XMJR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!XMJR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!XMJR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!XMJR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3adb347e-bbb4-4ea1-8581-03abd6684c63_1672x941.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When I was in grad school, Smalltalk was all the rage. Commercial Smalltalk systems were expensive, so we didn&#8217;t get much time with them, but the experience of sitting at the console and building something by interacting with a live system has always stuck with me. You didn&#8217;t write a program and then run it. You worked inside a running world of objects, poked at them, changed them, and watched what happened.</p><p>In time, the software industry settled on the C model of edit, compile, and run because it offered reproducible, reasonably portable code on standard operating systems. Java arrived in the 1990s and stole the object-oriented limelight with a C-style syntax and a familiar build model. Smalltalk slowly faded into relative obscurity. Still, I never forgot the joy of working with a live system or the convenience of debugging from a console against a real image. So when we built the <a href="https://github.com/Picolab/pico-engine">pico engine</a>, Bruce Conrad built a developer UI that lets you see a pico mesh, send events and queries to any pico in it, and examine the results.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!olcD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!olcD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png 424w, https://substackcdn.com/image/fetch/$s_!olcD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png 848w, https://substackcdn.com/image/fetch/$s_!olcD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!olcD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!olcD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png" width="1331" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1331,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The pico engine developer UI showing a pico mesh&quot;,&quot;title&quot;:&quot;The pico engine developer UI showing a pico mesh&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The pico engine developer UI showing a pico mesh" title="The pico engine developer UI showing a pico mesh" srcset="https://substackcdn.com/image/fetch/$s_!olcD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png 424w, https://substackcdn.com/image/fetch/$s_!olcD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png 848w, https://substackcdn.com/image/fetch/$s_!olcD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!olcD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c56fb23-0286-490f-9360-881d02892b13_1331x1024.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The pico engine developer UI showing a pico mesh (click to enlarge)</figcaption></figure></div><p>The <a href="https://github.com/Picolab/pico-engine/releases/tag/v1.8.0">latest release of the pico engine, version 1.8</a>, doubles down on that idea and makes the developer experience better than it has ever been. And since developers now often include AI agents, we&#8217;ve made it better for them as well. An accompanying <a href="https://github.com/Picolab/manifold-api/releases/tag/v1.8.0">Manifold 1.8 release</a> brings the Manifold rulesets along. This post describes the changes and why I think they matter beyond the developers who write KRL.</p><h2><strong>Smalltalk&#8217;s Vision for Developers</strong></h2><p>A Smalltalk system wasn&#8217;t a program you compiled. It was an <em>image</em>: a saved snapshot of a whole world of live objects, including the classes, the windows, the compiler, and the development tools themselves. You started the image and picked up where you left off, with every object still holding its state. Everything in that world was an object, and objects talked by sending messages. Alan Kay later <a href="https://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/016029.html">said</a> that calling it &#8220;object-oriented&#8221; was a mistake because the big idea was messaging; what mattered was what happened between objects, not what was inside them. That idea runs through actors and, eventually, to picos, as I described in <a href="https://www.windley.com/archives/2026/10/closures_objects_actors_and_picos.shtml">Closures, Objects, Actors, and Picos</a>.</p><p>The tools were where Smalltalk put developers first. Each was a live view into running objects:</p><ul><li><p><strong>Browser:</strong> every class and method in the system, including the system&#8217;s own source, open for editing, with changes taking effect immediately.</p></li><li><p><strong>Workspace:</strong> a scratch pad where you could select any expression and <em>do it</em>, <em>print it</em>, or <em>inspect it</em> against real objects before committing it to a method.</p></li><li><p><strong>Inspector:</strong> open any object, see its instance variables, and change them in place.</p></li><li><p><strong>Debugger:</strong> stop on an error with the live stack intact, fix the method right there, and resume.</p></li></ul><p>Together these collapsed the edit, compile, run, and debug cycle into one continuous conversation with a running system. You didn&#8217;t reproduce a bug; you were already standing in it. And Kay had a bigger goal than developer convenience. His <a href="https://en.wikipedia.org/wiki/Dynabook">Dynabook</a>work at Xerox PARC imagined a world where children and other non-specialists would use Smalltalk to build their own tools. Users would be builders, not just consumers of software. Both of those ideas, the continuous conversation and users as builders, sit at the center of this release.</p><h2><strong>Changes to the Testing Tab</strong></h2><p>The Testing tab in the pico engine UI has always been the closest thing we had to a Smalltalk workspace. You pick a pico, choose an event or query, fill in some attributes, and send it. Until now, though, the forms came from a hidden <code>__testing</code> structure that the compiler guessed at exposing a cacophony of confusing choices in the Testing tab without much quidance.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Dq2P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Dq2P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Dq2P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Dq2P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Dq2P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!Dq2P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png" width="1331" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1331,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The 1.8 Testing tab&quot;,&quot;title&quot;:&quot;The 1.8 Testing tab&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The 1.8 Testing tab" title="The 1.8 Testing tab" srcset="https://substackcdn.com/image/fetch/$s_!Dq2P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Dq2P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Dq2P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Dq2P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0ecf756-9f48-4eed-a64c-f36eb54bf81e_1331x1024.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The new 1.8 Testing tab (click to enlarge)</figcaption></figure></div><p>In 1.8, the Testing tab is built from the ruleset&#8217;s schema, which I&#8217;ll describe in a moment. That brings several improvements:</p><ul><li><p><strong>KRL console:</strong> evaluate a KRL expression in the context of an installed ruleset on a pico, with access to its global functions, its modules, and its entity variables. This was something that <a href="https://www.windley.com/archives/2016/02/evaluating_krl_declarations.shtml">Classic Pico Engine had </a>that I&#8217;ve missed since we rewrote it in Node many years ago.</p></li><li><p><strong>Typed forms and presets:</strong> each operation shows its attributes with types and descriptions, and any <code>@example</code> in the ruleset becomes a pre-filled form.</p></li><li><p><strong>Rule outcomes:</strong> when you send an event, the response tells you, for each annotated rule, whether it fired, was selected but didn&#8217;t fire because its condition was false, or wasn&#8217;t selected at all because an attribute pattern didn&#8217;t match.</p></li><li><p><strong>History and saved requests:</strong> every request you send is kept with its outcome, and you can name and save the ones that work. These live in the pico, so they move with it when the pico <a href="https://www.windley.com/archives/2026/10/moving_picos_from_mesh_to_mesh.shtml">moves to another engine</a>.</p></li><li><p><strong>Copy as </strong><code>@example</code><strong>:</strong> a request that works on a live pico can be copied into the ruleset as an example, promoting something you discovered by experiment into the source to guide others using that ruleset.</p></li></ul><p>The console is the piece that feels most like Smalltalk. Want to know how many relationships a pico has? Evaluate <code>ent:established.length()</code> in the subscription ruleset and see the answer from the running pico rather than reasoning about what it ought to be. The console is read-only by construction; it compiles your input as an expression and runs it the way a query runs, so it can&#8217;t assign entity variables or take actions. It&#8217;s also owner-only, available on the UI channel and to the local developer tools, never on discovery or app channels. The Rulesets tab gets a companion Docs view that renders each ruleset&#8217;s documentation from the same schema, with a &#8220;Try it&#8221; button next to every example.</p><h2><strong>Changes for Agents</strong></h2><p>Coding agents like Claude Code and Cursor work best in exactly the loop Smalltalk made famous: try something, observe the result, and adjust. A person can stare at code for a long time before running it. An agent learns by running it, many times, and anything that makes the loop slow or silent hurts an agent more than it hurts a human.</p><p>Version 1.8 attacks the loop from both ends. On the checking side, <code>krl-check</code> parses and compiles a ruleset, lints its annotations, and reports errors with line and column. Installing or flushing a ruleset now validates it first, and a failure raises <code>wrangler:ruleset_install_failed</code> or <code>wrangler:ruleset_flush_failed</code> with the errors so they can be handled programmatically.</p><p>On the live side, rule outcomes and the console give an agent the same answers they give a person in the Testing tab. Each of the repositories now carries a <code>CLAUDE.md</code> and <code>AGENTS.md</code> explaining layering, conventions, and commands, and the engine serves its documentation as <code>llms.txt</code> along with an OpenAPI description of its HTTP API.</p><p>The engine also has a built-in MCP server with two faces. The first is for agents acting as developers. Running <code>pico-engine mcp --stdio</code> connects an agent to a local engine with tools to validate and install rulesets, create and delete picos, raise events, run queries, evaluate expressions in the console, and tail the event log. Our bar for the release was simple: a fresh Claude Code session with only <code>CLAUDE.md</code> and the MCP server should be able to start an engine, write a ruleset that passes <code>krl-check</code>, install it, raise an event, and query the result without ever opening the wiki. That&#8217;s the Smalltalk loop, carried out by an agent. I&#8217;ve already used this multiple times, telling Cursor to update a live mesh rather than doing it myself.</p><p>The second face is for agents acting as operators of a running mesh. Any channel can be reached over Streamable HTTP at <code>/mcp/&lt;eci&gt;</code>, where <code>&lt;eci&gt;</code> is the channel&#8217;s ECI, using an OAuth bearer token scoped to that channel. The tools aren&#8217;t written by hand; they&#8217;re generated from what the channel allows, one tool for each event and query the channel&#8217;s policy permits. When we built a <a href="https://www.windley.com/archives/2026/04/building_a_conversational_interface_for_manifold_with_mcp_and_picos.shtml">conversational interface for Manifold</a>, my students hand-wrote MCP wrappers for Manifold&#8217;s events and queries. The mesh MCP server generalizes that work to any pico, and it can do so because of the schema.</p><h2><strong>Schema as a Foundation for It All</strong></h2><p>The change that makes everything above possible is that a pico can now describe itself. Ruleset authors add structured doc comments, <code>/** ... */</code>, directly before the rules and shared functions they want callers to see.</p><p>We considered declaring events and queries in a block inside the ruleset&#8217;s <code>meta</code> section and rejected it for three reasons:</p><ol><li><p>A declaration in <code>meta</code> is a second copy of every event and function, far from the code, and it will drift.</p></li><li><p>It describes events, but functionality lives in rules, so it needed extra machinery to say what a rule&#8217;s <code>select when</code> already says.</p></li><li><p>It would have had to absorb <code>shares</code>, forcing every existing ruleset to change.</p></li></ol><p>Comments on the rules themselves avoid all three problems. Here&#8217;s an annotated rule from Manifold:</p><pre><code>/**
 * Create a thing pico as a child and subscribe it as a manifold_thing.
 * Only fires while Manifold has fewer than max_picos children. When the thing is
 * fully initialized, community:thing_created is sent to callback_eci with the
 * caller&#8217;s rcn.
 * @attr name String &#8220;display name of the new thing&#8221;
 * @attr callback_eci String optional &#8220;channel to receive community:thing_created&#8221;
 * @attr rcn String optional &#8220;caller&#8217;s correlation id, echoed in the callback&#8221;
 */
rule create_thing {
  select when manifold create_thing
  ...
}</code></pre><p>The author writes only what the code can&#8217;t say: a description, the attributes the rule cares about, and their types. Everything else is derived by the compiler: the entry event from <code>select when</code>, any constraints in its <code>where</code> clause, the rule&#8217;s condition, the shared functions a caller can check in advance, and the events the rule may raise or send. Annotations are opt-in. A rule without one still runs; it just isn&#8217;t advertised. Annotations also decide only what is <em>advertised</em>, never what is permitted; <code>shares</code> still decides what is queryable and channel policy still decides who may do what.</p><p>From those annotations the engine builds two schemas. The <em>ruleset schema</em> describes what one ruleset offers, rule by rule, with all the derived detail a developer wants. That&#8217;s what the Testing tab and the Docs view use. The <em>pico schema</em> merges the ruleset schemas of every ruleset installed on a pico into one aggregate, grouped by event, because a caller doesn&#8217;t care which ruleset handles an event, only what it can send and query. Filter the pico schema by a channel&#8217;s policy and you get a <em>channel schema</em>: what someone using this particular can do.</p><p>That chain, from ruleset schemas to pico schema to channel schema, is what the rest of the release consumes. The Testing tab, the Docs view, discovery bindings for integrators, and the generated mesh MCP tools all read from it, so they can&#8217;t disagree with each other or with the code. The surface that a developer sees in the UI is the same surface an agent sees through MCP.</p><p>The schema also turns reference documentation into a build step rather than a writing task. The engine repository includes a <code>krl-schema</code> tool that reads a ruleset&#8217;s annotations and derived data and writes a reference page in Markdown: each operation with its entry event, attributes, condition, and the events it may emit, and each query with its arguments and return type. Because the page is generated from the same schema the engine uses, it can&#8217;t fall out of date the way hand-written ruleset documentation always has. A project can feed the same output into its <code>llms.txt</code>, so the reference an agent reads matches the one a person reads.</p><h2><strong>Why the Pico Engine Is Different</strong></h2><p>If live systems were so good, why did edit, lint, and compile win? Mostly because of the image. Code lived inside it alongside the objects, which made Smalltalk hard to version, diff, and merge in a world that standardized on text files and version control. Images accumulated state in addition to the run context, so &#8220;it works in my image&#8221; was a harder problem than &#8220;it works on my machine.&#8221; And Smalltalk was a world of its own that didn&#8217;t integrate well with other operating system or languages.</p><p>Liveness didn&#8217;t die, though. It survived as a layer on top of files: REPLs, Jupyter notebooks, the browser&#8217;s developer console, hot reload, and things like Erlang&#8217;s hot code loading. Files won as the source of truth. Liveness stayed as the way you explore. But several things have changed since Smalltalk lost that argument:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RoUc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RoUc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png 424w, https://substackcdn.com/image/fetch/$s_!RoUc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png 848w, https://substackcdn.com/image/fetch/$s_!RoUc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png 1272w, https://substackcdn.com/image/fetch/$s_!RoUc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!RoUc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png" width="705" height="544.6259541984733" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:506,&quot;width&quot;:655,&quot;resizeWidth&quot;:705,&quot;bytes&quot;:82104,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/222377372?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RoUc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png 424w, https://substackcdn.com/image/fetch/$s_!RoUc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png 848w, https://substackcdn.com/image/fetch/$s_!RoUc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png 1272w, https://substackcdn.com/image/fetch/$s_!RoUc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa52fb38-9469-4aee-86ef-6fee68f2d3f2_655x506.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Many of today&#8217;s systems are long-lived and stateful. A pico or a cloud service runs for months, accumulating state, and new code changes what that running thing does rather than starting a fresh program. That&#8217;s the world Smalltalk assumed, and it&#8217;s the world picos live in.</p><p>But picos don&#8217;t have to choose between Smalltalk&#8217;s model and the file-based one. Smalltalk merged code and state in one image, and that&#8217;s what made it hard to version and reproduce. Picos separate the two. Code lives in rulesets, which are text files at URLs, versioned in <code>git</code> and checked by <code>krl-check</code>. State lives in picos, which are persistent, always on, and live; you talk to them through the Testing tab, the console, events, and queries.</p><p>Version 1.8 strengthens both sides at once. Validation on install, install-failure events, and <code>krl-check</code> make the file side better. The console, rule outcomes, and schemas make the live side better. The developer MCP server gives an agent both in one loop: write a file, check it, install it, and then have a conversation with the running pico. Smalltalk was right about the live conversation, and the industry was right about files. Now that agants can be builders too, you need both.</p><h2><strong>Other Changes</strong></h2><p>Two other changes deserve mention. The first is a fix to channel policy. As of 1.8, <code>deny</code>overrides <code>permit</code>, so a narrow deny can&#8217;t be widened by a broader permit. Parents can set a <em>policy ceiling</em> when they create a child so that the child can&#8217;t create channels more permissive than its parent allows, operators can configure engine-wide deny lists, and wildcard channels can optionally require a validated caller identity. This might look like an operator concern in a release for builders, but it&#8217;s what makes the mesh MCP server safe to use. Tools generated from a channel&#8217;s schema are only as safe as the channel that scopes them, and a leaked ECI shouldn&#8217;t be a key to more than it was meant to open. We published an <a href="https://github.com/Picolab/pico-engine/blob/master/docs/design/channel-policy-audit-2026-10.md">audit of the engine&#8217;s channel policies</a> alongside the release.</p><p>The second is an engine configuration file. Engine settings can now live in <code>~/.config/pico-engine/config.json</code>, or in another file named with <code>pico-engine -c</code>or <code>PICO_ENGINE_CONFIG</code>, which makes running several engines on one machine much less fiddly. Environment variables still work, but the config file wins when both are set. Here&#8217;s the example config that ships with the engine:</p><pre><code>{
  &#8220;home&#8221;: &#8220;~/.pico-engine&#8221;,
  &#8220;port&#8221;: 3000,
  &#8220;baseUrl&#8221;: &#8220;http://localhost:3000&#8221;,
  &#8220;allowSelfSignup&#8221;: false,
  &#8220;allowLocalhostChannelBypass&#8221;: true,
  &#8220;wildcardSkyRequireBearer&#8221;: false,
  &#8220;logToStdout&#8221;: false,
  &#8220;webauthn&#8221;: {
    &#8220;rpId&#8221;: &#8220;localhost&#8221;,
    &#8220;origin&#8221;: &#8220;http://localhost:3000&#8221;,
    &#8220;rpName&#8221;: &#8220;Pico Engine&#8221;
  }
}</code></pre><p>The complete list of configuration options, along with the environment variables they replace, is in the <a href="https://github.com/Picolab/pico-engine/blob/master/packages/pico-engine/public/docs/pico-engine.md#config-json-fields">operator guide</a>. The guide also covers running several engines on one host and the new policy settings, such as <code>defaultRootPolicyCeiling</code> and the global deny lists.</p><p>Annotations are only useful if people know how to write them, so we annotated the rulesets that every pico engine developer already depends on. The main Wrangler ruleset, along with its companion subscription, PDS, OAuth, and other rulesets now carry annotations in place of the hand-maintained <code>__testing</code> maps they used before. That makes them the first place you&#8217;ll see the new Testing tab and Docs view at work, and the place to look when you want to see how a rule with forwarded attributes or several <code>@example</code> presets is described. If you&#8217;re annotating your own rulesets, start by reading Wrangler&#8217;s.</p><p>The <a href="https://github.com/Picolab/manifold-api/releases/tag/v1.8.0">Manifold 1.8 release</a> does the same for a framework built on top of Wrangler. Manifold&#8217;s rulesets are annotated throughout, including the delegation rules, like <code>create_thing</code> above, that take a <code>callback_eci</code> and correlation ID and finish their work asynchronously. Its <a href="https://github.com/Picolab/manifold-api/tree/main/docs/rulesets">ruleset reference pages</a> and <code>llms.txt</code> are generated with <code>krl-schema</code>, which makes Manifold the first full example of documentation built from annotations. SafeAndMine and the Journal ruleset build their discovery bindings with <code>wrangler:schemaBindings</code> rather than hand-written maps. The release also adds a Home Assistant notification channel and retires the old skills registry in favor of the engine&#8217;s MCP server.</p><h2><strong>Builders</strong></h2><p>In Smalltalk, the conversation with a running system was a metaphor. You typed an expression, chose <em>Do It</em>, and the system answered. With an agent on the developer MCP server, the conversation is literal. Imagine telling an agent, &#8220;make a pico that watches my freezer sensor and tells me when it gets warm.&#8221; The agent creates the pico, writes the KRL, validates it, installs it, raises test events, reads the rule outcomes, and reports back. That&#8217;s the same live loop, carried out in plain language, and the 1.8 features are what make it work: errors the agent can act on, outcomes that say why a rule didn&#8217;t fire, and a console that shows real state instead of a guess.</p><p>Kay&#8217;s second idea, users as builders, is the one I find most interesting, partly because it mostly didn&#8217;t happen. Smalltalk became a tool for professionals. The real successes in end-user building were spreadsheets and HyperCard, and both succeeded by narrowing what you could build. The barrier was never just the tools; building required learning a formal language. Agents lower that barrier in a way Smalltalk couldn&#8217;t. A builder now needs to know what they want and be able to judge whether they got it, not how to write KRL. That changes who gets to shape the software that acts on their behalf. A builder who isn&#8217;t a developer, working through an agent, needs a few things from the system, and the MCP surface is where 1.8 provides them:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_w6P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_w6P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png 424w, https://substackcdn.com/image/fetch/$s_!_w6P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png 848w, https://substackcdn.com/image/fetch/$s_!_w6P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png 1272w, https://substackcdn.com/image/fetch/$s_!_w6P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!_w6P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png" width="726" height="474.3496932515337" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:426,&quot;width&quot;:652,&quot;resizeWidth&quot;:726,&quot;bytes&quot;:63029,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/222377372?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_w6P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png 424w, https://substackcdn.com/image/fetch/$s_!_w6P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png 848w, https://substackcdn.com/image/fetch/$s_!_w6P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png 1272w, https://substackcdn.com/image/fetch/$s_!_w6P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a9a0f0-541e-4b4b-8898-dd184824a1e5_652x426.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Smalltalk trusted everyone inside the image, and that was fine when the image belonged to one programmer at one workstation. A world where systems interact and people build through agents can&#8217;t make that assumption. Picos have always had channel policies; what 1.8 adds is tightening them and tying the schema to them, so what a builder&#8217;s agent can see is exactly what it&#8217;s allowed to do. None of this finishes Kay&#8217;s project; plenty of hard problems remain between &#8220;tell an agent what you want&#8221; and software you can rely on. But it moves the line. Version 1.8 gives the people who build with picos a live conversation with the running system, and it opens that conversation to builders who don&#8217;t have to be programmers. That&#8217;s who this release is for.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/10/pico_conversations.png">Building in conversation with a pico</a> from ChatGPT (public domain)</p>]]></content:encoded></item><item><title><![CDATA[Closures, Objects, Actors, and Picos]]></title><description><![CDATA[Summary: I&#8217;ve been intrigued by closures since I taught introductory computer science from SICP at UC Davis in 1988.]]></description><link>https://www.technometria.com/p/closures-objects-actors-and-picos</link><guid isPermaLink="false">https://www.technometria.com/p/closures-objects-actors-and-picos</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Wed, 21 Oct 2026 15:49:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Buhj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary:</strong> <em>I&#8217;ve been intrigued by closures since I taught introductory computer science from SICP at UC Davis in 1988. This post dives into a little programming language theory to trace a line from closures to objects to actors to picos, showing what each step adds. A pico is a closure that has been made to answer for itself in the world, with persistent state, a durable identity, and relationships it can carry when it moves.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Buhj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Buhj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!Buhj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!Buhj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!Buhj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Buhj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Closure to Pico&quot;,&quot;title&quot;:&quot;Closure to Pico&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="Closure to Pico" title="Closure to Pico" srcset="https://substackcdn.com/image/fetch/$s_!Buhj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!Buhj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!Buhj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!Buhj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54ddcb02-b1d4-4a41-af02-00c1666f8b63_1672x941.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I&#8217;ve been intrigued by closures ever since I taught an introductory computer science course from <em><a href="https://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs">Structure and Interpretation of Computer Programs</a></em> (SICP) at UC Davis in 1988. Watching students realize that a function plus the environment it was born in was enough to build objects, with no classes and no special syntax, was one of the great pleasures of teaching that course. I&#8217;ve followed the idea around ever since and used it wherever I could. When I built picos, I described each one as <a href="https://www.windley.com/archives/2022/07/the_most_inventive_thing_ive_done.shtml">a closure over services and data</a>. I&#8217;ve also described picos as <a href="https://www.windley.com/archives/2015/11/reactive_programming_with_picos.shtml">implementing the actor model of distributed computing.</a> But as this week&#8217;s post on <a href="https://www.windley.com/archives/2026/10/moving_picos_from_mesh_to_mesh.shtml">moving picos between engines</a> shows, they&#8217;re something more than that.</p><h2><strong>Closures in SICP</strong></h2><p>A <em>closure</em> is a procedure bundled with the environment in which it was created. When you call it, the body runs against bindings that were captured at creation time and that nothing outside the closure can see. Chapter 3 of SICP uses this to build a bank account:</p><pre><code>(define (make-account balance)
  (define (withdraw amount)
    (if (&gt;= balance amount)
        (begin (set! balance (- balance amount))
               balance)
        &#8220;Insufficient funds&#8221;))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (define (dispatch m)
    (cond ((eq? m &#8216;withdraw) withdraw)
          ((eq? m &#8216;deposit) deposit)
          (else (error &#8220;Unknown request&#8221; m))))
  dispatch)

(define acc (make-account 100))
((acc &#8216;withdraw) 50)   ; =&gt; 50</code></pre><p>The variable <code>balance</code> lives in the environment that <code>make-account</code> created, and the only way to reach it is through <code>dispatch</code>. Each call to <code>make-account</code> produces a new environment, so every account has its own private balance. SICP calls this style <em>message passing</em>: you don&#8217;t operate on the account&#8217;s data; you send the account a message and it decides what to do.</p><p>SICP is also careful about what this costs. Once a closure holds mutable state, two accounts that start with the same balance are no longer interchangeable, and the book spends a section on <em>sameness and change</em> to work through what that means. With state comes identity. That observation turns out to be the thread that runs all the way to picos.</p><h2><strong>Closures and Objects</strong></h2><p>The account above is an object in every way that matters: encapsulated state, behavior bound to that state, and an interface defined by the messages it accepts. <code>make-account</code>plays the role of a class, and <code>dispatch</code> is a hand-built method table. There&#8217;s an old programming koan that captures the equivalence: closures are a poor man&#8217;s objects, and objects are a poor man&#8217;s closures. Each can be built from the other.</p><p>What object-oriented languages add is vocabulary and machinery. Classes give the constructor a name and a place to live; inheritance lets one dispatch table extend another; method syntax spares you from writing the <code>cond</code> yourself. Those are real conveniences, but they don&#8217;t change the underlying model. An object, like a closure, lives in one address space, is named by a pointer that means nothing outside that heap, and is invoked by a synchronous call that runs on the caller&#8217;s thread. When the process ends, so does the object.</p><h2><strong>Actors</strong></h2><p>The <a href="https://en.wikipedia.org/wiki/Actor_model">actor model</a>, introduced by Carl Hewitt in 1973 and formalized by Gul Agha in the 1980s, takes message passing literally. An <em>actor</em> has private state and a mailbox. It processes messages one at a time, and in response to a message it can do three things: send messages to actors it knows about, create new actors, and decide how it will handle the next message. Messages are asynchronous; the sender doesn&#8217;t wait, and there is no shared memory between actors.</p><p>Agha&#8217;s framing of an actor as a closure with a mailbox is the halfway point between the SICP account and a pico. The dispatch is still there, but the call has become a message in a queue, and the one-at-a-time rule replaces locks as the way an actor protects its state. Actors also introduce something closures and objects lack: an address that is useful only to those who have been given it. Knowing an actor&#8217;s address is the capability to talk to it. That&#8217;s a short step from a reference to a relationship.</p><h2><strong>Picos</strong></h2><p>A pico is an actor, and you can easily translate the SICP <code>account</code> to KRL. Here&#8217;s the <code>withdraw</code> written as a KRL rule:</p><pre><code>rule withdraw {
  select when account withdrawal
  pre {
    amount = event:attrs{&#8221;amount&#8221;}
  }
  if ent:balance &gt;= amount then noop()
  fired {
    ent:balance := ent:balance - amount
    raise account event &#8220;balance_updated&#8221; attributes {
      &#8220;balance&#8221; : ent:balance
    }
  } else {
    raise account event &#8220;insufficient_funds&#8221; attributes {
      &#8220;balance&#8221; : ent:balance,
      &#8220;amount&#8221; : amount
    }
  }
}</code></pre><p>The entity variable <code>ent:balance</code> is the captured environment, the <code>select when</code> clause is the <code>dispatch</code>, and an <code>account:withdrawal</code> event is the message. Each pico has its own event queue and retrieves events from it one at a time, just as an actor drains its mailbox. A pico usually has several rulesets installed, each with its own entity variables, so it&#8217;s more precisely a set of closures over separate environments that share one identity and one event queue.</p><p>Where picos depart from closures, objects, and most actor systems is that they insist on surviving. A pico&#8217;s state is persistent by default, so it outlives the process that happens to be running it. Picos are internet-first; its identity is a <a href="https://www.windley.com/archives/2026/08/pico-to-pico_identity_arrives.shtml">DID that anyone on the network can resolve</a>, not a pointer or a runtime address. Its references to other picos are channels and peer DIDs, each named, governed by policy, and revocable, rather than raw pointers with unlimited authority. And its code can change over its lifetime as rulesets are installed and removed. Each of those properties follows from the first: once state has to outlive the process, it has to be persistent; once a persistent entity can be reached from anywhere, its identity has to be a name; once that name can be handed to strangers, the reference has to carry policy.</p><p>Those same choices are what make a pico movable. Nobody moves closures between machines, because the captured environment is opaque and full of pointers into the local heap; the <a href="https://en.wikipedia.org/wiki/Code_mobility">mobile-code</a> systems that tried, like <a href="https://en.wikipedia.org/wiki/Emerald_(programming_language)">Emerald</a>, <a href="https://en.wikipedia.org/wiki/Obliq">Obliq</a>, and <a href="https://en.wikipedia.org/wiki/Telescript_(programming_language)">Telescript</a>, had to invent restrictions to make it work. A pico never captures anything that can&#8217;t follow it. Entity variables are plain data, rulesets are fetched by URL, and every reference to another pico is a name. Exporting a pico is closure serialization, importing it is rehydration, and the ECI remapping on import is <a href="https://en.wikipedia.org/wiki/Pointer_swizzling">pointer swizzling</a> under a different name.</p><h2><strong>Side by Side</strong></h2><p>The table lines up the four models on the properties that change as you move from one to the next. Every cell could be argued at length, and particular languages and actor systems blur some of these lines, but the rows are the properties that matter when you want software to last longer than the process running it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!m3J2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!m3J2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png 424w, https://substackcdn.com/image/fetch/$s_!m3J2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png 848w, https://substackcdn.com/image/fetch/$s_!m3J2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png 1272w, https://substackcdn.com/image/fetch/$s_!m3J2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!m3J2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png" width="657" height="654" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:654,&quot;width&quot;:657,&quot;resizeWidth&quot;:657,&quot;bytes&quot;:92180,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/221504442?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!m3J2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png 424w, https://substackcdn.com/image/fetch/$s_!m3J2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png 848w, https://substackcdn.com/image/fetch/$s_!m3J2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png 1272w, https://substackcdn.com/image/fetch/$s_!m3J2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21aec974-6f18-4f9b-a0c9-245133679f55_657x654.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Read left to right, each column keeps what the one before it had and adds something. Objects give closures a vocabulary. Actors give objects asynchrony and isolation. Picos give actors persistence, a durable identity, and relationships they can carry with them. SICP&#8217;s lesson about sameness and change was that state brings identity with it; picos take that seriously enough to make the identity cryptographic and the state portable.</p><p>A closure in 1988 was a beautiful way to think about computation. A pico is a closure that has been made to answer for itself in the world, one that can belong to a person rather than being tied to the machine it runs on.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/10/closure_to_pico.png">Closure to Pico</a> from ChatGPT (public domain)</p>]]></content:encoded></item><item><title><![CDATA[Moving Picos from Mesh to Mesh]]></title><description><![CDATA[Summary: Software that can&#8217;t leave the machine it was born on isn&#8217;t really yours.]]></description><link>https://www.technometria.com/p/moving-picos-from-mesh-to-mesh</link><guid isPermaLink="false">https://www.technometria.com/p/moving-picos-from-mesh-to-mesh</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Tue, 13 Oct 2026 14:20:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ZmvN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>Software that can&#8217;t leave the machine it was born on isn&#8217;t really yours. Version 1.7 of the pico engine lets a pico and its subtree move between engines while its relationships keep working, because other picos follow its DID rather than its address. This post describes what moves, why identity is what makes it possible, and what&#8217;s still ahead.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZmvN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZmvN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!ZmvN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!ZmvN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!ZmvN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZmvN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A pico packs up and moves to a new engine&quot;,&quot;title&quot;:&quot;A pico packs up and moves to a new engine&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="A pico packs up and moves to a new engine" title="A pico packs up and moves to a new engine" srcset="https://substackcdn.com/image/fetch/$s_!ZmvN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!ZmvN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!ZmvN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!ZmvN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6585f3a0-65b3-4d24-93ce-f27c6b5bed6d_1672x941.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In one of my favorite books, Vernor Vinge&#8217;s <em><a href="http://www.amazon.com/exec/obidos/ASIN/125084150X/technometria-20">Rainbows End</a></em>, Juan Orozco and a pair of troublesome twins play in a public park where the physical world is overlaid with a constantly shifting digital one. Creatures, games, and other virtual constructs inhabit the park, interacting with people and with the networked infrastructure around them. What caught my attention in that scene is that these software entities have an identity independent of any particular piece of infrastructure while still maintaining a relationship with the physical and network environment they inhabit. They exist <em>in</em> the world without belonging to a particular computer.</p><p>I think the scene sticks with me because that idea has long been my dream for picos. A pico has an identity, persistent state, rules, and relationships, but none of those things inherently require it to remain on the machine where it was created. If we separate the identity of a pico from its execution location, a pico could move from one host to another while remaining the same computational entity. Other picos and applications could keep interacting with it without needing to know where it&#8217;s running.</p><p>Why would we want a pico to move? There are plenty of reasons:</p><ul><li><p><strong>Resilience and censorship:</strong> Move away from a host that becomes unavailable, hostile, or filtered.</p></li><li><p><strong>Economics:</strong> Migrate to cheaper compute or storage when there&#8217;s no reason to stay put.</p></li><li><p><strong>Latency:</strong> Move computation closer to the people, devices, or other picos it interacts with.</p></li><li><p><strong>Bandwidth:</strong> Move toward a data source rather than continually hauling data across the network.</p></li><li><p><strong>Privacy and jurisdiction:</strong> Keep a pico on infrastructure with appropriate governance or data-handling rules.</p></li></ul><p>Underneath all of those is a more powerful reason. If your picos can only live on one engine, you don&#8217;t own them in any meaningful sense; you&#8217;re renting a seat from whoever runs that engine. Portability is how we avoid lock-in, and avoiding lock-in is a precondition for personal agency in a system built from software that acts on your behalf. Version 1.7 of the <a href="https://github.com/Picolab/pico-engine">pico engine</a>, released a few days ago, takes the first real step: a pico and its subtree can move from one mesh to another, on a different engine, while the relationships it has with other picos keep working.</p><h2><strong>A Bike Changes Hands</strong></h2><p>The easiest way to see what this means is to watch it happen. The scenario in the <a href="https://youtu.be/7SnLJY7Rw-A">demo video</a> shown below imagines a bike club that owns gravel bikes for members to borrow and runs a community pico to coordinate rides. Each bike has a pico that serves as its <em>digital twin</em>: the pico holds the bike&#8217;s state and history, has a child pico for the bike&#8217;s computer, and has relationships with the club&#8217;s Manifold app and with the Trail Ride Community. A ride coordinator with his own mesh has formed a relationship with Gravel Bike #7 so it can take part in the rides he organizes. Then the club sells bike #7, and the bike&#8217;s pico needs to move to the new owner&#8217;s mesh on a different engine.</p><div id="youtube2-7SnLJY7Rw-A" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;7SnLJY7Rw-A&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/7SnLJY7Rw-A?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>The bike club and Alice, the new owner, use <a href="https://github.com/Picolab/manifold-api">Manifold</a>, the framework for managing things and communities that I&#8217;ve <a href="https://www.windley.com/archives/2026/06/manifold_api_and_sensor_network_two_new_repos.shtml">written about before</a> and recently <a href="https://www.windley.com/2026/09/moving_my_sensor_network_onto_manifold.shtml">moved my own sensor network onto</a>. Manifold matters here for a reason I&#8217;ll come back to: a thing pico assumes certain services exist above it in the tree, and the destination has to provide them. What you see in the video is the engine&#8217;s developer interface rather than anything a bike owner would use; it lets us observe and manipulate the picos directly, which is what a demo of the plumbing needs. Three meshes run on two engines, the club&#8217;s and the coordinator&#8217;s on one and the new owner&#8217;s on the other.</p><p>The bike&#8217;s pico and its bike-computer child are exported from the club&#8217;s mesh as an encrypted blob and imported under the new owner&#8217;s Manifold. After the import, the bike has the same <code>did:webvh</code> identity it had before, the ride coordinator&#8217;s relationship with it still works, and the Trail Ride Community back on the club&#8217;s engine still has a link to it. The new owner&#8217;s Manifold forms a fresh relationship with the bike, since that one belongs to the new context rather than the old. Nothing had to be reintroduced.</p><p>A pico that stands in for a physical thing grows more valuable the longer it lives, because it accumulates the thing&#8217;s history, relationships, and state over years. I made this argument <a href="https://www.windley.com/archives/2026/08/why_not_spiffe_for_pico_identity.shtml">in August</a> using an example from Fuse, where <a href="https://www.windley.com/archives/2014/07/fuse_as_a_microservice_architecture.shtml">selling a car meant handing its pico to the new owner</a> with the maintenance history intact. The bike is the same idea. Its identity is bound to the bike, not to the club, and it has to be able to outlive any particular owner or engine because the bike will.</p><h2><strong>What Makes a Pico Portable?</strong></h2><p>Making a pico portable requires separating what the pico is from where the pico runs. A pico isn&#8217;t a process, container, or virtual machine; those are execution mechanisms tied to particular infrastructure. A pico is an <strong>enduring computational entity with an identity, state, rules, and relationships</strong>. The host pico engine is simply the place where that entity happens to execute.</p><p>That distinction defines what has to move. A portable pico needs all the information necessary to recreate itself on a new engine: its rulesets, persistent state, configuration, keys, and information about its relationships with other picos and services. Some of that information needs special handling. Private keys, for example, shouldn&#8217;t be copied around indiscriminately. But conceptually the goal is clear: capture the pico&#8217;s computational state, transfer it to another compatible host, resume execution there, and retire the old instance.</p><p>Identity continuity poses the hard problem. If a pico moves, everyone it interacts with shouldn&#8217;t have to get reacquainted with it; its identity must remain stable even when its location changes. That means addressing and routing have to be indirect: send an event to the pico, not to the server currently running it. Some discovery mechanism maps the pico&#8217;s enduring identity to its current network location, and moving becomes a routing update rather than an identity change.</p><p>Relationships create a similar requirement. A pico might have channels to dozens of other picos in different meshes and even on different engines, and those relationships should survive migration without being recreated. Ideally, the endpoints of a relationship identify the participating picos rather than their hosts, so that after a move messages simply begin flowing to the pico&#8217;s new location. Webhooks don&#8217;t enjoy this property; each one holds a URL, and every one of them has to be updated by hand when the thing it points at moves. This is the difference between having a protocol and merely having a convention.</p><p>One thing I learned building this is that the unit of portability isn&#8217;t a single pico and it isn&#8217;t a whole mesh either. Exporting an entire mesh is the wrong granularity; the bike club isn&#8217;t moving, only the bike is. But a pico rarely travels alone. Bike #7 has a bike-computer child, and parent-child relationships are part of how a pico behaves: children rely on their parent for rulesets, shared relationships, and policy. So what moves is a <em>subtree</em>, the pico and its descendants, and the importer attaches it under a new parent in the destination mesh.</p><p>That subtree boundary creates a dependency the design has to take into account. A thing pico inside the Manifold framework assumes Manifold&#8217;s services exist above it; importing it under a bare root on another engine would leave it running but functionally broken. The export carries the subtree only, not its ancestors, so the importer is responsible for supplying the platform the subtree expects. In the demo that means adopting the bike under the new owner&#8217;s Manifold app pico, which is exactly where a thing pico belongs.</p><p>Those pieces are what 1.7 puts in place, and they&#8217;re the foundation for the capability imagined in the scene from <em>Rainbow&#8217;s End</em> I mentioned earlier. With a stable identity, relationships that follow it, and an export that captures what it is, migration could become part of a pico&#8217;s own behavior in a future release. A pico could monitor the environment in which it runs, discover alternative hosts, evaluate them against its own policies, and decide whether moving is advantageous, weighing cost, latency, bandwidth, reliability, jurisdiction, trust, or the availability of particular services. None of that exists today, but nothing in the architecture stands in its way now. At that point portability stops being a deployment feature; just as a pico can react to an event by updating state or sending a message, it could react by moving itself. The infrastructure provides places to run; the pico decides where it wants to live.</p><h2><strong>Why DIDs Make the Difference</strong></h2><p>When I added <a href="https://www.windley.com/archives/2026/08/pico-to-pico_identity_arrives.shtml">pico-to-pico identity in version 1.6</a>, I said it was the foundation portability was waiting on. That wasn&#8217;t a side benefit; I built the layer for this express purpose. Before 1.6, a pico&#8217;s only identifiers were its channel identifiers (ECIs), and an ECI is both a local routing address and, in practice, a capability. Change the ECI and you break every peer, UI link, and webhook that holds the old value. Moving a pico while keeping its ECIs is fraught from both a security and an operability standpoint, and moving it without them meant starting over.</p><p>Giving every pico two kinds of DIDs splits those concerns apart. The <code>did:webvh</code> is the pico&#8217;s stable, long-term address, the passport it hands to strangers. Its self-certifying identifier (SCID) is fixed for the life of the DID, while the host and path in the DID&#8217;s log can change; a move appends an entry to the log saying where the pico now lives, and anyone who resolves the DID finds the new location. The <code>did:peer</code> pairs that each relationship uses are private, point-to-point identifiers with no engine address baked into them. Peers follow the DID, and the engine mints fresh ECIs on the new host as nothing more than routing handles.</p><p>Relationships survive because <a href="https://identity.foundation/didcomm-messaging/spec/">DIDComm</a> already knows how to handle a party whose endpoint or keys change. After an import, the moved pico sends a rotation message to each of its peers, and each peer updates where it sends traffic for that relationship. The ride coordinator&#8217;s mesh never learned the bike&#8217;s new ECI and never needed to; it learned that the DID it already trusted now resolves somewhere else. That&#8217;s an example of what it means for identity to be a protocol rather than a convention: the update is a message the relationship was designed to carry, not a chore for the operator.</p><h2><strong>What Actually Happens in a Move</strong></h2><p>The export walks the subtree and packages everything needed to reconstitute it: installed rulesets, entity state for each ruleset, channels with their tags and policies, scheduled events, and an identity snapshot for each pico that includes its <code>did:webvh</code> log and keys and its peer relationships. Rulesets with a canonical remote URL are carried by reference and fetched again on import; only rulesets that can&#8217;t be retrieved on the destination get embedded inline. The whole package is encrypted with a secret the exporter chooses, because a blob that contains keys and relationship state is a capability-bearing secret and has to be handled like one. Transferring the blob is up to you; nothing in Wrangler moves it for you yet.</p><p>The import creates the picos under the recipent parent, mints new ECIs for every channel, and hydrates entity state, remapping any old ECIs that rulesets had stored in their own state. Then it raises <code>wrangler:pico_imported</code> so rulesets can run their own migration logic. With the picos in place, the identity service relocates each <code>did:webvh</code>by appending the new location to its log and notifies every peer of the move over DIDComm. Picos on the destination engine that had relationships with the subtree before it arrived get reconciled locally, so a relationship formed before the move keeps working after it.</p><p>What 1.7 implements is more accurately a copy than a move. The import does nothing to the source; the donor subtree is left behind in a vestigial state, still holding the same DID, and has to be deleted once peers have cut over. Leaving it there is worse than untidy, since an engine that still has a local pico with that DID will route to the stale copy rather than the real one. Atomicity, rollback when a move half-completes, and forwarding from the old location are all open problems. The <a href="https://github.com/Picolab/pico-engine/blob/master/docs/design/pico-move.md">design notes</a> in the repository lay out what&#8217;s done and what isn&#8217;t.</p><h2><strong>Release 1.7</strong></h2><p><a href="https://github.com/Picolab/pico-engine/releases/tag/v1.7.0">Version 1.7.0</a> of the pico engine ships two things. The first is the portable move described above. Underneath are engine primitives: <code>ctx:exportRulesetState</code> and <code>ctx:importRulesetState</code> for a single ruleset&#8217;s state, and <code>ctx:exportSubtree</code> and <code>ctx:importSubtree</code> for a whole subtree. The developer&#8217;s interface to that functionality is <code>io.picolabs.portable_subtree</code>, part of Wrangler, which wraps the full pipeline, including DID relocation and peer notification, in a single query to export and a single event to import. On the Manifold side, <code>io.picolabs.manifold_portable_thing</code> in the <a href="https://github.com/Picolab/manifold-api">manifold-api</a> repository builds on that interface to export a thing from one Manifold and import it, with registration, into another. The repository includes a docker-compose file that stands up two engines so you can run the cross-engine demo yourself.</p><p>The second is an upgrade to the peer DIDs themselves. Relationships formed on 1.7 use <code>did:peer:4</code>, the variant on DIF&#8217;s standardization path, in place of the hand-rolled <code>did:peer:2</code> identifiers 1.6 used. No npm package existed, so the engine carries a TypeScript port of DIF&#8217;s reference implementation that I intend to contribute upstream. Existing relationships keep their <code>did:peer:2</code> identifiers and keep working; nothing converts automatically, and I&#8217;d rather let old relationships age out than rewrite identifiers that other picos already hold.</p><h2><strong>Just a Start</strong></h2><p>What I ultimately want is for a pico to move itself on command, and eventually on its own judgment, with the old instance retired as part of the same operation. This release gives us the export, the import, and the identity machinery that lets relationships follow the pico, but the transfer and cleanup have to be handled <em>ad hoc</em>, either manually using the developer console or programmatically in KRL. Those are the pieces that turn a copy into a move.</p><p>I also want to be careful about what one working demo proves. We implemented and tested this against a scenario we designed. A scenario you design will contain the cases you thought of. There are almost certainly dependencies between picos, relationships that cross subtree boundaries, and external systems holding old addresses that the bike club demo didn&#8217;t exercise. The only way to find them is to move real picos between real meshes, which is why I expect the next few releases to be shaped by what breaks.</p><p>The important lesson is that <em>supporting personal agency in a technical system is a choice</em>, and it&#8217;s almost always the harder one. Pinning a pico to the engine where it was born is easy; making its identity survive a move took an identity layer, a messaging protocol, and a careful accounting of what a pico actually is. We can build systems that people own or systems they merely rent. The choice is ours, and this release is my vote.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/10/pico-moving-house.png">A pico packs up and moves to a new engine</a> from ChatGPT (public domain)</p>]]></content:encoded></item><item><title><![CDATA[Human in the Loop Control for OpenClaw]]></title><description><![CDATA[Summary: Some agent actions are too consequential to leave to policy alone.]]></description><link>https://www.technometria.com/p/human-in-the-loop-control-for-openclaw</link><guid isPermaLink="false">https://www.technometria.com/p/human-in-the-loop-control-for-openclaw</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Thu, 24 Sep 2026 21:38:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ZkQD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>Some agent actions are too consequential to leave to policy alone. This post describes a new OpenClaw demo that uses Cedar and a Yubikey to put a human in the loop, binding each approval to the exact action being approved. Because the control lives in the harness rather than the prompt, the agent can&#8217;t reason its way around it.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZkQD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZkQD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!ZkQD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!ZkQD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!ZkQD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZkQD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Human in the Loop&quot;,&quot;title&quot;:&quot;Human in the Loop&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="Human in the Loop" title="Human in the Loop" srcset="https://substackcdn.com/image/fetch/$s_!ZkQD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!ZkQD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!ZkQD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!ZkQD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd121935-8bde-40b2-a7e8-8a69027c09b8_1672x941.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This post is part of a series on using dynamic authorization to control and coordinate AI agents. See the <a href="https://www.windley.com/archives/2026/03/agentic_ai_and_dynamic_authorization_a_series_recap.shtml">series recap</a> to find other posts in this series.</em></p><p>I&#8217;ve been <a href="https://www.windley.com/archives/2026/03/agentic_ai_and_dynamic_authorization_a_series_recap.shtml">writing about how we can use Cedar to control agent actions</a> and releasing <a href="https://github.com/windley/openclaw-cedar-policy-demo/tree/main/demo">demos showing Cedar as the authorization step</a> in OpenClaw. One of the constant worries with agents is that a sufficiently motivated agent will find creative ways around controls. For example, I might think to limit access to a specific directory, but not think to keep the agent from creating a link to it so that the policy allows what it would otherwise deny. Policies are written by people who can&#8217;t anticipate everything; agents are very good at finding the thing we didn&#8217;t anticipate.</p><p>One way to protect high-impact actions is by putting a human in the loop (HItL). Some actions, like sending email on my behalf, moving money, or deleting data, carry consequences that are hard to undo. For those, I don&#8217;t want to rely solely on having written the perfect policy. I want the agent to stop and wait until I&#8217;ve looked at exactly what it&#8217;s about to do and said yes. This post describes a <a href="https://github.com/windley/openclaw-cedar-policy-demo/blob/main/demo/README-hitl.md">new OpenClaw demo</a> that does that using Cedar and a Yubikey.</p><h2><strong>Controls, Not Prompts</strong></h2><p>The easy way to get a human in the loop is to tell the agent to ask. You put &#8220;always check with me before sending email&#8221; in the system prompt and hope for the best. That instruction is a suggestion to a language model. It competes with everything else in the context window, including the content of a web page or document that might have been written specifically to talk the agent out of asking. A prompt is guidance; it isn&#8217;t a control.</p><p>The theme running through this series is that authorization belongs in the harness, not the prompt. In the <a href="https://www.windley.com/archives/2026/02/a_policy-aware_agent_loop_with_cedar_and_openclaw.shtml">policy-aware agent loop</a>, every tool invocation passes through a policy enforcement point (PEP) that asks Cedar whether the action is allowed. The model doesn&#8217;t get a vote. It can <a href="https://www.windley.com/archives/2026/02/beyond_denial_using_policy_constraints_to_guide_openclaw_planning.shtml">reason about the denial and replan</a>, but it can&#8217;t skip the check, because the check isn&#8217;t something the model does. It&#8217;s something the harness does to the model&#8217;s proposed actions.</p><p>Human approval works the same way in this demo. The PEP, not the agent, decides when a human must approve, and the PEP, not the agent, supplies the evidence that a human did. The agent can&#8217;t forge that evidence because it never touches it. That&#8217;s the difference between asking an agent to behave and building a system where misbehaving doesn&#8217;t work.</p><h2><strong>What the Demo Does</strong></h2><p>Earlier demos answered the question &#8220;may the agent do this?&#8221; This one answers a different question: &#8220;may the agent send <em>this</em> email now that a human has cryptographically attested to it?&#8221; The demo adds a simulated <code>send_email</code> tool to OpenClaw. Gathering information and drafting the message are ungated; the agent can read files and write a scratch draft just as before. Sending is different. The following diagram shows the agent loop from the earlier posts with the HItL modifications added.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cC17!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cC17!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png 424w, https://substackcdn.com/image/fetch/$s_!cC17!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png 848w, https://substackcdn.com/image/fetch/$s_!cC17!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png 1272w, https://substackcdn.com/image/fetch/$s_!cC17!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!cC17!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png" width="1160" height="716" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:716,&quot;width&quot;:1160,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Agent Loop with Human in the Loop Authorization&quot;,&quot;title&quot;:&quot;Agent Loop with Human in the Loop Authorization&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Agent Loop with Human in the Loop Authorization" title="Agent Loop with Human in the Loop Authorization" srcset="https://substackcdn.com/image/fetch/$s_!cC17!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png 424w, https://substackcdn.com/image/fetch/$s_!cC17!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png 848w, https://substackcdn.com/image/fetch/$s_!cC17!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png 1272w, https://substackcdn.com/image/fetch/$s_!cC17!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc6daa79-83a9-4f90-9050-6c8d552fa9c1_1160x716.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Agent Loop with Human in the Loop Authorization (click to enlarge)</figcaption></figure></div><p>When the agent calls <code>send_email</code>, the PEP asks Cedar for a decision and gets a <code>deny</code>, because no human has approved the message. Cedar doesn&#8217;t know anything about approval workflows; it just says no. The PEP intercepts that <code>deny</code> and interprets it. Because the tool is <code>send_email</code>, the PEP treats the <code>deny</code> as &#8220;not yet&#8221; rather than &#8220;no,&#8221; and instead of returning it to the agent, it parks the request and waits for a human.</p><p>The human opens an approver page, reviews the recipient, subject, and body, and taps a Yubikey. The PEP then retries the Cedar request with the human&#8217;s approval injected into the context. This time Cedar returns <code>permit</code>, and the email is &#8220;sent,&#8221; which in the demo means a JSON file lands in a mailbox directory.</p><p>If nobody taps the key before the timeout (three minutes by default), the PEP returns a hard <code>deny</code> to the agent and doesn&#8217;t wait again. You can see this in the diagram as the timeout path that runs from the <code>/authorize</code> box back to the agent&#8217;s evaluation step. The agent learns that the send didn&#8217;t happen and can replan or report back, but it can&#8217;t try again and hope the human is more agreeable the second time.</p><p>The Cedar policies that enforce this are short. One permits <code>SendEmail</code> when a verified WebAuthn approval is present and matches the request; the other forbids it otherwise:</p><pre><code>@id(&#8221;hitl-1-allow-send-with-approval&#8221;)
permit(
  principal,
  action == OpenClaw::Action::&#8221;ToolExec::SendEmail&#8221;,
  resource
)
when {
  context has humanApproval &amp;&amp;
  context.humanApproval.verified == true &amp;&amp;
  context.humanApproval.method == &#8220;webauthn&#8221; &amp;&amp;
  context has requestHash &amp;&amp;
  context.humanApproval.requestHash == context.requestHash
};
</code></pre><p>The forbid policy is the same test negated. Since Cedar&#8217;s forbid always overrides permit, the explicit forbid means that no other permit policy, now or added later, can accidentally open up email sending without a human. The timeout lives in the PEP rather than the policy because Cedar has no notion of the current time; it evaluates the context it&#8217;s given, which is exactly what makes its decisions predictable.</p><p>Notice what the policies don&#8217;t say. Nothing in them tells anyone to go find a human; Cedar just returns <code>deny</code>, the same answer it gives for any other forbidden action. The PEP is what turns that <code>deny</code> into a request for approval. It intercepts the decision before the agent sees it and interprets a <code>deny</code> on <code>send_email</code> as &#8220;waiting for a human&#8221; rather than &#8220;no.&#8221; In other words, Cedar decides whether the action is allowed, and the PEP decides what a denial means. That division keeps the policy engine simple and deterministic, but it also means the rule about which denials a human can override lives in code, a point I&#8217;ll come back to below.</p><h2><strong>A Passkey for Each Approval</strong></h2><p>The approval isn&#8217;t a generic &#8220;the human said OK.&#8221; The demo uses ordinary WebAuthn, the protocol behind passkeys, and binds the challenge to a hash of the specific request. When I tap the Yubikey, I&#8217;m signing a statement about this recipient, this subject, and this body. The <code>requestHash</code> check in the policy makes sure the approval Cedar sees matches the action the agent is actually trying to take. If the agent changes a word in the body after I approve, the hashes don&#8217;t match and the send is denied.</p><p>Think about the difference between signing a check and signing a blank check. A blank check says &#8220;I trust whoever holds this&#8221;; a signed check for a specific amount to a specific payee says &#8220;I approve this.&#8221; Most approval flows for agents are closer to the blank check: the human clicks &#8220;allow&#8221; once and the agent carries that authority forward. Binding each approval to a single request keeps the human&#8217;s authority attached to the human&#8217;s decision. The approval can&#8217;t be replayed for a different message or stretched to cover the next ten sends.</p><p>The &#8220;human&#8221; part of human in the loop is only as strong as where the passkey lives. On a Yubikey or other roaming hardware key, the credential stays on the device and approval requires someone to physically present the key and touch it. In a software authenticator, like a browser&#8217;s passkey store or a password manager, the WebAuthn ceremony succeeds just the same, but anything that can unlock that store can approve. The demo asks the browser for a cross-platform authenticator so you&#8217;ll be prompted for the security key rather than Touch ID. For a while, at least, we don&#8217;t expect software agents to physically insert and tap Yubikeys. That&#8217;s the point.</p><h2><strong>Try It Yourself</strong></h2><p>The code is in the <a href="https://github.com/windley/openclaw-cedar-policy-demo">openclaw-cedar-policy-demo repository</a> on GitHub, and the <a href="https://github.com/windley/openclaw-cedar-policy-demo/blob/main/demo/README-hitl.md">HItL README</a> walks through running it. Clone the repo, but don&#8217;t start with the HItL demo. It builds on the earlier ones, so work through the <a href="https://github.com/windley/openclaw-cedar-policy-demo/blob/main/demo/README.md">basic Cedar demo</a> first to get the PDP, the PEP, and your OpenClaw configuration in place. The README also includes commands to verify that the earlier demos still pass once the HItL changes are added.</p><p>The README covers starting the PDP (which also serves the approver page), registering your Yubikey, and running a set of policy tests that don&#8217;t need a key at all. The live walkthrough asks the agent to send a simulated email, and then you approve it on the approver page. If you let it time out instead, you&#8217;ll see the agent receive the denial and no mailbox file appear. I&#8217;d recommend trying both; watching the agent handle the timeout says as much about the design as watching the approval succeed.</p><h2><strong>Shortcuts and the Road to Production</strong></h2><p>Like the other demos in this series, this one is built to show an architecture, not to run in production. It takes several shortcuts:</p><ul><li><p><strong>Simulated delivery&#8212;</strong>No email leaves the machine. An approved send writes a JSON file to <code>demo/mailbox/sent/</code>, named with a UTC timestamp.</p></li><li><p><strong>No notification&#8212;</strong>Nothing tells you a request is waiting. You have to open the approver page yourself and watch for it.</p></li><li><p><strong>One gated action, chosen in code&#8212;</strong>The policies name <code>SendEmail</code> directly, and the PEP is hard-coded to park any <code>deny</code> on <code>send_email</code>. Only that one tool requires a human, and the PEP, not policy, decides that a <code>deny</code> there should wait for approval. It will even park a send that some other policy forbids, asking for a tap that can&#8217;t change the outcome.</p></li><li><p><strong>One approver on localhost&#8212;</strong>The PDP serves the approver page, there&#8217;s a single registered credential, and it has to run on <code>localhost</code> so the WebAuthn origin matches.</p></li><li><p><strong>Trust in the authenticator&#8212;</strong>The demo asks for a roaming authenticator, but nothing verifies that the credential actually lives on hardware.</p></li></ul><p>None of these change the architecture, and each points toward how you&#8217;d generalize it into a production system:</p><ul><li><p><strong>Policy-selected actions&#8212;</strong>Policy rather than code would decide which actions need a human, perhaps based on resource attributes like sensitivity or on the scope of a delegation. The PEP still interprets the <code>deny</code>, but it would take its cue from policy. For example, it could park only when every policy behind the <code>deny</code>carries an annotation like <code>@hitl("required")</code>, or use <a href="https://www.windley.com/archives/2026/02/beyond_denial_using_policy_constraints_to_guide_openclaw_planning.shtml">partial evaluation</a> to confirm that human approval is the only thing standing between the request and a <code>permit</code>.</p></li><li><p><strong>Approvers as principals&#8212;</strong>The approver would be a principal in the policy model, so Cedar could say who is allowed to approve what; approving a wire transfer and approving a calendar invite shouldn&#8217;t require the same person.</p></li><li><p><strong>An approval service&#8212;</strong>A dedicated service would replace the page served by the PDP and push requests to the approver&#8217;s phone or other device.</p></li><li><p><strong>Durable state and audit&#8212;</strong>The pending store would be durable and every approval would be logged, giving you an audit trail that ties each consequential action to a specific human decision.</p></li><li><p><strong>Authenticator attestation&#8212;</strong>Checking the authenticator&#8217;s attestation would let policy require hardware keys for the actions that matter most.</p></li><li><p><strong>Multiple approvers&#8212;</strong>Requiring more than one approval is a natural extension of the multi-signature patterns I discussed in <a href="https://www.windley.com/archives/2026/03/its_not_just_what_agents_can_doits_when_they_can_do_it.shtml">It&#8217;s Not Just What Agents Can Do...It&#8217;s When They Can Do It!</a></p></li></ul><p>One more thing matters that no amount of cryptography fixes: the human has to see what they&#8217;re approving. The Yubikey tap attests to the request hash, but the human decides based on what the approver page shows. If the display summarizes or hides part of the action, the attestation covers something the human never saw. A production approval UI needs to present the action faithfully, which is an old lesson from digital signatures that applies to agents just as well.</p><h2><strong>Humans Where They Matter</strong></h2><p>Putting a human in the loop for everything would defeat the purpose of having an agent. People who are asked to approve every action stop reading and start tapping, and a tap without attention is just a slower way of saying yes. The value of this design is that policy decides where the human belongs. Most actions flow through Cedar and never interrupt anyone. The few that carry real consequences stop and wait for a person who can see exactly what&#8217;s about to happen.</p><p>Agents act on our behalf, and the authority they carry is ours. When the stakes are high, the agent shouldn&#8217;t be able to decide on its own that we would have approved, and it shouldn&#8217;t be able to argue its way past a prompt that says to ask. Placing the control in the harness, bound to a specific action and a physical key, keeps that decision where it belongs. We can build agents that treat our approval as a formality, or we can build ones where our approval is a real control. The second is harder, but it&#8217;s the one that keeps people in charge of what&#8217;s done in their name.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/09/hitl_agent_waiting.png">Human in the Loop</a> from ChatGPT (public domain)</p>]]></content:encoded></item><item><title><![CDATA[Moving My Sensor Network onto Manifold]]></title><description><![CDATA[Summary: I moved my working LoRaWAN sensor network onto the new Manifold framework and pointed Home Assistant at it as the interface.]]></description><link>https://www.technometria.com/p/moving-my-sensor-network-onto-manifold</link><guid isPermaLink="false">https://www.technometria.com/p/moving-my-sensor-network-onto-manifold</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Thu, 17 Sep 2026 16:22:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!BXb9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>I moved my working LoRaWAN sensor network onto the new Manifold framework and pointed Home Assistant at it as the interface. The port went smoothly until the OAuth protection on the mesh blocked the inbound webhooks Helium uses to deliver readings. The fix was to let a mesh owner scope access channel by channel, and the pico engine now supports it.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BXb9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BXb9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png 424w, https://substackcdn.com/image/fetch/$s_!BXb9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png 848w, https://substackcdn.com/image/fetch/$s_!BXb9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png 1272w, https://substackcdn.com/image/fetch/$s_!BXb9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BXb9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png" width="1456" height="825" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/adacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:825,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Cabin temperatures in Home Assistant&quot;,&quot;title&quot;:&quot;Cabin temperatures in Home Assistant&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="Cabin temperatures in Home Assistant" title="Cabin temperatures in Home Assistant" srcset="https://substackcdn.com/image/fetch/$s_!BXb9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png 424w, https://substackcdn.com/image/fetch/$s_!BXb9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png 848w, https://substackcdn.com/image/fetch/$s_!BXb9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png 1272w, https://substackcdn.com/image/fetch/$s_!BXb9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacff78-7760-4a9e-b482-15dd39f4ffc1_1582x896.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I have been working to make Manifold a good framework for <a href="https://www.windley.com/archives/2026/06/manifold_api_and_sensor_network_two_new_repos.shtml">building pico meshes</a>, the kind I use for my network of <a href="https://www.windley.com/archives/2023/03/monitoring_temperatures_in_a_remote_pump_house_using_lorawan.shtml">LoRaWAN sensors</a>. The new <a href="https://github.com/Picolab/manifold-api">Manifold API</a> doesn&#8217;t have a UI like the old Manifold did. I want to use Home Assistant (HA) for that and <a href="https://www.windley.com/archives/2026/08/using_home_assistant_with_manifold.shtml">recently created a custom HA integration</a>. With the groundwork laid, it was time to move my actual sensor network onto the new framework running on the <a href="https://github.com/Picolab/pico-engine">updated pico engine</a>. This post describes that move and the problems I ran into, and fixed, along the way.</p><h2><strong>Manifold as a Framework for Pico Meshes</strong></h2><p>Manifold began as an application for managing your things and creating communities to group them together. The primary application was Safe and Mine, a QR-code-based tagging system to identify your keys, bags, and mugs. Manifold was expandable with custom applications (written in KRL) that could be added to each thing.</p><p>When I rebuilt it as the Manifold API, I stopped treating it as a finished app and started treating it as a framework, a set of domain rulesets other people can extend to build their own meshes. A <em>pico mesh</em> is a small network of independent, addressable computational things, each with its own state, its own rules, and its own relationships. It still supports Safe and Mine, but I wanted it to be more than that&#8212;a personal space to manage both inactive (like your mug) and active (like a temperature sensor) things. The reason to build on Manifold is ownership; the mesh belongs to the person who runs it, not to me and not to a platform, and they decide what connects to it and what it exposes.</p><p>That distinction is the whole point. I&#8217;ve been working for years to build alternatives to what I call the <a href="https://www.windley.com/archives/2014/04/the_compuserve_of_things.shtml">CompuServe of Things</a>. A sensor network you rent from a vendor is legible to the vendor first and to you second. A sensor network that runs as your own pico mesh answers to you, and the framework underneath it exists to keep that relationship intact as the network grows.</p><h2><strong>The Network I Was Moving</strong></h2><p>The network I wanted to move is not a demo. It is a working LoRaWAN deployment I have written about before, starting with <a href="https://www.windley.com/archives/2022/04/easier_iot_deployments_with_lorawan_and_helium.shtml">easier IoT deployments on Helium</a> and then the <a href="https://www.windley.com/archives/2023/03/monitoring_temperatures_in_a_remote_pump_house_using_lorawan.shtml">temperature sensors in a remote pumphouse</a>. I have temperature probes in the crawl space of my cabin, on the north side deck, and in my beehive in addition to the pumphouse. Those sensors report over Helium, and until now they ran on the old sensor-network code, essentially recreating the features of the Manifold framework in addition to their specific duties interpreting and managing the payloads received over LoRaWAN.</p><p>Rebuilding the network on top of Manifold simplifies the code and gives the sensors additional capabilities. Each sensor becomes a thing in a community, with an owner pico above the Manifold pico that ties the whole mesh together. The structure is easier to see than to describe, so here is the mesh as it stands after the move.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7cBx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7cBx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png 424w, https://substackcdn.com/image/fetch/$s_!7cBx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png 848w, https://substackcdn.com/image/fetch/$s_!7cBx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png 1272w, https://substackcdn.com/image/fetch/$s_!7cBx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!7cBx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png" width="1231" height="949" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:949,&quot;width&quot;:1231,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The sensor network as a pico mesh&quot;,&quot;title&quot;:&quot;The sensor network as a pico mesh&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The sensor network as a pico mesh" title="The sensor network as a pico mesh" srcset="https://substackcdn.com/image/fetch/$s_!7cBx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png 424w, https://substackcdn.com/image/fetch/$s_!7cBx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png 848w, https://substackcdn.com/image/fetch/$s_!7cBx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png 1272w, https://substackcdn.com/image/fetch/$s_!7cBx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b38f48c-3202-4880-ad49-84b7d5f03807_1231x949.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The sensor network as a pico mesh, with the owner and Manifold picos above the individual sensor things (click to enlarge)</figcaption></figure></div><p>Everything below the Manifold pico is a sensor or a community. The pumphouse, cabin crawl space, cabin north side deck, triple-temperature probe, and beehive are sensors. The <em>Sensors</em> pico is a Manifold community pico for the sensors. It handles things like notifications, sensor initiation, and reading aggregation. Moving to Manifold didn&#8217;t change what the sensors measure, but it makes them more capable and manageable. And having them in a standard mesh means I can write HA integrations that work for lots of different meshes.</p><h2><strong>Home Assistant as the Interface</strong></h2><p>Because the new Manifold API has no interface of its own, I spent some time making Home Assistant fill that role. In <a href="https://www.windley.com/archives/2026/08/using_home_assistant_with_manifold.shtml">Using Home Assistant with Manifold</a> I described the integration: Home Assistant runs the pico engine&#8217;s OAuth flow, comes away with a scoped token, and reads the mesh through it. That gives me dashboards, history, and alerts on software many people already run at home, without my having to write a UI of my own. The sensor network ships a companion Home Assistant component so its sensor things show up as real temperature and humidity entities, not just generic mesh objects. The code serves as an example of how to write HA companion components that work with the Manifold integration.</p><h2><strong>Where It Broke: OAuth Meets Webhooks</strong></h2><p>The initial port looked good. Every sensor came across, the communities lined up, and the readings flowed into the mesh the way they had before. The trouble started when I wired the mesh to Home Assistant, because that connection depends on the OAuth protection I added to the engine in <a href="https://www.windley.com/archives/2026/07/identity_for_the_pico_engine.shtml">Identity for the Pico Engine</a>. Turning on OAuth secured the mesh against outside access, which is exactly what I wanted for Home Assistant; it also secured the mesh against webhook calls from Helium, which is not what I wanted at all.</p><p>Helium delivers sensor readings by calling a webhook defined on the pico for a specific sensor. The Helium console is software sitting outside my mesh that needs to POST data in, on its own schedule, with no human present to complete a login. The same protection that made Home Assistant&#8217;s access deliberate and revocable made the inbound webhook fail with an authorization error. That is the tension at the center of this move: authentication that assumes a person in the loop breaks the moment a machine needs to knock on the door.</p><h2><strong>Two Ways Through</strong></h2><p>There are two reasonable ways to let a machine through without tearing down the protection around everything else. Picos define webhooks by creating <em>channels</em>. Each channel has a policy saying what events and queries are allowed on that channel.</p><ul><li><p><strong>Client-credentials channels.</strong> The engine already supports OAuth client credentials for a channel. I described this feature in <a href="https://www.windley.com/archives/2026/07/identity_for_the_pico_engine.shtml">Identity for the Pico Engine</a>. A channel configured this way lets the caller authenticate as itself, against that one channel, rather than as a person against the whole mesh. You configure the bearer token in Helium as part of defining the webhook and Helium includes it on each POST.</p></li><li><p><strong>Owner-declared exempt channels.</strong> Alternately, the mesh owner can mark a channel as exempt from the OAuth protection. This is only safe when the channel&#8217;s policy is tight enough to keep the exemption from becoming an open door, and in this case it is, because the channel accepts one narrow shape of sensor data and nothing else.</p></li></ul><p>Both of these approaches rely on the owner being careful about scoping the authority of the webhook so that it doesn&#8217;t represent a security threat. Neither one weakens the mesh as a whole, and neither one hands a machine the standing of a person. I updated the pico engine to support the owner-declared exemption, so the choice now belongs where it should, with the person who runs the mesh, decided channel by channel rather than for the network all at once.</p><h2><strong>The Window onto the Mesh</strong></h2><p>With data flowing again, Home Assistant does exactly what I hoped. The dashboard at the top of this post is my cabin: the pumphouse, the crawl space, the north side deck, each updating every few minutes from the sensor network now running on Manifold. I get history, thresholds, and a picture of the current temperatures at a glance, all from software I run.</p><p>Home Assistant also makes alerting easier. I already had notifications on the old setup, but each one was its own bit of wiring off to the side; Home Assistant keeps the readings, the history, and the rules that act on them together in one place. I can build an automation directly on a reading, so a low temperature in the pumphouse sends me a notification while there is still time to act, rather than after a freeze has cracked a pipe and left the cabin without water. Having that alongside everything else I watch, instead of bolted on separately, is exactly what I want an interface for the mesh to do.</p><p>None of this is a new capability so much as a boundary drawn in the right place. The reading Helium sends and the reading Home Assistant shows are the same as they were a year ago. What changed is the software and systems are less creaky and easier to manage and update. The mesh belongs to the person who runs it, and Home Assistant is just a window onto it.</p>]]></content:encoded></item><item><title><![CDATA[Software-Defined Three-Way Switch]]></title><description><![CDATA[Summary]]></description><link>https://www.technometria.com/p/software-defined-three-way-switch</link><guid isPermaLink="false">https://www.technometria.com/p/software-defined-three-way-switch</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Tue, 15 Sep 2026 15:17:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!yebu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4><strong>Summary</strong></h4><p><em>A remodel left me with lights over two fireplace benches wired to separate switches, so turning them on meant a walk to both ends of the room. Rather than tear open the wall, I let Home Assistant and a pair of Inovelli switches make the two behave as one. The wiring doesn&#8217;t have to change if software controls the switches.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 image2-align-right image2-offset-right is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yebu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yebu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png 424w, https://substackcdn.com/image/fetch/$s_!yebu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png 848w, https://substackcdn.com/image/fetch/$s_!yebu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!yebu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yebu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png" width="372" height="496" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1280,&quot;width&quot;:960,&quot;resizeWidth&quot;:372,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Lights over the fireplace benches&quot;,&quot;title&quot;:&quot;Lights over the fireplace benches&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;right&quot;,&quot;offset&quot;:true}" class="sizing-normal" alt="Lights over the fireplace benches" title="Lights over the fireplace benches" srcset="https://substackcdn.com/image/fetch/$s_!yebu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png 424w, https://substackcdn.com/image/fetch/$s_!yebu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png 848w, https://substackcdn.com/image/fetch/$s_!yebu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!yebu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda702d2a-8b29-4b61-a52b-7a89b4e498a7_960x1280.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As part of our remodel, Lynne wanted lights over the built-in benches on either side of our fireplace. The fireplace itself made it hard to run both fixtures back to a single switch, so the easy path left us with one switch at each end of the hearth. That works, but it means anyone who wants the benches lit has to cross the room and flip two switches. It&#8217;s a small annoyance, the first-world that the physical world imposes from time to time. Fortunately, software can fix it.</p><p>Both switches are <a href="https://inovelli.com/products/zigbee-matter-blue-series-smart-2-1-on-off-dimmer-switch">Inovelli Blue Series 2-1 dimmers</a>, Zigbee devices that report their state and take commands over the network as readily as a person flips them by hand. That makes them programmable in a way an ordinary switch is not; the paddle still does the obvious thing, but the switch is also something software can watch and control. I&#8217;ve leaned on that elsewhere in the house. One of them runs the bathroom fan, turning it on by itself when the humidity spikes and off again once the room dries out, so nobody has to remember.</p><p>The fix for the benches uses the same idea. Each light keeps its own switch, and a pair of <a href="https://www.windley.com/archives/2026/08/using_home_assistant_with_manifold.shtml">Home Assistant</a> automations wires the two together in software: when one switch turns on, it turns on the other, and the same for off. Flip either paddle and both fixtures respond, which is exactly how a three-way switch behaves when it controls a single light. Here there are two lights and two circuits that never meet in the wall, made to act as one from the automation layer instead.</p><p>And nothing about this arrangement is fixed, either. The same two switches could join a scene that dims the whole room for a movie, answer a voice command, or turn themselves off when the house goes to bed, none of which requires a visit from an electrician. Because the coordination lives in software rather than in the wiring, teaching the switches a new behavior simply requires writing another automation, not running another wire. The pairing I set up today is just the first thing I have asked them to do.</p><p>The wires in the wall didn&#8217;t change; the behavior did. That&#8217;s the beauty of adding a little software to a physical control: the constraints of the wiring are no longer the constraints of the room. When the layout fights you, you don&#8217;t always have to open the wall. Sometimes you can just change what the switches do.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/09/software_defined_3_pole_switch.png">Lights over the fireplace benches</a> from Phil Windley (CC BY 4.0)</p>]]></content:encoded></item><item><title><![CDATA[There's a Personal App for That]]></title><description><![CDATA[Summary: My twenty-five-year-old Intel Play QX3 microscope had no software that would run on a modern Mac, so I used Claude to write one in a morning.]]></description><link>https://www.technometria.com/p/theres-a-personal-app-for-that</link><guid isPermaLink="false">https://www.technometria.com/p/theres-a-personal-app-for-that</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Thu, 10 Sep 2026 19:35:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qTF9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>My twenty-five-year-old Intel Play QX3 microscope had no software that would run on a modern Mac, so I used Claude to write one in a morning. When an app takes a morning instead of two weeks, software can stop being a product and start being personal.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qTF9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qTF9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png 424w, https://substackcdn.com/image/fetch/$s_!qTF9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png 848w, https://substackcdn.com/image/fetch/$s_!qTF9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!qTF9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qTF9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png" width="1456" height="1092" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The QX3 microscope beside my laptop running Windley Microscope&quot;,&quot;title&quot;:&quot;The QX3 microscope beside my laptop running Windley Microscope&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="The QX3 microscope beside my laptop running Windley Microscope" title="The QX3 microscope beside my laptop running Windley Microscope" srcset="https://substackcdn.com/image/fetch/$s_!qTF9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png 424w, https://substackcdn.com/image/fetch/$s_!qTF9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png 848w, https://substackcdn.com/image/fetch/$s_!qTF9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!qTF9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3a78004-b875-4da4-9f80-ba4e1db0f8a6_1600x1200.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Over twenty-five years ago, I bought an Intel Play QX3 microscope for my kids to play with. It came with a CD-ROM holding the control software, which, as I recall, ran only on Windows. The microscope then spent the better part of two decades in the back of a cabinet in my office, gathering dust.</p><p>I pulled it out recently for my grandkids, hoping the Mac might simply recognize it as a camera. It didn&#8217;t. I couldn&#8217;t find any software that would run on a modern machine, and I was about ready to send the whole thing to the thrift store. Then I had an idea: what if I used Claude to write an app for it?</p><p>A morning later I had one, and my grandkids were watching the ridges of a seashell fill the screen. The interesting part of this story isn&#8217;t the microscope; it&#8217;s that building a custom app for a single obsolete device is now a morning&#8217;s work instead of a project. That change is going to reshape what we expect software to be.</p><h2><strong>A Microscope With No Software</strong></h2><p>The QX3 is a small USB microscope that Intel and Mattel sold around the turn of the century. It magnifies at 10x, 60x, and 200x (using physcial lenses, not software); it has a camera in the head, a light on top and another in the stage, and a focus wheel. For a toy, it is genuinely good, and it still works exactly as well as it did in 2000. The problem is not the hardware; it is everything the hardware expects to talk to.</p><p>The QX3 predates USB Video Class, the standard that lets a modern operating system treat any conforming camera as a webcam with no driver at all. To macOS, the QX3 is not a camera; it is an unknown vendor-specific USB device, and the system has no idea what to do with it. Over the years, hobbyists filled that gap with their own drivers and apps for Linux and the Mac. Those projects are mostly dead now.</p><p>They died for an ordinary reason. Each one depended on the operating-system internals of its moment, and macOS kept moving: it went 64-bit, it tightened what kernel extensions could do, and it reworked its USB and camera frameworks more than once. Keeping a driver alive for a discontinued children&#8217;s toy is a lot of unpaid work for an audience of a few, so the maintainers moved on and the code stopped building. The hardware still worked; the software around it rotted away.</p><h2><strong>Building It With Claude</strong></h2><p>I opened Claude in Cursor and worked in stages. I didn&#8217;t begin with a plan for an app; I began by trying to talk to the device at all. Each stage did one small thing and proved it worked before I asked for the next.</p><ol><li><p><strong>Identify the device.</strong> I gave Claude the handful of facts the macOS &#8220;About This Mac&#8221; USB panel showed for the microscope: a vendor ID, a product ID, and not much else.</p></li><li><p><strong>Blink the lights.</strong> I had Claude write a small command-line program that turned the microscope&#8217;s LEDs on and off. That was the entire test: could code I control make something physical happen across the USB cable? It could.</p></li><li><p><strong>See through it.</strong> Next came a command-line tool that pulled the image the microscope was seeing and saved a snapshot to a file.</p></li><li><p><strong>Give it a face.</strong> Then a real Mac app with a window: switches for the two lights, a brightness slider, a live preview, and a button to take a picture.</p></li><li><p><strong>Record.</strong> After that, movie capture and time-lapse, so my grandkids could watch an ant walk or a drop of water evaporate.</p></li><li><p><strong>Clean it up.</strong> Finally the work that separates a demo from a tool: an app icon, a proper Quit item in the menu, and the usual round of small bug fixes.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vOUp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vOUp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png 424w, https://substackcdn.com/image/fetch/$s_!vOUp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png 848w, https://substackcdn.com/image/fetch/$s_!vOUp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png 1272w, https://substackcdn.com/image/fetch/$s_!vOUp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!vOUp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png" width="1192" height="1004" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/51246753-247f-400e-8938-4269a60ffeec_1192x1004.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1004,&quot;width&quot;:1192,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The Windley Microscope app showing a live view of a seashell&quot;,&quot;title&quot;:&quot;The Windley Microscope app showing a live view of a seashell&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The Windley Microscope app showing a live view of a seashell" title="The Windley Microscope app showing a live view of a seashell" srcset="https://substackcdn.com/image/fetch/$s_!vOUp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png 424w, https://substackcdn.com/image/fetch/$s_!vOUp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png 848w, https://substackcdn.com/image/fetch/$s_!vOUp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png 1272w, https://substackcdn.com/image/fetch/$s_!vOUp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51246753-247f-400e-8938-4269a60ffeec_1192x1004.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The Windley Microscope app showing a live view of a seashell</figcaption></figure></div><p>The result is a few hundred lines of Swift that talk to the microscope directly over USB. I called it Windley Microscope, which is the kind of name you give something built for exactly one household. It does what the original Windows software did, and only what my grandkids and I actually want it to do.</p><h2><strong>Why This Works</strong></h2><p>The QX3 is easy to bring back precisely because it is old. A modern webcam sits behind several layers: USB Video Class, the camera framework, the operating system&#8217;s device and privacy management. Those layers are what make a new camera &#8220;just work,&#8221; and they are also what you cannot reach around when it doesn&#8217;t. The QX3 has none of them.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RNoW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RNoW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png 424w, https://substackcdn.com/image/fetch/$s_!RNoW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png 848w, https://substackcdn.com/image/fetch/$s_!RNoW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png 1272w, https://substackcdn.com/image/fetch/$s_!RNoW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!RNoW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png" width="352" height="288" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:288,&quot;width&quot;:352,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A seashell captured through the QX3&quot;,&quot;title&quot;:&quot;A seashell captured through the QX3&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A seashell captured through the QX3" title="A seashell captured through the QX3" srcset="https://substackcdn.com/image/fetch/$s_!RNoW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png 424w, https://substackcdn.com/image/fetch/$s_!RNoW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png 848w, https://substackcdn.com/image/fetch/$s_!RNoW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png 1272w, https://substackcdn.com/image/fetch/$s_!RNoW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ec6456-9bf4-4284-b7bc-54e07ca7ec9e_352x288.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A seashell captured through the QX3 </figcaption></figure></div><p>It sits right on the USB wire, speaking a simple protocol, with nothing between my code and the device. The same plainness that made it invisible to macOS made it straightforward to control myself; there was no abstraction to defeat, only a device to address. Simple architecture wins. When the platform declines to capture a device, you are not locked out of it; you are left free to talk to it on your own terms.</p><h2><strong>An App for an Audience of One</strong></h2><p>Here is the part that reaches past one microscope. A few years ago I would not have spent two weeks building a custom app to run a discontinued toy for my grandkids; the effort was far larger than the result was worth. I was happy to spend a morning. That shift changes the cost dynamics of software in a profound way.</p><p>An app no longer has to be a product. It does not need a market, a store listing, or a user base large enough to justify the build. It can be personal<sup>1</sup>: written for exactly what one person needs, and for no one else. The world is full of a backlog of small software that never get written because the audience is one (or small) and the price was two weeks (or two years). That backlog has quietly become approachable. Imagine all the things that will be built because of this profound change in cost.</p><p>An important point: This is easy on a laptop because computers still let their owners run whatever code they write and talk to whatever hardware they plug in. It is not easy on iOS, where the platform, not the owner, decides what is allowed to run. The model that let me revive the QX3 in a morning barely exists on the devices most people actually use; that is a decision about how those platforms are built, not a fact of nature. As personal software becomes ordinary, it will press on that decision.</p><p>The microscope works again, and that is a small, good thing. The larger thing I got back is the ability to make the computer do the specific thing I want, without waiting for a company to decide enough people want it too. That capability used to belong to firms with a market to serve. It is starting to belong to the rest of us.</p><div><hr></div><h3><strong>Notes</strong></h3><ol><li><p><em>Personal</em> is not <em>personalized</em>. In 2026, a personalized system is one a company tunes to you from the data it collects about you; the tuning serves the company, and the surveillance that feeds it is the point. A personal app is the reverse: you build or commission it, it runs on your own machine, and it answers only to you. I mean <em>personal</em> in its older, plainer sense: software that belongs to you, not software aimed at you.</p></li></ol><p>Photo Credit: <a href="https://www.windley.com/archives/2026/09/app_running_on_laptop.png">The QX3 microscope beside my laptop running Windley Microscope</a> from Phil Windley (CC BY 4.0)</p>]]></content:encoded></item><item><title><![CDATA[Authentication Is Largely Solved. Authorization Isn't.]]></title><description><![CDATA[Summary: My new book, Authorization in Action, is out from Manning.]]></description><link>https://www.technometria.com/p/authentication-is-largely-solved</link><guid isPermaLink="false">https://www.technometria.com/p/authentication-is-largely-solved</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Tue, 08 Sep 2026 15:46:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!OT_r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>My new book, </em>Authorization in Action<em>, is out from Manning. It&#8217;s about the question that comes after we know who you are: what are you allowed to do, under what conditions, on whose behalf, and in what context? Authentication is largely a solved problem; authorization is not, and AI agents are about to make that gap impossible to ignore.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 image2-align-right is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OT_r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OT_r!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg 424w, https://substackcdn.com/image/fetch/$s_!OT_r!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg 848w, https://substackcdn.com/image/fetch/$s_!OT_r!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!OT_r!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OT_r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg" width="270" height="338.25" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:451,&quot;width&quot;:360,&quot;resizeWidth&quot;:270,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Authorization in Action book cover&quot;,&quot;title&quot;:&quot;Authorization in Action&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;right&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="Authorization in Action book cover" title="Authorization in Action" srcset="https://substackcdn.com/image/fetch/$s_!OT_r!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg 424w, https://substackcdn.com/image/fetch/$s_!OT_r!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg 848w, https://substackcdn.com/image/fetch/$s_!OT_r!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!OT_r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71258517-fad8-4bce-a62d-ffd6922ff961_360x451.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>My new book, <em><a href="https://www.manning.com/books/authorization-in-action">Authorization in Action</a></em>, is now available from Manning. It&#8217;s a book about the question that comes after we know who you are: <em>what are you allowed to do?</em> Knowing who someone is doesn&#8217;t tell you what they should be able to touch, change, or spend. For most of the last two decades I&#8217;ve worked on the first question, proving who someone is; this book is about why the second one is now the one that matters, and how to build systems that answer it well.</p><p>The short version of the argument is one I didn&#8217;t expect to be making a few years ago. Authentication, the act of proving who someone is, has become about as good as we can reasonably ask; passkeys and FIDO have quietly closed most of the gap that kept me up at night in 2005. Authorization, the act of deciding what someone can actually do, is still mostly improvised, buried in application code, and reinvented badly on every team. That imbalance is the reason the book exists.</p><h2><strong>How I Got Here</strong></h2><p>When I was CIO for the State of Utah in 2001, I noticed that nearly every problem that reached my desk had an identity component hiding inside it. Consolidating directories so every employee could have a <code>utah.gov</code> address, moving the state&#8217;s website to a new domain, sorting out who could touch which system: none of these looked like identity problems on the surface, yet all of them turned on knowing who someone was and what they were permitted to do. I didn&#8217;t have language for it then, but that observation set the direction for everything I&#8217;ve worked on since.</p><p>A few years later Doc Searls, Kaliya Young, and I started the <a href="https://internetidentityworkshop.com/">Internet Identity Workshop</a>(IIW), and it has now met 42 times. IIW has become the place where the identity community works on its hardest problems together. Along the way I wrote three books; <em><a href="https://www.amazon.com/exec/obidos/ASIN/0596008783/windleyofente-20">Digital Identity</a></em> helped enterprises build identity strategies, <em><a href="https://www.amazon.com/exec/obidos/ASIN/1133686680/windleyofente-20">The Live Web</a></em> moved the focus from organizations to individuals with their own data and APIs, and <em><a href="https://www.amazon.com/exec/obidos/ASIN/B0BS2H4HT1/technometria-20">Learning Digital Identity</a></em> finally named the thing I&#8217;d been circling for years: identity is fundamentally about <em>relationships, not identifiers</em>. Each book was really an attempt to answer a question the previous one had raised.</p><p>While I was finishing <em>Learning Digital Identity</em>, the next question came into focus, and conversations at IIW confirmed it. Knowing who someone is tells you almost nothing about what they should be able to do; the interesting, unsolved work all lives on the far side of authentication. That&#8217;s the work my new book takes on.</p><h2><strong>The Second Question</strong></h2><p>The reason the second question is harder is that it&#8217;s not one question but several, and they&#8217;re the ones that actually govern what happens inside a system. What can this person do; under what conditions; on whose behalf; and in which context? Miss any one of them and the rest stop meaning much; the same request can be right for a manager at noon from the office and wrong for a contractor at midnight from an unknown device. A login gets you through the door, but it says nothing about which rooms you can enter, what you can carry out, or whether the person who sent you had the standing to send you at all.</p><p>In late 2022 I joined AWS Identity, and one of the teams we worked closely with was building <a href="https://aws.amazon.com/verified-permissions/">Amazon Verified Permissions</a> and the <a href="https://cedarpolicy.com/en">Cedar policy language</a>. Working at that scale showed me something the theory hadn&#8217;t: fine-grained authorization doesn&#8217;t only make a system safer, it makes it more usable. When the rules about who can do what are explicit and external to the code, you can hand people exactly the access they need without either drowning them in prompts or handing over the keys to everything. Getting authorization right is how a system stays both safe and pleasant to use, and those goals stop fighting each other.</p><h2><strong>Then Came the Agents</strong></h2><p>What finally convinced me the world needed this book was AI. As agents begin acting on people&#8217;s behalf, &#8220;what is this thing allowed to do, and on whose authority?&#8221; stops being a background concern and becomes the whole game. An agent that can read your calendar, spend your money, or send mail as you is only as trustworthy as the boundaries around it, and those boundaries are authorization. I&#8217;ve argued before that <a href="https://www.windley.com/archives/2026/02/why_authorization_is_the_hard_problem_in_agentic_ai.shtml">authorization is the hard problem in agentic AI</a>, and nothing since has changed my mind.</p><p>This is where the technical question turns into a human one. If we can&#8217;t say precisely what an agent may do on our behalf, we&#8217;re left choosing between agents that can&#8217;t do anything useful and agents we have to trust blindly; neither of those is a world I want to live in. Authorization is the infrastructure that lets us delegate real authority to software while keeping it bounded, accountable, and revocable. That&#8217;s not a convenience feature. It&#8217;s what makes it possible to act through machines without surrendering to them.</p><h2><strong>What&#8217;s in the Book</strong></h2><p><em>Authorization in Action</em> follows a fictional company, ACME, as it works its way from the tangled access-control code most teams start with toward policy-based authorization it can actually reason about. The book uses that story to get concrete about the models and mechanics&#8212;relationships, roles, attributes, policy languages, and the architecture that separates deciding from enforcing&#8212;rather than leaving them as abstractions. This is the book I needed on my own shelf while I was solving these problems as an enterprise architect at BYU, so it&#8217;s aimed at the developers and architects who have to make these decisions everyday</p><p>Identity tells us who is involved. Authorization determines what happens next. I&#8217;ve come to believe that second question is quietly becoming the heart of security, governance, and trust online, and I hope the book makes the case as clearly to you as the last few years have made it to me. You can find <em><a href="https://www.manning.com/books/authorization-in-action">Authorization in Action</a></em><a href="https://www.manning.com/books/authorization-in-action"> at Manning</a> and <a href="https://www.amazon.com/exec/obidos/ASIN/B0H518RVH5/technometria-20">coming soon to Amazon</a>.</p>]]></content:encoded></item><item><title><![CDATA[Why Not SPIFFE for Pico Identity?]]></title><description><![CDATA[Summary: A pico is arguably just a workload, so why give it a DID instead of using SPIFFE, the standard workload identifier?]]></description><link>https://www.technometria.com/p/why-not-spiffe-for-pico-identity</link><guid isPermaLink="false">https://www.technometria.com/p/why-not-spiffe-for-pico-identity</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Thu, 03 Sep 2026 14:18:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0PAo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>A pico is arguably just a workload, so why give it a DID instead of using SPIFFE, the standard workload identifier? The answer comes down to whether the identity is meant to last. SPIFFE derives a workload&#8217;s identity from what it is and where it runs, so it&#8217;s re-minted per environment; a pico&#8217;s identity is long-lived and travels with it.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0PAo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0PAo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!0PAo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!0PAo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!0PAo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0PAo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A printed visitor badge and a passport&quot;,&quot;title&quot;:&quot;A printed visitor badge and a passport&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="A printed visitor badge and a passport" title="A printed visitor badge and a passport" srcset="https://substackcdn.com/image/fetch/$s_!0PAo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!0PAo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!0PAo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!0PAo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84c92e1-9461-454d-9686-07666d066c0b_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When I wrote about <a href="https://www.windley.com/archives/2026/08/pico-to-pico_identity_arrives.shtml">pico-to-pico identity arriving in version 1.6</a>, I explained why I reached for DIDs rather than KERI. The other obvious question is &#8220;Why not <a href="https://spiffe.io/">SPIFFE</a>, the workload-identity stack that Kubernetes shops already run?&#8221; It&#8217;s a fair question, because a pico is, from one angle, just a workload; it&#8217;s a running process that needs to prove which process it is before another one will talk to it. So why give it a DID instead of a SPIFFE ID?</p><p>The answer comes down to a single property: whether the identity travels with the thing it names. SPIFFE and picos give opposite answers to that, and the opposition isn&#8217;t an accident. It falls out of what each one is built to identify.</p><h2><strong>What SPIFFE Gets Right</strong></h2><p>SPIFFE is a genuinely good design for the problem it takes on. A workload asks the local agent for its identity, and instead of holding a secret it proves who it is by what it is and where it runs; the platform attests to the process, and the workload gets back a short-lived credential called an SVID. There&#8217;s no long-lived key to leak, because the credential expires in minutes and renews on its own. For a datacenter full of ephemeral, interchangeable containers, that&#8217;s exactly right; you don&#8217;t want a Kubernetes pod hoarding a private key that outlives it.</p><p>The trust anchor for all of this is a server that runs the trust domain. That server decides which workloads exist, attests to them, and signs their SVIDs, and every workload in the domain trusts it by construction. Inside one administrative boundary, that centralization is a feature, not a flaw; someone runs the cluster, and that someone is exactly who should be minting identities in it. SPIFFE fits the shape of the place it lives.</p><h2><strong>Identity that&#8217;s Derived versus Identity that Lasts</strong></h2><p>That fit is also the reason SPIFFE isn&#8217;t what a pico needs. A SPIFFE identity is <em>derived</em>: it comes from what the workload is and where it runs, and the domain&#8217;s server mints it fresh in whatever environment the workload happens to land in. Move the workload to a different cluster and it gets a different identity from a different authority, because the identity was never the workload&#8217;s to carry; it was a fact about the environment. That is a badge the building prints for you at the door. It works beautifully inside the building and means nothing the moment you step outside.</p><p>A pico&#8217;s identity is <em>long-lived</em> by design. Every pico holds its own keys and carries a <a href="https://identity.foundation/didwebvh/v1.0/">did:webvh</a> that stays the same identifier no matter which engine it runs on or how long it runs; the identity is a property of the pico, not of the host underneath it. When a pico moves between engines, its identity moves with it, because the pico is the one holding the keys that prove it. That is a passport rather than a printed badge; you carry it across borders, and it still says who you are on the other side. For a system whose whole point is <a href="https://www.windley.com/archives/2026/08/pico-to-pico_identity_arrives.shtml">picos and meshes that are portable between engines</a>, an identity that gets re-minted per environment just isn&#8217;t the right choice.</p><p>Durable identity is a property that makes picos useful for tasks that ephemeral workloads can&#8217;t do easily.</p><ul><li><p><strong>Persistent relationships.</strong> A subscription links two identifiers; if they reset on every restart, the relationship can&#8217;t outlive the move. Durable identity is what lets a mesh of relationships accumulate and survive.</p></li><li><p><strong>Reputation and history.</strong> Because a pico keeps the same identifier over time, the parties it deals with can remember their history with it and decide how far to trust it. An identifier that resets each session gives them nothing to base that judgment on.</p></li><li><p><strong>Credentials.</strong> A verifiable credential is a claim about a subject, and the subject has to persist for the claim to keep meaning anything. Without a durable identity there is nothing to hold or present a credential.</p></li><li><p><strong>Delegation.</strong> An actor operating on your behalf needs a stable identity so the authority you grant persists and stays revocable. Ephemeral identity means re-authorizing constantly and having nothing durable to take back.</p></li><li><p><strong>Continuity across infrastructure.</strong> Because the keys belong to the pico, the actor is decoupled from the host; you can move engines, change providers, or recover from a crash without losing who the pico is.</p></li><li><p><strong>Longevity beyond any vendor.</strong> The identity outlives the company that built the device, so a pico doesn&#8217;t die when someone&#8217;s cloud is switched off. This is the Internet of My Things rather than the <a href="https://www.windley.com/archives/2014/04/the_compuserve_of_things.shtml">CompuServe of Things</a>.</p></li><li><p><strong>A lifecycle that follows the thing.</strong> For something with a long life that changes hands, identity and history span custodians instead of resetting with each one.</p></li></ul><p>A <em>digital twin</em> is a good example of where durable identity matters. A pico that stands in for an IoT device grows more valuable the longer it lives, because it accumulates the device&#8217;s history, relationships, and state over years rather than minutes. When I built Fuse, each car had its own pico, and <a href="https://www.windley.com/archives/2014/07/fuse_as_a_microservice_architecture.shtml">selling the car meant handing that pico to the new owner</a> with the maintenance history and important relationships intact; the identity was bound to the vehicle, not to me. That is the case ownership language gets wrong. The pico&#8217;s identity outlives any particular owner, and it has to, because the car it represents might too.</p><h2><strong>Trust Domains and Strangers</strong></h2><p>The same split shows up when two identities from different places need to trust each other. SPIFFE can federate across trust domains, but it does it the administrative way: the operators of two domains exchange trust bundles ahead of time, and only then can workloads on one side verify workloads on the other. That&#8217;s reasonable when both domains belong to the same company, or to two companies that signed a contract; someone with authority on each side sets the relationship up in advance. It assumes the parties already have a reason, and a person, to arrange the introduction.</p><p>Picos owned by two different people, on two different engines, don&#8217;t have that person in the middle, and I don&#8217;t want to require one. A pico resolves another pico&#8217;s DID and the two form a relationship directly, with no administrator on either side pre-arranging a federation. This is the same first-person idea I keep pushing for human identity, now applied to software actors: identity you present yourself, not identity an authority vouches for on your behalf. Trust between strangers shouldn&#8217;t require a treaty negotiated by their landlords.</p><h2><strong>An Actor, Not a Process</strong></h2><p>None of this makes SPIFFE wrong; it&#8217;s just built for a different kind of thing. SPIFFE names a <em>process</em>: a unit of execution that runs, does its work, and can be killed and restarted at will, where you care that some process is handling the request rather than which one. A pico is an <em>actor</em>: something that persists, holds state and relationships, and acts for someone or something over time. A process has an identity so the system can manage it; an actor has an identity that it uses over time.</p><p>Systems engineers have a mantra for this divide: treat your servers as cattle, not pets. Cattle are numbered and interchangeable, and when one gets sick you replace it instead of nursing it back to health; that is exactly the right way to run a fleet of workloads, and it&#8217;s the world SPIFFE is built for. A pico is a pet. It has a name and a history, and relationships that make it worth keeping this one rather than swapping in another that would do the same job.</p><p>That distinction is the thread running through everything above. Persistent relationships, reputation, credentials, delegation, history, continuity, and longevity are not affordances a process needs; they are what it takes to be an actor rather than a process, and every one of them presupposes an identity that lasts. So a durable identity isn&#8217;t a feature bolted onto a workload. It&#8217;s foundational.</p><p>The choice between SPIFFE and DIDs, then, isn&#8217;t really a choice between two identity technologies; it&#8217;s a question about what you&#8217;re naming. If you are naming a replaceable process inside one administrator&#8217;s domain then SPIFFE is the right tool, and I&#8217;d use it. But a pico is an actor that persists over time, not a process that happens to carry an identity, and the identity model has to reflect that. Give the thing that&#8217;s meant to persist and travel an identity that persists and travels with it.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/08/badge_vs_passport.png">A printed visitor badge and a passport</a> from ChatGPT (public domain)</p>]]></content:encoded></item><item><title><![CDATA[Pico-to-Pico Identity Arrives]]></title><description><![CDATA[Summary: Version 1.6 of the Pico Engine ships the pico-to-pico identity layer I promised but hadn't built.]]></description><link>https://www.technometria.com/p/pico-to-pico-identity-arrives</link><guid isPermaLink="false">https://www.technometria.com/p/pico-to-pico-identity-arrives</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Wed, 12 Aug 2026 16:24:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!UN-4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><strong>Summary</strong>: Version 1.6 of the Pico Engine ships the pico-to-pico identity layer I promised but hadn't built. Every pico now carries two DIDs: a portable </em><code>did:webvh</code><em> that says who it is, and a private </em><code>did:peer</code><em> for each relationship it forms. This is the piece that lets a pico move between engines and lets two meshes create a relationship without a federation agreement set up in advance.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UN-4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UN-4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png 424w, https://substackcdn.com/image/fetch/$s_!UN-4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png 848w, https://substackcdn.com/image/fetch/$s_!UN-4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png 1272w, https://substackcdn.com/image/fetch/$s_!UN-4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UN-4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Two kinds of identity for a pico&quot;,&quot;title&quot;:&quot;Two kinds of identity for a pico&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="Two kinds of identity for a pico" title="Two kinds of identity for a pico" srcset="https://substackcdn.com/image/fetch/$s_!UN-4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png 424w, https://substackcdn.com/image/fetch/$s_!UN-4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png 848w, https://substackcdn.com/image/fetch/$s_!UN-4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png 1272w, https://substackcdn.com/image/fetch/$s_!UN-4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57305cb1-da2c-4055-9759-41fd5eb7b130_1531x875.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Last month I released <a href="https://www.windley.com/archives/2026/07/identity_for_the_pico_engine.shtml">version 1.5 of the Pico Engine</a> and argued that identity inside the engine is really three problems, not one. A human needs to prove who they are to a pico mesh; an outside app or webhook needs a scoped way into the mesh; and one pico needs to know which pico is calling it and whether to trust it. I shipped the human and third-party layers then and left the harder one for later. Today I&#8217;m releasing version 1.6, and that third layer, pico-to-pico identity, is here.</p><p>The short version is that every pico now has its own cryptographic identity, and that identity can travel. This is the piece I&#8217;ve wanted for a long time, because it&#8217;s the foundation for a goal I keep circling back to: picos and whole meshes that are portable between engines rather than pinned to the machine where they happened to be born. Let me describe the shape of it, because the design turns on a distinction that took me a while to get right.</p><h2><strong>The Layer I Was Waiting to Build</strong></h2><p>I shipped the first and third layers in 1.5 and held this one back on purpose. Passkeys and OAuth sit on machinery the engine already had: channels, ECIs, and channel policy. Pico-to-pico identity required something a bit more complex. It meant moving <a href="https://identity.foundation/didwebvh/v1.0/">DID</a> keys into the engine as a core primitive, pulling a lot of KRL into wrangler, and running pico-to-pico traffic over <a href="https://identity.foundation/didcomm-messaging/spec/">DIDComm</a> instead of plain HTTP. That&#8217;s a large change, and it touches much of the engine, so I wanted to handle it separately.</p><p>This layer is what makes a pico an actor with a real online presence. A channel identifier tells you how to reach a pico on one engine right now; it says nothing durable about the pico&#8217;s identity. For introductions between strangers, for encrypted traffic, and eventually for verifiable credentials, a pico needs a stable answer to &#8220;which pico is this?&#8221; that is portable across engines. That answer is a DID, and in 1.6 every pico has one from the moment it&#8217;s created.</p><h2><strong>Two DIDs, Two Jobs</strong></h2><p>The design I landed on gives each pico <a href="https://picolabs.atlassian.net/wiki/spaces/docs/pages/4033413122/DIDs+Pico+Identity">two types of DIDs, each with different jobs</a>. The first is a <code>did:webvh</code>, the pico&#8217;s portable identity. Every pico gets one when it&#8217;s created, and the engine serves its DID document at a stable URL so anyone can resolve it. Think of it as the pico&#8217;s passport: it&#8217;s how a pico introduces itself, and it&#8217;s what you hand a stranger who needs to know who you are before they&#8217;ll talk to you.</p><p>The second is a <code>did:peer</code>, and there&#8217;s one of them for every relationship, called a <em>subscription</em>, a pico forms. It isn&#8217;t provisioned up front; the two engines mint a fresh pair during the introduction handshake. There is a separate pair of peer DIDs for each relationship. Think of it as an email you give to exactly one person. The passport says who you are to everyone; the email is the private line for a single connection, and it means nothing to anyone else.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MTNb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MTNb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png 424w, https://substackcdn.com/image/fetch/$s_!MTNb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png 848w, https://substackcdn.com/image/fetch/$s_!MTNb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png 1272w, https://substackcdn.com/image/fetch/$s_!MTNb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!MTNb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png" width="1014" height="998" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:998,&quot;width&quot;:1014,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Subscription developer UI showing webvh DID at the top and peer DIDs in the established subscription&quot;,&quot;title&quot;:&quot;Subscription developer UI showing webvh DID at the top and peer DIDs in the established subscription&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Subscription developer UI showing webvh DID at the top and peer DIDs in the established subscription" title="Subscription developer UI showing webvh DID at the top and peer DIDs in the established subscription" srcset="https://substackcdn.com/image/fetch/$s_!MTNb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png 424w, https://substackcdn.com/image/fetch/$s_!MTNb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png 848w, https://substackcdn.com/image/fetch/$s_!MTNb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png 1272w, https://substackcdn.com/image/fetch/$s_!MTNb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53cebdaf-ac6f-4efa-a2f3-4dca6ecbf09f_1014x998.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Subscription developer UI showing webvh DID at the top and peer DIDs in the established subscription (click to enlarge)</figcaption></figure></div><p>The developer UI makes the split concrete. The Identity panel at the top of a pico&#8217;s Subscriptions tab shows its one <code>did:webvh</code>, the passport it hands out, next to the switch that decides whether it accepts unsolicited introductions to that DID. Each established subscription below carries a different pair: the remote party&#8217;s peer DID and this pico&#8217;s own peer DID, minted for that one relationship. The subscription&#8217;s Rx channel is where policy still lives; the DIDs name who the two parties are, and the ECI decides what this one is allowed to do here.</p><p>That split matters more than you might think. A single, universal identifier is a mistake I&#8217;ve watched newcomers to identity make for years. Correlatability is a factor, but the bigger payoff is practical: because every relationship has its own identifier, each one can be managed on its own. You can rotate the keys on a single connection, or tear it down and rebuild it, without disturbing any of the others; if a peer DID is ever compromised, the damage stops there and you recover that one relationship in isolation. It&#8217;s the email analogy again, where changing the address you gave one contact doesn&#8217;t impact the rest.</p><h2><strong>How Picos Actually Talk</strong></h2><p>Two picos that aren&#8217;t parent and child talk to each other through a <a href="https://picolabs.atlassian.net/wiki/spaces/docs/pages/4032102406/Subscriptions">subscription</a>, which is just a pairwise relationship with a record on each side. In 1.6 you form one by handing the initiator the recipient&#8217;s <code>did:webvh</code> as the target; the two picos run the introduction, agree, and store each other&#8217;s peer DIDs. After that, queries and events flow over the peer relationship. On the same mesh, the engine keeps that traffic local; across meshes or across engines, it runs encrypted over DIDComm to the peer&#8217;s address.</p><p>DIDs didn&#8217;t need a new authorization mechanism; they slot into the channel model the engine already had. A subscription&#8217;s peer DID <em>is</em> its channel, and channel policy governs it exactly as it governs any other channel, so authorization is enforced right where it always was. The DID names who is on the other end of the relationship, and the policy on that channel decides what they are allowed to do. Legacy ECIs haven&#8217;t gone anywhere either; parent and child picos still talk over family channels named by ECIs, where a full DID would be overkill.</p><p>The consequence I care about is what this does for trust between strangers. A pico can choose to accept unsolicited introductions to its public identity, which lets a community pico or a registry take subscriptions from picos it has never met. Two meshes owned by two different people, on two different engines, can form a relationship because one resolved the other&#8217;s DID and both agreed; no one had to stand up a federation agreement or register with a common broker first. The relationship is <a href="https://www.windley.com/archives/2020/12/relationships_in_the_self-sovereign_internet_of_things.shtml">the unit of trust</a>, and these changes make it cryptographic and portable.</p><h2><strong>Why These Methods, Not KERI</strong></h2><p>Anyone who has spent time at IIW will ask why I reached for <code>did:webvh</code> and <code>did:peer</code>rather than <a href="https://keri.foundation/">KERI</a>, which answers the same &#8220;who is this actor&#8221; question with self-certifying identifiers and a key event log that needs no web host at all. KERI has a great design, and on the narrow point of surviving a move it&#8217;s arguably stronger than <code>did:webvh</code>; a KERI identifier carries no URL that has to stay reachable, which is exactly the loose end I admitted above. So this wasn&#8217;t a judgment that one approach is right and the other wrong. It came down to what picos already need to do the moment two of them are connected.</p><p>That need is messaging, and picos exchange events and queries over DIDComm. Peer dids were built for precisely that job: a pairwise, private relationship identity that DIDComm tooling already knows how to carry encrypted traffic over. Pairing it with <code>did:webvh</code> for the public introduction let me use a messaging philosophy the pico world has used for years since it parallels the DIDComm model. KERI&#8217;s strengths live mostly in the identifier and its key history; picos needed the identifier and the encrypted conversation that follows it, and the DIDComm path gave me both with the least new machinery. If the day comes when the portability tradeoff bites hard enough, I&#8217;d happily revisit that choice.</p><h2><strong>A Step Toward Portable Meshes</strong></h2><p>I won&#8217;t pretend a pico can pick up and move to a new engine today with no loose ends; the engine base URL is still baked into a pico&#8217;s <code>did:webvh</code>, and making that survive a move is work still ahead. But the hard part, giving each pico a real cryptographic identity and a way to carry its relationships, is now in the engine rather than wrapped around it. That&#8217;s the foundation portability was waiting on, and everything above it, from moving a mesh between engines to carrying credentials between them, builds on this.</p><p>Full portability is the largest gap, but it isn&#8217;t the only one. The identifiers are in place; the verifiable credentials that ride on them are not, so a pico can prove who it is but can&#8217;t yet hand another pico a signed claim about what it is or may do. Key management is thin across the board: the private keys behind a pico&#8217;s DIDs sit in the engine&#8217;s own store today, when they belong in the operating system&#8217;s key vault or hardware-backed storage, and rotation and recovery need more work now that a pico&#8217;s identity is the thing others rely on. Losing the keys shouldn&#8217;t mean losing the pico. Authorization also still keys off the channel a caller holds rather than the identity behind it, so the natural next step is to let a receiving pico decide based on who is actually calling using a proper authorization engine. Each of these builds on the identity that landed in 1.6 rather than replacing it.</p><p>I&#8217;ve spent a long time arguing that people deserve <a href="https://www.windley.com/archives/2011/11/the_second_pc_revolution_personal_clouds.shtml">software that acts for them and that they own outright</a>, not a rented seat on someone else&#8217;s platform. A mesh you can pick up and move provides infrastructure to realize that idea. If your picos can only live on one engine, you don&#8217;t really own them unless everyone is running their own engines (not likely). Version 1.6 doesn&#8217;t finish that story, but it lays down the identity it depends on. The next thing I want to do is exercise it in <a href="https://manifold.picolabs.io/">Manifold</a> and find the rough edges by using it. If you want the details, the <a href="https://picolabs.atlassian.net/wiki/spaces/docs/pages/4033413122/DIDs+Pico+Identity">DID</a> and <a href="https://picolabs.atlassian.net/wiki/spaces/docs/pages/4032102406/Subscriptions">Subscriptions</a> pages walk through each piece.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/08/passport-and-phone.png">Two kinds of identity for a pico</a> from ChatGPT (public domain)</p>]]></content:encoded></item><item><title><![CDATA[The Pressure Behind Identity's Diseconomies of Scale]]></title><description><![CDATA[Summary: Eve Maler argues that identity's apparent diseconomies of scale are really about gnarliness, not size.]]></description><link>https://www.technometria.com/p/the-pressure-behind-identitys-diseconomies</link><guid isPermaLink="false">https://www.technometria.com/p/the-pressure-behind-identitys-diseconomies</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Mon, 10 Aug 2026 17:21:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uBky!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>Eve Maler argues that identity's apparent diseconomies of scale are really about gnarliness, not size. That gnarliness has a shape I drew for chapter 19 of my forthcoming book: the gap between a growing decision surface and the infrastructure meant to govern it. That gap is authorization pressure, and it explains why identity gets harder even when a team does everything right.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uBky!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uBky!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!uBky!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!uBky!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!uBky!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uBky!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;An engineer trying to hold back a high-pressure system springing leaks from every joint&quot;,&quot;title&quot;:&quot;An engineer trying to hold back a high-pressure system springing leaks from every joint&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="An engineer trying to hold back a high-pressure system springing leaks from every joint" title="An engineer trying to hold back a high-pressure system springing leaks from every joint" srcset="https://substackcdn.com/image/fetch/$s_!uBky!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!uBky!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!uBky!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!uBky!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b263cb1-a322-4595-9316-9e1e611d6e81_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Eve Maler recently unpacked a statistic that is easy to misread. In <a href="https://workshop.vennfactory.com/p/what-makes-identity-gnarly">her post</a> she reports on an IANS Research finding that identity and access management was the only security category with negative economies of scale; IAM takes 8% of the security budget at organizations under $400M in revenue but 14% at organizations over $10B. The obvious reading is that identity gets more expensive, per dollar, the bigger you get. Eve&#8217;s better reading is that &#8220;gnarliness,&#8221; her word for the tangle that makes identity hard, is multi-factorial, and that company size is a poor proxy for it.</p><p>She lists the real drivers: how many jurisdictions you operate in, how large your partner ecosystem is, how many apps you are wiring to an identity provider, how loosely coupled your lines of business are, and whether anyone owns identity strategically. What predicts gnarliness, she argues, is not any single factor but the unique combination your organization lives with. Reading her post, I recognized a shape I had drawn for chapter 19 of my forthcoming book, <a href="https://www.manning.com/books/authorization-in-action">Authorization in Action</a>. I give the tangle she describes has a name and a diagram.</p><h2><strong>Gnarliness Has a Shape</strong></h2><p>In the book, I distinguish two things that grow at different rates as a system expands. The first is the <em>decision surface</em>: the total set of situations in which access has to be evaluated. The second is the <em>decision infrastructure</em>: the shared policy, consistent enforcement, contextual signals, governance, and delegation models that let those decisions be made well. The surface expands with more actors, more actions, more contexts, more delegation, and more automation. The infrastructure only expands when someone deliberately builds it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MuW_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MuW_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png 424w, https://substackcdn.com/image/fetch/$s_!MuW_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png 848w, https://substackcdn.com/image/fetch/$s_!MuW_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png 1272w, https://substackcdn.com/image/fetch/$s_!MuW_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MuW_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png" width="768" height="553" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:553,&quot;width&quot;:768,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Decision surface, decision infrastructure, and authorization pressure&quot;,&quot;title&quot;:&quot;Decision surface, decision infrastructure, and authorization pressure&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="Decision surface, decision infrastructure, and authorization pressure" title="Decision surface, decision infrastructure, and authorization pressure" srcset="https://substackcdn.com/image/fetch/$s_!MuW_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png 424w, https://substackcdn.com/image/fetch/$s_!MuW_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png 848w, https://substackcdn.com/image/fetch/$s_!MuW_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png 1272w, https://substackcdn.com/image/fetch/$s_!MuW_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f3e2879-0fb2-4c7a-9532-bc4ea1ea790b_768x553.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p style="text-align: center;"><em>The gap between the decision surface and the decision infrastructure is authorization pressure.</em></p><p>When the surface outruns the infrastructure, the gap between them shows up as <em>authorization pressure</em>: the growing difficulty of making decisions consistently, explaining why they came out the way they did, and keeping control as the system scales. Pressure is not a failure of effort; ACME, the company I follow through the book, was improving access control the whole time. Pressure is what you feel when access decisions are being made everywhere and governed nowhere. Eve&#8217;s drivers of gnarliness map almost one to one onto the things that expand the decision surface; more jurisdictions maps to more context, a bigger partner ecosystem is more delegation, and more apps across more brands is more actors taking more actions.</p><h2><strong>Why Size Was Never the Predictor</strong></h2><p>Once you see identity&#8217;s difficulty as pressure rather than size, Eve&#8217;s objection to size as a predictor is easy to explain. Revenue and headcount tell you almost nothing about the decision surface. A small, acquisitive fintech operating in a dozen regulatory regimes, wiring together the identity systems of the companies it just bought, can carry far more surface than a giant consumer brand running one simple app for five hundred million users. The first organization is under enormous authorization pressure; the second is barely under any. Size isn&#8217;t what matters in either case.</p><p>That is also why IAM shows up as the category with negative economies of scale while other security categories get cheaper per dollar. The IANS number is not measuring the cost of being big. It is measuring the pressure that accumulates when the decision surface expands faster than the infrastructure meant to govern it, and large organizations have simply had more time and more room to let that gap grow. In other words, the diseconomies of scale are a symptom of authorization pressure, and the pressure itself is what you get when the decision infrastructure falls behind the decision surface. The underlying cause is an infrastructure that never grew to match the surface, not size.</p><h2><strong>Relieving the Pressure</strong></h2><p>You cannot relieve the pressure by shrinking the decision surface, because the business is the thing expanding it. Every new partner, every new market, every agent you deploy is simply the company doing what it exists to do. The only durable move is to strengthen the infrastructure so decisions stay consistent, explainable, and bounded even as the surface grows. That means externalizing policy out of application code, evaluating decisions at runtime against relationships and attributes and context, governing the signals those decisions depend on, and making delegation explicit rather than implicit.</p><p>This is where Eve&#8217;s diagnosis and mine reinforce each other most usefully. She notes that the organizations doing well with identity treat it strategically, often under someone she calls an Identity Product Owner, and that unified identity has started pushing downmarket wherever identity turns out to be a <a href="https://masteringdigitalidentity.com/">revenue multiplier</a> rather than a cost. In the language of my book, those organizations have built decision infrastructure ahead of their decision surface, so the pressure never gets too high. Identity stops being the category that gets gnarlier with size and becomes a <em>capability</em> that lets a company expand the surface on purpose. A gap closed early is the difference between complexity that compounds and complexity you can manage.</p><h2><strong>The Surface Won&#8217;t Stop Expanding</strong></h2><p>Here&#8217;s the bad news: the decision surface is about to grow faster than it ever has. More interactions are crossing organizational boundaries; more actions are taken by services and agents instead of people; more decisions depend on real-time context that no static role can capture. I have argued in my <a href="https://www.windley.com/archives/2026/03/agentic_ai_and_dynamic_authorization_a_series_recap.shtml">series on agentic AI and authorization</a> that agents expand the surface precisely because they act over time, under changing conditions, and often on someone else&#8217;s behalf. The pressure Eve measured in enterprise IAM budgets is the same pressure that will decide whether agentic systems are governable at all.</p><p>That is the human stake underneath the budget line. Authorization is how we govern the ways authority gets exercised, by our people, by our partners, and increasingly by the software acting for them. When the pressure is high, people confront a digital world of inconsistent permissions and unexplainable denials, a world where no one can say why the door opened or stayed shut. When the infrastructure keeps pace, authority is legible and bounded, and people can act with confidence inside clear limits. Eve is right: gnarliness is multi-factorial and size is the wrong thing to measure. What we should measure instead is the pressure between the decisions we now have to make and the infrastructure we have built to make them well. That pressure is something we can manage.</p><div><hr></div><p>Photo Credits: <a href="https://www.windley.com/archives/2026/08/under-pressure.png">Under Pressure</a> from ChatGPT (public domain) and Decision Surface and Decision Infrastructure, from Chapter 19 of <em>Authorization in Action</em> (Manning)</p>]]></content:encoded></item><item><title><![CDATA[A Map of the Manifold Environment]]></title><description><![CDATA[Summary: A reader asked for a map of the whole Manifold environment and the functional capabilities of each part.]]></description><link>https://www.technometria.com/p/a-map-of-the-manifold-environment</link><guid isPermaLink="false">https://www.technometria.com/p/a-map-of-the-manifold-environment</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Wed, 05 Aug 2026 15:05:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!iJrp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>A reader asked for a map of the whole Manifold environment and the functional capabilities of each part. I have described this system across three posts, a piece at a time, but never in one picture. </em></p><p>Emil Sotirov <a href="https://x.com/sotirov/status/2084327258488197534?s=20">wrote</a> after my last few posts with a good request:</p><blockquote><p>Would you, please, do a map/diagram of the whole environment you&#8217;re describing, giving an idea about the functional capabilities?</p></blockquote><p>That&#8217;s a fair thing to ask. I have described this environment across three posts now, a piece at a time, and never in a single picture: the platform rebuild in <a href="https://www.windley.com/archives/2026/06/manifold_api_and_sensor_network_two_new_repos.shtml">Manifold API and Sensor Network</a>, the engine&#8217;s new identity layer in <a href="https://www.windley.com/archives/2026/07/identity_for_the_pico_engine.shtml">Identity for the Pico Engine</a>, and the interface in <a href="https://www.windley.com/archives/2026/08/using_home_assistant_with_manifold.shtml">Using Home Assistant with Manifold</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iJrp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iJrp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png 424w, https://substackcdn.com/image/fetch/$s_!iJrp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png 848w, https://substackcdn.com/image/fetch/$s_!iJrp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png 1272w, https://substackcdn.com/image/fetch/$s_!iJrp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iJrp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png" width="867" height="476" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:476,&quot;width&quot;:867,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The Manifold environment, from the pico engine to Home Assistant&quot;,&quot;title&quot;:&quot;The Manifold environment, from the pico engine to Home Assistant&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="The Manifold environment, from the pico engine to Home Assistant" title="The Manifold environment, from the pico engine to Home Assistant" srcset="https://substackcdn.com/image/fetch/$s_!iJrp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png 424w, https://substackcdn.com/image/fetch/$s_!iJrp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png 848w, https://substackcdn.com/image/fetch/$s_!iJrp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png 1272w, https://substackcdn.com/image/fetch/$s_!iJrp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad3fe8cd-51c8-4f80-84f8-3a398980fcfa_867x476.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The figure above puts the whole thing in one place and labels what each layer does:</p><ul><li><p><strong>Pico engine</strong>&#8212;hosts the picos and supplies, among other things, identity: passkeys for the owner and OAuth for outside software. One engine can run several independent meshes at once, as shown in the figure.</p></li><li><p><strong>Pico</strong>&#8212;the <a href="https://www.windley.com/archives/2015/11/reactive_programming_with_picos.shtml">actor</a>. Each pico is an independent, addressable entity with its own state, its own rules, and its own channels, and it interacts with other picos only by exchanging events. Everything above this layer in the diagram is running on picos.</p></li><li><p><strong>Wrangler</strong>&#8212;the pico operating system. It gives each pico its channels, children, and subscriptions, and it is the machinery every higher layer calls to create picos and wire them together.</p></li><li><p><strong>Manifold</strong>&#8212;the framework layer, responsible for mesh lifecycle and notifications.  It controls a mesh comprising a root pico, a Manifold pico that creates and tracks things and communities, all the things and communities, and tag and skills registries. It fans alerts out to various channels. Everything above delegates that work to Manifold rather than building it again.</p></li><li><p><strong>Sensor network</strong>&#8212;a domain layer that specializes the generic platform. It treats communities as sensor groups and things as LoRaWAN devices, decodes their payloads, and raises threshold alerts back through Manifold&#8217;s notifications.</p></li><li><p><strong>Home Assistant</strong>&#8212;the interface, where a person actually sees and drives everything: devices, dashboards, and automations. The Manifold hub integration authenticates over OAuth and renders things and communities as Home Assistant devices, and a companion integration adds sensor entities for the domain layer beneath it.</p></li></ul><p>The figure shows a classic delegation stack: each layer leans on the one beneath it and adds capabilities the layer below does not have. The one thing the figure hints at but does not yet deliver is the pair of light links between meshes, marked <code>x</code> and <code>y</code>. Those cross-mesh relationships are waiting on the pico-to-pico identity layer that is still ahead, which I will cover in its own post. That aside, this is the whole environment in a single picture.</p>]]></content:encoded></item><item><title><![CDATA[Using Home Assistant with Manifold]]></title><description><![CDATA[Summary: Manifold is evolving into a proper framework for building meshes of picos, and Home Assistant gives those meshes an interface.]]></description><link>https://www.technometria.com/p/using-home-assistant-with-manifold</link><guid isPermaLink="false">https://www.technometria.com/p/using-home-assistant-with-manifold</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Mon, 03 Aug 2026 14:44:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!GjH8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong><em>: Manifold is evolving into a proper framework for building meshes of picos, and Home Assistant gives those meshes an interface. A new Home Assistant integration proves out three pieces at once: an OAuth workflow on the pico-engine that lets outside software into the mesh on the owner&#8217;s terms, a mature interface rather than a custom one, and a pattern that lets specialized communities extend the platform.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GjH8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GjH8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!GjH8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!GjH8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!GjH8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GjH8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A Home for Your Pico Mesh&quot;,&quot;title&quot;:&quot;A Home for Your Pico Mesh&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="A Home for Your Pico Mesh" title="A Home for Your Pico Mesh" srcset="https://substackcdn.com/image/fetch/$s_!GjH8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!GjH8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!GjH8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!GjH8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6cdb8c9-da40-4526-8487-f34cf3c76ae7_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The original Manifold (which was a replacement for the old SquareTag) gave a person a place to gather their connected things under their own control, but it needed its own web application to provide the UI and manage accounts. Rebuilding <a href="https://github.com/Picolab/manifold-api">Manifold</a> on version 1.5 of the pico engine turned it into a framework for building meshes of picos. But that mesh is only useful if outside software can reach it, if the owner has an interface that is easy to use, and if specialized domains can extend it without forking the platform. Those are three separate problems, and a <a href="https://github.com/Picolab/manifold-home-assistant">Home Assistant integration</a> was how I proved I had an answer to each one.</p><p>This work sits directly on top of the last two things I wrote about. In <a href="https://www.windley.com/archives/2026/06/manifold_api_and_sensor_network_two_new_repos.shtml">Manifold API and Sensor Network: Two New Repos</a> I rebuilt Manifold as a framework and rewrote the sensor network as an example that runs on it, and I flagged a Home Assistant integration as the obvious next step. Then in <a href="https://www.windley.com/archives/2026/07/identity_for_the_pico_engine.shtml">Identity for the Pico Engine</a> I added OAuth to the engine and said the Home Assistant layer would be the first real exercise of that identity work. This post is where those two threads meet.</p><p>I&#8217;ll take them in the order they build on one another: an OAuth workflow that lets an outside application into the mesh, <a href="https://www.home-assistant.io/">Home Assistant</a> replacing the custom Manifold interface, and a pattern that lets a domain like a sensor network add its own behavior on top. Each of the three are working now. One thing still doesn&#8217;t, and I&#8217;ll come to that.</p><h2><strong>Letting an Application In</strong></h2><p>Version 1.5 of the pico engine finally moved identity into the engine itself, including OAuth for external applications and webhooks; I described that design earlier in <a href="https://www.windley.com/archives/2026/07/identity_for_the_pico_engine.shtml">Identity for the Pico Engine</a>. Home Assistant was the first real client I pointed at it. When someone adds the Manifold integration, Home Assistant runs the OAuth flow and comes away with a token it can use to access the mesh. This allows each mesh owner to grants access deliberately using a token that is scoped to what the application should see, and that the owner can revoke later.</p><h2><strong>An Interface I Didn&#8217;t Have to Build</strong></h2><p>The old Manifold answered the interface question by building a web application: accounts, dashboards, notification screens, all of it written and maintained as custom code. Home Assistant already solves that problem for a large community of users, and its open source. So rather than ask owners to learn another dashboard, Manifold now appears inside one that many of them already run.</p><p>Things and communities show up as Home Assistant devices, and Manifold&#8217;s notifications reach the owner through a dedicated channel that the <em>homeassistant</em> ruleset creates on install and forwards enabled alerts to. Home Assistant is already where many people run their home automation and sensors, and a Manifold mesh drops into that same surface, adding picos to HA, each with its own logic and its own relationships. Reusing a mature system beats maintaining a thinner copy of it. The time I would have spent on yet another dashboard goes to other projects.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RKds!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RKds!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png 424w, https://substackcdn.com/image/fetch/$s_!RKds!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png 848w, https://substackcdn.com/image/fetch/$s_!RKds!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png 1272w, https://substackcdn.com/image/fetch/$s_!RKds!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!RKds!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png" width="1456" height="1046" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1046,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Manifold Dashboard showing Safe &amp; Mine and Journal controls&quot;,&quot;title&quot;:&quot;Manifold Dashboard showing Safe &amp; Mine and Journal controls&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Manifold Dashboard showing Safe &amp; Mine and Journal controls" title="Manifold Dashboard showing Safe &amp; Mine and Journal controls" srcset="https://substackcdn.com/image/fetch/$s_!RKds!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png 424w, https://substackcdn.com/image/fetch/$s_!RKds!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png 848w, https://substackcdn.com/image/fetch/$s_!RKds!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png 1272w, https://substackcdn.com/image/fetch/$s_!RKds!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd227a428-2d40-40bc-bb5a-f785c31f98b3_3618x2600.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Manifold Dashboard showing Safe &amp; Mine and Journal controls (click to enlarge)</figcaption></figure></div><h2><strong>Room for Specialized Communities</strong></h2><p>A platform is only generative if other people can build on it without asking permission, and the third component demonstrated that idea. The <a href="https://www.windley.com/archives/2026/06/manifold_api_and_sensor_network_two_new_repos.shtml">sensor network</a> I rebuilt as a Manifold example needed sensor-specific behavior in Home Assistant, not just the generic view of things and communities. So it ships a companion integration, <em><a href="https://github.com/windley/sensor-network/tree/main/custom_components/pico_mesh_sensor_network">pico_mesh_sensor_network</a></em>, that declares the Manifold hub as a dependency and attaches sensor entities to the thing devices Manifold already created. The pattern is small: domain rulesets in the repo root, a companion component beside them that depends on the hub, and a stable surface to import from. Any Manifold community can follow it, which is exactly what I wanted to demonstrate.</p><h2><strong>What Still Doesn&#8217;t Work</strong></h2><p>One piece of the old Manifold has not made the trip yet. SafeAndMine, the application that started this line of work, depended on physical tags: an NFC sticker or a QR code on an object that resolves through a tag registry to the pico that represents that thing. The registry is in place and things can register against it, but scanning a tag and following it to the right pico does not yet work end to end. Until that path is solid, Manifold can model your things but it cannot let a stranger scan the tag on your lost backpack and reach you. That is the next thing to finish.</p><p>Manifold has evolved from a product with its own screens to maintain into a foundation for building meshes of picos that can sit at the network edge. What makes that real is the architecture holding together: identity that lets outside software in on the owner&#8217;s terms, an interface in a system people already trust, and an extension pattern that invites other domains to build. The tag path still has to land before I would call the old Manifold fully replaced. But the important parts are working now.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/08/manifold_home_assistant.png">A Home for Your Pico Mesh</a> from ChatGPT (public domain)</p>]]></content:encoded></item><item><title><![CDATA[Identity for the Pico Engine]]></title><description><![CDATA[Summary: Version 1.5 of the Pico Engine finally brings identity into the engine itself: passkeys for humans, and OAuth for external apps and webhooks.]]></description><link>https://www.technometria.com/p/identity-for-the-pico-engine</link><guid isPermaLink="false">https://www.technometria.com/p/identity-for-the-pico-engine</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Tue, 14 Jul 2026 18:47:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!RO9d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong><em>: Version 1.5 of the Pico Engine finally brings identity into the engine itself: passkeys for humans, and OAuth for external apps and webhooks. Here&#8217;s the shape of the design, why identity is really three problems and not one, and why I shipped the human and third-party layers before the pico-to-pico layer.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RO9d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RO9d!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!RO9d!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!RO9d!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!RO9d!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RO9d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Protecting your pico mesh&quot;,&quot;title&quot;:&quot;Protecting your pico mesh&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="Protecting your pico mesh" title="Protecting your pico mesh" srcset="https://substackcdn.com/image/fetch/$s_!RO9d!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!RO9d!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!RO9d!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!RO9d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0125c9e2-a612-46cf-8c95-eabd5021d6d0_1672x941.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Today I&#8217;m releasing version 1.5 of the <a href="https://picolabs.atlassian.net/wiki/spaces/docs/overview">Pico Engine</a>. The primary features in this release are support for accounts, authentication to the UI via passkeys, OAuth client credentials for channels used as webhooks, and optional OAuth Authorization Code Grant credentials for any given pico mesh. If you know me, you might be thinking &#8220;wait you&#8217;ve been working on picos and identity for 25 years and you&#8217;re <em>just</em> getting around to bringing them together?!?&#8221; There&#8217;s a story there.</p><p>The original pico engine (what we call the &#8220;classic&#8221; pico engine) was begun in 2008. In that era of Infrastructure and Platform as a Service models, we&#8217;d have been silly to build a product that didn&#8217;t support identity and accounts. And we did. The classic pico engine, written in over 400,000 lines of Perl as an Apache module, has a full-blown identity system with passwords, accounts, and OAuth support. When we rewrote it (after the demise of <a href="https://www.windley.com/tags/fuse.shtml">Fuse</a>) we were looking for something less of a platform and more personal. The new engine was implemented in Node and mainly used locally or in small experiments. Even as it grew and we started using it for more significant efforts like <a href="https://manifold.picolabs.io/">Manifold</a>, we just wrapped it in an identity layer written separately.</p><p>But I&#8217;ve got some projects in mind that need proper identity to work and so the time has come to bite the bullet and add identity to the pico engine itself. Let me tell you about the architecture and what I&#8217;m releasing today.</p><h2><strong>Three Kinds of Identity</strong></h2><p>The first thing to get straight is that identity here isn&#8217;t one problem. It&#8217;s three. They are easy to lump together, but they ask different questions and want different answers. When I open the engine&#8217;s UI, the engine needs to know it&#8217;s talking to me. When one pico calls another, the pico on the receiving end needs to know which pico is calling and whether it&#8217;s allowed to do what it&#8217;s asking. And when something outside the engine, like Home Assistant or an inbound webhook, hits the public API, the engine needs to know who that caller is and what it can do. Keeping these three apart is what keeps the whole thing from turning into a tangle.</p><p>Each one has a natural answer:</p><ul><li><p><strong>Human to pico mesh.</strong> You sign in to your root pico with a passkey. Each root pico is its own <a href="https://passkeys.dev/">WebAuthn</a> relying party, so there&#8217;s no shared password and no central table of users. Once you&#8217;re signed in, that root pico acts as the controller for the entire mesh.</p></li><li><p><strong>Pico to pico.</strong> This is the layer that gives a pico its own portable, cryptographic identity using <a href="https://identity.foundation/didwebvh/v1.0/">DIDs</a> and DIDComm to provide mutual authentication. That identity can survive a move from engine to engine, and it lets two picos from different meshes trust each other without anyone setting up a federation agreement first.</p></li><li><p><strong>Third-party access.</strong> A webhook or an app can&#8217;t use my passkey session, and I don&#8217;t want it holding a bare URL that works forever. So it gets an OAuth token instead, one it has to ask for and one I can take back.</p></li></ul><p>I&#8217;m building these as three layers, and I shipped the first and third in 1.5. That order probably looks backwards, so let me explain it. The pico-to-pico layer is the most interesting of the three, but it&#8217;s also the most work. It means moving DID keys into the engine as a core primitive, pulling a lot of KRL into wrangler, and eventually running pico-to-pico traffic over DIDComm instead of plain HTTP. That&#8217;s a big change, and it touches a lot of the engine. The other two layers don&#8217;t need any of that. Passkeys and OAuth sit on top of machinery the engine already has: channels, ECIs, and channel policy. So I could add human sign-in and third-party access now, and leave the deeper identity work for when I can give it the attention it deserves.</p><h2><strong>No Usernames, No Passwords</strong></h2><p>One decision inside the human-to-mesh layer is worth pointing out: there are no usernames and no passwords anywhere in the engine. You register with a passkey and you sign in with a passkey, and that&#8217;s the whole story. There&#8217;s no email-and-password form to fall back on, no step where you make up a username, and no password database sitting on the engine waiting to be leaked. When you register, the engine creates your account and your root pico and ties them to a passkey your device holds. That is the account.</p><p>Part of the reason is that passwords carry problems I didn&#8217;t want to inherit. They get reused, phished, and stolen in bulk, and every system that stores them becomes a target. Passkeys sidestep all of that: the secret never leaves your device, there&#8217;s nothing shared for an attacker to steal, and signing in is a touch or a PIN rather than something you have to remember. But the bigger reason is that I think passwordless authentication is where things are headed, and I wanted to build something with no passwords at all and explore how that works. It&#8217;s easy to bolt passkeys on next to a password form as one more option; it&#8217;s more interesting to commit to them as the only way in. The cost is that the engine leans entirely on the passkey, which is part of why recovery is such a sharp edge, and I&#8217;ll come back to that below.</p><p>As an initial experiment, I&#8217;m pretty happy with it. Logging into different meshes is quick and easy. My password manager (1Password) lets me easily choose between different meshes, and not having to type in a username is great. A passwordless user experience is definitely a <em>better</em> user experience.</p><h2><strong>Webhooks: Client Credentials</strong></h2><p>The simplest kind of outside access is one machine talking to another: a webhook that posts an event to a single channel. This is a common pattern that I use frequently. For example, <a href="https://www.windley.com/archives/2023/03/monitoring_temperatures_in_a_remote_pump_house_using_lorawan.shtml">the sensor network that monitors the temperatures in the pumphouse at my cabin</a> gets an event via a webhook from a Helium console.</p><p>Since a webhook only ever hits one channel, its credential should be scoped to one channel too. That&#8217;s a good fit for the OAuth Client Credentials grant. You create a channel for the webhook and tag it <em>oauth-webhook</em>. The channel&#8217;s ECI becomes its OAuth client id, and you create a secret for it from the Channels tab in the UI. The secret is shown once and stored hashed. The sender trades that secret for a bearer token at <code>/oauth/token</code>, then includes the token on every post to the channel&#8217;s <code>/sky/</code> URL.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ESi2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ESi2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png 424w, https://substackcdn.com/image/fetch/$s_!ESi2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png 848w, https://substackcdn.com/image/fetch/$s_!ESi2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png 1272w, https://substackcdn.com/image/fetch/$s_!ESi2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!ESi2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png" width="891" height="1211" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1211,&quot;width&quot;:891,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Client Credentials UI for a Channel&quot;,&quot;title&quot;:&quot;Client Credentials UI for a Channel&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Client Credentials UI for a Channel" title="Client Credentials UI for a Channel" srcset="https://substackcdn.com/image/fetch/$s_!ESi2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png 424w, https://substackcdn.com/image/fetch/$s_!ESi2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png 848w, https://substackcdn.com/image/fetch/$s_!ESi2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png 1272w, https://substackcdn.com/image/fetch/$s_!ESi2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda291e20-cba0-4e69-ae6f-23862afbbfeb_891x1211.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Client Credentials UI for a Channel (click to enlarge)</figcaption></figure></div><p>Two small decisions are worth noting. The first is that the access token is a real token, not the ECI itself. The old server used to hand back the ECI as a shared secret, which mixed up the pico&#8217;s address with the secret you need to reach it. Now the ECI stays in the URL, where routing needs it, and the token is a separate secret you can revoke on its own. The second is that tagging a channel <em>oauth-webhook</em> locks it right away. Any request without a valid token for that exact channel is turned away before channel policy even runs. Both decisions are about limiting the damage if something leaks. A webhook URL on its own is now useless, and even a stolen token only opens one channel.</p><p>Real webhook senders make this less tidy. Helium and Stripe, for instance, post to a fixed URL and will never call <code>/oauth/token</code> to get a token. For them, the bearer requirement still protects against someone discovering the URL, but it doesn&#8217;t verify that the payload actually came from Helium. That job usually falls to an HMAC signature, and I haven&#8217;t built that in here. Client Credentials is aimed at senders that can send an <em>Authorization</em>header. The fixed-URL senders are a separate problem for another day.</p><h2><strong>Whole-Mesh Apps: Authorization Code</strong></h2><p>The other kind of outside access is an app acting for a person across a whole mesh. The example driving the design is <a href="https://www.home-assistant.io/">Home Assistant</a> sitting in front of a pico mesh. A single channel is the wrong unit here, because the app needs to read and drive many picos under my root, not just one. So this uses the Authorization Code grant with PKCE, scoped to a root pico and everything under it. The flow is the ordinary OAuth dance. I register the app, which gets its own opaque id. The app sends me to <code>/oauth/authorize</code>, I sign in with my passkey and approve a consent screen, and the app trades the resulting code for a token it uses on any <code>/sky/</code><a href="https://picolabs.atlassian.net/wiki/spaces/docs/pages/1189914/Event+Exchange+Protocol"> event or query channel</a>. Refresh tokens allow for rotation, and the access tokens are the same opaque bearers as the webhook case. The only difference is that they&#8217;re checked against the whole mesh instead of one channel.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UCV5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UCV5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png 424w, https://substackcdn.com/image/fetch/$s_!UCV5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png 848w, https://substackcdn.com/image/fetch/$s_!UCV5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png 1272w, https://substackcdn.com/image/fetch/$s_!UCV5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!UCV5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png" width="766" height="1042" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1042,&quot;width&quot;:766,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;OAuth App Registration in the Settings Panel&quot;,&quot;title&quot;:&quot;OAuth App Registration in the Settings Panel&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="OAuth App Registration in the Settings Panel" title="OAuth App Registration in the Settings Panel" srcset="https://substackcdn.com/image/fetch/$s_!UCV5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png 424w, https://substackcdn.com/image/fetch/$s_!UCV5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png 848w, https://substackcdn.com/image/fetch/$s_!UCV5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png 1272w, https://substackcdn.com/image/fetch/$s_!UCV5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffcc63b35-fde2-425b-8805-a5730812efe3_766x1042.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">OAuth App Registration in the Settings Panel (click to enlarge)</figcaption></figure></div><p>OAuth isn&#8217;t required on every mesh and an engine-wide switch would be wrong, because one engine can now host several independent roots that belong to different people. So the switch is per mesh instead. You install an optional Wrangler ruleset, <em><a href="https://github.com/Picolab/pico-engine/blob/master/packages/pico-engine/krl/io.picolabs.oauth.krl">io.picolabs.oauth</a></em>, on the root pico. Once it&#8217;s there, every outside call to that mesh&#8217;s <code>/sky/</code> endpoints has to carry a token. Leave it off and the mesh works the way it always has, under channel policy, with the one exception that <em>oauth-webhook</em> channels are always locked. That means one engine can run a locked-down mesh and an open one right next to each other. The engine still does the real work, holding the tokens, running the ceremony, and serving the routes. The ruleset just marks the mesh and carries its OAuth settings.</p><p>Both grant types can live in the same mesh without getting in each other&#8217;s way. They share one token store and one check, which just looks at what kind of token it is. A Client Credentials token is tied to the ECI in the URL. An Authorization Code token is checked against everything under its app&#8217;s root. Because the two are separate, revoking Home Assistant&#8217;s access leaves the webhook credentials alone, and revoking a webhook leaves the app alone. This lets a pico grant access to different services for different reasons.</p><h2><strong>Tradeoffs and What&#8217;s Next</strong></h2><p>This release makes a few deliberate choices that limit what the engine will do, and they&#8217;re worth being explicit about rather than leaving for you to trip over. The first is that there&#8217;s no admin. Each mesh has a single owner, and that owner is simply whoever holds the passkey. If you lose track of your passkey, there&#8217;s no recovery and no back door that lets you in anyway. That&#8217;s a hard edge, but it keeps the model simple, and it fits the pico ethos, where a pico is something you own outright rather than an account someone else grants you. It may not be enough for someone who wants to use the engine as the root of a user-facing system, where ordinary users expect a way to recover a lost login. That&#8217;s a fair worry, and one I&#8217;ll come back to.</p><p>For now the engine also assumes one owner per mesh. That owner can register more than one passkey, so a laptop, a phone, and a hardware key can all open the same mesh; &#8220;one owner&#8221; doesn&#8217;t have to mean &#8220;one device.&#8221; I expect to relax the single-owner rule down the road, but I wanted to start simple. And while the engine is multi-tenanted now, meaning one engine can host meshes belonging to different people, it doesn&#8217;t let just anyone sign up and create one. By default, new meshes come through an invitation from an existing owner. You can turn self-signup on if you want an open system, but off is the default.</p><p>Using the root pico as the entry point for all of its descendants is powerful. Signing in once gives you a handle on a whole tree of picos, and everything under the root inherits from that single point of control. But I want to be careful about what that does and doesn&#8217;t buy you. None of these changes automatically makes an engine or a pico mesh secure. Passkeys, OAuth, and channel policy are tools, not guarantees. A builder can still open a channel too wide, hand out a token that never expires, or run the engine on a host that isn&#8217;t locked down. What I&#8217;ve tried to do is give builders the pieces they need to move in a secure direction, with defaults that don&#8217;t fight them along the way.</p><p>All of this passes the tests I&#8217;ve written, but I&#8217;ll be honest that I haven&#8217;t put it in front of a real use case yet. Tests tell you the machinery works; they don&#8217;t tell you the design holds up when someone actually leans on it. The next thing I want to build is a Home Assistant layer for Manifold-based pico meshes, and that will be the first real exercise of this identity work. I expect to find the rough spots that way, and I&#8217;d rather learn them by using the thing than by guessing at them now.</p><h2><strong>Who Gets In</strong></h2><p>I&#8217;ve spent a long time arguing that people should have a <a href="https://www.windley.com/archives/2011/11/the_second_pc_revolution_personal_clouds.shtml">personal cloud</a> (to use an antiquated term). By that I mean software that acts for you, that you control, and that isn&#8217;t just a rented seat on someone else&#8217;s platform. The pieces in this release line up with that idea. A passkey proves you&#8217;re you. Your root pico gives you a mesh of your own out in the world. And OAuth lets you lend that mesh&#8217;s capabilities to the tools you choose, on terms you can revoke whenever you like. The piece still missing is the pico-to-pico layer, the one that will let a pico move between meshes and let two meshes trust each other without anyone in the middle. That work is still ahead. What I&#8217;m releasing today is the part that lets you walk up to a pico engine, prove who you are, and start working in a mesh that is unmistakably yours. If you want the nuts and bolts, the <a href="https://picolabs.atlassian.net/wiki/spaces/docs/pages/3962044419/Identity+System">Identity System</a> documentation walks through each piece.</p>]]></content:encoded></item><item><title><![CDATA[The Shape of Context in Agentic Authorization]]></title><description><![CDATA[Summary: In agentic systems, the principal, action, and resource are often unknown until the moment an agent acts, and the context that governs the decision arrives as a flood of signals from many sources.]]></description><link>https://www.technometria.com/p/the-shape-of-context-in-agentic-authorization</link><guid isPermaLink="false">https://www.technometria.com/p/the-shape-of-context-in-agentic-authorization</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Mon, 06 Jul 2026 16:50:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!bHrE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>In agentic systems, the principal, action, and resource are often unknown until the moment an agent acts, and the context that governs the decision arrives as a flood of signals from many sources. This post looks at how that context takes shape, where each signal is actually consumed, and why a non-directed world of agents still needs decisions that humans can inspect and predict.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bHrE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bHrE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!bHrE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!bHrE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!bHrE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bHrE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The Shape of Context&quot;,&quot;title&quot;:&quot;The Shape of Context&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="The Shape of Context" title="The Shape of Context" srcset="https://substackcdn.com/image/fetch/$s_!bHrE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!bHrE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!bHrE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!bHrE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F14d5ed8c-af1e-4c80-9511-9730edd975a5_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>This post is part of a series on using dynamic authorization to control and coordinate AI agents. See the <a href="https://www.windley.com/archives/2026/03/agentic_ai_and_dynamic_authorization_a_series_recap.shtml">series recap</a> to find other posts in this series.</em></p><p>Agentic AI is still early, and the architectures, protocols, trust models, and operational patterns for agent-based systems will almost certainly change as organizations gain experience with them. The details of MCP, tool invocation, delegation, agent-to-agent interaction, and runtime governance are still being worked out. But the broad authorization problem is already visible: agents need a way to decide what they are allowed to do, what context matters, whose authority they are exercising, and when a requested action must be refused. Most of the difficulty in answering those questions lives in one word from the <a href="https://www.windley.com/archives/2026/02/why_authorization_is_the_hard_problem_in_agentic_ai.shtml">PARC model</a>: <em>context</em>. A reviewer of a draft of <a href="https://www.manning.com/books/authorization-in-action">my upcoming book on authorization</a> pushed on exactly that point, arguing that I had underplayed how complicated context becomes once agents are talking to agents, and he was right; this post is my attempt to think through that complication.</p><p>Agentic systems change the shape of authorization context. In a conventional application, the policy decision often begins with a familiar question: can this employee, application, or service perform this action on this resource? The principal, action, and resource are usually known to the system in advance, and the relevant context can be collected from a small number of well-understood sources. The decision is nearly self-contained, and an engineer can reason about it by reading a small number of policies.</p><h2><strong>The signals multiply</strong></h2><p>Agentic systems are different. An agent may act on behalf of a person, another agent, an organization, or some combination of delegated authorities. It may call tools, consult other agents, transform data, and produce intermediate results before it ever touches the resource that ultimately matters. The principal, action, and resource are no longer fixed at the start; they emerge as the agent plans, and the context that governs each step arrives as a flood of signals rather than a tidy record.</p><p>Those signals come in many kinds, and they come from many places. A single decision might have to weigh the initiating principal&#8217;s intent, the scope of delegation, consent constraints, personal preferences, organizational policy, data sensitivity, tool capabilities, resource state, risk signals, provenance, and the guardrails imposed by the agent platform or the enterprise. Some of these are stable and institutional, such as a company&#8217;s data-handling rules. Others are ephemeral and task-specific, such as the fact that this particular request is two hops removed from a human who only asked for a summary.</p><p>It helps to sort these signals by what they actually constrain. Some describe <em>who is really asking</em> and under what authority, such as delegation scope, initiating principal, and consent. Some describe <em>what is at stake</em>, such as data sensitivity, resource state, and tenant boundaries. Some describe <em>how much to trust the request itself</em>, such as provenance, risk scores, and the guardrails the platform is already enforcing. Naming the categories does not make the decision simple, but it keeps the flood from looking like undifferentiated noise.</p><h2><strong>Signals move through a mesh</strong></h2><p>Listing the signals is the easy part. The harder question is where each one is consumed, because a request rarely travels in a straight line from a person to a resource. It passes through a mesh of agents, each of which may plan, delegate, and call the next agent in turn. A signal that is decisive at one hop may be irrelevant at the next, and a signal that no intermediate agent cares about may be exactly what the resource needs to see.</p><p>Consider a person who asks a coordinating agent to reconcile an invoice, which calls a data-gathering agent, which in turn calls a tool that reads from the finance system. The person&#8217;s intent to &#8220;reconcile, not pay&#8221; has to shape what the coordinating agent is even willing to plan, but it cannot stop there; it has to travel all the way to the last hop so the finance system itself refuses a payment even if some agent in the chain proposes one. The delegation scope has to make the same journey, arriving intact so the finance system can confirm the request stays inside it. A freshly computed risk score on the intermediate data, by contrast, may matter only to the agent that produced it, and never needs to leave that hop at all.</p><p>So signals have distinct audiences. Some are <em>steering signals</em> that constrain the behavior of the next agent in the chain, and they need to be carried forward, narrowed, and re-evaluated at each hop. Others are <em>enforcement signals</em> that matter only at the point where authority finally lands on a resource, and they need to survive the whole journey without being flattened or forged along the way. And some are both: the intent in the example steers the coordinating agent&#8217;s early planning and still has to be enforced at the finance system, so it must be narrowed as it travels and honored when it arrives. Treating every signal as if it belonged everywhere produces both over-sharing and under-enforcement. Deciding, per signal, who consumes it and where is a large part of designing an agentic authorization system.</p><p>There is also a limit to how much of this the calling mesh gets to decide. The system behind an API or MCP server almost always has its own authorization, and it may be governed by a different organization entirely. The MCP server is a way to reach that system, not the place where authority finally lands; the finance system, the database, or the file server enforces its own policy no matter what the agents upstream concluded. Authorization here is layered rather than singular, and no single decision point speaks for all of them.</p><p>This is where policy constraints that can be queried along the way earn their keep. If a downstream resource can advertise what it will and will not permit, or answer a &#8220;would this be allowed?&#8221; question before an agent commits to a plan, the agents upstream can <a href="https://www.windley.com/archives/2026/02/beyond_denial_using_policy_constraints_to_guide_openclaw_planning.shtml">shape their behavior to fit</a> instead of discovering the boundary only when an action is refused. It also raises the bar for the signals a request carries, because the delegation and context have to stay legible to a policy engine the initiating organization does not control.</p><h2><strong>A non-directed world</strong></h2><p>There is a deeper shift underneath all of this. Traditional access control is directed and largely static: the system knows that Alice has access to the finance application, the finance application knows Alice, and the relationship is established before either of them does any work. The set of principals is small and enumerable, and the resource can hold a model of who is allowed to knock on its door.</p><p>Agentic systems are non-directed. A resource backend has no reliable way to know, in advance, which agent will arrive in the next minute or on whose behalf it will be acting. The requester may be an agent that did not exist 5 minutes ago, spun up to handle one task and then discarded. In that world, identity established ahead of time cannot carry the weight it used to, and the resource has to decide what to allow based on the authority and context presented at the moment of the request.</p><p>This is exactly where dynamic authorization earns its place. When the resource cannot pre-enroll every principal, the decision has to move to request time and rest on portable evidence: who initiated this, what were they trying to do, what delegation connects them to the agent now asking, and what constraints ride along with it. The point of the signals is to reconstruct, at the moment of the request, the accountability that a directed system used to establish in advance.</p><h2><strong>Complexity doesn&#8217;t change who decides</strong></h2><p>Faced with dozens or hundreds of signals in a single request, it is tempting to conclude that the decision itself has outgrown human-authored policy, and that we should let a model weigh the signals and decide. I think that conclusion mistakes a hard engineering problem for a change in who should be in charge. The volume of context is real, but it is an argument about how we gather, normalize, and route signals, not an argument for moving the judgment about what is allowed into a system whose reasoning we cannot inspect or reproduce.</p><p>The work that genuinely is hard belongs on the input side of the decision. Assembling the signals, resolving them into a consistent shape, summarizing evidence, and scoring risk are all tasks where models and other tooling can help enormously, and where an agent&#8217;s flexibility is an asset rather than a hazard. What should stay deterministic is the final question: given this principal, action, resource, and assembled context, is the action permitted? A policy that answers that question can be read, tested, and explained after the fact, which is precisely what the people whose data and money are at stake are entitled to.</p><p>Keeping that line clear does not make the policies simple. Deciding which signals a policy consults, and trusting that they were gathered honestly, is a substantial design problem, and it will pull more structure and more tooling into the space around the decision. But the decision stays somewhere a human can point to and understand. Complexity in the context is a reason to build better machinery for handling signals; it is not a reason to hand the judgment itself to a system that cannot tell us why it said yes.</p><p>Agentic AI will reshape almost everything about how context is gathered and carried, and much of what I have described here will look primitive in a few years. What I do not expect to change is the shape of the obligation. When authority lands on a real resource on behalf of a real person, someone has to be able to say why the action was allowed, in terms that person could check. Getting the context right is how we make that answer possible; keeping the decision inspectable is how we make sure it stays true.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/07/context_signals.png">The Shape of Context</a> from ChatGPT (public domain)</p>]]></content:encoded></item><item><title><![CDATA[Manifold API and Sensor Network: Two New Repos]]></title><description><![CDATA[Summary: Cleaning up manifold-api as a prerequisite for the spring conversational interface capstone turned into a complete platform update: Pico Engine 1.0 compatibility, automated bootstrap, centralized notifications, and a Docker-based integration test harness.]]></description><link>https://www.technometria.com/p/manifold-api-and-sensor-network-two</link><guid isPermaLink="false">https://www.technometria.com/p/manifold-api-and-sensor-network-two</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Tue, 09 Jun 2026 15:44:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!CBtu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>Cleaning up manifold-api as a prerequisite for the spring conversational interface capstone turned into a complete platform update: Pico Engine 1.0 compatibility, automated bootstrap, centralized notifications, and a Docker-based integration test harness. Once the platform was solid, the old temperature-network had an obvious new home inside Manifold's community framework, so I rewrote it too as an example of how Manifold can be a framework for pico networks.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CBtu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CBtu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png 424w, https://substackcdn.com/image/fetch/$s_!CBtu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png 848w, https://substackcdn.com/image/fetch/$s_!CBtu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png 1272w, https://substackcdn.com/image/fetch/$s_!CBtu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CBtu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png" width="1143" height="778" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/825f10f3-7883-4e35-92be-e0957e063510_1143x778.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:778,&quot;width&quot;:1143,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Sensor network on Manifold: communities and sensor things subscribed to the Manifold pico&quot;,&quot;title&quot;:&quot;Sensor network on Manifold: communities and sensor things subscribed to the Manifold pico&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="Sensor network on Manifold: communities and sensor things subscribed to the Manifold pico" title="Sensor network on Manifold: communities and sensor things subscribed to the Manifold pico" srcset="https://substackcdn.com/image/fetch/$s_!CBtu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png 424w, https://substackcdn.com/image/fetch/$s_!CBtu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png 848w, https://substackcdn.com/image/fetch/$s_!CBtu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png 1272w, https://substackcdn.com/image/fetch/$s_!CBtu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F825f10f3-7883-4e35-92be-e0957e063510_1143x778.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When I wrote about the <a href="https://www.windley.com/archives/2026/04/building_a_conversational_interface_for_manifold_with_mcp_and_picos.shtml">BYU capstone project that built a conversational interface for Manifold</a>, I glossed over something that had to happen first: the platform itself needed to be in shape before students could build a natural language layer on top of it. There were still some loose ends that needed to be cleaned up. That work is now complete, and I am releasing it as <a href="https://github.com/Picolab/manifold-api">manifold-api</a> on GitHub.</p><p>This update is the culmination of a pattern I have been refining across several projects. <a href="https://www.windley.com/tags/fuse">Fuse</a>, the connected-car application I built years ago, organized its picos into communities that we called <em>fleets</em>. The <a href="https://www.windley.com/archives/2023/03/monitoring_temperatures_in_a_remote_pump_house_using_lorawan.shtml">temperature-network that monitors my pump house</a> did the same thing with sensor devices and location groups. Manifold itself is built around that pattern. But each of these systems managed its own notifications, maintained its own pico hierarchy, and reinvented the same community lifecycle logic. The insight behind this update is that the community-of-picos pattern is general enough to be a framework; the domain-specific parts can be layered on top of the basic community logic. By giving Manifold&#8217;s community pico a delegation interface and centralizing notifications on the Manifold pico, any domain repo can build its network of picos on a stable platform without duplicating the plumbing.</p><p>The biggest architectural change in this update is the notification platform. Previously, domain-specific rulesets called Twilio or Prowl directly. Each network managed its own credentials and delivery logic, which meant the same plumbing was duplicated across repos. The new approach centralizes everything on the Manifold pico: any <code>thing</code> or <code>community</code> can raise a <code>manifold:add_notification</code> event with a subject, message, and identifying attributes, and Manifold handles the fan-out to whichever channels are enabled for that pico (inbox, SMS via Twilio, push via Prowl). Notification channels are opt-in per subject, so a sensor community can enable SMS alerts without every other pico in the network generating noise. This is a cleaner separation of concerns, and it means domain repos no longer need to know anything about how the owner gets notified.</p><p>The other major addition is automated bootstrap. The old manual three-step initialization&#8212;create tag registry, create owner pico, register tag server&#8212;is now handled by a single bootstrap ruleset installed on the root pico. In practice this means spinning up a fresh Manifold instance goes from a sequence of API calls that had to be executed in the right order to a single ruleset install. The test harness depends on this; it would not be practical to run a clean Docker container for every test run if setup were manual.</p><h2><strong>Testing Against a Real Engine</strong></h2><p>The <a href="https://github.com/Picolab/manifold-api/blob/main/t/README.md">test harness in </a><code>manifold-api</code> is a TypeScript NPM package that spins up a standard pico-engine in Docker, mounts the repo&#8217;s KRL files directly, runs bootstrap and lifecycle scenarios, then tears the container down. Because the engine mounts the KRL as <code>file://</code> URLs, you can edit a ruleset and re-run without rebuilding the image; the iteration loop is fast. The <code>npm test</code> command runs the full suite: KRL syntax parse gate, Docker startup, bootstrap (tag registry, owner, Manifold pico), and thing/community create/add/remove/delete flows. The current scenarios give you a regression baseline before touching any of the core rulesets.</p><h2><strong>Sensor Network Moves Inside Manifold</strong></h2><p>Once the platform was solid, I looked at my old temperature-network repo&#8212;the one behind the <a href="https://www.windley.com/archives/2023/03/monitoring_temperatures_in_a_remote_pump_house_using_lorawan.shtml">Dragino LoRaWAN sensor network I put in place at a remote pump house</a>&#8212;and saw an obvious refactoring opportunity. The original approach managed its own pico hierarchy independently of Manifold. That is no longer true. The new <a href="https://github.com/windley/sensor-network">sensor-network</a> repo replaces temperature-network entirely, rewriting all its rulesets to treat sensor communities and devices as ordinary Manifold <code>community</code> and <code>thing</code> picos.</p><p>The design is a clean layering. Manifold handles the pico hierarchy, subscription management, thing and community lifecycle, and notifications. The sensor network adds sensor-specific behavior on top. Installing <code>io.picolabs.sensor.network_bootstrap</code> on the Manifold pico is the only requirement to get started. From there, raising a <code>sensor:create_community</code> event delegates to Manifold&#8217;s generic community machinery to create a sensor network community pico.</p><p>To create a new sensor, raising the <code>sensor:initiation</code> event on a community&#8217;s sensor channel delegates to Manifold&#8217;s thing creation with a callback. The community receives <code>community:thing_created</code> and finishes sensor-specific setup, installing the appropriate router ruleset for the sensor type, setting up threshold monitoring, and enabling the requested notification channels. Threshold alerts are routed using <code>manifold:add_notification</code> rather than calling Twilio or Prowl directly. The sensor-network rulesets do not know the details of how the owner gets notified.</p><p>Supported hardware today is Dragino LoRaWAN sensors: LHT65 (temperature/humidity), LSE01 (soil), LSN50 (multi-purpose), and WL03A-LB (water leak). Each sensor type gets a router ruleset that decodes payloads and raises <code>sensor</code> domain events. Adding a new sensor type requires registering it in <code>io.picolabs.sensor.community</code> and providing a router ruleset&#8212;the rest of the stack does not change.</p><h2><strong>Shared Test Infrastructure</strong></h2><p>The sensor-network test harness reuses<code> manifold-api</code>&#8216;s infrastructure directly via <code>dependsOn</code>. When <code>npm test</code> runs in the sensor-network repo, it mounts both repos into a single pico-engine Docker container: <code>manifold-api</code> provides the platform rulesets, <code>sensor-network</code> provides the sensor-specific ones. The test suite bootstraps a full Manifold installation, creates a sensor community, initiates sensors for LHT65, LSE01, and LSN50, and tears everything down. Because the platform and the domain layer share a test container, integration failures between them surface immediately rather than waiting for production. A stable Manifold API means <code>sensor-network</code>&#8216;s tests can focus on sensor behavior instead of re-testing platform primitives.</p><h2><strong>Future Work</strong></h2><p>Three areas are on the near-term roadmap. The first is bringing over the Personal Data Store (PDS) ruleset from <a href="https://www.windley.com/tags/fuse">Fuse</a> and updating it for the Manifold model. The original PDS was more than a profile; it was a structured data contract for every pico, organizing state into a profile slice, a namespaced elements store for app and domain data, and a per-ruleset settings store. Apps wrote their configuration data using PDS events rather than touching entity vars directly, which meant the PDS owned the data and could enforce schemas, react to changes, and clean up on uninstall. The shared schema part is what made this useful: when a ruleset declared its data shape through the PDS, other rulesets and the platform could discover what that pico knew how to do and what data it held without hard-coding assumptions about what was installed where.</p><p>Right now Manifold has none of that. Profile and configuration data is scattered: wrangler stores a pico name in <code>myself()</code>, the Manifold pico stores names in its thing and community registries, and individual rulesets like SafeAndMine maintain their own contact info. Each domain repo works around the absence of a shared data contract by stitching together entity vars and event attributes on its own. A proper PDS ruleset installed on every pico would replace that sprawl with a single queryable API, give sensor-network a reliable way to describe its things, and, more importantly, give any future domain repo a foundation it can build on without reinventing storage conventions from scratch.</p><p>The second item is a <a href="https://www.home-assistant.io/">Home Assistant</a> integration. I have been running Home Assistant alongside this sensor network and the obvious next step is an API layer that lets Home Assistant read sensor state and trigger automations based on it. Home Assistant has a well-documented REST API model, and the Manifold thing and community queries map cleanly onto it; it is more a matter of building the bridge than solving a hard architectural problem. Longer term, I think we could recreate much of what the original Manifold web app provided&#8212;dashboards, thing management, notification configuration&#8212;directly inside Home Assistant, which already has a capable UI and a large ecosystem of integrations.</p><p>Further out, Manifold needs to support multi-tenancy and proper authentication. The current model assumes a single owner per engine instance, which works fine for a personal deployment but limits how broadly Manifold can be used. Proper authentication and richer authorization&#8212;controlling who can raise events and query state on which picos&#8212;is the deeper requirement. That is not something Manifold can solve on its own; it requires support from the pico engine itself. The engine would need to enforce identity and access control at the channel level before Manifold could reliably build multi-tenant behavior on top of it.</p><p>The pattern here&#8212;a domain repo that treats Manifold as a dependency and shares its test infrastructure&#8212;is intentional. Any pico-based application that needs communities, notifications, and thing management should be able to build on <code>manifold-api</code> without forking its bootstrap logic or reimplementing its notification plumbing. The goal is to make Manifold a framework that domain repos build on, not a collection of utilities that each repo copies. These two repos are the first concrete demonstration of that working end-to-end.</p><div><hr></div><p>Photo Credit: <a href="https://www.windley.com/archives/2026/06/sensor_network.png">Sensor network on Manifold</a> from the sensor-network repository documentation (public domain)</p>]]></content:encoded></item><item><title><![CDATA[AI Integration in Picos Starts with Events]]></title><description><![CDATA[Summary: Picos already have persistent identity, owned state, and an event-driven architecture&#8212;exactly the properties that make a good substrate for AI agents.]]></description><link>https://www.technometria.com/p/ai-integration-in-picos-starts-with</link><guid isPermaLink="false">https://www.technometria.com/p/ai-integration-in-picos-starts-with</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Tue, 02 Jun 2026 15:31:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!GdzM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GdzM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GdzM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!GdzM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!GdzM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!GdzM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GdzM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2077545,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200311372?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GdzM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!GdzM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!GdzM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!GdzM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca26f7e8-3f9f-457f-bf60-fd3711bcb63b_1672x941.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Summary</strong>:  <em>Picos already have persistent identity, owned state, and an event-driven architecture&#8212;exactly the properties that make a good substrate for AI agents. The integration path starts with a simple webhook and leads somewhere much more interesting: a world where AI works for you, reasoning over data that is stored in your picos rather than on someone else&#8217;s platform.</em></p><p>When I think about integrating AI into <a href="https://picolabs.atlassian.net/wiki/spaces/docs/overview">pico-based systems</a>, the temptation is to imagine some deep architectural rework&#8212;a new runtime, a new protocol, some fundamental change to how rulesets execute. But I think the right starting point is already there in the architecture: <a href="https://www.windley.com/archives/2015/11/reactive_programming_with_picos.shtml">events</a>. Picos already send and receive events. Claude routines already listen for triggers and respond with actions. Connecting them is not a research problem; it is an integration problem, and a shallow one at that.</p><p>The simplest version looks like this: a pico fires an event, a Claude routine receives it via webhook, does some reasoning, and posts a response event back to the pico&#8217;s event channel. The pico&#8217;s ruleset handles the response the same way it handles any other event: routing it, acting on it, updating state. Nothing in this picture requires changes to the pico engine or the Claude API. Both sides speak events; the webhook is just the seam between them.</p><p>I saw this pattern clearly when I was building Fuse, the connected-car application built on picos. Fuse picos held the car&#8217;s data and fired events when interesting things happened: location changes, diagnostic codes, ignition on and off. The missing piece, looking back, was anything that could <em>reason</em> over those events rather than just route them. An AI routine that receives a pico event carrying a diagnostic code and responds with an interpretation&#8212;or a question&#8212;is exactly the kind of capability Fuse needed and couldn&#8217;t easily have in 2014. Fuse sent notifications, but bare notifications are not very useful to most people. An AI layer that enriches a location event with context (&#8220;you&#8217;re near the dealership where your recall service is overdue&#8221;) or translates a diagnostic code into plain language and a recommendation would have made Fuse dramatically more useful to drivers.</p><p>Project Neck Pain showed something similar from a different angle. That project used picos to hold personal health data: appointments, sensor readings, notes. The pico owned the data; it didn&#8217;t live in some third-party health app&#8217;s database. But ownership without intelligence is just storage. The interesting question was always: what should happen next? We built rules that would automate some of the drudgery of dealing with the healthcare system. But, it proved to be too brittle. AI changes that completely. An AI routine that receives an event&#8212;a symptom log, a missed appointment, a change in a sensor trend&#8212;and responds with an inference is not replacing the pico&#8217;s role. It is extending it. The pico remains the locus of identity and state; the AI contributes reasoning that the ruleset alone can&#8217;t do.</p><p>This suggests a natural progression for AI integration in pico systems.</p><ol><li><p>The first step is the webhook pattern I described: AI as an external actor that exchanges events with the pico. This just uses the <code>http:post()</code> to call a URL.</p></li><li><p>The second step is tighter: rather than an external routine, a KRL action sends a request to Claude with a callback event URL, and a separate rule handles the response when it arrives asynchronously. This fits how picos actually work&#8212;rules fire in response to events, and Claude&#8217;s processing times make a synchronous call inside a rule impractical. The callback event is the right model; Claude becomes a capability the ruleset can invoke, not a separate system to coordinate with by hand.</p></li><li><p>The third step is the one I find most architecturally interesting. At this stage, Claude uses pico query endpoints as tools to read and write persistent state across sessions. The pico <em>is</em> the memory. This matters because most AI memory schemes are ad hoc, using a database or even a Markdown file for memory. Picos already have the right structure: they are named, persistent, and owned by a specific identity.</p></li><li><p>The fourth step follows from the third. If Claude holds a longer-running task and the pico holds the relevant state, then Claude can fire events into the pico graph to make things happen&#8212;not just to return data to the ruleset, but to orchestrate behavior using the pico&#8217;s event channels the way a person would. </p></li></ol><p>What makes this progression coherent is that picos already have the properties that make for an interesting AI integration.</p><ul><li><p>They have persistent identity&#8212;each pico is a specific thing with a stable address.</p></li><li><p>They have owned state&#8212;the data inside a pico belongs to the pico, not to a platform that might revoke access or change terms.</p></li><li><p>And they are event-driven&#8212;which is exactly the interface AI systems are designed to plug into. </p></li></ul><p>I&#8217;ve argued for years that picos are the right substrate for building systems where people and things control their own data. Adding AI reasoning to that substrate doesn&#8217;t change the argument; it strengthens it. An AI that reasons on your behalf, over your data, stored in your picos, is a fundamentally different thing from an AI that reasons on your behalf using data held by someone else. The first is an agent working for you. The second is an administrative intermediary with a language model grafted on.</p><p>Picos form natural hierarchies. A car pico holds what the car knows; the household pico that owns it can query across all its children&#8212;car, health devices, calendar&#8212;and give an AI a cross-domain view that no flat memory store provides naturally. Each pico in the hierarchy can have its own AI context and reasoning scope, and parent picos can aggregate across children. That hierarchy also encodes privacy boundaries: an AI reasoning on behalf of the household can traverse the graph with appropriate permissions, but no external system can simply reach in. The ownership structure is not metadata bolted on; it is the architecture.</p><p>The webhook integration is worth building right now because it establishes the semantics that the deeper integrations depend on. Which events are meaningful enough to route to an AI? What does a useful response event look like? How does the ruleset act on it? Answering those questions with a simple prototype clarifies the architecture far better than designing it on paper. That is how picos got to where they are today, through real use cases that forced the design into focus. The AI integration will be no different.</p><div><hr></div><p>Photo Credit: Owned AI Agents via Picos from DALL-E (public domain)</p>]]></content:encoded></item><item><title><![CDATA[Internet Identity Workshop XLII Report]]></title><description><![CDATA[Summary: IIW XLII brought 287 people to the Computer History Museum in Mountain View for three days of sessions on identity, agents, and the legal and technical foundations of first person digital life.]]></description><link>https://www.technometria.com/p/internet-identity-workshop-xlii-report</link><guid isPermaLink="false">https://www.technometria.com/p/internet-identity-workshop-xlii-report</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Mon, 01 Jun 2026 16:26:37 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!G454!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><strong>Summary:</strong> IIW XLII brought 287 people to the Computer History Museum in Mountain View for three days of sessions on identity, agents, and the legal and technical foundations of first person digital life. The agenda reflected a community grappling with real deployment challenges: SEDI and duty of loyalty, agentic identity, MyTerms, post-quantum cryptography, and the EUDI wallet. AIW2 followed on Friday, continuing the agentic internet conversation.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!G454!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!G454!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png 424w, https://substackcdn.com/image/fetch/$s_!G454!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png 848w, https://substackcdn.com/image/fetch/$s_!G454!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png 1272w, https://substackcdn.com/image/fetch/$s_!G454!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!G454!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png" width="1456" height="713" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:713,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1012764,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200143305?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!G454!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png 424w, https://substackcdn.com/image/fetch/$s_!G454!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png 848w, https://substackcdn.com/image/fetch/$s_!G454!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png 1272w, https://substackcdn.com/image/fetch/$s_!G454!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f464b8c-77a4-49bb-80a0-e8f732da14cd_1696x830.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The Internet Identity Workshop met for the 42nd time at the Computer History Museum in Mountain View, California, April 28&#8211;30, 2026. As always, the <a href="https://en.wikipedia.org/wiki/Open_space_technology">Open Space unconference format</a> let the agenda emerge from the people in the room. And, as always, the room delivered. Over three days and fifteen slots, participants convened 158 sessions spanning identity architecture, agentic systems, legal frameworks, cryptographic foundations, and the human stakes that tie all of it together.</p><p>We also held the second Agentic Internet Workshop (AIW2) on Friday, May 1, immediately following IIW. Like the first AIW last October, it used the same unconference format, this time with a sharper focus on how identity infrastructure supports autonomous agents operating on behalf of people.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y_X8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y_X8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png 424w, https://substackcdn.com/image/fetch/$s_!Y_X8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png 848w, https://substackcdn.com/image/fetch/$s_!Y_X8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png 1272w, https://substackcdn.com/image/fetch/$s_!Y_X8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y_X8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png" width="800" height="292" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:292,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:456860,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200143305?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Y_X8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png 424w, https://substackcdn.com/image/fetch/$s_!Y_X8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png 848w, https://substackcdn.com/image/fetch/$s_!Y_X8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png 1272w, https://substackcdn.com/image/fetch/$s_!Y_X8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb10a79f9-1f2e-4953-8bb6-d3a4d7b6679e_800x292.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Attendance</strong></h2><p>IIW 42 brought together 287 participants, matching last fall&#8217;s IIW 41 exactly. That consistency is worth noting. There are lots of identity conferences now and the hype cycle pulls attention in every direction, but the identity community keeps showing up. The number reflects sustained interest in solving real problems. Because that&#8217;s what IIW offers: space to solve problems. It&#8217;s a workshop in thr true sense of the word.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yJ-I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yJ-I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png 424w, https://substackcdn.com/image/fetch/$s_!yJ-I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png 848w, https://substackcdn.com/image/fetch/$s_!yJ-I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png 1272w, https://substackcdn.com/image/fetch/$s_!yJ-I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yJ-I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png" width="799" height="516" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:516,&quot;width&quot;:799,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:663251,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200143305?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yJ-I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png 424w, https://substackcdn.com/image/fetch/$s_!yJ-I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png 848w, https://substackcdn.com/image/fetch/$s_!yJ-I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png 1272w, https://substackcdn.com/image/fetch/$s_!yJ-I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c589cfa-9c7a-44b0-be37-8014fda92b5e_799x516.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The hallway track was as rich as always. Some of the best conversations at IIW happen between sessions, at lunch, or during the demo hour, where people pull out laptops and show working code rather than slides. One of the reasons that meals are included at IIW is to keep the energy high and the conversations flowing.</p><h2><strong>Geographic Diversity</strong></h2><p>The geographic picture at IIW 42 was familiar in its broad strokes. The United States accounted for 229 of 287 attendees, with California leading the way at 119. San Francisco (19), San Jose (14), and Oakland (8) anchored the Bay Area contingent, while Seattle (7) and Los Angeles (7) rounded out the West Coast presence. Utah contributed 14 attendees, Texas 12, and Massachusetts 12, reflecting the distributed geography of the identity community within the U.S.</p><p>Internationally, Japan continued its strong showing with 12 attendees, primarily from Tokyo (9). The United Kingdom sent 7, Canada 5, Switzerland 4 (all from Zurich), Poland 3, and Germany 3. We saw participation from South Korea and several other countries as well. The attendee map tells the story visually: clusters in North America and Europe, with welcome pins in Asia, South America, Africa, and Australia.</p><p>I am glad to see the map filling in beyond the usual corridors, but there is still work to do. Identity challenges are global, and the solutions we build at IIW benefit from hearing voices that face different regulatory environments, infrastructure constraints, and cultural expectations. We continue to support IIW-Inspired<sup>TM</sup> regional events like <a href="https://didunconf.africa/">DID:UNCONF Africa</a> and <a href="https://diceidentity.org/">DICE</a> to extend the conversation. If you know identity builders in underrepresented regions, point them our way.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0cbG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0cbG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png 424w, https://substackcdn.com/image/fetch/$s_!0cbG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png 848w, https://substackcdn.com/image/fetch/$s_!0cbG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png 1272w, https://substackcdn.com/image/fetch/$s_!0cbG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!0cbG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png" width="799" height="533" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:533,&quot;width&quot;:799,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:704449,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200143305?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0cbG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png 424w, https://substackcdn.com/image/fetch/$s_!0cbG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png 848w, https://substackcdn.com/image/fetch/$s_!0cbG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png 1272w, https://substackcdn.com/image/fetch/$s_!0cbG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2258f9ec-76dd-4447-ac65-638ed55d9076_799x533.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>One concrete way to help is through the IIW Global Participation Scholarship, which funds travel and registration for attendees from regions that are underrepresented. The scholarship makes a real difference; it brings perspectives into the room that change the quality of the conversation for everyone. If your organization benefits from the work that comes out of IIW, consider <a href="https://www.windley.com/contact.shtml">sponsoring a scholarship</a> for IIW 43. The identity infrastructure we are building is meant to serve people everywhere; the people building it should reflect that.</p><h2><strong>Topics and Themes</strong></h2><p>The agenda at IIW is built fresh each morning. Participants write their session titles on index cards, announce them to the room, and place them on the agenda wall. That emergent structure is one of the things that makes IIW work; the topics reflect what people are actually building, struggling with, and thinking about right now. Here&#8217;s a recap of what the community brought to the table this time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TyuJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TyuJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png 424w, https://substackcdn.com/image/fetch/$s_!TyuJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png 848w, https://substackcdn.com/image/fetch/$s_!TyuJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png 1272w, https://substackcdn.com/image/fetch/$s_!TyuJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!TyuJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png" width="800" height="419" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:419,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:601404,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200143305?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TyuJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png 424w, https://substackcdn.com/image/fetch/$s_!TyuJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png 848w, https://substackcdn.com/image/fetch/$s_!TyuJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png 1272w, https://substackcdn.com/image/fetch/$s_!TyuJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F420ca939-ee0a-4530-8aa9-cc1792f87cbd_800x419.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>SEDI and the duty of loyalty</em> were prominent throughout the workshop. Sam Smith led sessions on KERI/ACDC bulk issuance for SEDI privacy and on cryptographic foundations, while separate conversations explored SEDI&#8217;s legal framework, its duty of loyalty provision, and how it connects to protocols like MyTerms. As I wrote in Data Protection Missed the Point; Loyalty Gets It Right, the duty of loyalty shifts the basis for regulation from data to the relationship. That idea had real traction in the room, with people working through what it means for implementation, not just theory.</p><p><em>Agentic identity</em> was everywhere. Sessions covered agent taxonomy (what counts as an agent? ephemeral versus persistent?), OAuth for sub-agents, AI agents and open banking, agent storyboarding, and agentic identity credentials. Drummond Reed introduced the Decentralized Trust Graph and First Person Project. Dick Hardt led an AAuth deep dive, exploring his open protocol that gives agents their own cryptographic identity without pre-registration or shared secrets. The question running through all of these was not whether agents need identity; it was how we build identity systems that let agents act on behalf of people without becoming another layer of administrative intermediation. A Dilithium demo showed server-side user-agents operating at speed, and multiple sessions explored how authorization models need to adapt when the entity presenting a credential is not a human but a piece of software acting with delegated authority.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CoAe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CoAe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png 424w, https://substackcdn.com/image/fetch/$s_!CoAe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png 848w, https://substackcdn.com/image/fetch/$s_!CoAe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png 1272w, https://substackcdn.com/image/fetch/$s_!CoAe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!CoAe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png" width="787" height="493" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:493,&quot;width&quot;:787,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:491131,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200143305?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CoAe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png 424w, https://substackcdn.com/image/fetch/$s_!CoAe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png 848w, https://substackcdn.com/image/fetch/$s_!CoAe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png 1272w, https://substackcdn.com/image/fetch/$s_!CoAe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F011f42f7-6cfb-4ea7-9273-a88c856f0ae5_787x493.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>MyTerms</em>, the newly published <a href="https://myterms.info/">IEEE 7012 standard</a>, had a strong showing across all three days. Doc Searls led MyTerms 101 and 101.5 sessions, and Iain Henderson ran a session connecting VRM, MyTerms, and fiduciary agents. MyTerms gives individuals a protocol for proposing terms to websites as first parties rather than clicking through adhesion contracts. The connection to SEDI&#8217;s duty of loyalty&#8212;which I explored in a post from VRM Day&#8212;was a recurring thread. Together, they start to look like operational infrastructure for digital relationships where people have standing as participants, not just data subjects.</p><p>The standards and protocol track was robust. OpenID4VC had sessions covering updates and implementation details, including server-to-server issuance via OpenID4VCI. Aaron Parecki ran OAuth 101 and John Bradley covered FIDO and WebAuthn. The W3C Verifiable Credentials Working Group held a session on its new charter and current work. Frederik Krogsdal Jacobsen ran sessions on formal security verification of specs and on interaction endpoint authorization via first-party apps. Content authenticity also had a visible presence, with sessions on the C2PA standard and the Content Authenticity Working Group (CAWG), plus an originator profile session; as AI-generated content proliferates, provenance is becoming an identity problem whether the identity community planned for it or not. These sessions reflected a community that is past the design and implementation phases and into the details of making things work at scale.</p><p>On the cryptographic front, we saw renewed energy around:</p><ul><li><p><strong>Post-quantum readiness</strong>&#8212;a Dilithium demo and sessions on cryptographic agility showed the community taking the transition seriously, not just talking about it.</p></li><li><p><strong>Zero-knowledge proofs</strong>&#8212;ZKP 101 sessions, a ZKP age verification demo, and Sam Smith&#8217;s session on misapplications of bare signatures and ZKPs for non-ephemeral case proofs.</p></li><li><p><strong>KERI and GLEIF</strong>&#8212;Kent Bull ran KERI + did:webs 101 with GLEIF, connecting decentralized key management to real-world organizational identity at scale.</p></li></ul><p><em>Trust infrastructure</em> surfaced as a theme in its own right. Erica Bjune led a two-part session on trust infrastructure as a public utility. Mike Leahy convened the first Fiduciary Commons session, working from first principles toward law. Joe Andrieu provided a digital fiduciary update. These conversations share a premise: that trust is not just a technical property of a protocol; it is a social and institutional arrangement that needs its own infrastructure. That framing resonates with the broader shift from building identity tools to building identity institutions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!o6ve!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!o6ve!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png 424w, https://substackcdn.com/image/fetch/$s_!o6ve!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png 848w, https://substackcdn.com/image/fetch/$s_!o6ve!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png 1272w, https://substackcdn.com/image/fetch/$s_!o6ve!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!o6ve!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png" width="799" height="533" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:533,&quot;width&quot;:799,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:440654,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200143305?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!o6ve!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png 424w, https://substackcdn.com/image/fetch/$s_!o6ve!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png 848w, https://substackcdn.com/image/fetch/$s_!o6ve!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png 1272w, https://substackcdn.com/image/fetch/$s_!o6ve!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb7f8c03-9f35-466d-b077-feb8e7a28cd3_799x533.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The <em>EUDI wallet</em> drew attention with sessions on the German implementation and on wallet-level authentication and authorization. These sessions brought a European regulatory perspective into the room, grounding abstract wallet discussions in the specifics of what member states are actually building.</p><p>There were also sessions looking at identity at a more foundational level. Christopher Allen revisited SSI principles for the next decade in his &#8220;SSI 10th!&#8221; session. Denny Wong asked why personal identity matters in the era of AI. Eric Welton explored cognitive liberty and captive audiences through a First Amendment lens. Dean Saxe and Eve Maler convened a session on death and the digital estate, something that eventually concerns us all. And Wendy Seltzer led a session on identity and geopolitics, reminding us that the infrastructure we build operates within political systems that have their own ideas about who controls identity, a good counterpoint to the SEDI discussions.</p><p>The <em>101 sessions</em> deserve a mention. IIW has always been a place where newcomers can get grounded, and this time the program included introductions to OAuth, OpenID Connect, FIDO/WebAuthn, ZKPs, SSI, OpenID4VC, authorization, and content authenticity. Steve McCown and Omri Gazitt ran particularly well-attended sessions. These 101 tracks are not filler; they are how the community renews itself and ensures that the deep-dive sessions in later slots have a prepared audience.</p><h2><strong>Demo Hour</strong></h2><p>One of IIW&#8217;s distinctive features is the speed demo hour on Wednesday afternoon. Twenty tables, each with a numbered sign, fill the Grand Hall. Each demonstrator gives a five-minute demo, then the audience rotates to the next table. If you&#8217;re disciplined, you can see 10 of the 20 demos over the course of an hour. It is loud and seemingly chaotic, but it works. Demo hour is about working code and running systems. You can tell a lot about a community by what it chooses to demo.</p><p>This time, the demo tables told a clear story: agents have arrived, and the identity community is building the infrastructure to make them trustworthy. Niki Niyikiza showed Tenuo&#8217;s attenuating authorization tokens that cryptographically narrow an agent&#8217;s capabilities at each delegation hop. Dick Hardt demoed AAuth, an open protocol giving agents their own cryptographic identity without pre-registration or shared secrets. Kenta Takahashi and Takayuki Suzuki demonstrated Proof of Human Delegation, using biometrics to prove that an agent acts on behalf of a specific person within their stated intent. Ankit Agarwal showed KYAPay, a protocol for agent authentication and tokenized payments. And Alex Olivier and Atul Tulshibagwale demoed a reference implementation of the OpenID AuthZEN MCP Profile for fine-grained, parameter-level authorization before an MCP server executes a tool. The common thread: agents need identity, authorization, and accountability, and those cannot be afterthoughts bolted on later.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IcnI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IcnI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png 424w, https://substackcdn.com/image/fetch/$s_!IcnI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png 848w, https://substackcdn.com/image/fetch/$s_!IcnI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png 1272w, https://substackcdn.com/image/fetch/$s_!IcnI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!IcnI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png" width="800" height="357" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:357,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:456467,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200143305?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IcnI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png 424w, https://substackcdn.com/image/fetch/$s_!IcnI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png 848w, https://substackcdn.com/image/fetch/$s_!IcnI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png 1272w, https://substackcdn.com/image/fetch/$s_!IcnI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce11259e-0b90-4ba8-87c5-930ca9fc7823_800x357.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Wallets and credentials showed up in force. Rob De Feo showed an AI agent completing an age-verified purchase and hiring a car through the EUDI Wallet via OpenID4VP. Jarek Sygitowicz and Flora Frend demonstrated practical EUDI implementations using the Digital Credentials API on iOS and Android with fallback to legacy eIDs. Dmitri Zagidulin showed Freewallet, a free, open-source web wallet for DIDs and verifiable credentials. Christopher Allen demoed XIDs, DID-inspired identifiers built on Gordian Envelope that give holders, rather than issuers, control over what gets revealed through selective disclosure and redaction.</p><p>Several demos pushed into new territory. Iain Henderson and Jon Udell showed MyKey combined with MyTerms and XMLUI, connecting decentralized identifiers to privacy terms and a semantic UI framework. David Condrey&#8217;s WritersProof captured cryptographic proof of human authorship by entangling identity, keystrokes, and timing into an unforgeable hash chain. Mahesh Balan showed MyWellWallet, a patient-owned health wallet using local LLMs and FHIR to give people an intelligent view of their health data without sending it to the cloud. And Deb Bucci demoed an execution-time delegation harness that evaluates whether a delegated action still aligns with a person&#8217;s intent at the moment it is requested. Twenty tables, twenty teams showing things that did not exist a year ago.</p><h2><strong>Looking Ahead</strong></h2><p>Because IIW runs on Open Space, every workshop is a fresh expression of where the community actually is. No program committee selects topics months in advance; the people who show up decide what matters that morning. That is what makes each IIW genuinely new. The topics at IIW 42 reflected a community whose conversations were less about whether the architecture is right and more about how to deploy it, govern it, and make it work for people who will not attend an unconference. SEDI&#8217;s duty of loyalty, MyTerms, agentic identity, post-quantum readiness, the EUDI wallet: these are implementation challenges now, not research topics. The people in the room are doing the implementation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lkTp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lkTp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png 424w, https://substackcdn.com/image/fetch/$s_!lkTp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png 848w, https://substackcdn.com/image/fetch/$s_!lkTp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png 1272w, https://substackcdn.com/image/fetch/$s_!lkTp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!lkTp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png" width="799" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:799,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:537001,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/200143305?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lkTp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png 424w, https://substackcdn.com/image/fetch/$s_!lkTp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png 848w, https://substackcdn.com/image/fetch/$s_!lkTp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png 1272w, https://substackcdn.com/image/fetch/$s_!lkTp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53e32ccc-fb3c-41ea-9d44-e9f8de46680b_799x400.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Huge thanks to everyone who convened a session, asked a hard question, showed a demo, or pulled someone into a hallway conversation. That is what makes IIW work, and it has been working for 42 editions now. The <a href="https://internetidentityworkshop.com/past-workshops/">book of proceedings</a> will be available soon with session notes, links, and other important details.</p><p>Mark your calendars: <a href="https://internetidentityworkshop.com/">IIW 43</a> is November 3&#8211;5, 2026, with AIW3 on Friday, November 6. Tickets will be on sale in about a month. <a href="https://www.windley.com/contact.shtml">Sponsorships are available now</a>. Until then, keep building.</p><p>You can check out all of Doc&#8217;s photos of IIW 42 for a visual report on who, what and when.</p><div><hr></div><p>Photo Credit: <a href="https://www.flickr.com/photos/docsearls/albums/72177720333700061/">IIW XLII Photos</a> from Doc Searls (CC BY 4.0)</p>]]></content:encoded></item><item><title><![CDATA[Enhance, Duplicate, or Replace? None of the Above.]]></title><description><![CDATA[Summary: Alan Mayo frames the digital identity design choice as enhance, duplicate, or replace, and places Utah&#8217;s SEDI in the &#8220;replace&#8221; bucket alongside purist decentralized identity.]]></description><link>https://www.technometria.com/p/enhance-duplicate-or-replace-none</link><guid isPermaLink="false">https://www.technometria.com/p/enhance-duplicate-or-replace-none</guid><dc:creator><![CDATA[Phil Windley]]></dc:creator><pubDate>Wed, 20 May 2026 14:03:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!OWWl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Summary</strong>: <em>Alan Mayo frames the digital identity design choice as enhance, duplicate, or replace, and places Utah&#8217;s SEDI in the &#8220;replace&#8221; bucket alongside purist decentralized identity. That badly misreads the architecture and the policy goal. SEDI is not trying to eliminate institutional trust; it is state-endorsed, rights-first digital identity reuse that keeps institutional authority where it belongs while moving presentation and consent closer to the individual.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OWWl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OWWl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic 424w, https://substackcdn.com/image/fetch/$s_!OWWl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic 848w, https://substackcdn.com/image/fetch/$s_!OWWl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic 1272w, https://substackcdn.com/image/fetch/$s_!OWWl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OWWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65139,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.technometria.com/i/198488789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OWWl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic 424w, https://substackcdn.com/image/fetch/$s_!OWWl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic 848w, https://substackcdn.com/image/fetch/$s_!OWWl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic 1272w, https://substackcdn.com/image/fetch/$s_!OWWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F625a04ca-fe71-43ea-b25f-755bd89df5ae_1672x941.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Alan Mayo&#8217;s latest <a href="https://www.newsletters.identity25.com/p/26-enhance-duplicate-or-replace">Identity 2.5 newsletter</a> poses a useful strategic question: when we build digital identity reuse, are we enhancing existing infrastructure, duplicating it, or replacing it? He maps three approaches onto those choices: networked identity <em>enhances</em>, credential/wallet identity <em>duplicates</em>, and decentralized identity <em>replaces</em>. He then places Utah&#8217;s <a href="https://le.utah.gov/~2025/bills/static/SB0039.html">State-Endorsed Digital Identity (SEDI)</a> squarely in the third category and concludes that networked identity is the obvious, lowest-risk path forward. The framework is a good lens. But his classification of SEDI is <em>wrong</em>.</p><h2><strong>What Mayo Gets Right</strong></h2><p>Mayo is right that societies already have digital identity. Government agencies, banks, and healthcare systems hold digital records of who we are; what they issue to us are physical documents and credentials that allow a basic form of identity reuse. The strategic question is not whether to create digital identity but how to let people reuse it effectively. That reframing is valuable because it cuts through a lot of the hype that treats digital identity as something we still need to invent.</p><p>He is also right that wallet-based credentials introduce real operational complexity. Lifecycle management, revocation, device binding, recovery, verifier trust, wallet trust, and credential freshness all matter. His critique of naive &#8220;just put credentials in a wallet&#8221; thinking is fair; a high-assurance identity ecosystem cannot rely on static credentials floating around indefinitely. Utah&#8217;s own <a href="https://dld.utah.gov/utah-mdl/">mobile driver&#8217;s license work</a> already recognizes these problems by emphasizing consent, selective disclosure, anti-tracking, and state-signed credentials under individual control.</p><p>And he is right that institutional trust does not disappear. SEDI still needs authoritative issuers, governance, endorsement rules, certification, relying-party accountability, revocation, and legal frameworks. Even the <a href="https://www.aclu.org/news/privacy-technology/utah-digital-id-law">ACLU&#8217;s analysis</a> of Utah&#8217;s legislation praises it as a legal and governance framework with important privacy protections, not as magic cryptography that makes institutions irrelevant. None of that goes away in a world with digital credentials. The question is how institutional trust gets expressed and who controls the presentation.</p><h2><strong>Where the Framework Breaks</strong></h2><p>Mayo&#8217;s big mistake is classifying SEDI as &#8220;Decentralized Identity&#8221; in the purist replacement sense. He characterizes that category as individual-held identity, cryptographic security, self-sovereignty, and no central control. That badly misrepresents <a href="https://www.windley.com/archives/2025/04/first_person_identity.shtml">first person identity</a> in general and SEDI&#8217;s architecture in particular. SEDI is not trying to eliminate institutional trust or replace government identity infrastructure. It is a state-endorsed legal and governance framework for digital credentials. The state still verifies, endorses, regulates, and defines duties for participants. That is not anti-institutional decentralization; it is <em>public trust infrastructure with individual control over consent, disclosure, and the terms of the relationship</em>.</p><p>He also conflates credential identity and decentralized identity in a way that obscures what SEDI actually does. SEDI is closer to a hybrid: credential-based presentation with state endorsement, <a href="https://www.windley.com/archives/2026/04/data_protection_missed_the_point_loyalty_gets_it_right.shtml">legal duties</a>, privacy protections, and governance. It is not simply duplicating current identity infrastructure into wallets, and it is not replacing identity infrastructure with cryptographic self-sovereignty. It sits outside Mayo&#8217;s three-bucket taxonomy because it combines institutional authority with individual agency in ways his framework does not accommodate.</p><p>Mayo overstates the idea that credential systems make every phone wallet &#8220;a mini Identity Provider.&#8221; A wallet is never the authoritative source of identity. Even with self-issued credentials, the authority rests with the individual issuing the credential, not the container. The wallet is a presentation mechanism; the issuer remains authoritative for the claims it signs. The hard problems of binding, revocation, and recovery are real, but they do not turn the wallet into a source of truth. They turn it into a presentation layer, one the individual controls rather than the institution.</p><p>He also misses SEDI&#8217;s most important innovation, and it is not a technical one. SEDI&#8217;s distinguishing move is <em>law before technology</em>. The point is not that new cryptographic techniques will solve identity. The point is that digital identity needs constitutional principles, fiduciary-like duties, voluntary adoption, non-tracking rules, selective disclosure, and enforceable accountability. As I wrote in <a href="https://www.windley.com/archives/2026/03/a_legal_identity_foundation_isnt_optional.shtml">A Legal Identity Foundation Isn&#8217;t Optional</a>, SEDI provides a legal base layer for <a href="https://www.windley.com/archives/2025/04/first_person_identity.shtml">first person</a> digital trust. The ACLU did not praise Utah&#8217;s legislation because of its cryptographic architecture; they praised it because it adds civil-liberties protections to digital identity. The <a href="https://www.windley.com/archives/2026/04/myterms_and_sedis_duty_of_loyalty.shtml">duty of loyalty provision</a> places a fiduciary obligation on institutions that rely on a state-endorsed digital identity. That is a governance innovation, not a technology choice.</p><h2><strong>Networked Identity Is Not the Obvious Answer</strong></h2><p>Mayo treats networked identity as the obviously practical path, but that model has its own structural weaknesses. A central switch creates a single point of dependency and failure. Online-only availability means the system breaks when the network does. Relying-party accreditation creates bottlenecks that limit who can participate. And a model where every identity transaction runs through a network switch creates inherent opportunities for surveillance, correlation, and gatekeeper control. SEDI is partly a response to exactly those risks.</p><p>The Scandinavian <a href="https://en.wikipedia.org/wiki/BankID_(Sweden)">BankID systems</a> that Mayo points to work well in small, high-trust societies with strong institutional foundations. They are real accomplishments. But they also concentrate identity infrastructure in banking consortiums, require online connectivity for every transaction, and give the network operator visibility into every authentication event. Those are acceptable tradeoffs in some contexts. They are not acceptable when the policy goal is individual control, minimized disclosure, and resistance to tracking.</p><p>Networked identity is also inherently national; each country&#8217;s BankID is a separate system tied to its own banking consortium. Cross-border use requires additional federation infrastructure that reintroduces much of the complexity Mayo attributes only to credential and decentralized systems. A networked model can be useful for some transactions, but it does not automatically win when the policy goals include individual control, minimal disclosure, offline capability, cross-border portability, and resistance to surveillance.</p><h2><strong>What SEDI Actually Is</strong></h2><p>None of this means SEDI is the clean best-of-all-worlds answer. It has its own hard problems: wallet ecosystem maturity, credential lifecycle management, adoption incentives, and the political challenge of getting other states and countries to recognize Utah&#8217;s framework. Mayo&#8217;s operational concerns about credential systems apply to SEDI too; they are not magically resolved by putting a legal framework around them.</p><p>But SEDI does not fit cleanly into any of Mayo&#8217;s three buckets, and that is the point. It is better described as <em>state-endorsed, rights-first digital identity reuse</em>. SEDI keeps institutional authority where it belongs: the state still verifies identity, endorses credentials, and defines legal duties for participants. It moves presentation and consent closer to the individual: the person controls what they disclose, to whom, and under what terms. And it wraps the whole system in public-law governance: constitutional principles, a duty of loyalty, voluntary adoption, and enforceable accountability.</p><p>That is not &#8220;replacing&#8221; identity infrastructure. It is not &#8220;no central control&#8221; or &#8220;all power rests with the individual.&#8221; It is an attempt to join cryptographic trust and legal trust into a public identity foundation. The state provides the endorsement and the legal framework; the individual provides the consent and controls the presentation; the technology provides the mechanism for doing both securely. As I explored in <a href="https://www.windley.com/archives/2026/02/sedi_and_client-side_identity.shtml">SEDI and Client-Side Identity</a>, this resolves a problem that has plagued digital identity since the 1990s: people will not pay for identity proofing, but they already pay their state government for it without realizing it. SEDI routes around the economic bottleneck that killed client-side certificates.</p><p>Mayo&#8217;s useful contribution is the question itself. But the answer for SEDI is <em>none of the above</em>. SEDI enhances institutional trust by giving it a legal and cryptographic expression that the individual controls. It does not duplicate infrastructure into unsupervised wallets. It does not replace institutional authority with self-sovereign cryptography. It creates a new kind of public trust infrastructure in which the institution, the individual, and the law each carry weight. Getting SEDI&#8217;s category wrong makes it easy to dismiss. Getting it right means engaging with the harder, more interesting question: <em>what does identity infrastructure look like when it starts from rights and relationships rather than from databases and documents?</em></p><div><hr></div><p>Photo Credit: SEDI: None of the Above from ChatGPT (public domain)</p>]]></content:encoded></item></channel></rss>