<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Constant Itis</title>
    <description>The latest articles on DEV Community by Constant Itis (@constant_itis).</description>
    <link>https://dev.to/constant_itis</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4005961%2F3b206993-516f-42b7-8d12-a2aa3b4c59bc.png</url>
      <title>DEV Community: Constant Itis</title>
      <link>https://dev.to/constant_itis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/constant_itis"/>
    <language>en</language>
    <item>
      <title>What Happens If You Give a Fruit Fly Brain External Memory?</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Tue, 15 Sep 2026 20:54:27 +0000</pubDate>
      <link>https://dev.to/constant_itis/what-happens-if-you-give-a-fruit-fly-brain-external-memory-1gcm</link>
      <guid>https://dev.to/constant_itis/what-happens-if-you-give-a-fruit-fly-brain-external-memory-1gcm</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9hpu5anrupjc7v2bjr9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9hpu5anrupjc7v2bjr9i.png" alt="Fly brain connected to an external persistent memory graph" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Research and its collaborators mapped the male fruit fly nervous system: roughly 166,700 neurons and 125 million synaptic connections.&lt;/p&gt;

&lt;p&gt;Then somebody wired the thing to Doom.&lt;/p&gt;

&lt;p&gt;The project is called DOOMFLY.&lt;/p&gt;

&lt;p&gt;Not a living fly. Not consciousness in a jar. The biological wiring diagram is real; the dynamics and interfaces are modeled in software.&lt;/p&gt;

&lt;p&gt;Cool experiment.&lt;/p&gt;

&lt;p&gt;But it made me wonder about something else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if you give the simulated brain an external memory that it never has to explicitly query?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because that is the part of current AI memory systems that keeps bothering me.&lt;/p&gt;

&lt;p&gt;We keep building memory like a tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;something happens
save it

something similar happens later
search for it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That works for LLM agents.&lt;/p&gt;

&lt;p&gt;But it does not feel much like memory.&lt;/p&gt;

&lt;p&gt;I do not decide to remember.&lt;/p&gt;

&lt;p&gt;A smell drops me somewhere from 20 years ago. I walk into a room and it feels familiar before I know why. Nothing in my head calls a search function.&lt;/p&gt;

&lt;p&gt;And a fly definitely isn't reading a SKILL.md file telling it when to query its memory.&lt;/p&gt;

&lt;p&gt;Strip the language away and most agents look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LLM
+
system prompt
+
tool definitions
+
SKILL.md
+
workflow
+
memory.search()
+
memory.save()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fly has none of that. It cannot read a memory. It cannot parse JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"enemy appeared"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"turned right"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outcome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"survived"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If an external memory is going to change what the fly does, it has to become part of the fly's computational state. That is a harder problem. It is also a more honest one.&lt;/p&gt;

&lt;p&gt;Here is the loop the fly already runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sensory input
     |
     v
current neural state
     |
     v
connectome dynamics
     |
     v
motor activity
     |
     v
environment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So put the memory beside it, and never let the fly call it.&lt;/p&gt;

&lt;p&gt;The memory system observes the state. When a similar state comes around again, it does not return a result. It feeds back in as modulation: some populations get easier to fire, some get harder, and the network resolves the rest.&lt;/p&gt;

&lt;p&gt;No query. No lookup. The memory just becomes relevant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This shifts the problem from retrieval to resonance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I am not going to call this consciousness. Nobody understands consciousness well enough to claim a graph database bolted to a connectome creates it.&lt;/p&gt;

&lt;p&gt;I am going to call it individuality, because individuality is the part you can actually measure. You can put a number on how much of a behavioral identity survives a brain reset.&lt;/p&gt;

&lt;p&gt;That is what this series is about.&lt;/p&gt;

&lt;p&gt;So I built a tiny version.&lt;/p&gt;

&lt;p&gt;Not the full fruit fly connectome. A small recurrent network where I could control every assumption.&lt;/p&gt;

&lt;p&gt;Then I put Mycelium beside it.&lt;/p&gt;

&lt;p&gt;One rule: &lt;strong&gt;memory can change neural state. It can never choose an action.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the memory system says "turn right," the experiment is bullshit. I have just built a bot with a fake brain attached.&lt;/p&gt;

&lt;p&gt;The memory has to do something more subtle: make certain states easier or harder to reach, then let the network produce the behavior itself.&lt;/p&gt;

&lt;p&gt;I ran it.&lt;/p&gt;

&lt;p&gt;Then I reset the brain.&lt;/p&gt;

&lt;p&gt;Then I moved the memory into a fresh one.&lt;/p&gt;

&lt;p&gt;Then I swapped memories between two otherwise identical systems.&lt;/p&gt;

&lt;p&gt;That last experiment is where this stopped being a fun memory demo for me.&lt;/p&gt;

&lt;p&gt;Part 2 is the code, the controls, and the numbers.&lt;/p&gt;

&lt;p&gt;Clone it and tell me where I'm wrong.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The connectome (Janelia / MRC LMB / Cambridge / Google Research): &lt;a href="https://research.google/blog/a-connectomics-milestone-mapping-the-complete-male-fruit-fly-brain/" rel="noopener noreferrer"&gt;research.google — a connectomics milestone&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DOOMFLY: &lt;a href="https://github.com/Ovaday/doomfly" rel="noopener noreferrer"&gt;github.com/Ovaday/doomfly&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mycelium Memory: &lt;a href="https://github.com/constant-itis/mycelium-memory" rel="noopener noreferrer"&gt;github.com/constant-itis/mycelium-memory&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>memory</category>
      <category>biomimicry</category>
      <category>neuroscience</category>
    </item>
    <item>
      <title>I Try to Kill My Ideas Before I Build Them</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Thu, 10 Sep 2026 01:19:41 +0000</pubDate>
      <link>https://dev.to/constant_itis/i-try-to-kill-my-ideas-before-i-build-them-2422</link>
      <guid>https://dev.to/constant_itis/i-try-to-kill-my-ideas-before-i-build-them-2422</guid>
      <description>&lt;p&gt;AI makes it dangerously easy to build the wrong thing. I can point agents at a problem and have a mountain of code before I have proven the idea underneath it.&lt;/p&gt;

&lt;p&gt;So before I build too much, I try to kill the idea first.&lt;/p&gt;

&lt;p&gt;Not the whole project. The claim hiding inside the decision.&lt;/p&gt;

&lt;p&gt;Most decisions are secretly a bet that something is true. Name the bet out loud and you can test it.&lt;/p&gt;

&lt;p&gt;If I think we need a bigger model, that is not just a preference. It is a claim that the failure is caused by insufficient reasoning capacity.&lt;/p&gt;

&lt;p&gt;If I believe a new retrieval technique will improve memory, I am claiming that the current method is the bottleneck.&lt;/p&gt;

&lt;p&gt;If I assume the normal installer flow should work here, I am claiming that the environment behaves like a conventional writable Linux system.&lt;/p&gt;

&lt;p&gt;Sometimes, once you check, the answer is just no.&lt;/p&gt;

&lt;h2&gt;
  
  
  The useful failures
&lt;/h2&gt;

&lt;p&gt;On ShrekOS, I assumed the standard installer approach would work. It did not, because &lt;code&gt;/etc&lt;/code&gt; is sealed and read-only, and the normal recipe quietly depends on writing there.&lt;/p&gt;

&lt;p&gt;Finding that early instead of three layers of code later saved me from an architectural mess.&lt;/p&gt;

&lt;p&gt;On Mycelium, I tested an associative-memory approach that sounded great and performed worse than what I already had. Another promising retrieval technique improved zero out of six benchmark cases.&lt;/p&gt;

&lt;p&gt;Both died there.&lt;/p&gt;

&lt;p&gt;A prototype should not just prove something works. It should give the idea a cheap, honest chance to fail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It worked when I tried it isn't proof. It's a story about something that happened once.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Define PASS before you run it
&lt;/h2&gt;

&lt;p&gt;Decide what success means before the experiment, not after.&lt;/p&gt;

&lt;p&gt;If you skip this, you will get a mediocre result and immediately narrate why it is secretly encouraging. It is much harder to move the goalposts once you wrote them down.&lt;/p&gt;

&lt;p&gt;For a security boundary, I define what must never happen.&lt;/p&gt;

&lt;p&gt;For a retrieval change, I define what specifically has to improve.&lt;/p&gt;

&lt;p&gt;For a new capability, I want a regression test before I trust it.&lt;/p&gt;

&lt;p&gt;Without a hard definition of failure, you are just playing with toys.&lt;/p&gt;

&lt;p&gt;When you write down the criteria for death, you stop lying to yourself. You stop tweaking parameters until the graph looks pretty, and you take the result you actually got.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the assumption that can hurt you most
&lt;/h2&gt;

&lt;p&gt;I do not treat every unknown as equal.&lt;/p&gt;

&lt;p&gt;Not knowing what a button looks like can wait forever.&lt;/p&gt;

&lt;p&gt;Not knowing whether the security boundary underneath it is real gets tested now.&lt;/p&gt;

&lt;p&gt;The question is always: which assumption, if wrong, invalidates the most work?&lt;/p&gt;

&lt;p&gt;That one goes first.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Turn the idea into a claim that can be wrong.&lt;/li&gt;
&lt;li&gt;Find the assumption that would invalidate the most work.&lt;/li&gt;
&lt;li&gt;Build the cheapest thing that could kill it.&lt;/li&gt;
&lt;li&gt;Decide what PASS means before running it.&lt;/li&gt;
&lt;li&gt;Let bad results actually kill ideas.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is not about being pessimistic. It is about being efficient.&lt;/p&gt;

&lt;p&gt;AI makes implementation cheaper every month, and it makes building the wrong thing cheaper at exactly the same rate.&lt;/p&gt;

&lt;p&gt;So I have stopped being impressed by how fast I can turn an idea into code.&lt;/p&gt;

&lt;p&gt;What I care about now is whether the idea survives long enough to deserve the code.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>softwaredevelopment</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My AI Remembered Everything Important. It Forgot What I Did Last Night.</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Tue, 08 Sep 2026 18:20:46 +0000</pubDate>
      <link>https://dev.to/constant_itis/my-ai-remembered-everything-important-it-forgot-what-i-did-last-night-4ije</link>
      <guid>https://dev.to/constant_itis/my-ai-remembered-everything-important-it-forgot-what-i-did-last-night-4ije</guid>
      <description>&lt;p&gt;I built an AI memory system inspired by one thing brains seem to do well: reinforce associations through use. Most AI memory is a notes file with search. It stores documents and retrieves them based on text similarity. I wanted something that behaved more like actual memory. I wanted paths that strengthen when you use them and fade when you do not. So mycelium stores memories as nodes with connections.&lt;/p&gt;

&lt;p&gt;This is not just a graph database. It is an active system. When you recall a few things together enough times, the link between them gets stronger. This is a Hebbian approach to storage. If two concepts appear in the same context repeatedly, the system assumes they belong together. Ignore a memory long enough and it decays. This decay is deliberate. &lt;strong&gt;Forgetting is a feature, not a bug.&lt;/strong&gt; It keeps the system from becoming a static archive of everything you have ever typed.&lt;/p&gt;

&lt;p&gt;The core mechanism relies on SQLite with FTS5 for keyword matching. The connection graph lives on top of that. You might hear people talk about vectors for everything. Vectors exist as a secondary signal in mycelium. They are not the primary recall mechanism. The primary driver is this connection graph and the frequency of access.&lt;/p&gt;

&lt;p&gt;Recall is pattern completion. A query does not just match text against a document body. It fires the matching memories and spreads activation through their connections. A partial cue pulls back the whole cluster that tends to light up with it. The memories that win are the ones that are strongly connected and frequently accessed. I call those the hubs.&lt;/p&gt;

&lt;p&gt;Loading context at the start of a session deliberately returns the hubs. On average, the hubs are the load bearing knowledge. They are the concepts you have referenced most often. If you are building an agent that needs to know who you are, what you have been working on for weeks, or what your general preferences are, the hubs are the right answer.&lt;/p&gt;

&lt;p&gt;This is a feature. It is also the bug.&lt;/p&gt;

&lt;p&gt;I hit the issue during normal development cycles. I would open a fresh session and effectively ask, what was I just working on. I would paste in a code snippet or describe a problem I had solved minutes ago. I expected the system to surface that immediate context.&lt;/p&gt;

&lt;p&gt;Instead, I got my greatest hits.&lt;/p&gt;

&lt;p&gt;The system returned the architecture of the whole project. It returned the three facts I look up constantly. It returned the stuff from months ago that everything connects to. What I would NOT reliably get was last night's actual work. It was the thing I literally needed to resume.&lt;/p&gt;

&lt;p&gt;This was frustrating because the system was not broken. It was working exactly as designed. The ranking was correct. It was just answering the wrong question.&lt;/p&gt;

&lt;p&gt;The cause is not a bug in the usual sense. Every piece worked as intended. Ranking is centrality: connections times access. A memory I wrote an hour ago has close to zero of both. It has no connections yet because nothing has been recalled alongside it, and no access count because I have not pulled it up. So it sits at the bottom, structurally underneath every hub that has been reinforced for months.&lt;/p&gt;

&lt;p&gt;Nothing was wrong with retrieval. The new memory was present. &lt;strong&gt;It was simply losing honestly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Which is exactly the wrong answer to the question, what just happened.&lt;/p&gt;

&lt;p&gt;This is the same trade your own memory makes. You can describe the house you grew up in in detail. You cannot find your keys.&lt;/p&gt;

&lt;p&gt;Salience and recency are not the same axis. When salience is dominated by reinforcement, new memories are disadvantaged by construction. I had rebuilt that trade off in software without noticing. I had created a system that was excellent at telling me who I was, but terrible at telling me what I was doing.&lt;/p&gt;

&lt;p&gt;The obvious fix is to treat this as a weighting problem. Add a recency boost, push recent items up the list, tune it until the balance feels right.&lt;/p&gt;

&lt;p&gt;That was the wrong abstraction.&lt;/p&gt;

&lt;p&gt;Tuning &lt;code&gt;centrality + λ(recency)&lt;/code&gt; does not remove the conflict. It just slides the failure boundary around. Turn λ up enough to surface last night's work and you push the genuinely important hubs down on everyday queries, which breaks the thing that made recall good. Turn it back down to protect the hubs and recent work sinks again. One knob cannot serve two intents. It can only choose which one to disappoint today.&lt;/p&gt;

&lt;p&gt;The fix that actually worked was to stop pretending one score answers both questions. I had to accept that centrality and recency are two different routes.&lt;/p&gt;

&lt;p&gt;I kept centrality for what is important. That route remains unchanged. It still powers the general context loading. It still identifies the hubs.&lt;/p&gt;

&lt;p&gt;I added a separate recency route for what just happened. This route is ranked newest first. It does not care about connections. It does not care about access counts. It cares only about when the memory was created or last touched.&lt;/p&gt;

&lt;p&gt;I wired that recency route into session startup. When a new session begins, the system loads the recent memories first. This gives the agent the immediate context it needs to resume work. Once that context is loaded, it can pull in the hubs if it needs broader understanding.&lt;/p&gt;

&lt;p&gt;Two questions. Two routes.&lt;/p&gt;

&lt;p&gt;The moment I stopped forcing one relevance number to do both jobs, both got better. The recent memories surfaced correctly. The important memories stayed in their rightful place.&lt;/p&gt;

&lt;p&gt;But calling it two routes undersells what I actually learned. This is not two ranking algorithms. It is two retrieval intents, and I had spent months pretending there was one. I started with the naive shape, &lt;code&gt;memory(query)&lt;/code&gt; returns ranked results, when what I actually needed was closer to three different questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;continuity  what happened recently?
context     what matters generally?
recall      what relates to this cue?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you name the intent, a single universal relevance score starts to look suspicious. Those are not one question with different weights. They are different questions that happen to run over the same store.&lt;/p&gt;

&lt;p&gt;This is a lesson for anyone building retrieval systems. You are likely answering two different questions with one ranking function. You do not realize it because you are focused on relevance as a single metric.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"What matters" and "what just happened" pull in opposite directions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your system only has one relevance score, it is quietly bad at one of them. Which one depends on whether you tuned for salience or recency. If you tuned for salience, you will lose recency. If you tuned for recency, you will lose salience.&lt;/p&gt;

&lt;p&gt;The honest surprise for me was that the failure was not a ranking bug. It was a category error. I had one query where I needed two.&lt;/p&gt;

&lt;p&gt;The code is open at github.com/constant-itis/mycelium-memory. The separation is only a few lines. Noticing it needed to exist took months.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>database</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Keep Trying to Prove ShrekOS Doesn't Need to Exist</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Tue, 08 Sep 2026 03:26:03 +0000</pubDate>
      <link>https://dev.to/constant_itis/i-keep-trying-to-prove-shrekos-doesnt-need-to-exist-3m38</link>
      <guid>https://dev.to/constant_itis/i-keep-trying-to-prove-shrekos-doesnt-need-to-exist-3m38</guid>
      <description>&lt;p&gt;I have no idea what I'm f*cking doing. Something I keep questioning:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why the hell am I building an operating system for this?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Seriously.&lt;/p&gt;

&lt;p&gt;Every couple of weeks I look at ShrekOS, look at the amount of work involved in building an actual Linux distribution, and have basically the same reaction.&lt;/p&gt;

&lt;p&gt;This is f*cking ridiculous.&lt;/p&gt;

&lt;p&gt;I wanted a safer way to run AI agents on my computer.&lt;/p&gt;

&lt;p&gt;Somehow that turned into an immutable Debian system with isolated workloads, capability grants, controlled egress, verified updates, a desktop policy layer, an installer, and enough architecture documents to make me question every decision that led me here.&lt;/p&gt;

&lt;p&gt;There has to be an easier answer.&lt;/p&gt;

&lt;p&gt;There has to be some tool I missed.&lt;/p&gt;

&lt;p&gt;Run the agents in Docker.&lt;/p&gt;

&lt;p&gt;Use Podman.&lt;/p&gt;

&lt;p&gt;Use a VM.&lt;/p&gt;

&lt;p&gt;Use a better agent harness.&lt;/p&gt;

&lt;p&gt;Install some security middleware.&lt;/p&gt;

&lt;p&gt;Find a desktop application that manages all of this.&lt;/p&gt;

&lt;p&gt;Anything other than:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build a f*cking operating system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I keep trying to prove that ShrekOS does not need to exist.&lt;/p&gt;

&lt;p&gt;And the annoying part is that every time I do, I eventually end up back at the same problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  I already know containers exist
&lt;/h2&gt;

&lt;p&gt;I already wrote the technical version of this question in &lt;a href="https://dev.to/the_leon_odor/why-im-building-shrekos-when-containers-already-exist-1lg6"&gt;Why I'm Building ShrekOS When Containers Already Exist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am not going to repeat that whole argument here.&lt;/p&gt;

&lt;p&gt;Containers are useful. I use them.&lt;/p&gt;

&lt;p&gt;The Bench system in ShrekOS literally runs on rootless container technology. I did not invent a magical new isolation primitive because AI showed up.&lt;/p&gt;

&lt;p&gt;Namespaces exist.&lt;/p&gt;

&lt;p&gt;Seccomp exists.&lt;/p&gt;

&lt;p&gt;Landlock exists.&lt;/p&gt;

&lt;p&gt;Containers exist.&lt;/p&gt;

&lt;p&gt;Virtual machines exist.&lt;/p&gt;

&lt;p&gt;Linux already has an absurd number of ways to restrict a process.&lt;/p&gt;

&lt;p&gt;That is not the thing I keep getting stuck on.&lt;/p&gt;

&lt;p&gt;The thing I cannot seem to find is the &lt;strong&gt;user space around all of it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not userspace in the kernel terminology sense.&lt;/p&gt;

&lt;p&gt;I mean the actual space where the human uses the computer.&lt;/p&gt;

&lt;p&gt;The desktop.&lt;/p&gt;

&lt;p&gt;The workflow.&lt;/p&gt;

&lt;p&gt;The place where I can run several autonomous things on my machine and understand, at a glance, what each one is allowed to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  I want agents to feel like something the computer understands
&lt;/h2&gt;

&lt;p&gt;This is the part that keeps dragging me back into ShrekOS.&lt;/p&gt;

&lt;p&gt;Say I have three agents running.&lt;/p&gt;

&lt;p&gt;One is working on a source repository.&lt;/p&gt;

&lt;p&gt;One is researching something on the web.&lt;/p&gt;

&lt;p&gt;One is processing a folder full of documents.&lt;/p&gt;

&lt;p&gt;I want my computer to understand that these are three different actors with three different scopes.&lt;/p&gt;

&lt;p&gt;The coding agent might get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/projects/foo       read/write
github.com           network
compiler             allowed
shell                allowed
secrets              scoped GitHub credential
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The research agent might get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/research           read/write
web                  network
shell                no
secrets              none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The document agent might get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/documents/input    read only
~/documents/output   read/write
network              none
shell                maybe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I do not just want those rules buried in a Docker command somewhere.&lt;/p&gt;

&lt;p&gt;I want to &lt;strong&gt;see them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I want the desktop to understand them.&lt;/p&gt;

&lt;p&gt;I want an agent to be able to ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I need access to this folder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And I want the machine to show me exactly what is being requested.&lt;/p&gt;

&lt;p&gt;Not some vague:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Claude wants permission to use Bash.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What the f*ck does that mean?&lt;/p&gt;

&lt;p&gt;Bash can delete my files.&lt;/p&gt;

&lt;p&gt;Bash can read my SSH keys.&lt;/p&gt;

&lt;p&gt;Bash can run &lt;code&gt;curl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bash can launch another program.&lt;/p&gt;

&lt;p&gt;Bash is not a permission.&lt;/p&gt;

&lt;p&gt;I want the request to be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This workload wants read/write access to &lt;code&gt;/home/me/projects/foo&lt;/code&gt; for this task.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This workload wants HTTPS access to &lt;code&gt;github.com&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That I can reason about.&lt;/p&gt;

&lt;p&gt;That is a thing I can say yes or no to.&lt;/p&gt;

&lt;p&gt;And after I say yes, I want something &lt;strong&gt;outside the agent&lt;/strong&gt; to make it true.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is where I start wondering if I am insane
&lt;/h2&gt;

&lt;p&gt;Because now I hear myself.&lt;/p&gt;

&lt;p&gt;I wanted better permission prompts for AI agents, so apparently I am building a Linux distribution.&lt;/p&gt;

&lt;p&gt;Cool.&lt;/p&gt;

&lt;p&gt;Totally normal response.&lt;/p&gt;

&lt;p&gt;This is usually where I stop and go researching again.&lt;/p&gt;

&lt;p&gt;Surely somebody has made the nice version of this already.&lt;/p&gt;

&lt;p&gt;And I keep finding pieces.&lt;/p&gt;

&lt;p&gt;I find agent interfaces that make running multiple agents nicer.&lt;/p&gt;

&lt;p&gt;I find sandboxes that isolate code execution.&lt;/p&gt;

&lt;p&gt;I find container runtimes.&lt;/p&gt;

&lt;p&gt;I find VM based environments.&lt;/p&gt;

&lt;p&gt;I find approval systems.&lt;/p&gt;

&lt;p&gt;I find MCP permission mechanisms.&lt;/p&gt;

&lt;p&gt;I find orchestration layers.&lt;/p&gt;

&lt;p&gt;I find tools for giving an agent its own disposable computer.&lt;/p&gt;

&lt;p&gt;All useful.&lt;/p&gt;

&lt;p&gt;Some of them are really f*cking cool.&lt;/p&gt;

&lt;p&gt;But I keep failing to find the thing I am actually picturing.&lt;/p&gt;

&lt;p&gt;A general-purpose desktop environment where autonomous agents are treated as &lt;strong&gt;first-class untrusted actors&lt;/strong&gt;, and where their filesystem access, network access, tools, credentials, persistence, and escalation are coherent parts of the computer's operating model.&lt;/p&gt;

&lt;p&gt;Maybe it exists and I have somehow missed it.&lt;/p&gt;

&lt;p&gt;I would genuinely love to be wrong about that.&lt;/p&gt;

&lt;p&gt;Because it would save me a tremendous amount of work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem is not launching the agent
&lt;/h2&gt;

&lt;p&gt;Launching an agent is easy.&lt;/p&gt;

&lt;p&gt;I can open a terminal right now and run one.&lt;/p&gt;

&lt;p&gt;I can put it in a container.&lt;/p&gt;

&lt;p&gt;I can put the container in a VM.&lt;/p&gt;

&lt;p&gt;I can disconnect the network.&lt;/p&gt;

&lt;p&gt;I can bind mount a project folder.&lt;/p&gt;

&lt;p&gt;I can build an AppArmor policy.&lt;/p&gt;

&lt;p&gt;I can put nftables rules around it.&lt;/p&gt;

&lt;p&gt;I can do all kinds of things.&lt;/p&gt;

&lt;p&gt;But notice who is doing all of that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Manually.&lt;/p&gt;

&lt;p&gt;Before the agent runs.&lt;/p&gt;

&lt;p&gt;Using a collection of infrastructure tools that were not designed around this interaction.&lt;/p&gt;

&lt;p&gt;That is fine for testing a security architecture.&lt;/p&gt;

&lt;p&gt;It is a shitty everyday user experience.&lt;/p&gt;

&lt;p&gt;I do not want to spend the next ten years launching increasingly powerful agents with increasingly elaborate shell commands.&lt;/p&gt;

&lt;p&gt;And I definitely do not expect normal people to do it.&lt;/p&gt;

&lt;p&gt;There should be a layer above the primitives.&lt;/p&gt;

&lt;p&gt;Something should compose them.&lt;/p&gt;

&lt;p&gt;Something should remember that this project gets this directory, this network scope, these tools, and no credentials unless I explicitly grant one.&lt;/p&gt;

&lt;p&gt;Something should present that coherently to the human sitting at the machine.&lt;/p&gt;

&lt;p&gt;That is the layer I keep looking for.&lt;/p&gt;

&lt;h2&gt;
  
  
  And then I realize what I have been building
&lt;/h2&gt;

&lt;p&gt;This is the frustrating part.&lt;/p&gt;

&lt;p&gt;Every time I start with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ShrekOS is probably a stupid amount of work for this.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I eventually reduce the problem again.&lt;/p&gt;

&lt;p&gt;I do not need a new kernel.&lt;/p&gt;

&lt;p&gt;I do not need a new container runtime.&lt;/p&gt;

&lt;p&gt;I do not need to invent filesystem isolation.&lt;/p&gt;

&lt;p&gt;I do not need to invent network filtering.&lt;/p&gt;

&lt;p&gt;I need a computer that &lt;strong&gt;composes those things around agentic workflows as a normal part of using the machine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And then I look back at ShrekOS.&lt;/p&gt;

&lt;p&gt;Oh.&lt;/p&gt;

&lt;p&gt;F*ck.&lt;/p&gt;

&lt;p&gt;That is what I have been building.&lt;/p&gt;

&lt;p&gt;Not "Linux, but with AI."&lt;/p&gt;

&lt;p&gt;God, I hope not.&lt;/p&gt;

&lt;p&gt;Not an operating system where an LLM gets root and becomes Clippy with &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The idea is almost the opposite.&lt;/p&gt;

&lt;p&gt;It is a developer operating system where agents can be extremely capable without capability automatically becoming authority over the whole machine.&lt;/p&gt;

&lt;p&gt;The agent can ask.&lt;/p&gt;

&lt;p&gt;The agent can work.&lt;/p&gt;

&lt;p&gt;The agent can f*ck up.&lt;/p&gt;

&lt;p&gt;The machine still owns the boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maybe building the OS is still the wrong answer
&lt;/h2&gt;

&lt;p&gt;I want to leave this possibility open because I think it matters.&lt;/p&gt;

&lt;p&gt;ShrekOS could still prove itself unnecessary.&lt;/p&gt;

&lt;p&gt;Seriously.&lt;/p&gt;

&lt;p&gt;Maybe I finish enough of this architecture to understand the problem properly and discover that almost all of it can be extracted into a runtime that installs cleanly on Debian, Ubuntu, Fedora, whatever.&lt;/p&gt;

&lt;p&gt;Maybe the useful thing eventually looks less like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;install ShrekOS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;install the Shrek agent runtime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe ShrekOS becomes the reference implementation where every assumption is controlled, while the useful pieces escape into normal Linux.&lt;/p&gt;

&lt;p&gt;That would not make building ShrekOS a failure.&lt;/p&gt;

&lt;p&gt;It might actually be the best outcome.&lt;/p&gt;

&lt;p&gt;Because right now I do not know where the boundary between "this should be an application" and "this actually needs operating system support" is.&lt;/p&gt;

&lt;p&gt;I am finding it by building the f*cking thing.&lt;/p&gt;

&lt;p&gt;There are pieces I already suspect could live perfectly well on another distribution.&lt;/p&gt;

&lt;p&gt;There are other pieces where the host itself matters a lot more.&lt;/p&gt;

&lt;p&gt;If the thing enforcing the policy can be casually replaced or modified by the same environment the agent is operating in, that changes the trust model.&lt;/p&gt;

&lt;p&gt;If arbitrary software can silently punch holes around the policy layer, that changes it too.&lt;/p&gt;

&lt;p&gt;If the machine boots into some unknown pile of mutable state, I have more assumptions to reason about.&lt;/p&gt;

&lt;p&gt;How much of that matters in practice?&lt;/p&gt;

&lt;p&gt;I don't completely know yet.&lt;/p&gt;

&lt;p&gt;That is part of the experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  I think this is why I keep questioning the project
&lt;/h2&gt;

&lt;p&gt;At first I thought repeatedly asking "why the f*ck am I building an OS?" meant I lacked confidence in the idea.&lt;/p&gt;

&lt;p&gt;Maybe some of it is that.&lt;/p&gt;

&lt;p&gt;I am building something way outside the scale of anything I have built before. Questioning whether I have massively overcomplicated it seems pretty reasonable.&lt;/p&gt;

&lt;p&gt;But I think something else is happening too.&lt;/p&gt;

&lt;p&gt;I keep trying to &lt;strong&gt;kill the premise&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every time I find an existing technology that might make part of ShrekOS unnecessary, I want to use it.&lt;/p&gt;

&lt;p&gt;Good.&lt;/p&gt;

&lt;p&gt;Please make parts of this project unnecessary.&lt;/p&gt;

&lt;p&gt;I already have enough shit to build.&lt;/p&gt;

&lt;p&gt;If Docker solves something, use Docker.&lt;/p&gt;

&lt;p&gt;If Landlock solves something, use Landlock.&lt;/p&gt;

&lt;p&gt;If systemd solves something, use systemd.&lt;/p&gt;

&lt;p&gt;If somebody releases a better sandbox tomorrow, steal the lesson and reconsider the design.&lt;/p&gt;

&lt;p&gt;The goal is not to justify ShrekOS.&lt;/p&gt;

&lt;p&gt;The goal is to figure out what the smallest coherent answer to this problem actually is.&lt;/p&gt;

&lt;p&gt;So far, every time I strip another unnecessary invention away, I keep arriving at the same stubborn little requirement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;There needs to be a human-facing layer between autonomous agents and the authority of the computer they are operating on.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not just a prompt.&lt;/p&gt;

&lt;p&gt;Not just an agent framework permission checkbox.&lt;/p&gt;

&lt;p&gt;Not just a container I manually assembled.&lt;/p&gt;

&lt;p&gt;A real operating boundary, exposed as something a person can actually understand and use.&lt;/p&gt;

&lt;p&gt;Maybe that eventually belongs in every desktop operating system.&lt;/p&gt;

&lt;p&gt;Maybe ShrekOS is an unnecessarily large prototype of something that should eventually be much smaller.&lt;/p&gt;

&lt;p&gt;Maybe in three years I will look back at this and wonder why the hell I built half of it.&lt;/p&gt;

&lt;p&gt;I am completely open to that.&lt;/p&gt;

&lt;p&gt;But I cannot find the thing I want to use today.&lt;/p&gt;

&lt;p&gt;So apparently I am still building it.&lt;/p&gt;

&lt;p&gt;F*ck.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ai</category>
      <category>security</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Replacing Myself With AI, One Cognitive Habit at a Time</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Sun, 06 Sep 2026 03:23:43 +0000</pubDate>
      <link>https://dev.to/constant_itis/replacing-myself-with-ai-one-cognitive-habit-at-a-time-175k</link>
      <guid>https://dev.to/constant_itis/replacing-myself-with-ai-one-cognitive-habit-at-a-time-175k</guid>
      <description>&lt;p&gt;I have no idea what I'm f*cking doing. Something I figured out today:&lt;/p&gt;

&lt;p&gt;I do not start with the dark version of an idea.&lt;/p&gt;

&lt;p&gt;I start with a random curiosity, chase it because it is interesting, and then somewhere in the middle I look up and go: oh. This could turn bad. And it is probably already turning bad somewhere, run by someone who never bothered to look up.&lt;/p&gt;

&lt;p&gt;That happened again this week, while I was thinking about what I want my memory system to do next. So let me walk through the curiosity, and then the exact moment it flipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI memory is mostly boring
&lt;/h2&gt;

&lt;p&gt;Useful. But boring.&lt;/p&gt;

&lt;p&gt;Most memory systems store things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what projects you are working on&lt;/li&gt;
&lt;li&gt;what tools you use&lt;/li&gt;
&lt;li&gt;what your preferences are&lt;/li&gt;
&lt;li&gt;what decisions you already made&lt;/li&gt;
&lt;li&gt;what facts should survive between sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built one of these. It is called mycelium. Connections between memories get stronger when I use them and fade when I do not, so it is a little more alive than a notes file. But at the end of the day it stores what I know.&lt;/p&gt;

&lt;p&gt;So an AI plugged into it eventually learns:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I use Proxmox.&lt;br&gt;
I prefer LXC for a lot of workloads.&lt;br&gt;
I am building an operating system.&lt;br&gt;
I like local-first systems.&lt;br&gt;
I am suspicious of unnecessary dependencies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cool. Accurate. Still not the thing I actually care about.&lt;/p&gt;

&lt;p&gt;It captures what I know. It does not capture how I think. And more specifically, it does not capture how I become curious.&lt;/p&gt;

&lt;h2&gt;
  
  
  Humans randomly wonder about shit
&lt;/h2&gt;

&lt;p&gt;At least I do.&lt;/p&gt;

&lt;p&gt;I will be working on something unrelated and suddenly think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Wait, why does this work like that?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Has anyone tried it differently?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is this whole abstraction actually necessary?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And three hours later there is a new project directory on my machine and I am questioning all of my life choices.&lt;/p&gt;

&lt;p&gt;An LLM can generate questions if I ask it to. That is not the same thing. What it does not have is the persistent causal chain that led me, specifically, to ask certain kinds of questions over and over.&lt;/p&gt;

&lt;p&gt;A human brain does something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;event
  ↓
this feels weird
  ↓
question
  ↓
investigation
  ↓
aha
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most AI interaction still looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prompt
  ↓
answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I started wondering what it would take to model the first one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not a personality profile
&lt;/h2&gt;

&lt;p&gt;The obvious version of this sounds horrifying. "Build an AI profile of a human." Nothing dystopian about that sentence at all.&lt;/p&gt;

&lt;p&gt;But the interesting question is not what I like. It is what I tend to notice.&lt;/p&gt;

&lt;p&gt;What kinds of situations make me start questioning assumptions. What recurring questions I ask after living with a system for a while. What usually pushes me to investigate. That is less a personality profile and more a model of behavior.&lt;/p&gt;

&lt;p&gt;For example, a system watching me long enough might notice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new tool
→ use it for a while
→ accumulate friction
→ question the architecture
→ go looking for something simpler
→ rebuild the thing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are patterns of curiosity, not facts. And patterns can be turned into triggers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The useful part
&lt;/h2&gt;

&lt;p&gt;Say I have a project that has been running for three months. Normally nothing happens until I randomly remember to ask whether it is still worth it.&lt;/p&gt;

&lt;p&gt;But if a system had learned that I reliably revisit mature systems after enough use, it could notice the situation before I do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;maturity_reassessment&lt;/span&gt;
&lt;span class="na"&gt;observed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;revisits systems after sustained use&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;questions accumulated complexity&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;weighs maintenance cost against real benefit&lt;/span&gt;
&lt;span class="na"&gt;triggers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;project_age &amp;gt; 90_days&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;repeated_failures &amp;gt; threshold&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;overlapping_component_added&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;major_upstream_release&lt;/span&gt;
&lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;propose_lightweight_architecture_audit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the AI is not inventing curiosity at random. It is saying: under conditions like these, this person usually starts asking these questions. Want to start now?&lt;/p&gt;

&lt;p&gt;Here is the part I want to be honest about.&lt;/p&gt;

&lt;p&gt;That is not preserving my curiosity. That is replacing a specific mental habit I currently perform by hand. The habit of remembering to reassess. The habit of noticing I have fixed the same class of bug four times. The habit of going "hmm, that's weird."&lt;/p&gt;

&lt;p&gt;The whole thing is a slow machine for deleting chores out of my own head.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rest of the machine, briefly
&lt;/h2&gt;

&lt;p&gt;There is an obvious architecture, and it is not the interesting part, so I will keep it short. Pull conversations from wherever I allow it, ChatGPT and Claude and local sessions and commit messages and notes. Mine them for repeated behavior instead of dumping them into context. Promote a pattern only after it shows up enough times. Watch current context for matching conditions. Then propose, never act.&lt;/p&gt;

&lt;p&gt;That last constraint matters. A curiosity engine should not start rewriting production systems because it achieved enlightenment. It should say things like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You tend to reassess systems once they grow several overlapping layers. This one now has three retrieval mechanisms. Want me to find the redundant one?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is basically an outsourced "hmm, that's weird," which might be one of the more valuable things a persistent assistant could actually do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here is where I caught myself
&lt;/h2&gt;

&lt;p&gt;Read the last few paragraphs again as if a company wrote them.&lt;/p&gt;

&lt;p&gt;A system that extracts behavioral patterns from everything you say, learns what triggers you, models how you decide, and knows when you are likely to change your mind.&lt;/p&gt;

&lt;p&gt;Advertisers would sell organs for that. Employers would love it. Governments would really love it. A behavioral model is worse than a chat log. A chat log says what you said. A behavioral model says how to move you.&lt;/p&gt;

&lt;p&gt;This is the moment I meant at the top. I did not go looking for surveillance. I went looking for a way to stop running the same chores in my own head, followed it because it was interesting, and looked up to find I had sketched the exact machine a company would point straight back at you. The mechanism is the same one, bit for bit. The only difference is that I looked up. And that somebody, somewhere, has already built this and did not.&lt;/p&gt;

&lt;p&gt;So the design is only worth anything if the containment is the actual product. For me that means the boring non-negotiables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;local-first&lt;/li&gt;
&lt;li&gt;user-owned&lt;/li&gt;
&lt;li&gt;explicit data sources&lt;/li&gt;
&lt;li&gt;exportable, inspectable, deletable&lt;/li&gt;
&lt;li&gt;no hidden categories, no ad targeting, no silent experiments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the one I care about most. Every inferred pattern needs provenance. If the machine tells me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You make worse architecture decisions after 2 AM.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I want to click that and see the twelve nights it is talking about. Not "confidence: 92%." Show me the evidence, or delete the claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  The other failure is quieter
&lt;/h2&gt;

&lt;p&gt;Even with all of that, there is a subtler way this goes wrong. It turns you into a caricature.&lt;/p&gt;

&lt;p&gt;The system sees "preferred self-hosting in nineteen cases." That hardens into "prefers self-hosting." Future models treat it as a fact and recommend accordingly, which produces more self-hosting, which confirms the pattern. Eventually it decides "refuses cloud software," and it is wrong, and it built that cage out of my own past.&lt;/p&gt;

&lt;p&gt;If inferred behavior becomes permanent identity, you have built a machine that freezes a person in time.&lt;/p&gt;

&lt;p&gt;The fix has the same shape as the memory system I already run. Patterns need confidence, evidence counts, counterexamples, timestamps, and decay:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pattern"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prefers_self_hosting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"evidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"counterexamples"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"last_seen"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-28"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I need to be able to look at any of it and say: nah, that's bullshit. And kill it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this actually is
&lt;/h2&gt;

&lt;p&gt;The more I look at it, the less it feels like memory.&lt;/p&gt;

&lt;p&gt;Memory answers: what should the AI remember about me. This answers: which parts of my own reasoning can be modeled well enough that I stop running them by hand.&lt;/p&gt;

&lt;p&gt;That is not an assistant that knows everything about me. It is a slow, careful removal of cognitive work I no longer need to do myself. One habit at a time. The reassessment nag. The repeated-bug pattern. The weird feeling I usually ignore until it gets expensive.&lt;/p&gt;

&lt;p&gt;Which means the strange endgame of personal AI might not be a machine that knows you. It might be a machine that quietly takes over the parts of thinking you were only doing out of habit, and hands you back the attention.&lt;/p&gt;

&lt;p&gt;And yes, that is one config file away from the worst product ever shipped. That is the whole point. The dark version does not need me. It builds itself, and it is probably already deployed somewhere with the brakes filed off.&lt;/p&gt;

&lt;p&gt;The only thing I actually add is the part where somebody stops halfway through a fun idea and asks who this hurts, and then refuses to keep going until that has an answer.&lt;/p&gt;

&lt;p&gt;That reflex is not me being clever. It is the one curiosity I cannot switch off. Chase a mechanism far enough and I always end up asking who would abuse it, and whether they already have. I used to think that was pessimism. Lately I think it might be the only reason any of this is worth building.&lt;/p&gt;

&lt;p&gt;Anyway. I will probably regret writing this, because now I want to build it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>productivity</category>
      <category>architecture</category>
    </item>
    <item>
      <title>ShrekOS in two diagrams: giving an agent exactly one folder and one hostname</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Fri, 04 Sep 2026 22:44:28 +0000</pubDate>
      <link>https://dev.to/constant_itis/shrekos-in-two-diagrams-giving-an-agent-exactly-one-folder-and-one-hostname-d11</link>
      <guid>https://dev.to/constant_itis/shrekos-in-two-diagrams-giving-an-agent-exactly-one-folder-and-one-hostname-d11</guid>
      <description>&lt;p&gt;This is a companion map to my Building ShrekOS series. If you have read &lt;a href="https://dev.to/the_leon_odor/what-should-an-agent-be-allowed-to-change-1hgn"&gt;Part 2&lt;/a&gt;, you have the argument already. This post is the picture: how an untrusted workload gets to do real work while reaching almost nothing.&lt;/p&gt;

&lt;p&gt;The whole thing runs on one idea. An agent, or any untrusted job, runs inside a Bench: a disposable box that starts with no files and no network, and is handed capabilities one at a time, narrowly, and revocably.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four rules
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deny by default.&lt;/strong&gt; A Bench starts with nothing. No files it can see, no network it can reach. Everything below is an exception I opened on purpose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A grant is a pinned object, not a path.&lt;/strong&gt; When I grant a directory, the system pins the actual inode and relocates it into the Bench mounted &lt;code&gt;noexec&lt;/code&gt;. A swapped symlink cannot redirect it, and files cannot be directly executed from the granted host mount.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Egress is a sealed, pinned destination, never "the internet."&lt;/strong&gt; A Bench that needs the network gets a named profile, say the Debian package host. The supervisor resolves and pins it through sealed policy; the Bench itself gets no DNS access and everything else stays dropped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Bench never gets both egress and a secret.&lt;/strong&gt; A box that can read a token and reach arbitrary network destinations can mail that token to a stranger. So credentialed calls go through a broker outside the Bench, which holds the credential, makes the call, and hands back only the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Egress, at a glance
&lt;/h2&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TB
  BN["Bench (default: no net)"] --&amp;gt; P{"sealed profile (pinned)"}
  P --&amp;gt;|apt| DEB["deb.debian.org"]
  P --&amp;gt;|pip| PY["PyPI"]
  P --&amp;gt;|model| BR["broker to provider"]
  BN -.-&amp;gt;|blocked| H["host-local"]&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;
  
  
  One Bench, start to finish
&lt;/h2&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;sequenceDiagram
  autonumber
  actor U as You / Agent
  participant GK as gatekeeperd
  participant BN as Bench
  participant NET as Outside
  U-&amp;gt;&amp;gt;GK: create
  U-&amp;gt;&amp;gt;GK: grant [in]/[out] (pinned, noexec)
  U-&amp;gt;&amp;gt;GK: run
  GK-&amp;gt;&amp;gt;BN: start, NO network (holder PID 1)
  Note over BN,NET: fail-closed: zero egress
  GK-&amp;gt;&amp;gt;BN: inject veth + nft allowlist
  BN-&amp;gt;&amp;gt;NET: deb.debian.org:443 only
  U-&amp;gt;&amp;gt;GK: destroy (output kept, tooling gone)&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The last line is the point of the whole design. The box is thrown away, but the file it produced stays. Disposability protects the host's future; it does nothing about the present blast radius, which is why the grants above matter more than the teardown.&lt;/p&gt;

&lt;h2&gt;
  
  
  The deep-dives
&lt;/h2&gt;

&lt;p&gt;The mechanics behind each rule get their own parts in the series: why a Bench at all (&lt;a href="https://dev.to/the_leon_odor/what-should-an-agent-be-allowed-to-change-1hgn"&gt;Part 2&lt;/a&gt;), how a single grant is made attacker-proof, and how the one egress door stays honest. This post is just the map to hang them on.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>security</category>
      <category>architecture</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Threw the Box Away. The Damage Was Already Done.</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Fri, 04 Sep 2026 20:01:22 +0000</pubDate>
      <link>https://dev.to/constant_itis/i-threw-the-box-away-the-damage-was-already-done-43gi</link>
      <guid>https://dev.to/constant_itis/i-threw-the-box-away-the-damage-was-already-done-43gi</guid>
      <description>&lt;p&gt;&lt;em&gt;ShrekOS field notes · August 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have no idea what I'm f*cking doing. Something I learned today:&lt;/p&gt;

&lt;p&gt;Throwing away a disposable sandbox is a cleanup operation, not a security control.&lt;/p&gt;

&lt;p&gt;I was building a disposable sandbox for an AI agent to work in. A container I could simply delete when the task finished. I felt safe because I could destroy the environment. It felt like a reset button.&lt;/p&gt;

&lt;p&gt;Then it hit me. Destroying the container does nothing about what it could reach while it was running. A container can be handed half my home directory and the entire internet with two careless flags.&lt;/p&gt;

&lt;p&gt;An agent that is messy and can read my SSH keys and can POST them anywhere is not made safe by the fact that its container gets deleted at the end. If it exfiltrated my keys in the seconds it was alive, deleting the box afterward changes nothing. The damage is already done.&lt;/p&gt;

&lt;p&gt;I had confused the cleanup for the control.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  🧅 peel the jargon
  &lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In plain terms.&lt;/strong&gt; Throwing away the sandbox cleans up the mess it leaves behind. It does nothing about what it grabbed while it was running. If a burglar is in your house for ten minutes, demolishing the house afterward does not un-steal your stuff.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;&lt;/p&gt;

&lt;p&gt;So disposability protects the host's future. There is no leftover mutation, no permanent mess. It does nothing about the present blast radius, which is everything the box could touch while it was running.&lt;/p&gt;

&lt;p&gt;Destroying the container is a cleanup operation. It is not a security measure. The security measure is what I allow before it runs. A sandbox has to start with nothing. No files. No network. It gets narrow, revocable grants from there.&lt;/p&gt;

&lt;p&gt;The container runtime handed me disposability for free. That is real and useful. What it did not hand me was safety. I quietly assumed "I can delete it" meant "it cannot hurt me." Those are not the same sentence. Confusing the cleanup for the control was my mistake, not the runtime's.&lt;/p&gt;

&lt;p&gt;The container was not the wall. The permissions were the wall.&lt;/p&gt;

&lt;p&gt;If your sandbox's entire safety story is "I throw it away after," you have a cleanup plan, not a security model. Ask what it can reach while it is alive, because that window is where all the damage happens. Default the box to nothing, then grant it exactly what the task needs.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  🧪 What I actually tested
  &lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Try it, ten seconds.&lt;/strong&gt; &lt;code&gt;podman run --rm -v $HOME:/host --network=host alpine cat /host/.ssh/id_ed25519&lt;/code&gt; reads your private key, and the --rm tidies up the container afterward like nothing happened. The key already left the building. Do not actually pipe it anywhere. The point is only that the disposable box had full reach the entire time it was alive.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  ⚠️ Where I might be wrong
  &lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The honest caveat.&lt;/strong&gt; Disposability is worth having: no persistent host mutation, clean teardown, reproducible runs. The mistake is treating it AS the security boundary instead of a convenience sitting on top of one. And "no trace" is aspirational. A container shares the host kernel and can leave logs and side effects, so even clean teardown is its own separate problem. A reader of the main series pushed exactly here: if you want the box to stop sharing your kernel at all, that is a job for a microVM runtime like Kata, not for a stricter container, and it is worth its own note another day.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>containers</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>What Should an Agent Be Allowed to Change?</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Thu, 03 Sep 2026 16:26:37 +0000</pubDate>
      <link>https://dev.to/constant_itis/what-should-an-agent-be-allowed-to-change-1hgn</link>
      <guid>https://dev.to/constant_itis/what-should-an-agent-be-allowed-to-change-1hgn</guid>
      <description>&lt;p&gt;Part 1 ended with a sealed host. The machine was locked down. I felt a surge of relief because I had solved the wrong-feeling half of the security problem in a satisfying way. The base system could not be casually mutated. That felt secure. But it created a new problem immediately. On a sealed, deliberately bare host, the agent can do nothing useful.&lt;/p&gt;

&lt;p&gt;The naive approach is simple in theory and impossible in practice. The agent needs to install ffmpeg. It cannot. The host has no ffmpeg. It also lacks a compiler toolchain. It does not have curl or git or unzip installed on the base system. The idea of running &lt;code&gt;apt install ffmpeg&lt;/code&gt; on the host is not dangerous anymore. It is simply impossible. Which is correct, and also useless. I had restricted the host until it became inert. The agent is a client. It has a job to do. It needs tools. It needs to be messy.&lt;/p&gt;

&lt;p&gt;So the agent needs somewhere it can be messy without the mess landing on my machine. That somewhere is what I call a Bench. A Bench is a disposable, mutable environment. It provides fresh writable state every time it is invoked. I mount a scratch workspace at &lt;code&gt;/work&lt;/code&gt; inside that environment. The agent can install packages, compile things, write files, and break whatever it wants inside that space. When the task is done, the Bench is thrown away. The host never changed, because the host was never in the loop.&lt;/p&gt;

&lt;p&gt;The Bench runs as a rootless container. Podman with crun under the hood handles the actual execution. The privileged part of the operating system creates and supervises these environments. The agent never touches the container engine directly. It requests a Bench, and the operating system provides one. This separation is critical. The agent does not control the infrastructure. It only controls the workspace.&lt;/p&gt;

&lt;p&gt;At this point I had to ask myself whether I was just reinventing rootless Podman with extra steps. The answer is yes. The execution engine IS rootless Podman. I did not invent disposable mutable environments. A container already gives you that. So if the container already exists, what am I actually adding?&lt;/p&gt;

&lt;p&gt;The answer is not new container technology. It is making mutation itself a governed lifecycle on top of that engine. A bare &lt;code&gt;podman run&lt;/code&gt; leaves every authority decision ad hoc. I would have to wire up the mounts by hand. I would have to hand it a network by hand. There is no default and no record. The Bench is not about the container runtime. It is about the policy layer around it.&lt;/p&gt;

&lt;p&gt;A disposable box sounds safe because I can throw it away. But throwing it away afterward does nothing about what it could reach WHILE it ran. A default container configuration can bind-mount half my home directory. It can talk to the entire internet. An agent that is messy AND can read my SSH keys AND can POST them anywhere is not made safe by the fact that its container gets deleted at the end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disposability protects the host's future. It does nothing about the present blast radius.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the core tension. The agent needs to be able to change things. It needs to write to disk. It needs to fetch dependencies. But if the container has broad access, the damage is done before the container is destroyed. The destruction of the container is a cleanup operation. It is not a security measure. The security measure is what happens before the cleanup.&lt;/p&gt;

&lt;p&gt;So a Bench starts with nothing. No view of my files. No network at all. This is the default deny posture. From there I grant, explicitly and narrowly. For files, I grant a specific directory. It is read only or read write. Nothing above it is visible. The grants are mounted noexec. The agent cannot execute arbitrary binaries from my home directory. It can only use what is in its own scratch space.&lt;/p&gt;

&lt;p&gt;The grant is never "my home directory." It is "this one project folder, read write." This granularity matters. If the agent is transcribing audio, it needs access to the audio files. It does not need access to my tax returns. If the agent is installing a Python library, it needs network access. But it does not need access to my database.&lt;/p&gt;

&lt;p&gt;For network access, I do not grant "the internet." I grant a named set of destinations. When the agent needs to run &lt;code&gt;apt&lt;/code&gt; to install something, I grant it the Debian package egress and nothing else. It can reach the Debian mirrors and literally nowhere else. This is not just about convenience. It is about reducing the attack surface. If the agent is compromised, or if it makes a mistake, it cannot exfiltrate data to random endpoints. It can only talk to the sources it needs.&lt;/p&gt;

&lt;p&gt;The agent asks for what it needs. The operating system records the grant. I confirm it. The confirmation path is separate from the agent's control. The agent cannot fake the confirmation. How that works is a later post. Every grant is narrow, recorded, and revocable. The agent does not get permanent authority. It gets temporary capability.&lt;/p&gt;

&lt;p&gt;This is the shift that made the whole thing click for me. The question stopped being "do I trust this agent." That question has no good answer, because the agent is a client and a stochastic one. You cannot trust a stochastic process. You can only constrain its outcomes.&lt;/p&gt;

&lt;p&gt;The question became "what narrow, revocable capabilities does THIS task actually need."&lt;/p&gt;

&lt;p&gt;Transcoding a video needs the video directory and no network. Installing a Python library needs the package egress and a scratch dir. Neither needs my whole machine. Mutation stopped being a yes or no about the host and became a lifecycle with a default of no. The agent does not have rights. It has permissions granted per task.&lt;/p&gt;

&lt;p&gt;Now disposability means something. The Bench was powerful for exactly as long as the task ran. It operated inside walls I drew. It reached only what I granted. And then it was gone. The host never noticed. That is the thing I wanted at the end of Part 1. A place where an agent could be temporarily powerful without that power becoming authority over my machine.&lt;/p&gt;

&lt;p&gt;But there is a new problem. The agent builds something in a Bench that actually works. It installs a complex toolchain. It compiles a binary. It writes a script that solves the problem perfectly. And then the Bench is thrown away. The work is gone.&lt;/p&gt;

&lt;p&gt;This is the tension that Part 1 ignored and Part 2 has now exposed. The agent is useful only if its work persists. But if the work persists, the host is no longer sealed. The agent has left a mark. The question of mutation resurfaces.&lt;/p&gt;

&lt;p&gt;The obvious move is to save the Bench. To take that working environment and make it permanent. To promote it from a transient workspace to a persistent layer. But saving the whole messy box is going to turn out to be a bad idea. The Bench contains everything. It contains the tools, the dependencies, the temporary files, the logs, the cache. It contains the noise along with the signal.&lt;/p&gt;

&lt;p&gt;So if I want to keep what a Bench became, what exactly is worth keeping?&lt;/p&gt;

</description>
      <category>linux</category>
      <category>security</category>
      <category>architecture</category>
      <category>ai</category>
    </item>
    <item>
      <title>Why I'm Building ShrekOS When Containers Already Exist</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Wed, 02 Sep 2026 16:16:13 +0000</pubDate>
      <link>https://dev.to/constant_itis/why-im-building-shrekos-when-containers-already-exist-1lg6</link>
      <guid>https://dev.to/constant_itis/why-im-building-shrekos-when-containers-already-exist-1lg6</guid>
      <description>&lt;p&gt;An AI agent should not have to be trusted with the whole machine in order to be useful on the machine. That trust decision keeps getting dumped on the model or the agent framework. It belongs lower down, in the operating system.&lt;/p&gt;

&lt;p&gt;I wanted agents to do mundane, genuinely useful computer work. Install ffmpeg. Compile something. Poke at a project. Launch a tool. Hit a network resource. The surprise was that getting an LLM to emit the right shell commands was the easy part. The hard part was deciding what authority those commands should carry.&lt;/p&gt;

&lt;p&gt;Every time I made an agent more useful, I drifted toward one of two bad places. Either I locked the environment down so hard that ordinary tasks became awkward and I spent all day widening permissions by hand, or I kept handing the agent more of the real machine until a single hallucination, a poisoned dependency, a prompt injection, or a plain bug could do real damage.&lt;/p&gt;

&lt;p&gt;Restrict until useless, or trust until dangerous. I kept ping-ponging between them.&lt;/p&gt;

&lt;p&gt;This is not about theoretical edge cases. This is about the daily grind of trying to make software that helps you actually get things done. I am not claiming there are only two sandboxes in the world. Sophisticated sandboxes exist. Containers exist. This is about MY operating model, the way the authority question kept landing back on the agent's judgment instead of on something underneath it.&lt;/p&gt;

&lt;p&gt;Containers, namespaces, cgroups, egress filtering, package managers, mandatory access control, immutable filesystems, signed boot. Each already solves a PIECE of this. None of them, by itself, gave me a coherent operating model for a workload that decides at runtime which capabilities it needs and then asks the machine for them. That gap is the whole project.&lt;/p&gt;

&lt;p&gt;I did not write a kernel. I did not invent containers. I did not invent sandboxing. If this project required me to invent any of those, something would have gone badly wrong.&lt;/p&gt;

&lt;p&gt;The work is composition, not invention. ShrekOS is not a from-scratch operating system. It is an attempt to stitch existing mechanisms into a coherent operating model for a workload that asks for capabilities as it goes. The clearest way to explain what I mean is the example that made the whole problem concrete for me. ffmpeg.&lt;/p&gt;

&lt;p&gt;Walk through what "the agent needs ffmpeg" actually implies if you do it the naive way. I have an agent that needs to transcode a video file. It sees the tool missing. It decides to install it. It runs &lt;code&gt;apt install ffmpeg&lt;/code&gt; on the host.&lt;/p&gt;

&lt;p&gt;This permanent mutation of my machine touches the package database. It pulls dependencies I did not audit. It runs install scripts as part of a normal operation. It creates symlinks. It writes configuration files in places I did not expect. It assumes root privileges to write to system directories.&lt;/p&gt;

&lt;p&gt;Multiply that by every tool an agent decides it needs, over months, and the host becomes an unpredictable pile of state that some program I do not fully control has been editing. That is the moment the discomfort became concrete for me. The problem was never ffmpeg. It was that installing it meant giving an unpredictable program authority over my actual machine.&lt;/p&gt;

&lt;p&gt;I started building on an immutable Linux base so the host could not be casually mutated. I leaned Fedora at first, because its sealed verified boot story was landing upstream and looked like a free win. Then I un-chose it the same afternoon.&lt;/p&gt;

&lt;p&gt;The base turns out to be maybe fifteen percent of this project. The interesting part is base independent, the immutable image based update model I wanted is not Fedora specific, and I am simply faster in Debian on a build I will live in for years. So the base is Debian, sealed and immutable, with atomic updates I can roll back if one goes bad.&lt;/p&gt;

&lt;p&gt;AppArmor gives me a path based model with policy in plain readable files, which suits the kind of deterministic wall I want. Fedora survives only as a reference image I study in a VM and as a cheap escape hatch through the build tooling.&lt;/p&gt;

&lt;p&gt;The point of telling you this: I will reverse a "hard security win" the moment I realize it is not load bearing. That reflex is the whole methodology. I am not married to a distribution. I am married to the principle that the base layer should be stable and auditable.&lt;/p&gt;

&lt;p&gt;The agent is a client. Whether it is a cloud model, a local one, or something I swap next month does not change the security story, because the security is not supposed to live inside the agent. If it did, I would be trusting the least trustworthy component to police itself.&lt;/p&gt;

&lt;p&gt;The agent cannot be the thing that decides the limits of its own authority. That is the whole principle. It can be trusted to make a request. The operating system decides whether to grant it, and under what constraints. The useful version of this is not the agent promising to use curl responsibly. It is the agent asking for what it needs and the machine deciding what that request is actually allowed to touch.&lt;/p&gt;

&lt;p&gt;This is not about preventing the agent from working. It is about ensuring that when the agent works, it does so within a boundary that I defined before it started. The boundary is not a suggestion. It is a hard limit.&lt;/p&gt;

&lt;p&gt;Before I could have anything worth calling an operating system for agents, I needed something much smaller and more concrete. A place where an agent could be temporarily powerful without that power automatically becoming authority over my machine. That is where the next post starts. But first I have to answer the question sitting underneath all of it.&lt;/p&gt;

&lt;p&gt;What should an agent be allowed to change?&lt;/p&gt;

</description>
      <category>linux</category>
      <category>security</category>
      <category>architecture</category>
      <category>ai</category>
    </item>
    <item>
      <title>The Bot Cannot Grade the Bot</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Tue, 01 Sep 2026 23:55:01 +0000</pubDate>
      <link>https://dev.to/constant_itis/the-bot-cannot-grade-the-bot-ldl</link>
      <guid>https://dev.to/constant_itis/the-bot-cannot-grade-the-bot-ldl</guid>
      <description>&lt;p&gt;The current wave of AI agent memory posts are all secretly trying to build a system that lets the human stop knowing. That is impossible.&lt;/p&gt;

&lt;p&gt;There is a flood of articles on this topic. You see them everywhere on your feed. They talk about eviction policies. They discuss trust tiers. They use fancy terms like "institutional memory" and "stale state poisoning." One post claims that everything the agent remembers has the same authority and that this is the bug. These are smart posts. They are well written. They are technically sound. But they all circle the same drain and never name the bottom of it.&lt;/p&gt;

&lt;p&gt;The bottom is that everyone is searching for a way to offload the responsibility of knowing what is true. They want the machine to do the epistemic heavy lifting. They want the agent to remember so well that you no longer have to pay attention.&lt;/p&gt;

&lt;p&gt;This desire creates a recursion that does not terminate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recursion that does not terminate
&lt;/h2&gt;

&lt;p&gt;The standard dream fix for the problem of an agent being confidently wrong is to add a second agent to check the first. The logic seems sound at a glance. If Agent A hallucinates, Agent B will catch it. But look closer at the mechanics. For bot B to catch bot A's mistake, bot B must know something that bot A did not.&lt;/p&gt;

&lt;p&gt;If bot B has the same information as bot A, it is not a checker. It is just Agent A with a second signature. You are running the same hallucination twice and stapling a citation to the copy. Stacking bots adds correlated error, not ground truth. It happens at double the token cost. People keep building the thirteenth bot to grade the twelfth. They think they are adding rigor. They are adding noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it actually terminates
&lt;/h2&gt;

&lt;p&gt;The recursion only ends when the checker touches something falsifiable that is NOT another opinion. It needs contact with the world.&lt;/p&gt;

&lt;p&gt;It needs a test that goes red. A command that exits nonzero. A schema that rejects the payload. A live query that returns different rows than the memory claimed. Reality does not have a take. It either breaks or it does not. That is exactly why it can grade when another model cannot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An oracle is only an oracle if it is not a bot.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The checker does not need to know what the doer knew. It needs a source of truth that the claim can crash into. These are different requirements. Conflating them is how you get an infinite stack of graders and zero ground. You are trying to solve an epistemic problem with more epistemic noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can actually build
&lt;/h2&gt;

&lt;p&gt;So what can you actually build? You have to split memory in two.&lt;/p&gt;

&lt;p&gt;The mechanical half should be automated. This includes eviction, decay, and metering token costs. It involves noticing when a lesson goes cold or a fact rots from neglect. That is bookkeeping. Machines should own it. It is boring work. It is necessary work.&lt;/p&gt;

&lt;p&gt;The other half is not mechanical.&lt;/p&gt;

&lt;p&gt;A model rating how true its own memory is? Pure theater. The grader is the author. Self-assessed confidence is just a hallucination in a lab coat. You cannot trust a system to validate its own truthfulness because the system is the source of the potential error.&lt;/p&gt;

&lt;p&gt;Instead of trying to grade truth, do two things that defer to the human rather than replace them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First, record provenance.&lt;/strong&gt; Where did a memory come from? A human correction is a different object than an unverified model inference. Origin is a recordable fact. It is not a judgment about truth. It is metadata.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second, surface contradictions.&lt;/strong&gt; Flag when two memories disagree. Do not let the loser decay quietly in the dark. Detecting a conflict is cheap and structural. Deciding the winner belongs to a human.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part nobody wants to print
&lt;/h2&gt;

&lt;p&gt;The better your memory system, the more it matters that the human feeding it knows what is true. A great memory system in the hands of someone who does not know the domain does not make them right. It makes them confidently wrong faster. It does it at scale. It does it with a citation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Poison propagates better on good infrastructure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you build a system that automatically resolves conflicts, you are automating the wrong problem. You are automating the decision of what is true. That is not an engineering problem. That is a domain knowledge problem.&lt;/p&gt;

&lt;p&gt;The working systems are the ones where a human stayed on the hook and built the machine to serve that, not to relieve them of it. You have to know, as the human. No architecture absolves accountability.&lt;/p&gt;

&lt;p&gt;The buck stops at a person who gives a damn and knows the material. Everything else is plumbing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop looking for the bot that knows best
&lt;/h2&gt;

&lt;p&gt;We are seeing a generation of engineers trying to build autonomy by removing human judgment. This is a category error. Autonomy without accountability is just noise with better organization. The goal of agent memory is not to hide the truth from the user. The goal is to make the truth visible and traceable so the user can make better decisions.&lt;/p&gt;

&lt;p&gt;When you stop trying to make the bot the ultimate authority, you stop building the thirteenth bot to grade the twelfth. You start building systems that respect the boundary between what is known and what is claimed.&lt;/p&gt;

&lt;p&gt;The future of AI memory is not in smarter grading algorithms. It is in better provenance tracking. It is in clear signals about what is fresh and what is stale. It is in handing the conflict resolution back to the person who actually understands the context.&lt;/p&gt;

&lt;p&gt;If you are building agent memory, stop looking for the bot that knows best. Look for the tool that helps the human know best.&lt;/p&gt;




&lt;p&gt;I built my version of this in the open. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mycelium&lt;/strong&gt; automates the mechanical half (decay, eviction, reinforcement), keeps memory legible so a human can read and correct it, and leaves the grading with you. &lt;/p&gt;

&lt;p&gt;It does not pretend to know truth. It is built to serve someone who does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/constant-itis/mycelium-memory" rel="noopener noreferrer"&gt;github.com/constant-itis/mycelium-memory&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>6 Network+ Exam Traps: OSI Layers, Broadcasts, Protocols, and Subnetting</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Tue, 07 Jul 2026 20:21:13 +0000</pubDate>
      <link>https://dev.to/constant_itis/6-network-exam-traps-osi-layers-broadcasts-protocols-and-subnetting-2add</link>
      <guid>https://dev.to/constant_itis/6-network-exam-traps-osi-layers-broadcasts-protocols-and-subnetting-2add</guid>
      <description>&lt;p&gt;Network+ questions often hinge on one deciding fact. If you can pin that fact before reading the answers, the distractors get much less convincing.&lt;/p&gt;

&lt;p&gt;This guide covers the traps that show up around OSI layers, hub vs switch, switch vs router, collision domains, broadcast domains, Telnet vs SSH, IMAP vs POP3, /26 subnetting, and DHCP relay.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network+ exam traps summary table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trap&lt;/th&gt;
&lt;th&gt;Pinning fact&lt;/th&gt;
&lt;th&gt;What follows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hub vs switch vs router&lt;/td&gt;
&lt;td&gt;Hub repeats bits at Layer 1; switch forwards frames by MAC at Layer 2; router forwards packets by IP at Layer 3.&lt;/td&gt;
&lt;td&gt;Hubs share collision space, switches forward inside a VLAN, and routers move traffic between networks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collision vs broadcast domain&lt;/td&gt;
&lt;td&gt;Collision is about simultaneous Ethernet transmission. Broadcast is about who receives L2 broadcasts.&lt;/td&gt;
&lt;td&gt;Each switch port is a separate collision domain for exam purposes; one VLAN is one broadcast domain.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Telnet vs SSH&lt;/td&gt;
&lt;td&gt;Telnet is plaintext remote terminal. SSH is encrypted remote access.&lt;/td&gt;
&lt;td&gt;SSH uses TCP 22, encrypts client-to-server traffic, and supports public-key authentication.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IMAP vs POP3&lt;/td&gt;
&lt;td&gt;IMAP syncs mailbox state; POP3 downloads messages.&lt;/td&gt;
&lt;td&gt;POP3 may delete server copies, but that depends on client configuration.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/26 subnetting&lt;/td&gt;
&lt;td&gt;/26 means 26 network bits, 6 host bits.&lt;/td&gt;
&lt;td&gt;64 addresses per subnet, 62 usable hosts, mask 255.255.255.192.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DHCP relay&lt;/td&gt;
&lt;td&gt;DHCP Discover is local broadcast; routers do not forward broadcasts by default.&lt;/td&gt;
&lt;td&gt;A relay receives the broadcast, identifies the client subnet, and forwards DHCP information toward the server, generally by unicast.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Hub vs switch: Layer 1 repeating vs Layer 2 forwarding
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The trap:&lt;/strong&gt; both boxes connect Ethernet devices, so the answers blur into "it sends traffic where it needs to go."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pinning fact:&lt;/strong&gt; a hub does not make forwarding decisions. It is a Layer 1 repeater. A switch reads Layer 2 MAC addresses and forwards frames.&lt;/p&gt;

&lt;p&gt;From that fact, the rest follows. A hub repeats incoming bits out the other ports, so connected devices share the same collision domain. A switch learns which MAC addresses live behind which ports, so it can forward known unicast frames only where they need to go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exam wording to watch for:&lt;/strong&gt; "repeats signal," "no MAC table," or "all devices share bandwidth" points to a hub. "MAC address table," "forwards frames," or "separate collision domain per port" points to a switch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch vs router: local frames vs routed packets
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The trap:&lt;/strong&gt; both switches and routers forward traffic, and a Layer 3 switch is a real device, so learners overgeneralize the exception.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pinning fact:&lt;/strong&gt; a standard switch operates at Layer 2 using MAC addresses. A router operates at Layer 3 using IP addresses.&lt;/p&gt;

&lt;p&gt;A switch keeps traffic moving inside a Layer 2 segment, usually a VLAN. A router moves traffic between IP networks. That is why the default Network+ answer for breaking up broadcast domains is router, while a switch is the default answer for breaking up collision domains.&lt;/p&gt;

&lt;p&gt;VLANs are the nuance: VLANs create separate Layer 2 broadcast domains on switches. Routing is needed only when devices in different VLANs need to communicate with each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exam wording to watch for:&lt;/strong&gt; "primarily breaks broadcast domains" usually wants router. "Inter-VLAN routing at wire speed" points to a Layer 3 switch. "WAN edge," "NAT," or "full routing features" points back to router.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collision domain vs broadcast domain: two different boundaries
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The trap:&lt;/strong&gt; "domain" sounds like one category, so the switch rule gets copied from collisions to broadcasts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pinning fact:&lt;/strong&gt; collision domains are about Ethernet transmit contention. Broadcast domains are about how far a Layer 2 broadcast frame travels.&lt;/p&gt;

&lt;p&gt;For Network+ exam purposes, each switch port is a separate collision domain. In modern full-duplex Ethernet, collisions are effectively eliminated, but the exam still uses the one-port-one-collision-domain model to distinguish switches from hubs.&lt;/p&gt;

&lt;p&gt;A broadcast is different. A switch floods a broadcast out every other applicable port in the same VLAN, not literally every physical port on the device. Different VLANs are different broadcast domains.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exam wording to watch for:&lt;/strong&gt; "How many collision domains on a 24-port switch?" usually means 24. "How many broadcast domains without VLANs?" usually means 1. "With four VLANs?" usually means 4.&lt;/p&gt;

&lt;h2&gt;
  
  
  Telnet vs SSH: plaintext remote access vs encrypted remote access
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The trap:&lt;/strong&gt; both give command-line remote access, so the question gets treated like a port-number flashcard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pinning fact:&lt;/strong&gt; Telnet sends traffic in plaintext. SSH encrypts the connection between the SSH client and SSH server.&lt;/p&gt;

&lt;p&gt;Once encryption is the deciding fact, SSH is the secure replacement for Telnet. SSH also supports public-key authentication, which is why key-based Linux administration shows up in hardening questions.&lt;/p&gt;

&lt;p&gt;Ports still matter: SSH is TCP 22, Telnet is TCP 23.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exam wording to watch for:&lt;/strong&gt; "encrypted remote CLI," "secure shell," "key-based authentication," or "replace Telnet" points to SSH. "Plaintext terminal" points to Telnet.&lt;/p&gt;

&lt;h2&gt;
  
  
  IMAP vs POP3: sync the mailbox vs download the messages
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The trap:&lt;/strong&gt; both are incoming mail protocols, so people reduce the difference to "old vs new" or memorize only the ports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pinning fact:&lt;/strong&gt; IMAP keeps mailbox state on the server and syncs across clients. POP3 downloads messages to the client.&lt;/p&gt;

&lt;p&gt;That means IMAP fits multi-device mail: folders, read/unread state, and server-side mailbox state stay consistent. POP3 fits simple single-device retrieval. POP3 is often configured to remove messages from the server after download, but it does not always delete them; client settings control that behavior.&lt;/p&gt;

&lt;p&gt;Ports: IMAP is TCP 143, IMAPS is 993, POP3 is TCP 110, and POP3S is 995.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exam wording to watch for:&lt;/strong&gt; "multiple devices," "sync folders," or "leave mail on server" points to IMAP. "Download to local client" points to POP3. "Send mail" is SMTP, not either one.&lt;/p&gt;

&lt;h2&gt;
  
  
  /26 subnetting: 64 addresses, 62 usable hosts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The trap:&lt;/strong&gt; subnetting panic makes people jump straight to a memorized mask instead of counting the host bits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pinning fact:&lt;/strong&gt; IPv4 has 32 bits. A /26 uses 26 bits for the network, leaving 6 host bits.&lt;/p&gt;

&lt;p&gt;Six host bits gives 2^6 = 64 total addresses per subnet. Subtract the network address and broadcast address, and you get 62 usable host addresses. In the last octet, /26 is 11000000, so the mask is 255.255.255.192 and the block size is 64.&lt;/p&gt;

&lt;p&gt;The subnet starts at multiples of 64 in the interesting octet: .0, .64, .128, .192.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exam wording to watch for:&lt;/strong&gt; "How many usable hosts?" asks for 62. "What subnet mask?" asks for 255.255.255.192. "Which subnet contains .130/26?" asks for the .128 block.&lt;/p&gt;

&lt;h2&gt;
  
  
  DHCP relay: forwarding a local broadcast toward a remote server
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The trap:&lt;/strong&gt; DHCP starts with a broadcast, and routers do not forward broadcasts, so the remote DHCP server seems impossible unless it is on every subnet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pinning fact:&lt;/strong&gt; a DHCP relay agent receives the local client broadcast and forwards DHCP information toward a DHCP server on another subnet, generally using unicast, while identifying the client subnet.&lt;/p&gt;

&lt;p&gt;The relay is often configured on a router or Layer 3 interface. It listens for DHCP Discover messages from local clients, forwards the request to the configured DHCP server, and includes information that lets the server choose the right address scope for the client subnet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exam wording to watch for:&lt;/strong&gt; "DHCP server on a different subnet," "forward DHCP broadcasts," "ip helper," or "relay agent" all point to DHCP relay.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing pattern: identify the pinning fact first
&lt;/h2&gt;

&lt;p&gt;The fastest way through these Network+ traps is not to memorize longer definitions. It is to ask, "What one fact decides this question?"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Layer question? Identify the address or unit: bits, frames, packets, ports, or application data.&lt;/li&gt;
&lt;li&gt;Domain question? Decide whether the boundary is collision, broadcast, VLAN, or routed network.&lt;/li&gt;
&lt;li&gt;Protocol question? Decide whether the job is secure remote access, incoming mail sync, incoming mail download, or mail sending.&lt;/li&gt;
&lt;li&gt;Subnet question? Count host bits before choosing the mask.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The canonical version of this article is on Patternize: &lt;a href="https://patternize.app/learn/network-plus/common-exam-traps/" rel="noopener noreferrer"&gt;https://patternize.app/learn/network-plus/common-exam-traps/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>certification</category>
      <category>networking</category>
      <category>tutorial</category>
      <category>network</category>
    </item>
    <item>
      <title>The CompTIA concepts people keep confusing (and how to actually tell them apart)</title>
      <dc:creator>Constant Itis</dc:creator>
      <pubDate>Sun, 28 Jun 2026 01:50:21 +0000</pubDate>
      <link>https://dev.to/constant_itis/the-comptia-concepts-people-keep-confusing-and-how-to-actually-tell-them-apart-2cb2</link>
      <guid>https://dev.to/constant_itis/the-comptia-concepts-people-keep-confusing-and-how-to-actually-tell-them-apart-2cb2</guid>
      <description>&lt;p&gt;Most wrong answers on Security+ and Network+ aren't knowledge gaps. You read the objective, you watched the video, you could explain the term to a coworker. Then the exam hands you a scenario, two of the five answers look correct, and you pick the wrong one. That's not "I didn't study." That's "I couldn't tell which of these two similar things the question is describing."&lt;/p&gt;

&lt;p&gt;Those are different skills. Knowing what tokenization is and being able to separate it from masking under time pressure are not the same muscle. The exam is built almost entirely on the second one. It rarely asks "define X." It asks "a company needs Y — which control fits," and the trap is a near-neighbor concept that's correct in isolation but wrong for the scenario.&lt;/p&gt;

&lt;p&gt;This is why re-reading notes and grinding more questions past a certain point stops helping. Both reinforce recall. Neither trains discrimination — the ability to name the one feature that splits two look-alikes. Below are the pairs that trip people up the most, with the splitting feature for each. Once you can name the discriminator, the question gets easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  WPA2 vs WPA3
&lt;/h2&gt;

&lt;p&gt;Everyone knows WPA3 is newer and "more secure." The exam doesn't care that you know it's newer. It asks what WPA3 actually added, and that's where people stall.&lt;/p&gt;

&lt;p&gt;Three concrete additions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SAE (Simultaneous Authentication of Equals)&lt;/strong&gt; replaces WPA2's pre-shared key 4-way handshake. The WPA2 handshake can be captured and brute-forced offline. SAE is resistant to that offline dictionary attack and gives forward secrecy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OWE (Opportunistic Wireless Encryption)&lt;/strong&gt; encrypts traffic on &lt;em&gt;open&lt;/em&gt; networks — coffee-shop wifi with no password now has per-client encryption instead of plaintext.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;192-bit security suite&lt;/strong&gt; for WPA3-Enterprise, aimed at high-assurance environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Discriminator: if the scenario says "captured the handshake and cracked it offline," that's the WPA2 weakness SAE fixes. If it says "open network but still want encryption," that's OWE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wildcard vs SAN vs Single certificates
&lt;/h2&gt;

&lt;p&gt;This one is entirely about scope, and people miss it because they reach for "wildcard = covers everything." It does not.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single&lt;/strong&gt; certificate covers one fully qualified domain name. &lt;code&gt;www.example.com&lt;/code&gt; and nothing else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wildcard&lt;/strong&gt; (&lt;code&gt;*.example.com&lt;/code&gt;) covers one level of subdomains: &lt;code&gt;mail.example.com&lt;/code&gt;, &lt;code&gt;shop.example.com&lt;/code&gt;. It does &lt;strong&gt;not&lt;/strong&gt; cover the bare &lt;code&gt;example.com&lt;/code&gt;, and it does &lt;strong&gt;not&lt;/strong&gt; cover &lt;code&gt;api.v2.example.com&lt;/code&gt; — that's a second level down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SAN (Subject Alternative Name)&lt;/strong&gt; certificate covers an explicit list of names you specify: &lt;code&gt;example.com&lt;/code&gt;, &lt;code&gt;www.example.com&lt;/code&gt;, &lt;code&gt;mail.otherdomain.com&lt;/code&gt;. Different domains, multiple specific hosts, whatever you list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Discriminator: count the names and their shape. One host, single. One level of subdomains under a single domain, wildcard. An explicit mixed list, SAN.&lt;/p&gt;

&lt;h2&gt;
  
  
  DV vs OV vs EV certificates
&lt;/h2&gt;

&lt;p&gt;The trap here is assuming these are encryption tiers. They are not. A DV cert and an EV cert give you the &lt;em&gt;exact same&lt;/em&gt; TLS encryption. The difference is who the certificate authority verified before issuing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DV (Domain Validation)&lt;/strong&gt; — the CA confirmed you control the domain. A DNS record or a file on the server. Fast, automatable, no human checks who you are.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OV (Organization Validation)&lt;/strong&gt; — the CA confirmed an actual organization exists and is tied to the domain. Some manual vetting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EV (Extended Validation)&lt;/strong&gt; — the CA vetted the legal entity through a stricter, standardized process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Discriminator: the question is always &lt;em&gt;who got verified&lt;/em&gt;, never &lt;em&gt;how strong is the crypto&lt;/em&gt;. If an answer implies EV is "more encrypted," it's wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tokenization vs Masking vs Encryption
&lt;/h2&gt;

&lt;p&gt;Three ways to protect a data field, and the exam loves to swap them. Split them on two questions: is it reversible, and where does the original live.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encryption&lt;/strong&gt; — reversible with a key. The original is mathematically present in the ciphertext; the key unlocks it. Lose control of the key, lose the data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tokenization&lt;/strong&gt; — the value is swapped for a meaningless token. There's no algorithm that turns the token back into the original; the real value sits in a separate vault, and the token is just a lookup reference. Steal the token database without the vault and you have nothing useful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Masking&lt;/strong&gt; — the value is permanently obscured for display: &lt;code&gt;***-**-1234&lt;/code&gt;. There is no key, no vault, no way back. It's for showing data to people who don't need the full value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Discriminator: reversible with a key → encryption. Reversible only via a separate vault lookup → tokenization. Not reversible at all → masking.&lt;/p&gt;

&lt;h2&gt;
  
  
  MFA vs SSO vs Federation
&lt;/h2&gt;

&lt;p&gt;These get blended because they all sit around "logging in," but they answer different questions. MFA is about &lt;em&gt;how many proofs&lt;/em&gt;. SSO and federation are about &lt;em&gt;how many systems&lt;/em&gt; and &lt;em&gt;across what boundary&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MFA (Multi-Factor Authentication)&lt;/strong&gt; — one login that requires two or more &lt;em&gt;different factor types&lt;/em&gt;: something you know, have, are. A password plus a TOTP code. Two passwords is not MFA — same factor type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSO (Single Sign-On)&lt;/strong&gt; — one login grants access to many applications within the same organization. Authenticate once to the company IdP, reach email, the wiki, and the ticketing system without re-entering credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Federation&lt;/strong&gt; — SSO that crosses an organizational boundary via an established trust relationship, usually SAML or OIDC. Logging into a third-party SaaS vendor using your company identity is federation, because two separate trust domains agreed to honor each other's assertions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Discriminator: count factor types for MFA. Count organizational boundaries for the other two — zero boundaries crossed is SSO, one boundary crossed is federation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two more that cause the same trouble
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NAT vs PAT.&lt;/strong&gt; NAT maps private addresses to public ones. Plain NAT can be a one-to-one mapping. &lt;strong&gt;PAT (Port Address Translation)&lt;/strong&gt; — what most home routers actually do — maps &lt;em&gt;many&lt;/em&gt; private addresses to a &lt;em&gt;single&lt;/em&gt; public IP by tracking port numbers, also called NAT overload. Discriminator: many-to-one using ports is always PAT.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IDS vs IPS.&lt;/strong&gt; Both detect. Only one acts. An &lt;strong&gt;IDS&lt;/strong&gt; sits out of band, watches a copy of the traffic, and alerts — it cannot stop anything. An &lt;strong&gt;IPS&lt;/strong&gt; sits inline, in the traffic path, and can drop or block in real time. Discriminator: if the device can stop the packet, it's inline, and inline means IPS. "Out of band / monitor / SPAN port / alerts only" is IDS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this keeps happening
&lt;/h2&gt;

&lt;p&gt;Notice the shape of every section above. The hard part was never the definition. It was a single splitting feature — reversibility, scope, who-got-verified, how-many-boundaries — that the scenario hides and the wrong answer is built to obscure. Standard studying optimizes recall: flashcards, re-reading, watching the term explained again. None of that trains you to produce the discriminator on demand, which is the exact thing the exam tests.&lt;/p&gt;

&lt;p&gt;The fix is to study the pairs as pairs. Don't ask "what is tokenization." Ask "what one fact separates tokenization from masking, and which way does this scenario point." When you can state the discriminator in a sentence, the near-neighbor trap stops working on you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;If a question feels like a coin flip between two answers, that's the signal — you know both terms and you're missing the line between them. Find the line, write it down, and that whole class of question collapses.&lt;/p&gt;

&lt;p&gt;I built a small free tool that drills these specific confusion pairs the way I described above — &lt;a href="https://patternize.app/learn/most-confused/" rel="noopener noreferrer"&gt;the most-confused concepts list&lt;/a&gt; — but the distinctions in this article stand on their own. The point isn't the tool. It's that "I keep getting these two mixed up" is a fixable, specific problem, and the fix is naming the discriminator rather than studying harder.&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>cybersecurity</category>
      <category>comptia</category>
    </item>
  </channel>
</rss>
