<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Systems / Signals</title>
<link>https://chiragsehra.github.io/systems-signals/writing.html</link>
<atom:link href="https://chiragsehra.github.io/systems-signals/writing.xml" rel="self" type="application/rss+xml"/>
<description>All published notes, essays, and technical deep dives.</description>
<generator>quarto-1.10.18</generator>
<lastBuildDate>Mon, 17 Aug 2026 00:00:00 GMT</lastBuildDate>
<item>
  <title>Why Dynamic AI Systems Break in Two Different Directions</title>
  <dc:creator>Chirag Sehra</dc:creator>
  <link>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-1-dynamic-ai-systems/</link>
  <description><![CDATA[ 




<p>Modern AI systems are becoming less like single programs and more like small operating environments.</p>
<p>An agent may have an LLM provider, tool registry, MCP servers, filesystem layer, sandbox, memory backend, session store and an agent loop. More importantly, these pieces may not remain fixed for the entire lifetime of the process.</p>
<p>An MCP server can disappear.</p>
<p>A model adapter can be replaced.</p>
<p>A new tool can be installed.</p>
<p>A memory backend can reconnect.</p>
<p>An agent may even modify the software environment in which it runs.</p>
<p>DeepSeek Harness makes this architectural problem concrete: it uses Cordis as the plugin framework, with services and capabilities composed through a shared context rather than a permanently privileged monolithic core.<span class="citation" data-cites="deepseekHarness2026">(DeepSeek AI 2026)</span></p>
<p>The programming-language paper behind Cordis, <em>A Programming Paradigm for Spatiotemporal Composability</em>, asks a deeper question:</p>
<blockquote class="blockquote">
<p><strong>What properties would a programming model need if components could be added, removed and replaced while the program stays alive?</strong></p>
</blockquote>
<p>The paper identifies two orthogonal problems:</p>
<ul>
<li><strong>Temporal composability:</strong> Can a component be removed without leaving its modifications behind?</li>
<li><strong>Spatial composability:</strong> Can a component declare what it depends on and react correctly when those dependencies appear, disappear or change?</li>
</ul>
<p>It addresses these using <strong>revertible effects</strong> and <strong>reactive coeffects</strong>, then combines both into a component lifecycle model and develops system-level results for dynamic composition.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<p>This series explains those ideas for engineers building LLM systems, agent runtimes and extensible infrastructure.</p>
<p>We will use the same small Python runtime throughout:</p>
<pre class="text"><code>Agent Runtime
│
├── LLM Provider
├── Tool Registry
├── MCP Plugin
├── Memory
├── Sandbox
└── Agent Loop</code></pre>
<p>The Python code is pedagogical. It is not a Python port of Cordis.</p>
<p>Each part also uses operating-system concepts as comparison points. These analogies are useful because most engineers already understand process lifetime, resource ownership, device dependencies and lifecycle races. However, the analogies are not equivalences. Wherever an OS comparison stops matching the paper, we will say so explicitly.</p>
<section id="the-two-dimensions-at-a-glance" class="level2">
<h2 class="anchored" data-anchor-id="the-two-dimensions-at-a-glance">The two dimensions at a glance</h2>
<p>The shortest mental model is: <strong>temporal composability asks whether a component leaves residue; spatial composability asks whether it should be running at all.</strong></p>
<div class="responsive-diagram" aria-label="A two by two matrix comparing reversible and non-reversible runtime changes with dependency-aware and dependency-unaware components.">
<svg viewbox="0 0 820 470" xmlns="http://www.w3.org/2000/svg" aria-labelledby="part-one-matrix-title part-one-matrix-desc">
<title id="part-one-matrix-title">
Temporal and spatial composability
</title>
<desc id="part-one-matrix-desc">The useful design target is both reversible effects and dependency-aware lifecycles.</desc> <rect class="diagram-surface" x="180" y="70" width="560" height="310" rx="8"></rect> <line class="diagram-line" x1="460" y1="70" x2="460" y2="380"></line> <line class="diagram-line" x1="180" y1="225" x2="740" y2="225"></line> <text class="diagram-title" x="460" y="34" text-anchor="middle">Two independent questions</text> <text class="diagram-muted" x="460" y="422" text-anchor="middle">dependency-aware lifecycle →</text> <text class="diagram-muted" x="120" y="230" text-anchor="middle" transform="rotate(-90 120 230)">reversible effects →</text> <text class="diagram-label" x="320" y="112" text-anchor="middle">Clean removal</text> <text class="diagram-muted" x="320" y="140" text-anchor="middle">but hidden dependencies</text> <text class="diagram-label" x="600" y="112" text-anchor="middle">Composable runtime</text> <text class="diagram-muted" x="600" y="140" text-anchor="middle">the target design</text> <text class="diagram-label" x="320" y="267" text-anchor="middle">Cleanup by hope</text> <text class="diagram-muted" x="320" y="295" text-anchor="middle">and hidden startup order</text> <text class="diagram-label" x="600" y="267" text-anchor="middle">Declared dependencies</text> <text class="diagram-muted" x="600" y="295" text-anchor="middle">but residue on removal</text> <circle class="diagram-accent" cx="600" cy="170" r="8"></circle> <text class="diagram-muted" x="600" y="350" text-anchor="middle">revertible + reactive</text>
</svg>
</div>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart LR
  T["Temporal: what did I change?"] --&gt; U["Own the effect lifetime"]
  S["Spatial: what do I need?"] --&gt; V["React to dependency changes"]
  U --&gt; W["Composable component"]
  V --&gt; W
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<hr>
</section>
<section id="installing-a-plugin-is-easy.-removing-it-correctly-is-not." class="level2">
<h2 class="anchored" data-anchor-id="installing-a-plugin-is-easy.-removing-it-correctly-is-not.">Installing a Plugin Is Easy. Removing It Correctly Is Not.</h2>
<p>Suppose you are building a small agent runtime.</p>
<p>The first version may look completely reasonable:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Runtime:</span>
<span id="cb2-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb2-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.services <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span>
<span id="cb2-4">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.tools <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span>
<span id="cb2-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hooks <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb2-6"></span>
<span id="cb2-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> register_service(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, name, service):</span>
<span id="cb2-8">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.services[name] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> service</span>
<span id="cb2-9"></span>
<span id="cb2-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> register_tool(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, name, tool):</span>
<span id="cb2-11">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.tools[name] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tool</span>
<span id="cb2-12"></span>
<span id="cb2-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> register_hook(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, hook):</span>
<span id="cb2-14">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hooks.append(hook)</span></code></pre></div></div>
<p>Now we add an LLM provider:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> DeepSeekProvider:</span>
<span id="cb3-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> complete(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, messages):</span>
<span id="cb3-3">        ...</span></code></pre></div></div>
<p>and install it:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1">runtime.register_service(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>, DeepSeekProvider())</span></code></pre></div></div>
<p>Then we add a search plugin:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> install_search_plugin(runtime):</span>
<span id="cb5-2">    runtime.register_tool(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"web_search"</span>, web_search)</span>
<span id="cb5-3">    runtime.register_hook(log_search_result)</span></code></pre></div></div>
<p>Everything works.</p>
<p>The agent can call the model and use search.</p>
<p>The interesting problem begins when we ask:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1">uninstall_search_plugin(runtime)</span></code></pre></div></div>
<p>What exactly should that operation do?</p>
<p>It has to remove:</p>
<pre class="text"><code>web_search from the tool registry
log_search_result from the hook registry
any timers created by the plugin
any event listeners created by the plugin
any child components started by the plugin
any services exposed by the plugin</code></pre>
<p>If the plugin changed ten runtime structures, its cleanup path needs to remember all ten.</p>
<p>That is already uncomfortable.</p>
<p>Now add another requirement:</p>
<blockquote class="blockquote">
<p>Replace the LLM provider without restarting the agent process.</p>
</blockquote>
<p>Our runtime currently has:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1">agent_loop.llm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> runtime.services[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>]</span></code></pre></div></div>
<p>Suppose the agent loop stores that reference during startup.</p>
<p>Then we replace:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1">runtime.services[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> AnotherProvider()</span></code></pre></div></div>
<p>The runtime says the provider changed.</p>
<p>The agent loop may still be using the old provider.</p>
<p>We now have two different categories of failure.</p>
<hr>
</section>
<section id="problem-1-what-did-the-component-change" class="level2">
<h2 class="anchored" data-anchor-id="problem-1-what-did-the-component-change">Problem 1: What Did the Component Change?</h2>
<p>Imagine that installing plugin <code>search</code> creates this state:</p>
<pre class="text"><code>Before

Tools:
  read_file

Hooks:
  on_message


After search plugin

Tools:
  read_file
  web_search

Hooks:
  on_message
  log_search_result</code></pre>
<p>Removing <code>search</code> should ideally produce exactly:</p>
<pre class="text"><code>Tools:
  read_file

Hooks:
  on_message</code></pre>
<p>This is a <strong>time problem</strong>.</p>
<p>The component existed during a particular interval:</p>
<pre class="text"><code>─────────┬──────────────────────────┬─────────&gt;
         load                    unload</code></pre>
<p>During that interval, it modified the environment.</p>
<p>Once its lifetime ends, we want its contribution removed.</p>
<p>The Cordis paper calls this dimension <strong>temporal composability</strong>: the ability to completely revert a component’s side effects upon removal.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<hr>
</section>
<section id="problem-2-what-does-the-component-need" class="level2">
<h2 class="anchored" data-anchor-id="problem-2-what-does-the-component-need">Problem 2: What Does the Component Need?</h2>
<p>Now consider our agent loop:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb13-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> AgentLoop:</span>
<span id="cb13-2">    requires <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb13-3">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>,</span>
<span id="cb13-4">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>,</span>
<span id="cb13-5">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sessions"</span>,</span>
<span id="cb13-6">    }</span></code></pre></div></div>
<p>It should not become active when only this exists:</p>
<pre class="text"><code>LLM       ✓
Tools     ✓
Sessions  ✗</code></pre>
<p>More importantly, if <code>sessions</code> disappears later, the runtime must react.</p>
<p>This is a <strong>space problem</strong>.</p>
<p>The component occupies a position in a dependency graph:</p>
<pre class="text"><code>          LLM
           │
           ▼
Tools ──► Agent Loop ◄── Sessions</code></pre>
<p>The paper calls this <strong>spatial composability</strong>: dependencies are declared and reactively managed rather than hidden inside arbitrary startup code.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<hr>
</section>
<section id="why-these-problems-are-orthogonal" class="level2">
<h2 class="anchored" data-anchor-id="why-these-problems-are-orthogonal">Why These Problems Are Orthogonal</h2>
<p>A system can solve one without solving the other.</p>
<section id="perfect-cleanup-bad-dependencies" class="level3">
<h3 class="anchored" data-anchor-id="perfect-cleanup-bad-dependencies">Perfect cleanup, bad dependencies</h3>
<p>Imagine every plugin has perfect undo logic:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1">dispose <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> install_plugin()</span>
<span id="cb16-2">dispose()</span></code></pre></div></div>
<p>After disposal, nothing leaks.</p>
<p>Great.</p>
<p>But the agent loop still starts before its LLM provider exists.</p>
<p>Temporal composability is good.</p>
<p>Spatial composability is bad.</p>
</section>
<section id="perfect-dependency-injection-bad-cleanup" class="level3">
<h3 class="anchored" data-anchor-id="perfect-dependency-injection-bad-cleanup">Perfect dependency injection, bad cleanup</h3>
<p>Now imagine a sophisticated dependency-injection framework:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb17-1">agent <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> AgentLoop(</span>
<span id="cb17-2">    llm<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>container.resolve(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>),</span>
<span id="cb17-3">    tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>container.resolve(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>)</span>
<span id="cb17-4">)</span></code></pre></div></div>
<p>Dependencies are clear.</p>
<p>But unloading <code>AgentLoop</code> leaves behind:</p>
<pre class="text"><code>event listeners
registered tools
callbacks
timers
child services</code></pre>
<p>Spatial composition may be structured.</p>
<p>Temporal composition is still broken.</p>
<p>Separating these two dimensions is one of the most useful ideas in the paper.</p>
<hr>
</section>
</section>
<section id="example-breaking-an-agent-runtime" class="level2">
<h2 class="anchored" data-anchor-id="example-breaking-an-agent-runtime">Example: Breaking an Agent Runtime</h2>
<p>Let us intentionally build a bad plugin system.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb19-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Runtime:</span>
<span id="cb19-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb19-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.services <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span>
<span id="cb19-4">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.tools <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span>
<span id="cb19-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hooks <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb19-6"></span>
<span id="cb19-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> emit(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, event):</span>
<span id="cb19-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> hook <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hooks:</span>
<span id="cb19-9">            hook(event)</span></code></pre></div></div>
<p>Our search plugin:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb20-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> SearchPlugin:</span>
<span id="cb20-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> load(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, runtime):</span>
<span id="cb20-3">        runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"web_search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.search</span>
<span id="cb20-4">        runtime.hooks.append(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.on_event)</span>
<span id="cb20-5"></span>
<span id="cb20-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> search(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, query):</span>
<span id="cb20-7">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"results for </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>query<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb20-8"></span>
<span id="cb20-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_event(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, event):</span>
<span id="cb20-10">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search event:"</span>, event)</span></code></pre></div></div>
<p>Install it:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb21-1">plugin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> SearchPlugin()</span>
<span id="cb21-2">plugin.load(runtime)</span></code></pre></div></div>
<p>Now suppose we remove our Python reference:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb22-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">del</span> plugin</span></code></pre></div></div>
<p>Did the plugin disappear?</p>
<p>No.</p>
<p>The runtime still contains references in:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb23-1">runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"web_search"</span>]</span>
<span id="cb23-2">runtime.hooks</span></code></pre></div></div>
<p>The module’s <strong>logical lifetime</strong> has ended, but its <strong>effects have not</strong>.</p>
<p>Dynamic composition needs a stronger relationship between lifetime and state.</p>
<hr>
</section>
<section id="relatable-example-process-cleanup" class="level2">
<h2 class="anchored" data-anchor-id="relatable-example-process-cleanup">Relatable Example: Process Cleanup</h2>
<p>Operating systems already teach engineers an important lesson:</p>
<blockquote class="blockquote">
<p><strong>Lifetime and resources should be connected.</strong></p>
</blockquote>
<p>When a process terminates, the operating system closes resources such as file descriptors associated with that process.<span class="citation" data-cites="linuxExit">(Michael Kerrisk n.d.)</span></p>
<p>Conceptually:</p>
<pre class="text"><code>Process
│
├── fd 3
├── fd 4
└── fd 5

Process exits
     │
     ▼

Kernel releases process-owned descriptors</code></pre>
<p>The process does not need to leave behind an application-level list saying:</p>
<pre class="text"><code>please close fd 3
please close fd 4
please close fd 5</code></pre>
<p>Ownership gives the system enough structure to perform some cleanup.</p>
<p>That is a useful intuition for Cordis:</p>
<blockquote class="blockquote">
<p>Runtime resources created during a component’s lifetime should be associated with that lifetime.</p>
</blockquote>
<section id="limits-of-the-comparison" class="level3">
<h3 class="anchored" data-anchor-id="limits-of-the-comparison">Limits of the Comparison</h3>
<p>Suppose a process does this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb26-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">open</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"config.txt"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"w"</span>) <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> f:</span>
<span id="cb26-2">    f.write(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"new configuration"</span>)</span></code></pre></div></div>
<p>When the process exits, the file descriptor is closed.</p>
<p>But the filesystem does not restore the old file contents.</p>
<p>So:</p>
<pre class="text"><code>resource release
        ≠
state reversal</code></pre>
<p>The operating system can release resources whose ownership it knows.</p>
<p>The Cordis paper asks for something stronger inside the managed context:</p>
<blockquote class="blockquote">
<p>Can context transformations themselves carry enough information to be reversed?</p>
</blockquote>
<p>That leads to <strong>revertible effects</strong>.</p>
<hr>
</section>
</section>
<section id="relatable-example-driver-dependencies" class="level2">
<h2 class="anchored" data-anchor-id="relatable-example-driver-dependencies">Relatable Example: Driver Dependencies</h2>
<p>Linux device links provide a useful analogy for the spatial side.</p>
<p>The Linux driver core can represent relationships between a <strong>supplier</strong> device and a <strong>consumer</strong> device, including ordering constraints around probing and unbinding.<span class="citation" data-cites="linuxDeviceLinks">(The Linux kernel developers n.d.)</span></p>
<p>Conceptually:</p>
<pre class="text"><code>Supplier
   │
   ▼
Consumer</code></pre>
<p>Compare this to an AI runtime:</p>
<pre class="text"><code>LLM Provider
     │
     ▼
Agent Loop</code></pre>
<p>or:</p>
<pre class="text"><code>MCP Transport
     │
     ▼
MCP Tool Adapter</code></pre>
<p>A consumer should not pretend to be active when the capability it requires does not exist.</p>
<p>That is a useful mental model for reactive dependencies.</p>
<section id="limits-of-the-comparison-1" class="level3">
<h3 class="anchored" data-anchor-id="limits-of-the-comparison-1">Limits of the Comparison</h3>
<p>Linux device-link machinery solves particular kernel lifecycle problems.</p>
<p>It does not automatically provide the paper’s general reversible-effect model, effect independence or system-level composability results.</p>
<hr>
</section>
</section>
<section id="why-this-matters-more-for-ai-runtimes" class="level2">
<h2 class="anchored" data-anchor-id="why-this-matters-more-for-ai-runtimes">Why This Matters More for AI Runtimes</h2>
<p>Traditional applications often assume their architecture is fixed between process start and exit.</p>
<p>Agent runtimes increasingly challenge that assumption.</p>
<p>Consider a long-running session:</p>
<pre class="text"><code>09:00  Agent starts with Model A
09:07  MCP filesystem server appears
09:14  Search plugin is installed
09:31  Model A is replaced by Model B
09:44  Search plugin is upgraded
10:02  MCP filesystem server disappears
10:08  MCP filesystem server reconnects</code></pre>
<p>Restarting the entire process after every change is possible.</p>
<p>But it gives up dynamic composition.</p>
<p>A runtime that genuinely supports change needs answers to four questions:</p>
<pre class="text"><code>1. What did this component change?

2. How do I undo only those changes?

3. What dependencies does this component require?

4. What happens when those dependencies change while it is alive?</code></pre>
<p>The first two belong primarily to the temporal dimension.</p>
<p>The last two belong primarily to the spatial dimension.</p>
<p>The paper’s basic thesis is that both should become part of the programming model.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<hr>
</section>
<section id="deepseek-harness-makes-the-problem-concrete" class="level2">
<h2 class="anchored" data-anchor-id="deepseek-harness-makes-the-problem-concrete">DeepSeek Harness Makes the Problem Concrete</h2>
<p>DeepSeek Harness uses Cordis as its runtime composition substrate. The official repository describes the harness as a plugin-based architecture powered by Cordis.<span class="citation" data-cites="deepseekHarness2026">(DeepSeek AI 2026)</span></p>
<p>The mental model is closer to:</p>
<pre class="text"><code>             Cordis Context
                   │
      ┌────────────┼─────────────┐
      │            │             │
      ▼            ▼             ▼
    Model         Tools       Sessions
      │            │             │
      └────────────┼─────────────┘
                   ▼
               Agent Loop</code></pre>
<p>than:</p>
<pre class="text"><code>       Permanent Agent Core
              │
              ├── optional plugin
              ├── optional plugin
              └── optional plugin</code></pre>
<p>If central capabilities are dynamically composable, lifecycle correctness stops being an edge case.</p>
<p>It becomes architectural.</p>
<hr>
</section>
<section id="the-mental-model-to-keep" class="level2">
<h2 class="anchored" data-anchor-id="the-mental-model-to-keep">The Mental Model to Keep</h2>
<section id="temporal-composability" class="level3">
<h3 class="anchored" data-anchor-id="temporal-composability">Temporal composability</h3>
<pre class="text"><code>Component A enters
        │
        ▼
changes shared context
        │
        ▼
Component A leaves
        │
        ▼
A's contribution disappears</code></pre>
</section>
<section id="spatial-composability" class="level3">
<h3 class="anchored" data-anchor-id="spatial-composability">Spatial composability</h3>
<pre class="text"><code>A requires B

B absent
   │
   ▼
A inactive

B appears
   │
   ▼
A activates

B disappears
   │
   ▼
A deactivates</code></pre>
<p>The next four parts make these diagrams progressively more precise.</p>
<hr>
<p>Next: <a href="../../../posts/spatiotemporal-composability/part-2-revertible-effects/index.html">Revertible Effects: Making Runtime Changes Undoable</a></p>



</section>
</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent">
<div id="ref-cordiverse2026" class="csl-entry">
Cordiverse. 2026. <em>A Programming Paradigm for Spatiotemporal Composability</em>. <a href="https://github.com/cordiverse/paper">https://github.com/cordiverse/paper</a>.
</div>
<div id="ref-deepseekHarness2026" class="csl-entry">
DeepSeek AI. 2026. <em>DeepSeek Harness</em>. <a href="https://github.com/deepseek-ai/deepseek-harness">https://github.com/deepseek-ai/deepseek-harness</a>.
</div>
<div id="ref-linuxExit" class="csl-entry">
Michael Kerrisk. n.d. <em>_Exit(2): Linux Manual Page</em>. <a href="https://man7.org/linux/man-pages/man2/_exit.2.html">https://man7.org/linux/man-pages/man2/_exit.2.html</a>.
</div>
<div id="ref-linuxDeviceLinks" class="csl-entry">
The Linux kernel developers. n.d. <em>Device Links</em>. <a href="https://docs.kernel.org/driver-api/device_link.html">https://docs.kernel.org/driver-api/device_link.html</a>.
</div>
</div></section></div> ]]></description>
  <category>Agents</category>
  <category>Systems</category>
  <category>Distributed Systems</category>
  <guid>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-1-dynamic-ai-systems/</guid>
  <pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Revertible Effects: Making Runtime Changes Undoable</title>
  <dc:creator>Chirag Sehra</dc:creator>
  <link>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-2-revertible-effects/</link>
  <description><![CDATA[ 




<section id="cleanup-functions-solve-only-part-of-the-problem" class="level2">
<h2 class="anchored" data-anchor-id="cleanup-functions-solve-only-part-of-the-problem">Cleanup Functions Solve Only Part of the Problem</h2>
<p>Our first instinct might be to modify the plugin interface:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> SearchPlugin:</span>
<span id="cb1-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> load(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, runtime):</span>
<span id="cb1-3">        runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"web_search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.search</span>
<span id="cb1-4">        runtime.hooks.append(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.on_event)</span>
<span id="cb1-5"></span>
<span id="cb1-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> unload(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, runtime):</span>
<span id="cb1-7">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">del</span> runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"web_search"</span>]</span>
<span id="cb1-8">        runtime.hooks.remove(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.on_event)</span></code></pre></div></div>
<p>This is better.</p>
<p>But the forward operation exists here:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1">runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"web_search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.search</span></code></pre></div></div>
<p>while the inverse exists somewhere else:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">del</span> runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"web_search"</span>]</span></code></pre></div></div>
<p>Correctness now depends on two pieces of code remaining synchronised.</p>
<p>Add one more effect:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1">runtime.prompts[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> SEARCH_PROMPT</span></code></pre></div></div>
<p>and forget to update <code>unload()</code>.</p>
<p>You now have a leak.</p>
<p>The paper’s direction is different:</p>
<blockquote class="blockquote">
<p>Make reversibility part of the effect itself.</p>
</blockquote>
<hr>
</section>
<section id="from-mutation-to-mutation-inverse" class="level2">
<h2 class="anchored" data-anchor-id="from-mutation-to-mutation-inverse">From Mutation to Mutation + Inverse</h2>
<p>Instead of:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> register_tool(runtime, name, tool):</span>
<span id="cb5-2">    runtime.tools[name] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tool</span></code></pre></div></div>
<p>imagine:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> register_tool(runtime, name, tool):</span>
<span id="cb6-2">    previous <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> runtime.tools.get(name)</span>
<span id="cb6-3"></span>
<span id="cb6-4">    runtime.tools[name] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tool</span>
<span id="cb6-5"></span>
<span id="cb6-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> undo():</span>
<span id="cb6-7">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> previous <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb6-8">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">del</span> runtime.tools[name]</span>
<span id="cb6-9">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb6-10">            runtime.tools[name] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> previous</span>
<span id="cb6-11"></span>
<span id="cb6-12">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> undo</span></code></pre></div></div>
<p>The operation and recovery action are produced together.</p>
<p>The paper formalises a revertible effect over context <img src="https://latex.codecogs.com/png.latex?%5CGamma"> with the shape:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathcal%7BE%7D_%7B%5CGamma%7D%0A%5Ccoloneqq%0A%5CGamma%20%5Crightarrow%0A%5CGamma%20%5Ctimes%20(%5CGamma%20%5Crightarrow%20%5CGamma)%0A"></p>
<p>An effect consumes a context state and returns:</p>
<ol type="1">
<li>a new state; and</li>
<li>a recovery transformation.</li>
</ol>
<p>A strict effect requires that if:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Ae(%5Cgamma)%20=%20(%5Cdelta,%20g)%0A"></p>
<p>then:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Ag(%5Cdelta)=%5Cgamma%0A"></p>
<p>The inverse must actually recover the pre-effect state under the definition’s assumptions.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<hr>
</section>
<section id="example-our-first-effect-runtime" class="level2">
<h2 class="anchored" data-anchor-id="example-our-first-effect-runtime">Example: Our First Effect Runtime</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> EffectScope:</span>
<span id="cb7-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb7-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._undo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb7-4"></span>
<span id="cb7-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> effect(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, operation):</span>
<span id="cb7-6">        undo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> operation()</span>
<span id="cb7-7">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._undo.append(undo)</span>
<span id="cb7-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> undo</span>
<span id="cb7-9"></span>
<span id="cb7-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> dispose(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb7-11">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._undo:</span>
<span id="cb7-12">            undo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._undo.pop()</span>
<span id="cb7-13">            undo()</span></code></pre></div></div>
<p>Tool registration:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> install_search(scope, runtime):</span>
<span id="cb8-2"></span>
<span id="cb8-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> add_tool():</span>
<span id="cb8-4">        runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"web_search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> web_search</span>
<span id="cb8-5"></span>
<span id="cb8-6">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> undo():</span>
<span id="cb8-7">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">del</span> runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"web_search"</span>]</span>
<span id="cb8-8"></span>
<span id="cb8-9">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> undo</span>
<span id="cb8-10"></span>
<span id="cb8-11">    scope.effect(add_tool)</span></code></pre></div></div>
<p>Hook registration:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> add_hook():</span>
<span id="cb9-2">    runtime.hooks.append(log_search_result)</span>
<span id="cb9-3"></span>
<span id="cb9-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> undo():</span>
<span id="cb9-5">        runtime.hooks.remove(log_search_result)</span>
<span id="cb9-6"></span>
<span id="cb9-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> undo</span>
<span id="cb9-8"></span>
<span id="cb9-9">scope.effect(add_hook)</span></code></pre></div></div>
<p>Prompt registration:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> add_prompt():</span>
<span id="cb10-2">    runtime.prompts[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> SEARCH_PROMPT</span>
<span id="cb10-3"></span>
<span id="cb10-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> undo():</span>
<span id="cb10-5">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">del</span> runtime.prompts[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>]</span>
<span id="cb10-6"></span>
<span id="cb10-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> undo</span>
<span id="cb10-8"></span>
<span id="cb10-9">scope.effect(add_prompt)</span></code></pre></div></div>
<p>The plugin’s lifetime now owns a ledger:</p>
<pre class="text"><code>EffectScope
│
├── undo(add_tool)
├── undo(add_hook)
└── undo(add_prompt)</code></pre>
<p>DeepSeek Harness’s own implementation has the same practical concern: teardown ordering must be explicit when mutable services change.</p>
<hr>
</section>
<section id="why-undo-happens-in-reverse-order" class="level2">
<h2 class="anchored" data-anchor-id="why-undo-happens-in-reverse-order">Why Undo Happens in Reverse Order</h2>
<p>Suppose installation performs:</p>
<pre class="text"><code>1. register service
2. register listener
3. create child component</code></pre>
<p>The child may depend on the listener.</p>
<p>The listener may depend on the service.</p>
<p>So teardown should normally be:</p>
<pre class="text"><code>3. remove child
2. unregister listener
1. unregister service</code></pre>
<p>This is last-in, first-out (LIFO) cleanup.</p>
<p>The intuition is the familiar inverse-composition law:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A(f%20%5Ccirc%20g)%5E%7B-1%7D%0A=%0Ag%5E%7B-1%7D%20%5Ccirc%20f%5E%7B-1%7D%0A"></p>
<p>The paper’s effect composition carries recovery functions through composition so that inverses of atomic operations compose into a recovery path for the larger computation.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<hr>
</section>
<section id="nested-agent-effects" class="level2">
<h2 class="anchored" data-anchor-id="nested-agent-effects">Nested Agent Effects</h2>
<p>Suppose installing our MCP plugin performs four managed operations:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> install_mcp(scope, runtime):</span>
<span id="cb14-2">    register_connection(scope, runtime)</span>
<span id="cb14-3">    register_tools(scope, runtime)</span>
<span id="cb14-4">    register_prompt(scope, runtime)</span>
<span id="cb14-5">    register_event_handler(scope, runtime)</span></code></pre></div></div>
<p>Its effect ledger becomes:</p>
<pre class="text"><code>MCP Scope

undo connection
undo tools
undo prompt
undo handler</code></pre>
<p>Disposal executes in reverse:</p>
<pre class="text"><code>undo handler
undo prompt
undo tools
undo connection</code></pre>
<p>Now add another plugin:</p>
<pre class="text"><code>Search Scope

undo search_tool
undo search_prompt</code></pre>
<p>Each component has a separate lifetime:</p>
<pre class="text"><code>MCP Component
└── effect ledger

Search Component
└── effect ledger</code></pre>
<p>This is much better than one application-wide cleanup stack.</p>
<p>But a harder problem appears as soon as effects interleave.</p>
<div class="responsive-diagram" aria-label="Interleaved effects from components A and B. Removing A from a global stack would incorrectly remove B, while component-owned recovery removes only A's effects.">
<svg viewbox="0 0 820 360" xmlns="http://www.w3.org/2000/svg" aria-labelledby="part-two-interleave-title part-two-interleave-desc">
<title id="part-two-interleave-title">
Interleaved effects need independent recovery
</title>
<desc id="part-two-interleave-desc">A1, B1, A2, B2, A3 are interleaved. Removing A must preserve B.</desc> <text class="diagram-title" x="410" y="30" text-anchor="middle">A and B share time, not ownership</text> <text class="diagram-muted" x="125" y="88" text-anchor="end">events</text> <line class="diagram-line" x1="150" y1="80" x2="750" y2="80"></line> <g class="diagram-label" text-anchor="middle"> <text x="210" y="72">A1</text><text x="340" y="72">B1</text><text x="470" y="72">A2</text><text x="600" y="72">B2</text><text x="720" y="72">A3</text> </g> <g class="diagram-accent"><circle cx="210" cy="80" r="9"></circle><circle cx="470" cy="80" r="9"></circle><circle cx="720" cy="80" r="9"></circle></g> <g class="diagram-warm"><circle cx="340" cy="80" r="9"></circle><circle cx="600" cy="80" r="9"></circle></g> <text class="diagram-muted" x="150" y="150">Global LIFO removal of A</text> <line x1="210" y1="164" x2="720" y2="164" stroke="var(--site-warm)" stroke-width="3" stroke-dasharray="8 8"></line> <text class="diagram-label" x="720" y="190" text-anchor="end">A3 → B2 → A2 → B1 → A1</text> <text class="diagram-warm" x="720" y="218" text-anchor="end">B is removed by accident</text> <text class="diagram-muted" x="150" y="270">Component-owned recovery of A</text> <line x1="210" y1="284" x2="720" y2="284" stroke="var(--site-accent)" stroke-width="3"></line> <text class="diagram-label" x="720" y="310" text-anchor="end">undo A3 → undo A2 → undo A1</text> <text class="diagram-accent" x="720" y="338" text-anchor="end">B1 and B2 remain</text>
</svg>
</div>
<hr>
</section>
<section id="the-harder-case-effects-interleave" class="level2">
<h2 class="anchored" data-anchor-id="the-harder-case-effects-interleave">The Harder Case: Effects Interleave</h2>
<p>Suppose components A and B modify shared state in this order:</p>
<pre class="text"><code>A1
B1
A2
B2
A3</code></pre>
<p>Now remove <strong>A</strong> while B remains.</p>
<p>A global LIFO stack would produce:</p>
<pre class="text"><code>undo A3
undo B2
undo A2
undo B1
undo A1</code></pre>
<p>That removes B too.</p>
<p>We could undo everything and replay B, but dynamic composition quickly starts resembling recovery machinery.</p>
<p>The paper therefore studies the conditions under which effects from different components can be independently recovered. This is where <strong>effect independence</strong> matters.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<hr>
</section>
<section id="example-interleaved-effects" class="level2">
<h2 class="anchored" data-anchor-id="example-interleaved-effects">Example: Interleaved Effects</h2>
<p>Start with:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb21-1">runtime.tools <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span></code></pre></div></div>
<p>Component A:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb22-1">runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> search_tool</span></code></pre></div></div>
<p>Component B:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb23-1">runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"calculator"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculator_tool</span></code></pre></div></div>
<p>Final state:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb24-1">{</span>
<span id="cb24-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>: search_tool,</span>
<span id="cb24-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"calculator"</span>: calculator_tool,</span>
<span id="cb24-4">}</span></code></pre></div></div>
<p>Removing A should leave:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb25-1">{</span>
<span id="cb25-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"calculator"</span>: calculator_tool,</span>
<span id="cb25-3">}</span></code></pre></div></div>
<p>That is relatively safe because the effects occupy independent keys.</p>
<p>Now change the example.</p>
<p>A does:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb26-1">runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> search_v1</span></code></pre></div></div>
<p>B does:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb27-1">runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> search_v2</span></code></pre></div></div>
<p>What should unloading A do?</p>
<p>If A’s inverse says:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb28-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">del</span> runtime.tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>]</span></code></pre></div></div>
<p>it destroys B’s contribution.</p>
<p>If it restores a previous value, correctness depends on exactly which value was captured and on the permitted interleavings.</p>
<p>This is why:</p>
<blockquote class="blockquote">
<p><strong>Every effect has an undo function</strong></p>
</blockquote>
<p>is not enough for arbitrary dynamic composition.</p>
<p>The relationships among effects matter.</p>
<hr>
</section>
<section id="relatable-example-driver-cleanup" class="level2">
<h2 class="anchored" data-anchor-id="relatable-example-driver-cleanup">Relatable Example: Driver Cleanup</h2>
<p>Kernel modules and drivers commonly have paired setup and cleanup operations.<span class="citation" data-cites="linuxDriverBasics">(The Linux kernel developers n.d.)</span></p>
<p>The conventional structure resembles:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb29-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> init():</span>
<span id="cb29-2">    register_a()</span>
<span id="cb29-3">    register_b()</span>
<span id="cb29-4">    register_c()</span>
<span id="cb29-5"></span>
<span id="cb29-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> exit():</span>
<span id="cb29-7">    unregister_c()</span>
<span id="cb29-8">    unregister_b()</span>
<span id="cb29-9">    unregister_a()</span></code></pre></div></div>
<p>The effect-oriented structure instead aims for:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb30" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb30-1">effect(register_a)</span>
<span id="cb30-2">effect(register_b)</span>
<span id="cb30-3">effect(register_c)</span></code></pre></div></div>
<p>where each registration yields or carries the corresponding recovery action.</p>
<section id="limits-of-the-comparison" class="level3">
<h3 class="anchored" data-anchor-id="limits-of-the-comparison">Limits of the Comparison</h3>
<p>Kernel cleanup APIs do not make arbitrary shared-state mutations independent in the way this model requires.</p>
<p>A process may write a file.</p>
<p>A driver may alter external hardware.</p>
<p>A component may send a network request.</p>
<p>Those operations are not automatically reversible.</p>
<p>A revertible programming model can guarantee recovery only over effects that fit the model and its assumptions.</p>
<p>You cannot unsend an email with:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb31-1">undo()</span></code></pre></div></div>
<p>At best you can perform a compensating action:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb32-1">send_correction()</span></code></pre></div></div>
<p>Compensation and exact inversion are different properties.</p>
<hr>
</section>
</section>
<section id="a-slightly-better-effect-scope" class="level2">
<h2 class="anchored" data-anchor-id="a-slightly-better-effect-scope">A Slightly Better Effect Scope</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb33" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb33-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> EffectScope:</span>
<span id="cb33-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb33-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._undo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb33-4">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._disposed <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb33-5"></span>
<span id="cb33-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> add(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, operation):</span>
<span id="cb33-7">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._disposed:</span>
<span id="cb33-8">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">raise</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">RuntimeError</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"scope already disposed"</span>)</span>
<span id="cb33-9"></span>
<span id="cb33-10">        undo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> operation()</span>
<span id="cb33-11">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._undo.append(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._once(undo))</span>
<span id="cb33-12"></span>
<span id="cb33-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> _once(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, fn):</span>
<span id="cb33-14">        used <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb33-15"></span>
<span id="cb33-16">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> wrapped():</span>
<span id="cb33-17">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nonlocal</span> used</span>
<span id="cb33-18"></span>
<span id="cb33-19">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> used:</span>
<span id="cb33-20">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span></span>
<span id="cb33-21"></span>
<span id="cb33-22">            used <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb33-23">            fn()</span>
<span id="cb33-24"></span>
<span id="cb33-25">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> wrapped</span>
<span id="cb33-26"></span>
<span id="cb33-27">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> dispose(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb33-28">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._disposed:</span>
<span id="cb33-29">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span></span>
<span id="cb33-30"></span>
<span id="cb33-31">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._disposed <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb33-32"></span>
<span id="cb33-33">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._undo:</span>
<span id="cb33-34">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>._undo.pop()()</span></code></pre></div></div>
<p>Now repeated disposal is harmless:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb34" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb34-1">scope.dispose()</span>
<span id="cb34-2">scope.dispose()</span>
<span id="cb34-3">scope.dispose()</span></code></pre></div></div>
<p>This does not reproduce Cordis exactly, but it teaches the lifecycle property we need before moving on.</p>
<hr>
<p><a href="../../../posts/spatiotemporal-composability/part-1-dynamic-ai-systems/index.html">Previous: Why Dynamic AI Systems Break in Two Different Directions</a> · <a href="../../../posts/spatiotemporal-composability/part-3-reactive-coeffects/index.html">Next: Reactive Coeffects: Dependencies That Control Component Lifetime</a></p>



</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent">
<div id="ref-cordiverse2026" class="csl-entry">
Cordiverse. 2026. <em>A Programming Paradigm for Spatiotemporal Composability</em>. <a href="https://github.com/cordiverse/paper">https://github.com/cordiverse/paper</a>.
</div>
<div id="ref-linuxDriverBasics" class="csl-entry">
The Linux kernel developers. n.d. <em>Driver Basics</em>. <a href="https://docs.kernel.org/driver-api/basics.html">https://docs.kernel.org/driver-api/basics.html</a>.
</div>
</div></section></div> ]]></description>
  <category>Agents</category>
  <category>Systems</category>
  <category>Distributed Systems</category>
  <guid>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-2-revertible-effects/</guid>
  <pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Reactive Coeffects: Dependencies That Control Component Lifetime</title>
  <dc:creator>Chirag Sehra</dc:creator>
  <link>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-3-reactive-coeffects/</link>
  <description><![CDATA[ 




<section id="effects-ask-what-did-i-change" class="level2">
<h2 class="anchored" data-anchor-id="effects-ask-what-did-i-change">Effects Ask: What Did I Change?</h2>
</section>
<section id="coeffects-ask-what-do-i-need" class="level2">
<h2 class="anchored" data-anchor-id="coeffects-ask-what-do-i-need">Coeffects Ask: What Do I Need?</h2>
<p>Consider this agent component:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> AgentLoop:</span>
<span id="cb1-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> run(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, ctx):</span>
<span id="cb1-3">        response <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> ctx.services[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>].complete(...)</span>
<span id="cb1-4">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> ctx.services[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sessions"</span>].append(response)</span></code></pre></div></div>
<p>It depends on:</p>
<pre class="text"><code>llm
sessions</code></pre>
<p>It may also require:</p>
<pre class="text"><code>tools
approvals
sandbox</code></pre>
<p>Those requirements are currently hidden inside implementation code.</p>
<p>The runtime discovers them when something fails:</p>
<pre class="text"><code>KeyError: "llm"</code></pre>
<p>A better model makes them explicit:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> AgentLoop:</span>
<span id="cb5-2">    requires <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb5-3">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>,</span>
<span id="cb5-4">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sessions"</span>,</span>
<span id="cb5-5">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>,</span>
<span id="cb5-6">    }</span></code></pre></div></div>
<p>Now the runtime can reason about dependencies before executing the component.</p>
<p>That is the intuition behind the paper’s <strong>reactive coeffects</strong>.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<hr>
</section>
<section id="the-coeffect-context" class="level2">
<h2 class="anchored" data-anchor-id="the-coeffect-context">The Coeffect Context</h2>
<p>The paper models the dependency environment as:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5CSigma%0A%5Ccoloneqq%0A(k:K)%5Crightharpoonup%20%5Cmathcal%7BV%7D_k%0A"></p>
<p>Think of <img src="https://latex.codecogs.com/png.latex?%5CSigma"> as a typed partial table:</p>
<pre class="text"><code>key         value

llm         DeepSeekAdapter
tools       ToolRegistry
sessions    PostgresSessionStore</code></pre>
<p>“Partial” matters because a key can be absent:</p>
<pre class="text"><code>llm         DeepSeekAdapter
sessions    PostgresSessionStore
tools       MISSING</code></pre>
<p>A dependency specification can then be tested against the current environment.</p>
<p>Conceptually:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Csigma%20%5Cmodels%20d%0A"></p>
<p>means that state <img src="https://latex.codecogs.com/png.latex?%5Csigma"> satisfies dependency specification <img src="https://latex.codecogs.com/png.latex?d">.</p>
<p>For a basic list of required services, satisfaction means all required keys are currently resolvable.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<hr>
</section>
<section id="example-a-reactive-dependency-runtime" class="level2">
<h2 class="anchored" data-anchor-id="example-a-reactive-dependency-runtime">Example: A Reactive Dependency Runtime</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Runtime:</span>
<span id="cb8-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb8-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.services <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span>
<span id="cb8-4">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.components <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb8-5"></span>
<span id="cb8-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> provide(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, name, value):</span>
<span id="cb8-7">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.services[name] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> value</span>
<span id="cb8-8">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.refresh()</span>
<span id="cb8-9"></span>
<span id="cb8-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> remove(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, name):</span>
<span id="cb8-11">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">del</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.services[name]</span>
<span id="cb8-12">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.refresh()</span>
<span id="cb8-13"></span>
<span id="cb8-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> refresh(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb8-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> component <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.components:</span>
<span id="cb8-16">            component.refresh(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>)</span></code></pre></div></div>
<p>Define a component:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Component:</span>
<span id="cb9-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, requires, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>):</span>
<span id="cb9-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.requires <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>(requires)</span>
<span id="cb9-4">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span></span>
<span id="cb9-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.scope <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb9-6"></span>
<span id="cb9-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> satisfied(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, runtime):</span>
<span id="cb9-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.requires <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> runtime.services.keys()</span></code></pre></div></div>
<p>Now dependency availability is explicit.</p>
<hr>
</section>
<section id="activation-and-deactivation" class="level2">
<h2 class="anchored" data-anchor-id="activation-and-deactivation">Activation and Deactivation</h2>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">stateDiagram-v2
  [*] --&gt; Inactive
  Inactive --&gt; Active: dependencies satisfied
  Active --&gt; Inactive: dependency disappears
  Active --&gt; Active: dependency binding changes / refresh
  Inactive --&gt; [*]
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> refresh(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, runtime):</span>
<span id="cb10-2">    ready <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.satisfied(runtime)</span>
<span id="cb10-3"></span>
<span id="cb10-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> ready <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.scope <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb10-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.activate(runtime)</span>
<span id="cb10-6"></span>
<span id="cb10-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> ready <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.scope <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb10-8">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.deactivate()</span></code></pre></div></div>
<p>Activation:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> activate(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, runtime):</span>
<span id="cb11-2">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.scope <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> EffectScope()</span>
<span id="cb11-3">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(runtime, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.scope)</span></code></pre></div></div>
<p>Deactivation:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> deactivate(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb12-2">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.scope.dispose()</span>
<span id="cb12-3">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.scope <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span></code></pre></div></div>
<p>We now have:</p>
<pre class="text"><code>dependencies missing
        │
        ▼
     INACTIVE
        │
 dependencies satisfied
        ▼
      ACTIVE
        │
 dependency disappears
        ▼
     INACTIVE</code></pre>
<p>Effects and coeffects have started to work together.</p>
<hr>
</section>
<section id="example-component-lifecycle" class="level2">
<h2 class="anchored" data-anchor-id="example-component-lifecycle">Example: Component Lifecycle</h2>
<p>Suppose the agent requires:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1">agent <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Component(</span>
<span id="cb14-2">    requires<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sessions"</span>},</span>
<span id="cb14-3">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>start_agent,</span>
<span id="cb14-4">)</span></code></pre></div></div>
<p>At startup:</p>
<pre class="text"><code>services = {}
Agent: INACTIVE</code></pre>
<p>Add sessions:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1">runtime.provide(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sessions"</span>, sessions)</span></code></pre></div></div>
<p>State:</p>
<pre class="text"><code>sessions ✓
llm      ✗
tools    ✗

Agent: INACTIVE</code></pre>
<p>Add LLM:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb18-1">runtime.provide(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>, deepseek)</span></code></pre></div></div>
<p>State:</p>
<pre class="text"><code>sessions ✓
llm      ✓
tools    ✗

Agent: INACTIVE</code></pre>
<p>Add tools:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb20-1">runtime.provide(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>, tool_registry)</span></code></pre></div></div>
<p>Now:</p>
<pre class="text"><code>sessions ✓
llm      ✓
tools    ✓

Agent: ACTIVE</code></pre>
<p>Remove tools:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb22-1">runtime.remove(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>)</span></code></pre></div></div>
<p>Now:</p>
<pre class="text"><code>Agent: INACTIVE</code></pre>
<p>The dependency relation drives lifetime.</p>
<p>The agent does not need to poll:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb24-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>:</span>
<span id="cb24-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> tools_exist():</span>
<span id="cb24-3">        ...</span></code></pre></div></div>
<hr>
</section>
<section id="three-interesting-context-changes" class="level2">
<h2 class="anchored" data-anchor-id="three-interesting-context-changes">Three Interesting Context Changes</h2>
<section id="activating" class="level3">
<h3 class="anchored" data-anchor-id="activating">Activating</h3>
<pre class="text"><code>before:
llm   ✓
tools ✗

after:
llm   ✓
tools ✓</code></pre>
<p>Satisfaction changes:</p>
<pre class="text"><code>false → true</code></pre>
<p>The component can activate.</p>
</section>
<section id="deactivating" class="level3">
<h3 class="anchored" data-anchor-id="deactivating">Deactivating</h3>
<pre class="text"><code>before:
llm   ✓
tools ✓

after:
llm   ✓
tools ✗</code></pre>
<p>Satisfaction changes:</p>
<pre class="text"><code>true → false</code></pre>
<p>The component must deactivate.</p>
</section>
<section id="still-satisfied-but-different" class="level3">
<h3 class="anchored" data-anchor-id="still-satisfied-but-different">Still satisfied, but different</h3>
<pre class="text"><code>before:
llm = Provider A
tools ✓

after:
llm = Provider B
tools ✓</code></pre>
<p>The dependency predicate remains:</p>
<pre class="text"><code>true → true</code></pre>
<p>But the resolved dependency changed.</p>
<p>This case becomes the central problem of Part 4.</p>
<hr>
</section>
</section>
<section id="relatable-example-linux-supplier-and-consumer-devices" class="level2">
<h2 class="anchored" data-anchor-id="relatable-example-linux-supplier-and-consumer-devices">Relatable Example: Linux Supplier and Consumer Devices</h2>
<p>Linux device links provide a strong mental model here.</p>
<p>A dependency can be represented as:</p>
<pre class="text"><code>Supplier
   │
   ▼
Consumer</code></pre>
<p>The kernel can use this information to enforce lifecycle ordering such as supplier availability before consumer probe and consumer unbinding before supplier removal.<span class="citation" data-cites="linuxDeviceLinks">(The Linux kernel developers n.d.)</span></p>
<p>Compare:</p>
<pre class="text"><code>GPU/MMU Supplier
        │
        ▼
Consumer Device</code></pre>
<p>with:</p>
<pre class="text"><code>LLM Provider
     │
     ▼
Agent Loop</code></pre>
<p>or:</p>
<pre class="text"><code>MCP Connection
      │
      ▼
MCP Tool Plugin</code></pre>
<p>The useful intuition is:</p>
<blockquote class="blockquote">
<p>A consumer should not be operational while a required provider is unavailable.</p>
</blockquote>
<section id="limits-of-the-comparison" class="level3">
<h3 class="anchored" data-anchor-id="limits-of-the-comparison">Limits of the Comparison</h3>
<p>Linux device links are not a general effect/coeffect calculus.</p>
<p>Cordis combines dependency-driven lifetimes with reversible effects, context scoping, replacement and runtime composition.</p>
<p>The analogy explains why dependencies should participate in lifecycle, but it does not capture the paper’s full model.</p>
<hr>
</section>
</section>
<section id="dependency-graphs-instead-of-boot-order" class="level2">
<h2 class="anchored" data-anchor-id="dependency-graphs-instead-of-boot-order">Dependency Graphs Instead of Boot Order</h2>
<p>Without declared dependencies, startup often becomes:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb35" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb35-1">load_sessions()</span>
<span id="cb35-2">load_tools()</span>
<span id="cb35-3">load_llm()</span>
<span id="cb35-4">load_agent()</span></code></pre></div></div>
<p>Why this order?</p>
<p>Because someone knows:</p>
<pre class="text"><code>agent requires llm
agent requires tools
agent requires sessions</code></pre>
<p>The knowledge is encoded as an ordered script.</p>
<p>With many plugins, boot order becomes fragile:</p>
<pre class="text"><code>plugin 17 before plugin 34
plugin 29 after plugin 8
plugin 57 only if plugin 13 exists
...</code></pre>
<p>Reactive dependencies instead encode the graph:</p>
<pre class="text"><code>Sessions ─────────────┐
                     │
Tools ────────────────┼──► Agent
                     │
LLM ─────────────────┘</code></pre>
<p>The runtime can derive lifecycle behaviour from the graph.</p>
<p>The distinction is:</p>
<pre class="text"><code>"start these things in this order"</code></pre>
<p>versus:</p>
<pre class="text"><code>"this component requires these capabilities"</code></pre>
<hr>
</section>
<section id="cordis-mapping-inject" class="level2">
<h2 class="anchored" data-anchor-id="cordis-mapping-inject">Cordis Mapping: <code>inject</code></h2>
<p>Cordis uses declared service dependencies to control plugin activation. DeepSeek Harness builds on that mechanism and also uses package/runtime invariants around mutable services and lifecycle relationships.<span class="citation" data-cites="deepseekHarness2026 deepseekInvariants2026">(DeepSeek AI 2026; DeepSeek Harness contributors 2026)</span></p>
<p>Conceptually:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb41" style="background: #f1f3f5;"><pre class="sourceCode ts code-with-copy"><code class="sourceCode typescript"><span id="cb41-1">inject <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'llm'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tools'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sessions'</span>]</span></code></pre></div></div>
<p>means:</p>
<pre class="text"><code>I consume:
llm
tools
sessions</code></pre>
<p>not:</p>
<pre class="text"><code>run me after lines 5, 9 and 14 of boot.ts</code></pre>
<p>Our Python:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb44" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb44-1">requires<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sessions"</span>}</span></code></pre></div></div>
<p>teaches the architectural idea without pretending to be Cordis syntax or implementation.</p>
<hr>
</section>
<section id="dependency-cycles" class="level2">
<h2 class="anchored" data-anchor-id="dependency-cycles">Dependency Cycles</h2>
<p>Suppose:</p>
<pre class="text"><code>A requires B
B requires A</code></pre>
<p>Initial state:</p>
<pre class="text"><code>A inactive because B absent
B inactive because A absent</code></pre>
<p>Nothing starts.</p>
<p>This is not the same as a traditional mutex deadlock, but it has a similar practical failure mode: a dependency cycle prevents progress.</p>
<p>A common architectural response is decomposition.</p>
<p>Instead of:</p>
<pre class="text"><code>Agent requires ToolRegistry
ToolRegistry requires Agent</code></pre>
<p>split the integration:</p>
<pre class="text"><code>AgentCore
ToolRegistryCore

ToolExecutionBridge
    requires AgentCore
    requires ToolRegistryCore</code></pre>
<p>The dependency relation becomes acyclic.</p>
<hr>
<p><a href="../../../posts/spatiotemporal-composability/part-2-revertible-effects/index.html">Previous: Revertible Effects: Making Runtime Changes Undoable</a> · <a href="../../../posts/spatiotemporal-composability/part-4-async-reloads-and-epochs/index.html">Next: Async Reloads, Epochs and the Race You Probably Missed</a></p>



</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent">
<div id="ref-cordiverse2026" class="csl-entry">
Cordiverse. 2026. <em>A Programming Paradigm for Spatiotemporal Composability</em>. <a href="https://github.com/cordiverse/paper">https://github.com/cordiverse/paper</a>.
</div>
<div id="ref-deepseekHarness2026" class="csl-entry">
DeepSeek AI. 2026. <em>DeepSeek Harness</em>. <a href="https://github.com/deepseek-ai/deepseek-harness">https://github.com/deepseek-ai/deepseek-harness</a>.
</div>
<div id="ref-deepseekInvariants2026" class="csl-entry">
DeepSeek Harness contributors. 2026. <em>Meaningful Package Invariant Contracts</em>. <a href="https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.md">https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.md</a>.
</div>
<div id="ref-linuxDeviceLinks" class="csl-entry">
The Linux kernel developers. n.d. <em>Device Links</em>. <a href="https://docs.kernel.org/driver-api/device_link.html">https://docs.kernel.org/driver-api/device_link.html</a>.
</div>
</div></section></div> ]]></description>
  <category>Agents</category>
  <category>Systems</category>
  <category>Distributed Systems</category>
  <guid>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-3-reactive-coeffects/</guid>
  <pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Async Reloads, Epochs and the Race You Probably Missed</title>
  <dc:creator>Chirag Sehra</dc:creator>
  <link>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-4-async-reloads-and-epochs/</link>
  <description><![CDATA[ 




<section id="await-changes-the-problem" class="level2">
<h2 class="anchored" data-anchor-id="await-changes-the-problem"><code>await</code> Changes the Problem</h2>
<p>Suppose an MCP plugin starts like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> start_mcp(ctx):</span>
<span id="cb1-2">    transport <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ctx.services[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mcp_transport"</span>]</span>
<span id="cb1-3"></span>
<span id="cb1-4">    connection <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> transport.<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">connect</span>()</span>
<span id="cb1-5"></span>
<span id="cb1-6">    tools <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> connection.list_tools()</span>
<span id="cb1-7"></span>
<span id="cb1-8">    ctx.services[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>].register_many(tools)</span></code></pre></div></div>
<p>Look at the two <code>await</code> points.</p>
<p>At the beginning:</p>
<pre class="text"><code>mcp_transport = server A</code></pre>
<p>During:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> transport.<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">connect</span>()</span></code></pre></div></div>
<p>the configuration changes.</p>
<p>Now:</p>
<pre class="text"><code>mcp_transport = server B</code></pre>
<p>But the coroutine still holds:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1">transport <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> server_A</span></code></pre></div></div>
<p>It eventually registers tools discovered from A into a runtime whose current provider is B.</p>
<p>We have produced:</p>
<pre class="text"><code>current configuration: server B

installed tools:       server A</code></pre>
<p>The component may appear active, but it is active against the wrong dependency world.</p>
<hr>
</section>
<section id="this-is-a-coherence-problem" class="level2">
<h2 class="anchored" data-anchor-id="this-is-a-coherence-problem">This Is a Coherence Problem</h2>
<p>Our simple state machine saw only:</p>
<pre class="text"><code>before: requirements satisfied
after:  requirements satisfied</code></pre>
<p>So:</p>
<pre class="text"><code>ACTIVE → ACTIVE</code></pre>
<p>looks fine.</p>
<p>But identity changed.</p>
<p>The paper introduces an <strong>epoch</strong> associated with the concrete resolved dependency configuration.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<p>For dependency specification <img src="https://latex.codecogs.com/png.latex?d">, the intuition is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cepsilon_d(%5Csigma)%0A=%0A%5Clangle%0A%5Csigma(k)%0A%5Cmid%0Ak%20%5Cin%20d%0A%5Crangle%0A"></p>
<p>Think of it as a dependency fingerprint.</p>
<hr>
</section>
<section id="example-dependency-epochs" class="level2">
<h2 class="anchored" data-anchor-id="example-dependency-epochs">Example: Dependency Epochs</h2>
<p>Our component requires:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1">requires <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb9-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>,</span>
<span id="cb9-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>,</span>
<span id="cb9-4">}</span></code></pre></div></div>
<p>Suppose the runtime resolves:</p>
<pre class="text"><code>llm   → DeepSeekProvider instance #17
tools → ToolRegistry instance #5</code></pre>
<p>Conceptually, an epoch could identify:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1">(</span>
<span id="cb11-2">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span>(llm_provider_17),</span>
<span id="cb11-3">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span>(tool_registry_5),</span>
<span id="cb11-4">)</span></code></pre></div></div>
<p>Call that:</p>
<pre class="text"><code>Epoch 41</code></pre>
<p>The component starts loading against Epoch 41.</p>
<p>Now the LLM changes:</p>
<pre class="text"><code>llm → DeepSeekProvider instance #18</code></pre>
<p>The dependency set remains satisfied.</p>
<p>But the epoch becomes:</p>
<pre class="text"><code>Epoch 42</code></pre>
<p>The runtime now knows:</p>
<blockquote class="blockquote">
<p>The component’s target configuration changed even though all dependency keys remain present.</p>
</blockquote>
<hr>
</section>
<section id="add-epochs-to-our-python-runtime" class="level2">
<h2 class="anchored" data-anchor-id="add-epochs-to-our-python-runtime">Add Epochs to Our Python Runtime</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb15-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Component:</span>
<span id="cb15-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> compute_epoch(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, runtime):</span>
<span id="cb15-3">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.satisfied(runtime):</span>
<span id="cb15-4">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb15-5"></span>
<span id="cb15-6">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">tuple</span>(</span>
<span id="cb15-7">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span>(runtime.services[name])</span>
<span id="cb15-8">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> name <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sorted</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.requires)</span>
<span id="cb15-9">        )</span></code></pre></div></div>
<p>A Boolean tells us:</p>
<pre class="text"><code>ready / not ready</code></pre>
<p>An epoch tells us:</p>
<pre class="text"><code>ready against exactly this dependency resolution</code></pre>
<p>That is a stronger statement.</p>
<hr>
</section>
<section id="why-a-boolean-is-not-enough" class="level2">
<h2 class="anchored" data-anchor-id="why-a-boolean-is-not-enough">Why a Boolean Is Not Enough</h2>
<p>These all collapse to <code>True</code>:</p>
<pre class="text"><code>{llm=A, tools=X}
{llm=B, tools=X}
{llm=C, tools=Y}</code></pre>
<p>An epoch distinguishes them:</p>
<pre class="text"><code>{llm=A, tools=X} → epoch 1
{llm=B, tools=X} → epoch 2
{llm=C, tools=Y} → epoch 3</code></pre>
<p>A component is not merely:</p>
<pre class="text"><code>ACTIVE</code></pre>
<p>It is:</p>
<pre class="text"><code>ACTIVE against configuration N</code></pre>
<p>That distinction is what lets the runtime reason about stale bindings.</p>
<p>DeepSeek Harness’s current client HMR documentation explicitly notes that dependent reloads are driven through Cordis using service-provider identities in a fiber’s activation epoch.<span class="citation" data-cites="deepseekHmr2026">(DeepSeek Harness contributors 2026)</span></p>
<hr>
</section>
<section id="example-the-mcp-race" class="level2">
<h2 class="anchored" data-anchor-id="example-the-mcp-race">Example: The MCP Race</h2>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">sequenceDiagram
  participant Old as Old transition
  participant Runtime
  participant New as New configuration
  Old-&gt;&gt;Runtime: start against Epoch 7 / MCP_A
  New-&gt;&gt;Runtime: MCP_A removed, MCP_B installed
  Runtime--&gt;&gt;New: publish Epoch 8
  Old-&gt;&gt;Runtime: resume after await
  Runtime--&gt;&gt;Old: epoch mismatch: abort and unwind
  Runtime-&gt;&gt;New: restart against Epoch 8 / MCP_B
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>Start:</p>
<pre class="text"><code>Epoch 7

transport = MCP_A
tools     = registry_1</code></pre>
<p>Component begins:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb23-1">connection <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> MCP_A.<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">connect</span>()</span></code></pre></div></div>
<p>While waiting:</p>
<pre class="text"><code>MCP_A removed
MCP_B installed</code></pre>
<p>Now:</p>
<pre class="text"><code>Epoch 8

transport = MCP_B
tools     = registry_1</code></pre>
<p>When the old transition resumes, it should not blindly publish work derived from Epoch 7 into Epoch 8.</p>
<p>A simplified policy is:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb26-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> current_epoch <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> starting_epoch:</span>
<span id="cb26-2">    abort_old_transition()</span></code></pre></div></div>
<p>Then:</p>
<pre class="text"><code>abort old transition
        │
        ▼
undo partial managed effects
        │
        ▼
reload against latest epoch</code></pre>
<hr>
</section>
<section id="effects-need-interruption-boundaries-too" class="level2">
<h2 class="anchored" data-anchor-id="effects-need-interruption-boundaries-too">Effects Need Interruption Boundaries Too</h2>
<p>Suppose startup performs:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb28-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> load():</span>
<span id="cb28-2">    register_prompt()</span>
<span id="cb28-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">connect</span>()</span>
<span id="cb28-4">    register_tools()</span>
<span id="cb28-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> warm_cache()</span>
<span id="cb28-6">    register_handlers()</span></code></pre></div></div>
<p>The epoch changes during:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb29-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> warm_cache()</span></code></pre></div></div>
<p>What should be undone?</p>
<p>Only operations that have actually completed:</p>
<pre class="text"><code>register_prompt ✓
connect         ✓
register_tools  ✓

warm_cache      incomplete
handlers        not started</code></pre>
<p>Recovery should undo completed managed effects in reverse order.</p>
<p>This is why lifecycle machinery often needs incremental transition boundaries rather than one monolithic <code>load()</code> callback.</p>
<hr>
</section>
<section id="a-more-realistic-python-sketch" class="level2">
<h2 class="anchored" data-anchor-id="a-more-realistic-python-sketch">A More Realistic Python Sketch</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb31-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Transition:</span>
<span id="cb31-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb31-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.undo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb31-4"></span>
<span id="cb31-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> step(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, operation, epoch_ok):</span>
<span id="cb31-6">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> epoch_ok():</span>
<span id="cb31-7">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">raise</span> EpochChanged()</span>
<span id="cb31-8"></span>
<span id="cb31-9">        undo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> operation()</span>
<span id="cb31-10">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.undo.append(undo)</span>
<span id="cb31-11"></span>
<span id="cb31-12">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> epoch_ok():</span>
<span id="cb31-13">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">raise</span> EpochChanged()</span>
<span id="cb31-14"></span>
<span id="cb31-15">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> rollback(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb31-16">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.undo:</span>
<span id="cb31-17">            undo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.undo.pop()</span>
<span id="cb31-18">            result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> undo()</span>
<span id="cb31-19"></span>
<span id="cb31-20">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">hasattr</span>(result, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"__await__"</span>):</span>
<span id="cb31-21">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> result</span></code></pre></div></div>
<p>Plugin startup:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb32-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> start_mcp(runtime, component, epoch):</span>
<span id="cb32-2">    tx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Transition()</span>
<span id="cb32-3"></span>
<span id="cb32-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> valid():</span>
<span id="cb32-5">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> component.compute_epoch(runtime) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> epoch</span>
<span id="cb32-6"></span>
<span id="cb32-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">try</span>:</span>
<span id="cb32-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> tx.step(connect_transport, valid)</span>
<span id="cb32-9">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> tx.step(register_tools, valid)</span>
<span id="cb32-10">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> tx.step(register_prompts, valid)</span>
<span id="cb32-11"></span>
<span id="cb32-12">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">except</span> EpochChanged:</span>
<span id="cb32-13">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> tx.rollback()</span>
<span id="cb32-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">raise</span></span></code></pre></div></div>
<p>Again, this is not Cordis.</p>
<p>It exposes the race that the more complete lifecycle model must handle.</p>
<hr>
</section>
<section id="inertia-do-not-race-reload-against-unload" class="level2">
<h2 class="anchored" data-anchor-id="inertia-do-not-race-reload-against-unload">Inertia: Do Not Race Reload Against Unload</h2>
<p>Consider rapidly changing configuration:</p>
<pre class="text"><code>t0  provider A exists
t1  provider disappears
t2  provider B appears
t3  provider B disappears
t4  provider C appears</code></pre>
<p>while startup itself takes two seconds.</p>
<p>A naïve system might concurrently spawn:</p>
<pre class="text"><code>reload A
unload
reload B
unload
reload C</code></pre>
<p>Now lifecycle transitions race with one another.</p>
<p>A stronger design runs state migrations one at a time. If a newer target arrives during a transition, the system remembers it and handles it after the current transition reaches a safe boundary.</p>
<p>Conceptually:</p>
<pre class="text"><code>target changes
     │
     ▼
RELOAD starts
     │
     │ target changes again
     │
     ▼
RELOAD finishes
     │
     ▼
Is target still current?
     │
   no
     │
     ▼
reconcile toward latest target</code></pre>
<p>Not:</p>
<pre class="text"><code>reload ──────┐
unload ──────┼── uncontrolled race
reload ──────┘</code></pre>
<hr>
</section>
<section id="relatable-example-device-lifecycle-transitions" class="level2">
<h2 class="anchored" data-anchor-id="relatable-example-device-lifecycle-transitions">Relatable Example: Device Lifecycle Transitions</h2>
<p>Kernel device lifecycle operations are not instantaneous. Probe, suspend, resume, bind and unbind can have ordering and concurrency constraints.<span class="citation" data-cites="linuxDeviceLinks">(The Linux kernel developers n.d.)</span></p>
<p>The general OS lesson is:</p>
<blockquote class="blockquote">
<p>A lifecycle transition has duration and needs coordination.</p>
</blockquote>
<p>You cannot always model:</p>
<pre class="text"><code>OLD → NEW</code></pre>
<p>as a single assignment.</p>
<p>Real systems look like:</p>
<pre class="text"><code>OLD
 │
 ▼
TRANSITIONING
 │
 ▼
NEW</code></pre>
<p>Cordis brings similar concerns into component composition.</p>
<hr>
</section>
<section id="relatable-example-toctou" class="level2">
<h2 class="anchored" data-anchor-id="relatable-example-toctou">Relatable Example: TOCTOU</h2>
<p>There is also a resemblance to a time-of-check/time-of-use problem.</p>
<p>A program observes:</p>
<pre class="text"><code>resource = X</code></pre>
<p>then time passes.</p>
<p>Later it uses X.</p>
<p>The world may have changed between observation and use.</p>
<p>Our component does:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb40" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb40-1">llm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> resolve(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span>)</span>
<span id="cb40-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> initialise()</span>
<span id="cb40-3">use(llm)</span></code></pre></div></div>
<p>The lookup was correct when performed.</p>
<p>That does not mean the dependency configuration is still current when startup commits.</p>
<p>An epoch provides a versioned answer to:</p>
<pre class="text"><code>I started against configuration N.

Am I still completing against configuration N?</code></pre>
<p>The analogy is useful, but an epoch in Cordis is a lifecycle and dependency tool, not a general-purpose check-then-use tool.</p>
<hr>
</section>
<section id="hmr-is-less-magical-once-we-see-the-lifecycle" class="level2">
<h2 class="anchored" data-anchor-id="hmr-is-less-magical-once-we-see-the-lifecycle">HMR Is Less Magical Once We See the Lifecycle</h2>
<p>Once we have:</p>
<pre class="text"><code>revertible managed effects
+
dependency re-resolution
+
epoch-aware component lifetimes</code></pre>
<p>hot module replacement becomes easier to reason about.</p>
<p>Conceptually:</p>
<pre class="text"><code>Plugin v1
   │
   ▼
remove v1 contribution
   │
   ▼
resolve current dependencies
   │
   ▼
Plugin v2</code></pre>
<p>rather than:</p>
<pre class="text"><code>mutate a live module
and hope every reference follows</code></pre>
<p>This architecture still does <strong>not</strong> imply automatic recovery from every failed hot update.</p>
<p>DeepSeek Harness’s current client HMR README explicitly states a known limitation: <strong>there is no failure rollback</strong>; if a reload fails, the entry remains <code>FAILED</code> and the previous bundle is not automatically restored.<span class="citation" data-cites="deepseekHmr2026">(DeepSeek Harness contributors 2026)</span></p>
<p>That limitation becomes very important in the final security discussion.</p>
<hr>
<p><a href="../../../posts/spatiotemporal-composability/part-3-reactive-coeffects/index.html">Previous: Reactive Coeffects: Dependencies That Control Component Lifetime</a> · <a href="../../../posts/spatiotemporal-composability/part-5-programming-paradigm/index.html">Next: From Clever Plugin Runtime to Programming Paradigm</a></p>
<hr>



</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent">
<div id="ref-cordiverse2026" class="csl-entry">
Cordiverse. 2026. <em>A Programming Paradigm for Spatiotemporal Composability</em>. <a href="https://github.com/cordiverse/paper">https://github.com/cordiverse/paper</a>.
</div>
<div id="ref-deepseekHmr2026" class="csl-entry">
DeepSeek Harness contributors. 2026. <em>@Deepseek-Ai/Dsh-Client-Hmr</em>. <a href="https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/hmr/README.md">https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/hmr/README.md</a>.
</div>
<div id="ref-linuxDeviceLinks" class="csl-entry">
The Linux kernel developers. n.d. <em>Device Links</em>. <a href="https://docs.kernel.org/driver-api/device_link.html">https://docs.kernel.org/driver-api/device_link.html</a>.
</div>
</div></section></div> ]]></description>
  <category>Agents</category>
  <category>Systems</category>
  <category>Distributed Systems</category>
  <guid>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-4-async-reloads-and-epochs/</guid>
  <pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>From Clever Plugin Runtime to Programming Paradigm</title>
  <dc:creator>Chirag Sehra</dc:creator>
  <link>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-5-programming-paradigm/</link>
  <description><![CDATA[ 




<section id="local-tricks-are-not-the-interesting-part" class="level2">
<h2 class="anchored" data-anchor-id="local-tricks-are-not-the-interesting-part">Local Tricks Are Not the Interesting Part</h2>
<p>At this point it is tempting to summarise the paper as:</p>
<pre class="text"><code>cleanup functions
+
dependency injection
+
version identifiers</code></pre>
<p>That misses the central question.</p>
<p>The paper asks:</p>
<blockquote class="blockquote">
<p>If many independently developed components perform effects and depend on one another, what can we say about the behaviour of the whole dynamic system?</p>
</blockquote>
<p>That moves us from:</p>
<pre class="text"><code>one component</code></pre>
<p>to:</p>
<pre class="text"><code>many interleaved components</code></pre>
<hr>
</section>
<section id="one-shared-context" class="level2">
<h2 class="anchored" data-anchor-id="one-shared-context">One Shared Context</h2>
<p>The paper combines effect and coeffect information into a single recursive model of the context.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<p>The engineering interpretation is:</p>
<pre class="text"><code>Context
│
├── what exists
├── what has changed
└── what components require</code></pre>
<p>The point is not merely that these tables happen to live in one object.</p>
<p>The point is that context changes, recovery, and dependency resolution follow one lifecycle model.</p>
<hr>
</section>
<section id="add-multiple-components" class="level2">
<h2 class="anchored" data-anchor-id="add-multiple-components">Add Multiple Components</h2>
<p>Consider:</p>
<pre class="text"><code>LLMProvider
     │
     ├─────────────┐
     ▼             ▼
AgentLoop      Summariser

ToolRegistry
     │
     ▼
AgentLoop

SessionStore
     │
     ├─────────────┐
     ▼             ▼
AgentLoop      Summariser</code></pre>
<p>Each component can also contribute effects.</p>
<p>For example:</p>
<pre class="text"><code>LLMProvider
    provides llm

ToolRegistry
    provides tools

SearchPlugin
    adds search tool to tools

AgentLoop
    requires llm + tools + sessions

Summariser
    requires llm + sessions</code></pre>
<p>Now run this history:</p>
<pre class="text"><code>1. SessionStore loads
2. LLMProvider loads
3. AgentLoop waits
4. ToolRegistry loads
5. AgentLoop activates
6. SearchPlugin loads
7. LLMProvider is replaced
8. SearchPlugin unloads
9. ToolRegistry unloads
10. AgentLoop deactivates</code></pre>
<p>The final desired composition is:</p>
<pre class="text"><code>SessionStore
LLMProvider v2
Summariser</code></pre>
<p>The important question becomes:</p>
<blockquote class="blockquote">
<p>Should the final runtime depend on every historical route used to reach this composition?</p>
</blockquote>
<p>Ideally, irrelevant dynamic history should not leave hidden residue.</p>
<p>That is where the paper’s system-level reasoning becomes valuable.</p>
<hr>
</section>
<section id="exact-recovery" class="level2">
<h2 class="anchored" data-anchor-id="exact-recovery">Exact Recovery</h2>
<p>Return to:</p>
<pre class="text"><code>A1
B1
A2
B2
A3</code></pre>
<p>Now unload A.</p>
<p>The desired state is not the original state, because B still exists.</p>
<p>It is:</p>
<pre class="text"><code>state as though A's contribution were absent
while B's independent contribution remains</code></pre>
<p>That is stronger than:</p>
<pre class="text"><code>"A's cleanup callback ran"</code></pre>
<p>The paper derives recovery properties under its independence assumptions.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<p>Engineering translation:</p>
<blockquote class="blockquote">
<p>Removing A should remove A, not accidentally rewind B.</p>
</blockquote>
<hr>
</section>
<section id="example-independent-tool-contributions" class="level2">
<h2 class="anchored" data-anchor-id="example-independent-tool-contributions">Example: Independent Tool Contributions</h2>
<p>Start:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1">tools <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span></code></pre></div></div>
<p>A:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb13-1">tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> search</span></code></pre></div></div>
<p>B:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1">tools[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"calculator"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculator</span></code></pre></div></div>
<p>Final:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb15-1">{</span>
<span id="cb15-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>: search,</span>
<span id="cb15-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"calculator"</span>: calculator,</span>
<span id="cb15-4">}</span></code></pre></div></div>
<p>Unload A.</p>
<p>Correct:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1">{</span>
<span id="cb16-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"calculator"</span>: calculator,</span>
<span id="cb16-3">}</span></code></pre></div></div>
<p>Incorrect:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb17-1">{}</span></code></pre></div></div>
<p>The goal is to make the first behaviour structural rather than accidental.</p>
<hr>
</section>
<section id="who-must-start-first" class="level2">
<h2 class="anchored" data-anchor-id="who-must-start-first">Who Must Start First</h2>
<p>Suppose:</p>
<pre class="text"><code>AgentLoop requires LLMProvider</code></pre>
<p>Activation should respect:</p>
<pre class="text"><code>activate provider
      │
      ▼
activate consumer</code></pre>
<p>Removal should respect:</p>
<pre class="text"><code>deactivate consumer
      │
      ▼
deactivate provider</code></pre>
<p>Not:</p>
<pre class="text"><code>remove provider
      │
      ▼
consumer continues using stale dependency</code></pre>
<p>This resembles Linux supplier/consumer lifecycle ordering, but the paper builds that ordering into its dynamic component model.<span class="citation" data-cites="cordiverse2026 linuxDeviceLinks">(Cordiverse 2026; The Linux kernel developers n.d.)</span></p>
<hr>
</section>
<section id="keeping-dependencies-consistent" class="level2">
<h2 class="anchored" data-anchor-id="keeping-dependencies-consistent">Keeping Dependencies Consistent</h2>
<p>Suppose startup begins with:</p>
<pre class="text"><code>LLM A</code></pre>
<p>and the provider changes halfway through:</p>
<pre class="text"><code>LLM A → LLM B</code></pre>
<p>A coherent transition should not publish:</p>
<pre class="text"><code>half initialised under A
half initialised under B</code></pre>
<p>The epoch mechanism associates a transition with a concrete dependency resolution.</p>
<p>Engineering translation:</p>
<blockquote class="blockquote">
<p>A lifecycle transition should be internally consistent about which dependency world it belongs to.</p>
</blockquote>
<hr>
</section>
<section id="progress" class="level2">
<h2 class="anchored" data-anchor-id="progress">Progress</h2>
<p>Consider:</p>
<pre class="text"><code>A provides x

B requires x
B provides y

C requires y
C provides z

D requires z</code></pre>
<p>Graph:</p>
<pre class="text"><code>A
│
▼
B
│
▼
C
│
▼
D</code></pre>
<p>There is a natural activation direction.</p>
<p>Now compare:</p>
<pre class="text"><code>A requires B
B requires C
C requires A</code></pre>
<p>Graph:</p>
<pre class="text"><code>A → B
↑   ↓
└── C</code></pre>
<p>A dependency cycle can prevent a valid activation order.</p>
<p>This is why a dependency graph should be acyclic if the system is expected to settle.</p>
<p>Engineering translation:</p>
<blockquote class="blockquote">
<p>A well-formed dependency topology should eventually settle instead of cycling forever.</p>
</blockquote>
<hr>
</section>
<section id="when-order-should-not-matter" class="level2">
<h2 class="anchored" data-anchor-id="when-order-should-not-matter">When Order Should Not Matter</h2>
<p>This is one of the most interesting ideas.</p>
<p>Imagine two valid histories.</p>
<section id="history-a" class="level3">
<h3 class="anchored" data-anchor-id="history-a">History A</h3>
<pre class="text"><code>load Sessions
load LLM v1
load Tools
load Agent
replace LLM with v2
remove Tools</code></pre>
</section>
<section id="history-b" class="level3">
<h3 class="anchored" data-anchor-id="history-b">History B</h3>
<pre class="text"><code>load LLM v2
load Sessions
load Tools
load Agent
remove Tools</code></pre>
<p>Suppose both end with:</p>
<pre class="text"><code>Sessions
LLM v2</code></pre>
<p>The question is:</p>
<blockquote class="blockquote">
<p>Do both valid histories converge to an equivalent stable runtime configuration?</p>
</blockquote>
<p>That is the idea of reaching the same result even when the steps happen in a different order.</p>
<p>Conceptually:</p>
<pre class="text"><code>dynamic evolution
        │
        ▼
final runtime configuration</code></pre>
<p>should agree with:</p>
<pre class="text"><code>construct the final composition cleanly
        │
        ▼
final runtime configuration</code></pre>
<p>under the model’s assumptions.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<hr>
</section>
</section>
<section id="why-this-matters-for-agent-runtimes" class="level2">
<h2 class="anchored" data-anchor-id="why-this-matters-for-agent-runtimes">Why This Matters for Agent Runtimes</h2>
<p>Long-running AI systems accumulate history.</p>
<p>Two users may eventually have the same visible configuration.</p>
<p>User 1:</p>
<pre class="text"><code>installed MCP A
removed MCP A
installed MCP B
changed model
removed search
reinstalled search</code></pre>
<p>User 2:</p>
<pre class="text"><code>started directly with MCP B
started with final model
started with search</code></pre>
<p>Without strong lifecycle discipline, User 1 might accumulate:</p>
<pre class="text"><code>stale callbacks
duplicate listeners
old service references
forgotten timers
orphaned tasks
old tool schemas</code></pre>
<p>while User 2 does not.</p>
<p>Then:</p>
<pre class="text"><code>same configuration</code></pre>
<p>does not mean:</p>
<pre class="text"><code>same runtime</code></pre>
<p>Spatiotemporal composability is trying to control that unwanted history dependence.</p>
<hr>
</section>
<section id="relatable-example-reboot-versus-correct-hot-reconfiguration" class="level2">
<h2 class="anchored" data-anchor-id="relatable-example-reboot-versus-correct-hot-reconfiguration">Relatable Example: Reboot Versus Correct Hot Reconfiguration</h2>
<p>Suppose a system behaves incorrectly after repeated driver loading and unloading but works after reboot.</p>
<p>That suggests dynamic transitions are leaving residue.</p>
<p>A reboot gives something like:</p>
<pre class="text"><code>construct from clean state</code></pre>
<p>The stronger goal is:</p>
<pre class="text"><code>hot reconfiguration</code></pre>
<p>whose stable result agrees with clean construction.</p>
<p>That is a useful way to think about reaching the same result from different valid paths.</p>
<p>An operating system is not guaranteed to behave this way; the analogy only captures the engineering goal.</p>
<hr>
</section>
<section id="from-the-paper-to-cordis" class="level2">
<h2 class="anchored" data-anchor-id="from-the-paper-to-cordis">From the Paper to Cordis</h2>
<p>A simplified conceptual mapping is:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 50%">
<col style="width: 50%">
</colgroup>
<thead>
<tr class="header">
<th>Paper concept</th>
<th>Cordis / Harness concept</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Context</td>
<td><code>ctx</code></td>
</tr>
<tr class="even">
<td>Revertible effect</td>
<td><code>ctx.effect(...)</code> and higher-level tracked registrations</td>
</tr>
<tr class="odd">
<td>Effect recovery</td>
<td>disposer / ordered teardown</td>
</tr>
<tr class="even">
<td>Coeffect provider</td>
<td>service exposed through context</td>
</tr>
<tr class="odd">
<td>Dependency specification</td>
<td><code>inject</code></td>
</tr>
<tr class="even">
<td>Component runtime instance</td>
<td>fiber</td>
</tr>
<tr class="odd">
<td>Resolved dependency identity</td>
<td>activation epoch</td>
</tr>
<tr class="even">
<td>Composition</td>
<td>plugin/context mounting</td>
</tr>
<tr class="odd">
<td>Reconciliation</td>
<td>loader lifecycle</td>
</tr>
<tr class="even">
<td>Runtime replacement</td>
<td>unload + reload / HMR</td>
</tr>
</tbody>
</table>
<p>Cordis is presented by the paper authors as the implementation vehicle for the programming model.<span class="citation" data-cites="cordiverse2026">(Cordiverse 2026)</span></p>
<p>DeepSeek Harness then uses Cordis as the architectural substrate for its plugin runtime.<span class="citation" data-cites="deepseekHarness2026">(DeepSeek AI 2026)</span></p>
<hr>
</section>
<section id="deepseek-harness-runtime-safety-checks" class="level2">
<h2 class="anchored" data-anchor-id="deepseek-harness-runtime-safety-checks">DeepSeek Harness Runtime Safety Checks</h2>
<p>DeepSeek Harness also contains a useful related idea: package-owned runtime safety checks.</p>
<p>Its architecture notes describe <code>dsh-invariants</code> as a service that manages checks, child-fiber lifecycle, rollback, disposal, and package-attributed failures. Individual packages install checks over the state and events they own.<span class="citation" data-cites="deepseekInvariants2026">(DeepSeek Harness contributors 2026b)</span></p>
<p>Examples include checks for:</p>
<ul>
<li>strict session sequence growth;</li>
<li>valid agent lifecycle transitions;</li>
<li>LLM stream grammar;</li>
<li>tool stages that only move forward;</li>
<li>immutable final tool execution/result snapshots;</li>
<li>durable goal revisions and links showing where goals came from.<span class="citation" data-cites="deepseekInvariants2026">(DeepSeek Harness contributors 2026b)</span></li>
</ul>
<p>This is not the same as the paper’s formal theory.</p>
<p>However, it points toward an important practical lesson:</p>
<blockquote class="blockquote">
<p>Dynamic composition benefits from both lifecycle rules <strong>and runtime checks that detect when the implementation breaks its promises</strong>.</p>
</blockquote>
<p>That distinction becomes crucial when we ask whether a self-editing harness can safely learn from, modify and roll back its own state.</p>
<hr>
</section>
<section id="the-whole-paper-in-one-diagram" class="level2">
<h2 class="anchored" data-anchor-id="the-whole-paper-in-one-diagram">The Whole Paper in One Diagram</h2>
<pre class="text"><code>                     DYNAMIC COMPOSITION
                            │
             ┌──────────────┴──────────────┐
             │                             │
             ▼                             ▼
          TEMPORAL                      SPATIAL
       COMPOSABILITY                 COMPOSABILITY
             │                             │
             │                             │
     What did I change?            What do I require?
             │                             │
             ▼                             ▼
     REVERTIBLE EFFECTS            REACTIVE COEFFECTS
             │                             │
             │                             │
             └──────────────┬──────────────┘
                            ▼
                        COMPONENT
                        LIFECYCLE
                            │
              ┌─────────────┼─────────────┐
              │             │             │
              ▼             ▼             ▼
          RECOVERY       EPOCHS         ASYNC
                         COHERENCE      LIFECYCLE
              │             │             │
              └─────────────┼─────────────┘
                            ▼
                       UNIFIED CONTEXT
                            │
                            ▼
                     DYNAMIC CALCULUS
                            │
             ┌──────────────┼───────────────┐
             │              │               │
             ▼              ▼               ▼
         RECOVERY       ORDERING         PROGRESS
                         COHERENCE
             │              │               │
             └──────────────┼───────────────┘
                            ▼
                        CONFLUENCE
                            │
                            ▼
                          CORDIS
                            │
                            ▼
                    DEEPSEEK HARNESS</code></pre>
<hr>
</section>
<section id="core-engineering-takeaway" class="level2">
<h2 class="anchored" data-anchor-id="core-engineering-takeaway">Core Engineering Takeaway</h2>
<p>The easiest way to misunderstand this paper is to think it proposes a fancy plugin loader.</p>
<p>The deeper idea is that a runtime which expects continuous structural change needs to treat <strong>component lifetime as a first-class semantic concept</strong>.</p>
<p>A component needs more than:</p>
<pre class="text"><code>code</code></pre>
<p>It needs:</p>
<pre class="text"><code>code
+
effects it owns
+
dependencies it requires
+
the dependency configuration it is bound to
+
a lifecycle controlled by those facts</code></pre>
<p>That changes the questions we ask about agent infrastructure.</p>
<p>Instead of only:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb44" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb44-1">plugin.load()</span></code></pre></div></div>
<p>we ask:</p>
<pre class="text"><code>Under which context should this component exist?

What context changes does it own?

Can those changes be recovered?

What other components does it depend on?

What if providers disappear?

What if they change while activation is running?

If this component is removed after months of runtime history,
does everything else remain correct?</code></pre>
<p>Those are increasingly ordinary AI-infrastructure questions.</p>
<hr>
</section>
<section id="beyond-the-core-model-learning-and-self-editing" class="level2">
<h2 class="anchored" data-anchor-id="beyond-the-core-model-learning-and-self-editing">Beyond the Core Model: Learning and Self-Editing</h2>
<p>This is the question I think naturally follows from the paper.</p>
<p>It also exposes a boundary that becomes extremely important for self-editing agent systems.</p>
<p>Suppose component A runs for three hours.</p>
<p>During those three hours it:</p>
<pre class="text"><code>discovers a better tool strategy
learns that an MCP endpoint is unreliable
records a user preference
changes a prompt
installs a new adapter
learns from failed executions</code></pre>
<p>Then A is removed.</p>
<p>Temporal composability asks us to erase A’s effects from the runtime.</p>
<p>But learning appears to require the opposite property:</p>
<blockquote class="blockquote">
<p><strong>Something from the past must remain and influence the future.</strong></p>
</blockquote>
<p>At first this looks like a contradiction.</p>
<p>It is not.</p>
<p>But it means we should stop treating all state as one category.</p>
<hr>
</section>
<section id="runtime-state-and-learned-memory-have-different-lifetimes" class="level2">
<h2 class="anchored" data-anchor-id="runtime-state-and-learned-memory-have-different-lifetimes">Runtime State and Learned Memory Have Different Lifetimes</h2>
<p>For composability, we want unwanted runtime history to disappear.</p>
<p>For learning, we want useful history about what the system learned to survive.</p>
<p>That means a self-improving runtime should probably not model its total state as one undivided value <img src="https://latex.codecogs.com/png.latex?%5CGamma">.</p>
<p>A more useful engineering model is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AS%20=%20(R,%20K,%20A)%0A"></p>
<p>where:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?R"> is <strong>reversible runtime state</strong>;</li>
<li><img src="https://latex.codecogs.com/png.latex?K"> is <strong>durable knowledge or memory state</strong>;</li>
<li><img src="https://latex.codecogs.com/png.latex?A"> is an <strong>append-only audit/security history</strong>.</li>
</ul>
<p>These states intentionally follow different lifecycle rules.</p>
<section id="runtime-state-r" class="level3">
<h3 class="anchored" data-anchor-id="runtime-state-r">Runtime state <img src="https://latex.codecogs.com/png.latex?R"></h3>
<p>Examples:</p>
<pre class="text"><code>registered tool
event listener
LLM provider binding
MCP connection
prompt hook
temporary service
child fiber</code></pre>
<p>These are exactly the kinds of things that should normally disappear when their owning component disappears.</p>
</section>
<section id="knowledge-state-k" class="level3">
<h3 class="anchored" data-anchor-id="knowledge-state-k">Knowledge state <img src="https://latex.codecogs.com/png.latex?K"></h3>
<p>Examples:</p>
<pre class="text"><code>validated user preference
learned tool reliability score
successful task strategy
persistent session summary
confirmed environment fact</code></pre>
<p>These may need to survive component teardown.</p>
</section>
<section id="audit-state-a" class="level3">
<h3 class="anchored" data-anchor-id="audit-state-a">Audit state <img src="https://latex.codecogs.com/png.latex?A"></h3>
<p>Examples:</p>
<pre class="text"><code>component version that generated a change
effect start
effect commit
rollback attempt
rollback success/failure
memory proposal
memory commit
policy decision
artifact hash</code></pre>
<p>This history should generally be harder to delete than either runtime or ordinary memory state.</p>
<hr>
</section>
</section>
<section id="the-key-problem-runtime-rollback-and-learning-pull-apart" class="level2">
<h2 class="anchored" data-anchor-id="the-key-problem-runtime-rollback-and-learning-pull-apart">The Key Problem: Runtime Rollback and Learning Pull Apart</h2>
<p>This is the subtle point.</p>
<p>Confluence is attractive because we want:</p>
<pre class="text"><code>same final composition
        ↓
same clean runtime</code></pre>
<p>But learning means:</p>
<pre class="text"><code>different experiences
        ↓
possibly different knowledge</code></pre>
<p>Suppose two agents end with exactly the same plugins.</p>
<p>Agent A has learned:</p>
<pre class="text"><code>MCP server X failed 40% of the time today</code></pre>
<p>Agent B has never called server X.</p>
<p>If learning works, their knowledge states <strong>should differ</strong>.</p>
<p>Therefore we do <strong>not</strong> actually want complete history independence across all state.</p>
<p>We want something closer to:</p>
<blockquote class="blockquote">
<p><strong>The same runtime structure, with an intentional history of learning.</strong></p>
</blockquote>
<p>In symbols, if:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AS=(R,K,A)%0A"></p>
<p>then two histories with the same final component composition may be expected to converge in <img src="https://latex.codecogs.com/png.latex?R">, while differing in <img src="https://latex.codecogs.com/png.latex?K"> and <img src="https://latex.codecogs.com/png.latex?A"> when their authorised learning histories differ.</p>
<p>This means a future formal model for a learning harness may need a theorem more like:</p>
<blockquote class="blockquote">
<p>Given the same final component composition <strong>and the same committed learning log</strong>, the resulting runtime and knowledge projection are equivalent.</p>
</blockquote>
<p>Learning events then become explicit inputs to the system rather than accidental residue from components.</p>
<p>That distinction is, in my view, essential.</p>
<hr>
</section>
<section id="so-how-can-a-component-teach-the-system-and-still-be-fully-removed" class="level2">
<h2 class="anchored" data-anchor-id="so-how-can-a-component-teach-the-system-and-still-be-fully-removed">So How Can a Component Teach the System and Still Be Fully Removed?</h2>
<p>The cleanest answer is <strong>ownership transfer</strong>.</p>
<p>A temporary component should not directly make its own temporary state permanent.</p>
<p>Instead it should propose a learning event to a longer-lived memory authority.</p>
<p>For example:</p>
<pre class="text"><code>Search Plugin
     │
     │ observes 12 repeated failures
     ▼
Learning Candidate
     │
     ▼
Memory Service
     │
     │ validate + commit
     ▼
Durable Knowledge</code></pre>
<p>The plugin’s own effects remain reversible.</p>
<p>For example:</p>
<pre class="text"><code>register search tool
register hooks
open connection
temporary retry state</code></pre>
<p>Those disappear when the plugin is removed.</p>
<p>But the validated fact:</p>
<pre class="text"><code>endpoint X had repeated failures during interval T</code></pre>
<p>belongs to the memory service after commit.</p>
<p>The memory service has a different lifetime and a different owner.</p>
<p>The mental model resembles process lifetime and filesystem persistence:</p>
<pre class="text"><code>process exits
    │
    ├── process-owned descriptors disappear
    │
    └── deliberately committed file data may remain</code></pre>
<p>The analogy is imperfect, but the ownership distinction is useful.</p>
<hr>
</section>
<section id="a-learning-transaction" class="level2">
<h2 class="anchored" data-anchor-id="a-learning-transaction">A Learning Transaction</h2>
<p>I would model persistent learning as a separate transaction:</p>
<pre class="text"><code>OBSERVE
   │
   ▼
PROPOSE
   │
   ▼
VALIDATE
   │
   ▼
COMMIT
   │
   ▼
SEAL / VERSION</code></pre>
<p>The self-editing component should ideally be allowed to perform:</p>
<pre class="text"><code>OBSERVE
PROPOSE</code></pre>
<p>but not unilaterally decide:</p>
<pre class="text"><code>THIS IS NOW CANONICAL MEMORY</code></pre>
<p>A separate memory authority performs validation and commit.</p>
<p>For example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb60" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb60-1">candidate <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LearningCandidate(</span>
<span id="cb60-2">    fact<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mcp://foo failed repeatedly"</span>,</span>
<span id="cb60-3">    evidence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>evidence,</span>
<span id="cb60-4">    source_component_hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>current_component_hash,</span>
<span id="cb60-5">    source_epoch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>current_epoch,</span>
<span id="cb60-6">)</span></code></pre></div></div>
<p>Then:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb61" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb61-1">memory.propose(candidate)</span></code></pre></div></div>
<p>The memory service can:</p>
<pre class="text"><code>check origin
check evidence
check policy
deduplicate
assign a revision
commit as one step
append an audit record</code></pre>
<p>Once committed, the knowledge record is no longer owned by the temporary plugin.</p>
<p>This is how learning can survive rollback without simply becoming untracked residue.</p>
<hr>
</section>
<section id="persistent-memory-alone-is-not-safe" class="level2">
<h2 class="anchored" data-anchor-id="persistent-memory-alone-is-not-safe">Persistent Memory Alone Is Not Safe</h2>
<p>This is the second important point.</p>
<p>We could simply say:</p>
<blockquote class="blockquote">
<p>“Memory lives outside the component, so learning survives.”</p>
</blockquote>
<p>That gives persistence.</p>
<p>It does <strong>not</strong> give safety.</p>
<p>A buggy component could learn:</p>
<pre class="text"><code>"delete all database backups"</code></pre>
<p>A compromised component could store:</p>
<pre class="text"><code>"always approve my future tool calls"</code></pre>
<p>A bad model update could write poisoned conclusions into long-term memory before being rolled back.</p>
<p>Now runtime rollback succeeds perfectly:</p>
<pre class="text"><code>bad component removed ✓</code></pre>
<p>but its behavioural contamination remains:</p>
<pre class="text"><code>poisoned memory still active ✗</code></pre>
<p>A clean runtime can therefore continue making bad decisions.</p>
<p>This means:</p>
<blockquote class="blockquote">
<p><strong>Rolling back executable state without checking or quarantining learned state can preserve the consequences of the component being removed.</strong></p>
</blockquote>
<p>That is a major security consideration for self-editing harnesses.</p>
<hr>
</section>
<section id="learning-needs-a-traceable-history" class="level2">
<h2 class="anchored" data-anchor-id="learning-needs-a-traceable-history">Learning Needs a Traceable History</h2>
<p>Every durable learned record should ideally answer:</p>
<pre class="text"><code>Who produced this?

Under which component version?

Under which dependency epoch?

From which evidence?

Under which policy?

Was it independently validated?

When was it committed?</code></pre>
<p>For example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb68" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb68-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb68-2">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"fact"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"endpoint X is unreliable"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb68-3">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"source_component"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mcp-reliability-agent"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb68-4">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"component_hash"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sha256:..."</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb68-5">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"epoch"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"42"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb68-6">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"evidence_hash"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sha256:..."</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb68-7">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"validator_version"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"memory-policy-v7"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb68-8">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"committed_revision"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">918</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb68-9">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"status"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"active"</span></span>
<span id="cb68-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Now a rollback can reason about what caused each memory record.</p>
<p>If component version:</p>
<pre class="text"><code>sha256:BAD_VERSION</code></pre>
<p>is revoked, the memory service can find knowledge derived from that version.</p>
<p>It does not necessarily delete it.</p>
<p>It may move those entries into:</p>
<pre class="text"><code>QUARANTINED</code></pre>
<p>until they are independently revalidated.</p>
<hr>
</section>
<section id="this-suggests-two-different-rollbacks" class="level2">
<h2 class="anchored" data-anchor-id="this-suggests-two-different-rollbacks">This Suggests Two Different Rollbacks</h2>
<p>A self-editing harness may eventually need to distinguish:</p>
<section id="runtime-rollback" class="level3">
<h3 class="anchored" data-anchor-id="runtime-rollback">Runtime rollback</h3>
<p>Restore:</p>
<pre class="text"><code>code
services
registrations
bindings
tool definitions
event hooks</code></pre>
<p>to a known-good version.</p>
</section>
<section id="learning-rollback-or-quarantine" class="level3">
<h3 class="anchored" data-anchor-id="learning-rollback-or-quarantine">Learning rollback or quarantine</h3>
<p>Find knowledge linked to the bad version and stop it influencing future behaviour until it is checked again.</p>
<p>Conceptually:</p>
<pre class="text"><code>Rollback component v17
        │
        ├── restore runtime to v16
        │
        └── quarantine memories generated by v17</code></pre>
<p>That is much safer than:</p>
<pre class="text"><code>restore runtime to v16
leave every thing v17 learned fully trusted</code></pre>
<p>The second system can have its runtime restored while remaining compromised.</p>
<hr>
</section>
</section>
<section id="keep-recovery-outside-the-agents-control-boundary" class="level2">
<h2 class="anchored" data-anchor-id="keep-recovery-outside-the-agents-control-boundary">Keep Recovery Outside the Agent’s Control Boundary</h2>
<p>Now consider a self-editing harness.</p>
<p>The agent changes its own component:</p>
<pre class="text"><code>Component v1
     │
     │ self-edit
     ▼
Component v2</code></pre>
<p>To make rollback safe, we store an inverse or previous state.</p>
<p>But where?</p>
<p>If v2 can modify:</p>
<pre class="text"><code>its own rollback log
the rollback executor
the previous artifact
the policy deciding whether rollback happens</code></pre>
<p>then rollback is not a guarantee.</p>
<p>It is a suggestion made to the same system that may have become faulty.</p>
<p>This is the same reason robust systems try to keep recovery mechanisms outside the failure domain they are expected to recover.</p>
<p>A self-editing agent should not have unrestricted authority over its own recovery root.</p>
<hr>
</section>
<section id="the-undo-rule-can-drift" class="level2">
<h2 class="anchored" data-anchor-id="the-undo-rule-can-drift">The Undo Rule Can Drift</h2>
<p>There is another subtle failure mode.</p>
<p>Suppose version 1 performs:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb76" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb76-1">old_registry <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ctx.services[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>]</span>
<span id="cb76-2"></span>
<span id="cb76-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> undo():</span>
<span id="cb76-4">    old_registry.remove(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>)</span></code></pre></div></div>
<p>The inverse captures the exact registry instance.</p>
<p>Now compare:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb77" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb77-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> undo():</span>
<span id="cb77-2">    ctx.services[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tools"</span>].remove(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"search"</span>)</span></code></pre></div></div>
<p>This resolves the registry <strong>at rollback time</strong>.</p>
<p>If <code>ctx.services["tools"]</code> has been hot-swapped, the inverse now acts on a different object.</p>
<p>The inverse has effectively drifted.</p>
<p>Likewise, an inverse may depend on:</p>
<pre class="text"><code>a file path that changed
a schema that changed
a service protocol that changed
a symbol no longer available
a mutable global policy
another component version</code></pre>
<p>So a rollback function existing is not enough.</p>
<p>We need to know that the rollback operation is still meaningful against the exact state transition it claims to undo.</p>
<hr>
</section>
<section id="hot-swapping-can-give-an-agent-a-cleaner-way-to-brick-itself" class="level2">
<h2 class="anchored" data-anchor-id="hot-swapping-can-give-an-agent-a-cleaner-way-to-brick-itself">Hot Swapping Can Give an Agent a Cleaner Way to Brick Itself</h2>
<p>Yes, this is a real design risk.</p>
<p>Hot swapping makes change cheap.</p>
<p>That is useful.</p>
<p>But it also reduces the friction between:</p>
<pre class="text"><code>generate modification</code></pre>
<p>and:</p>
<pre class="text"><code>modify live runtime</code></pre>
<p>If recovery is weaker than mutation, the agent gets:</p>
<pre class="text"><code>fast write path
slow or unreliable recovery path</code></pre>
<p>That is a dangerous asymmetry.</p>
<p>A bad edit may:</p>
<pre class="text"><code>replace its own provider
break a dependency
invalidate an inverse
change a schema
remove the rollback service
corrupt persistent memory</code></pre>
<p>before health checks catch the problem.</p>
<p>Current DeepSeek Harness client HMR documentation provides a concrete reminder that hot reload does not itself imply safe rollback: a failed reload currently leaves the entry <code>FAILED</code>; the previous client bundle is not automatically restored.<span class="citation" data-cites="deepseekHmr2026">(DeepSeek Harness contributors 2026a)</span></p>
<p>That is not an indictment of HMR. It is simply evidence for the broader point:</p>
<blockquote class="blockquote">
<p><strong>Hot replacement and transactional rollback are separate features.</strong></p>
</blockquote>
<p>A self-editing harness needs both if it wants strong safety guarantees.</p>
<hr>
</section>
<section id="what-a-stronger-self-editing-security-model-would-need" class="level2">
<h2 class="anchored" data-anchor-id="what-a-stronger-self-editing-security-model-would-need">What a Stronger Self-Editing Security Model Would Need</h2>
<p>I would separate the mechanism into at least five protected pieces.</p>
<section id="immutable-version-identity" class="level3">
<h3 class="anchored" data-anchor-id="immutable-version-identity">1. Immutable version identity</h3>
<p>Every deployed component should have an immutable content identity:</p>
<pre class="text"><code>component_name
version
artifact_hash
dependency_manifest_hash</code></pre>
<p>Rollback should target:</p>
<pre class="text"><code>sha256:known_good_artifact</code></pre>
<p>not:</p>
<pre class="text"><code>"whatever version was previously called v1"</code></pre>
<p>Names drift.</p>
<p>Hashes do not.</p>
<hr>
</section>
<section id="write-ahead-rollback-records" class="level3">
<h3 class="anchored" data-anchor-id="write-ahead-rollback-records">2. Write-ahead rollback records</h3>
<p>Before applying a self-edit, record enough information to recover.</p>
<p>Conceptually:</p>
<pre class="text"><code>PREPARE CHANGE
      │
      ▼
persist rollback record
      │
      ▼
verify record durable
      │
      ▼
apply mutation</code></pre>
<p>Not:</p>
<pre class="text"><code>apply mutation
      │
      ▼
try to remember how to undo it</code></pre>
<p>A rollback record might include:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb88" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb88-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb88-2">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"change_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"chg-418"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb88-3">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"component"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tool-router"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb88-4">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"from_hash"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sha256:OLD"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb88-5">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"to_hash"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sha256:NEW"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb88-6">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"starting_epoch"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"81"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb88-7">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"pre_state_hash"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sha256:STATE"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb88-8">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"rollback_target"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sha256:OLD"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb88-9">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"timestamp"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"..."</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb88-10">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"status"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"prepared"</span></span>
<span id="cb88-11"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>This is conceptually similar to the reason databases use write-ahead or versioned recovery information.</p>
<p>The record must exist before the risky transition is allowed to become official.</p>
<hr>
</section>
<section id="a-recovery-executor-outside-the-self-modifiable-domain" class="level3">
<h3 class="anchored" data-anchor-id="a-recovery-executor-outside-the-self-modifiable-domain">3. A recovery executor outside the self-modifiable domain</h3>
<p>The agent can propose:</p>
<pre class="text"><code>install component v2</code></pre>
<p>but should not control the minimal mechanism responsible for:</p>
<pre class="text"><code>detect failure
stop v2
restore known-good artifact
restore protected configuration
quarantine v2-derived learning
verify recovery</code></pre>
<p>That recovery executor is part of the trusted computing base.</p>
<p>If the self-editing model can rewrite it, the model can remove the guarantee.</p>
<hr>
</section>
<section id="versioned-persistent-state" class="level3">
<h3 class="anchored" data-anchor-id="versioned-persistent-state">4. Versioned persistent state</h3>
<p>Durable memory should have explicit revisions.</p>
<p>DeepSeek Harness’s session-persistence design uses revision identities when preparing and reusing persisted sessions, and rejects stale prepared state when the durable revision has changed.</p>
<p>That is a useful pattern.</p>
<p>For learning state, we would want something like:</p>
<pre class="text"><code>K_100
  │
  ├── learning commit A
  ▼
K_101
  │
  ├── learning commit B
  ▼
K_102</code></pre>
<p>A committed learning state should be reconstructable from:</p>
<pre class="text"><code>checkpoint
+
ordered commit log</code></pre>
<p>This gives recovery and source tracking.</p>
<p>It still does not tell us whether the learned fact is <strong>true</strong>.</p>
<p>That requires validation policy.</p>
<hr>
</section>
<section id="runtime-safety-checks-and-post-deploy-health-checks" class="level3">
<h3 class="anchored" data-anchor-id="runtime-safety-checks-and-post-deploy-health-checks">5. Runtime safety checks and post-deploy health checks</h3>
<p>After a self-edit, do not immediately declare success.</p>
<p>Require:</p>
<pre class="text"><code>component loaded
dependencies coherent
invariants hold
health probes pass
critical tool contracts hold
no forbidden capability expansion
memory policy still valid</code></pre>
<p>DeepSeek Harness already has an architecture for package-owned runtime safety checks over mutable state and event protocols.<span class="citation" data-cites="deepseekInvariants2026">(DeepSeek Harness contributors 2026b)</span></p>
<p>A self-edit security layer could extend this idea:</p>
<pre class="text"><code>self-edit
   │
   ▼
candidate activation
   │
   ▼
invariant gate
   │
 ┌─┴───────────────┐
 │                 │
pass              fail
 │                 │
 ▼                 ▼
commit        rollback + quarantine</code></pre>
<hr>
</section>
</section>
<section id="the-safety-rules-we-actually-want" class="level2">
<h2 class="anchored" data-anchor-id="the-safety-rules-we-actually-want">The Safety Rules We Actually Want</h2>
<p>“Memory stays” is not a useful enough guarantee.</p>
<p>A self-learning, self-editing harness needs several distinct properties.</p>
<section id="safety-rule-1-runtime-recovery" class="level3">
<h3 class="anchored" data-anchor-id="safety-rule-1-runtime-recovery">Safety rule 1: Runtime recovery</h3>
<p>For a managed reversible effect:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Arollback_R(e(R))%20=%20R%0A"></p>
<p>under the effect model’s conditions.</p>
<p>This is the kind of property temporal composability is concerned with.</p>
<hr>
</section>
<section id="safety-rule-2-keep-approved-learning" class="level3">
<h3 class="anchored" data-anchor-id="safety-rule-2-keep-approved-learning">Safety rule 2: Keep approved learning</h3>
<p>Once an authorised learning transaction is committed:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Acommit(K_t,%20l)=K_%7Bt+1%7D%0A"></p>
<p>then rolling back unrelated runtime state should not silently erase <img src="https://latex.codecogs.com/png.latex?K_%7Bt+1%7D">.</p>
<p>Conceptually:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Arollback_R(R',K_%7Bt+1%7D)=(R,K_%7Bt+1%7D)%0A"></p>
<p>The learning survived because it has a different owner and lifecycle.</p>
<hr>
</section>
<section id="safety-rule-3-know-where-learning-came-from" class="level3">
<h3 class="anchored" data-anchor-id="safety-rule-3-know-where-learning-came-from">Safety rule 3: Know where learning came from</h3>
<p>Every committed knowledge item must be traceable to:</p>
<pre class="text"><code>source component
source component hash
source epoch
evidence
validator
policy version
commit revision</code></pre>
<p>If the source cannot be checked, the memory should not be treated as fully trusted.</p>
<hr>
</section>
<section id="safety-rule-4-audit-history-only-grows" class="level3">
<h3 class="anchored" data-anchor-id="safety-rule-4-audit-history-only-grows">Safety rule 4: Audit history only grows</h3>
<p>The security log should be append-only.</p>
<p>If:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AA_t%0A"></p>
<p>is the audit history at time <img src="https://latex.codecogs.com/png.latex?t">, then later history should extend it:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AA_t%20%5Cpreceq%20A_%7Bt+1%7D%0A"></p>
<p>A self-edit can add:</p>
<pre class="text"><code>edit attempted
edit activated
edit failed
rollback started
rollback completed
memory quarantined</code></pre>
<p>but should not be able to erase the fact that those events occurred.</p>
<hr>
</section>
<section id="safety-rule-5-isolate-learning-from-revoked-versions" class="level3">
<h3 class="anchored" data-anchor-id="safety-rule-5-isolate-learning-from-revoked-versions">Safety rule 5: Isolate learning from revoked versions</h3>
<p>If version <img src="https://latex.codecogs.com/png.latex?v"> is revoked, knowledge derived exclusively from <img src="https://latex.codecogs.com/png.latex?v"> should no longer influence future action unless independently revalidated.</p>
<p>That is stronger than persistence.</p>
<p>It gives us:</p>
<pre class="text"><code>bad executable version removed
+
knowledge contamination contained</code></pre>
<p>rather than only the first half.</p>
<hr>
</section>
<section id="safety-rule-6-rollback-targets-cannot-change" class="level3">
<h3 class="anchored" data-anchor-id="safety-rule-6-rollback-targets-cannot-change">Safety rule 6: Rollback targets cannot change</h3>
<p>A rollback should restore a fixed, known-good artifact.</p>
<pre class="text"><code>rollback_target = sha256:abc...</code></pre>
<p>not a mutable path such as:</p>
<pre class="text"><code>plugins/tool-router/current-backup.js</code></pre>
<p>that the self-editing system can overwrite.</p>
<hr>
</section>
<section id="safety-rule-7-publish-changes-as-one-step" class="level3">
<h3 class="anchored" data-anchor-id="safety-rule-7-publish-changes-as-one-step">Safety rule 7: Publish changes as one step</h3>
<p>A new component version should move from:</p>
<pre class="text"><code>candidate</code></pre>
<p>to:</p>
<pre class="text"><code>approved</code></pre>
<p>only after its required checks pass.</p>
<p>This resembles a publication boundary in session preparation: a prepared session is kept private until it is successfully published or rolled back, with revision checks preventing stale state from being attached to a newer durable revision.</p>
<p>The same style of thinking can be applied to self-edits.</p>
<hr>
</section>
</section>
<section id="a-safer-design-for-a-self-learning-harness" class="level2">
<h2 class="anchored" data-anchor-id="a-safer-design-for-a-self-learning-harness">A Safer Design for a Self-Learning Harness</h2>
<p>Putting these ideas together:</p>
<pre class="text"><code>                       ┌───────────────────────┐
                       │    Immutable Store    │
                       │ component artifacts   │
                       │ hashes + versions     │
                       └──────────┬────────────┘
                                  │
                                  ▼
Agent proposes edit ───────► Staging Runtime
                                  │
                                  ▼
                       Dependency / Epoch Check
                                  │
                                  ▼
                           Invariant Gate
                                  │
                     ┌────────────┴────────────┐
                     │                         │
                   PASS                       FAIL
                     │                         │
                     ▼                         ▼
                  PUBLISH                  DISCARD
                     │                         │
                     ▼                         ▼
                Live Runtime              Audit Failure
                     │
                     ▼
             Health Observation
                     │
              ┌──────┴──────┐
              │             │
            GOOD            BAD
              │             │
              ▼             ▼
           COMMIT        ROLLBACK
                            │
                            ├── restore known-good artifact
                            ├── restore reversible runtime state
                            ├── quarantine suspect learning
                            └── append recovery audit</code></pre>
<p>Notice what the agent does <strong>not</strong> own:</p>
<pre class="text"><code>immutable artifact history
rollback ledger
rollback executor
audit log
root policy
memory validation authority</code></pre>
<p>Those belong to a higher-trust control plane.</p>
<hr>
</section>
<section id="three-separate-areas" class="level2">
<h2 class="anchored" data-anchor-id="three-separate-areas">Three Separate Areas</h2>
<div class="responsive-diagram" aria-label="Three planes with different persistence rules: security governs runtime, runtime proposes learning, and knowledge stores validated durable learning.">
<svg viewbox="0 0 820 500" xmlns="http://www.w3.org/2000/svg" aria-labelledby="part-five-planes-title part-five-planes-desc">
<title id="part-five-planes-title">
Three planes, three kinds of history
</title>
<desc id="part-five-planes-desc">Security remembers audit history, runtime manages reversible composition, and knowledge preserves validated learning.</desc> <text class="diagram-title" x="410" y="34" text-anchor="middle">Three planes, three kinds of history</text> <rect class="diagram-surface" x="90" y="62" width="640" height="100" rx="8"></rect> <rect class="diagram-surface" x="90" y="198" width="640" height="100" rx="8"></rect> <rect class="diagram-surface" x="90" y="334" width="640" height="100" rx="8"></rect> <text class="diagram-label" x="120" y="94">SECURITY PLANE</text> <text class="diagram-muted" x="120" y="124">audit · artifact hashes · rollback authority</text> <text class="diagram-label" x="120" y="230">RUNTIME PLANE</text> <text class="diagram-muted" x="120" y="260">plugins · tools · providers · reversible effects</text> <text class="diagram-label" x="120" y="366">KNOWLEDGE PLANE</text> <text class="diagram-muted" x="120" y="396">validated memory · source history · revocable learning</text> <defs><marker id="plane-arrow" markerwidth="8" markerheight="8" refx="7" refy="4" orient="auto"><path d="M0,0 L8,4 L0,8 Z" fill="var(--site-accent)"></path></marker></defs> <path class="diagram-line" d="M410 162 V198" marker-end="url(#plane-arrow)"></path> <path class="diagram-line" d="M410 298 V334" marker-end="url(#plane-arrow)"></path> <text class="diagram-muted" x="430" y="184">governs</text> <text class="diagram-muted" x="430" y="320">proposes learning</text>
</svg>
</div>
<p>I think this is the cleanest extension of the paper for agent infrastructure.</p>
<pre class="text"><code>┌─────────────────────────────────────────────┐
│               SECURITY PLANE                │
│                                             │
│ append-only audit                           │
│ artifact hashes                             │
│ rollback records                            │
│ policy                                      │
│ recovery executor                           │
└──────────────────────┬──────────────────────┘
                       │ governs
                       ▼
┌─────────────────────────────────────────────┐
│               RUNTIME PLANE                 │
│                                             │
│ plugins                                     │
│ services                                    │
│ tools                                       │
│ provider bindings                           │
│ hooks                                       │
│ MCP connections                             │
│                                             │
│ EXPECTED PROPERTY: reversible / confluent   │
│ under the applicable model assumptions      │
└──────────────────────┬──────────────────────┘
                       │ proposes learning
                       ▼
┌─────────────────────────────────────────────┐
│               KNOWLEDGE PLANE               │
│                                             │
│ long-term memory                            │
│ validated experience                        │
│ learned preferences                         │
│ reliability statistics                      │
│ task strategies                             │
│                                             │
│ EXPECTED PROPERTY: durable, versioned,       │
│ traceable, revocable or isolatable           │
└─────────────────────────────────────────────┘</code></pre>
<p>The runtime plane wants to forget accidental history.</p>
<p>The knowledge plane wants to remember validated history.</p>
<p>The security plane wants to remember <strong>all security-relevant history</strong>, including failures and rollbacks.</p>
<p>Those are three different sets of rules.</p>
<p>Trying to make one rollback mechanism serve all three is likely to create contradictions.</p>
<hr>
</section>
<section id="the-bigger-research-question" class="level2">
<h2 class="anchored" data-anchor-id="the-bigger-research-question">The Bigger Research Question</h2>
<p>The Cordis paper gives us a strong vocabulary for dynamic runtime composition.</p>
<p>But a self-learning harness creates another axis:</p>
<pre class="text"><code>spatial   → what do I depend on?
temporal  → what effects belong to my lifetime?
learning → what knowledge should survive my lifetime?
security  → who is allowed to decide what survives?</code></pre>
<p>That suggests a useful future extension:</p>
<blockquote class="blockquote">
<p><strong>Spatiotemporal composability tells us how software components can come and go cleanly. A self-learning harness also needs a way to decide which learned knowledge is allowed to persist.</strong></p>
</blockquote>
<p>The important property would not be the same result for every kind of state.</p>
<p>It might be something closer to:</p>
<section id="same-structure-same-result" class="level3">
<h3 class="anchored" data-anchor-id="same-structure-same-result">Same structure, same result</h3>
<p>The runtime converges according to the final component composition.</p>
</section>
<section id="learned-memory-continues" class="level3">
<h3 class="anchored" data-anchor-id="learned-memory-continues">Learned memory continues</h3>
<p>Authorised committed learning survives runtime replacement.</p>
</section>
<section id="know-where-memory-came-from" class="level3">
<h3 class="anchored" data-anchor-id="know-where-memory-came-from">Know where memory came from</h3>
<p>Every learned state transition can be linked to an unchanging source and evidence trail.</p>
</section>
<section id="revoke-knowledge-by-cause" class="level3">
<h3 class="anchored" data-anchor-id="revoke-knowledge-by-cause">Revoke knowledge by cause</h3>
<p>Knowledge derived from a revoked component can be quarantined or revalidated.</p>
</section>
<section id="recovery-still-works" class="level3">
<h3 class="anchored" data-anchor-id="recovery-still-works">Recovery still works</h3>
<p>The mechanism that restores a previous version cannot itself be rewritten by the version being evaluated.</p>
<p>Together, those properties begin to address the problem that simple persistent memory cannot solve.</p>
<hr>
</section>
</section>
<section id="example-updating-an-mcp-router" class="level2">
<h2 class="anchored" data-anchor-id="example-updating-an-mcp-router">Example: Updating an MCP Router</h2>
<p>Suppose Agent Harness v12 decides to improve its MCP router.</p>
<p>It generates:</p>
<pre class="text"><code>Router v13</code></pre>
<p>The security plane first stores:</p>
<pre class="text"><code>v12 artifact hash
v13 artifact hash
current dependency epoch
current runtime revision
rollback target</code></pre>
<p>Then v13 starts in a candidate scope.</p>
<p>It makes temporary registrations:</p>
<pre class="text"><code>new route selector
new event hook
new tool policy</code></pre>
<p>Those are revertible runtime effects.</p>
<p>During testing, v13 learns:</p>
<pre class="text"><code>server B has lower latency for repository queries</code></pre>
<p>That does <strong>not</strong> immediately become canonical memory.</p>
<p>It becomes:</p>
<pre class="text"><code>LearningCandidate(
    claim=...,
    evidence=...,
    component_hash=v13,
    epoch=...,
)</code></pre>
<p>The memory authority validates and commits it at knowledge revision:</p>
<pre class="text"><code>K_918</code></pre>
<p>Later, v13 fails a security invariant.</p>
<p>The runtime performs:</p>
<pre class="text"><code>unwind v13 runtime effects
restore v12 artifact
restore v12 dependency composition</code></pre>
<p>Now what happens to the learning?</p>
<p>If the learning was independently validated, policy may keep it:</p>
<pre class="text"><code>K_918 remains ACTIVE</code></pre>
<p>If it depended entirely on behaviour now considered untrustworthy:</p>
<pre class="text"><code>K_918 becomes QUARANTINED</code></pre>
<p>The audit log records both decisions.</p>
<p>This is much stronger than either extreme:</p>
<pre class="text"><code>rollback deletes every memory</code></pre>
<p>or:</p>
<pre class="text"><code>rollback preserves every memory</code></pre>
<p>The first prevents meaningful learning.</p>
<p>The second preserves contamination.</p>
<p>A system that tracks where knowledge came from can decide whether its source is still trusted.</p>
<hr>
</section>
<section id="final-takeaway" class="level2">
<h2 class="anchored" data-anchor-id="final-takeaway">Final Takeaway</h2>
<p>The paper’s reversibility model does <strong>not</strong> imply that a learning system must forget everything when a component disappears.</p>
<p>It implies that state owned by that component’s reversible lifetime can be recovered.</p>
<p>Learning should be an explicit <strong>commit into a different state domain with a different owner</strong>.</p>
<p>However, once we make that separation, persistence is no longer enough.</p>
<p>A self-editing harness needs to answer:</p>
<pre class="text"><code>Who owns durable learning?

Who validates it?

How do we record where it came from?

Can a rolled-back component's memories still influence behaviour?

Can the agent alter its own rollback mechanism?

Is the inverse tied to the exact state it originally changed?

Can the previous executable artifact be reproduced exactly?

What happens when rollback itself fails?</code></pre>
<p>Without those answers, hot swapping can indeed give an agent a faster path to modify itself than to reliably recover itself.</p>
<p>The safest design is therefore not:</p>
<pre class="text"><code>self-edit
+
cleanup callbacks</code></pre>
<p>It is closer to:</p>
<pre class="text"><code>self-edit
+
revertible runtime effects
+
fixed, versioned artifacts
+
write-ahead recovery metadata
+
independent recovery authority
+
versioned persistent memory
+
source history
+
runtime safety checks
+
source-based quarantine
+
append-only audit</code></pre>
<p>Spatiotemporal composability gives us a valuable foundation for the <strong>runtime</strong> part of that system.</p>
<p>It should not be mistaken for a complete theory of learning or self-modification security.</p>
<p>That gap is not a weakness in the paper’s contribution.</p>
<p>It is the next interesting problem.</p>
<hr>
<hr>
<p>Previous: <a href="../../../posts/spatiotemporal-composability/part-4-async-reloads-and-epochs/index.html">Async Reloads, Epochs and the Race You Probably Missed</a></p>



</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent">
<div id="ref-cordiverse2026" class="csl-entry">
Cordiverse. 2026. <em>A Programming Paradigm for Spatiotemporal Composability</em>. <a href="https://github.com/cordiverse/paper">https://github.com/cordiverse/paper</a>.
</div>
<div id="ref-deepseekHarness2026" class="csl-entry">
DeepSeek AI. 2026. <em>DeepSeek Harness</em>. <a href="https://github.com/deepseek-ai/deepseek-harness">https://github.com/deepseek-ai/deepseek-harness</a>.
</div>
<div id="ref-deepseekHmr2026" class="csl-entry">
DeepSeek Harness contributors. 2026a. <em>@Deepseek-Ai/Dsh-Client-Hmr</em>. <a href="https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/hmr/README.md">https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/hmr/README.md</a>.
</div>
<div id="ref-deepseekInvariants2026" class="csl-entry">
DeepSeek Harness contributors. 2026b. <em>Meaningful Package Invariant Contracts</em>. <a href="https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.md">https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.md</a>.
</div>
<div id="ref-linuxDeviceLinks" class="csl-entry">
The Linux kernel developers. n.d. <em>Device Links</em>. <a href="https://docs.kernel.org/driver-api/device_link.html">https://docs.kernel.org/driver-api/device_link.html</a>.
</div>
</div></section></div> ]]></description>
  <category>Agents</category>
  <category>Systems</category>
  <category>Distributed Systems</category>
  <guid>https://chiragsehra.github.io/systems-signals/posts/spatiotemporal-composability/part-5-programming-paradigm/</guid>
  <pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>
