the published fragment. --> Zero Residue

cordispy · interactive model of examples/run_benefit.py

What a component
leaves behind: zero

One application, built twice — on the cordis runtime and on a conventional plugin registry. Step through the walkthrough, or drive them yourself, and watch where they stop agreeing.

The lab

Both runtimes receive every action you take

The component under test is tool_kv. It mounts routes and opens a journal connection when it loads — and it opens a sqlite connection per key shard, arms a compaction timer and subscribes a tracer while serving a request, long after setup() returned. That last part is the whole experiment.

Walkthrough · not started Press Next step to begin
CORDIS effects on a fiber
resourceliveleaked
total residue 0
CONVENTIONAL REGISTRY setup() / teardown()
resourceliveleaked
total residue 0
WALKTHROUGH

Reach the state that --scenario residue measures to check the model against the real run.

Free play

Drive the two runtimes yourself. The walkthrough above never touches these controls, so anything you change here is your own experiment - press Restart to put the walkthrough back in charge.

store provider
tool_kv
traffic
a component that raises mid-load
 

Why it diverges

Two mechanisms, and neither is a cleanup checklist

Effects

The undo is written where the do is

An effect is a pair — acquire this, and here is how to give it back — recorded on the fiber rather than on the call that ran it. An effect created inside a request handler lands on the same accumulator as one created at load time, so unloading reverses both. Recovery is last-applied-first and happens at most once.

The registry’s teardown() is a method whose author knew only what setup() did. It pops the two routes it mounted and closes the journal it opened. It cannot know about the /kv index route the mount helper added on its behalf, and it certainly cannot know about a connection opened by a request that had not happened yet.

Coeffects

Declare the need, don’t fetch the thing

tool_kv reads ctx.store once and holds it for its whole life. In a conventional system that cached reference is a bug waiting for the provider to be replaced. Here it is correct, because replacing the provider changes the fiber’s target, which unloads the component and loads it again — with a fresh read.

That is also why a component the runtime can activate is one it can deactivate. Set the provider to none and watch one side go quiet and give everything back, while the other keeps reporting itself registered and healthy right up until the next request.

Run it for real

This page models it; these commands measure it

The walkthrough above is modelled on tests/UAT/benefit.sh, which runs the same sequence against the real runtime and asserts each step. There the counts come from a live process: pending tasks are asyncio.all_tasks() set differences, a connection counts as open only if it still answers select 1, and routes and subscribers are read off the actual dispatcher and bus.

./tests/UAT/benefit.sh # step through it, one keypress per step
./tests/UAT/benefit.sh --auto # run it unattended and print a verdict
uv run python examples/run_benefit.py --scenario all

cordispy is a Python realization of the runtime described in A Programming Paradigm for Spatiotemporal Composability (Shi, Zhang, Cui). The conventional side is a faithful implementation of the design most plugin systems converge on — no missing cleanup call and no planted bug; its teardown() undoes exactly what its setup() did. See examples/naive/, docs/benefits.md, and tests/UAT/.