Chapter 1
The problem
Two dimensions
| Temporal composability | Spatial composability | |
|---|---|---|
| Question | When a component is removed, are its modifications to the shared environment completely and safely reversed? | Can components declare, discover and resolve dependencies on one another, and can the system react when those dependencies change? |
| Static answer | Lexical scoping: RAII, bracket, linear types. | Module import resolution. |
| Why it fails dynamically | A plugin loaded after deployment has no lexical scope to bound its long-lived, stateful effects. | No compile-time context can anticipate dependencies that appear, disappear, or change identity at runtime. |
The evidence (§1.2)
VSCode. All extensions share one extension host; there is no way to unload one extension's code. Of the top 100 extensions, 87 contain code and so require a host restart to remove. The deactivate hook only runs at host shutdown, and it is separated from activate, so cleanup completeness cannot be checked locally. Spatially, only 7 of the top 100 declare extensionDependencies on non-built-ins, and cross-extension exports are any. The paper's diagnosis: the API steers extensions toward fixed host-provided extension points, so they never depend on one another.
Self-evolving agent harnesses. A harness that generates and deploys modifications to its own components continuously cannot afford a restart per change (loses process state, disrupts in-flight tasks, and a faulty modification can disable the recovery path itself), nor ad-hoc detection of dependency changes.
The coarse-grained workaround (§1.2.3)
Operating systems give temporal composability at the grain of a process; container orchestrators give spatial composability at the grain of a service. Most software lives with that: restart the misbehaving process, let Kubernetes manage the dependency. The costs are the state a restart discards (caches, connections, partial computations — seconds to minutes to rebuild; replicas to cover the gap) and the inability of container-level orchestration to see dependencies inside one address space, plus network overhead for what could be a function call. "This granularity mismatch demands a compositional abstraction that manages effects and dependencies at the same level as the components themselves."