Cordis In-Depth: Reactive Resource Tracking and Spatiotemporal Composability
> A responsive microkernel with automatic resource tracking — making reversible plugin installation and reactive dependency resolution runtime invariants
This article examines cordis, a TypeScript meta-framework for spatiotemporal composability, and its theoretical foundation in *A Programming Paradigm for Spatiotemporal Composability*. The assessment combines an 88-page theoretical reading of the paper with first-party source-code and repository evidence from two parallel research tracks. Statements directly supported by the paper are marked [Paper], while inferences are marked [Inference].
Key points
- Cordis is more than an IoC container. It controls both the lifecycle of plugin side effects and the availability-driven lifecycle of plugin dependencies.
- Temporal composability means safe rollback. Effects carry explicit cleanup operations, and teardown applies them in reverse order.
- Spatial composability means reactive dependency management. A fiber remains pending when a required service is unavailable, unloads when the service disappears, and reloads when it returns.
- The formal model is coherent with the implementation. Proxy contexts, fiber state machines, effect trees,
extend,isolate, andinterceptcorrespond closely to the paper's formal constructs. - Production maturity remains questionable. The upstream API is unstable, its maintenance is highly concentrated, and a vendored version in DeepSeek Harness previously required concurrency and disposal hardening.
- “Algebraic effect system” is an imprecise description. Cordis has no type-level effect rows or continuation capture; it is a library-level, dynamic mechanism built around disposer-returning effects.
extend(meta)creates an inherited context with shadowing.
-isolate(name, label?)- Twisted composition: forward functions are composed normally, while inverse functions are accumulated in reverse order.
- Effect context: combines the current state with an inverse-accumulation function.
- Witnessed effects: every resulting state selects an inverse that returns to the state from which that effect began.
- a value type;
- an equivalence relation; and
- operations supplied for that key.
- declared dependencies;
- keys it provides; and
- an effect function with a witnessed inverse.
- A fiber state machine coordinates loading, unloading, inertia, and HMR.
- Proxy-mediated property access enforces declared coeffect specifications, while bare
- protecting effect ownership during reentrant disposal;
- rolling back cleanup when synchronous setup fails;
- rejecting new effects while an owner is unloading;
- making loader and include updates transactional;
- preventing a group update from becoming permanently unsettled under reentrant concurrency;
- handling Windows file-system races and path-format conflicts; and
- adopting lazy configuration resolution from upstream PR
- Koishi, the mature chat-bot framework and strongest real-world ecosystem example;
- Cordis upstream;
- the theoretical paper repository; and
- DeepSeek Harness.
- A dependency cycle can leave a component predictably
- The reported include/HMR update deadlock was an implementation failure in which the fiber never settled.
- long-lived processes;
- agent runtimes;
- extensible development-tool hosts;
- chat-bot systems;
- multi-tenant plugin platforms; and
- architectures requiring frequent runtime addition or removal of capabilities.
- Paper: https://github.com/cordiverse/paper
- Raw PDF: https://github.com/cordiverse/paper/raw/main/paper.pdf
- Cordis primer: https://deepseek-harness.github.io/deepseek-harness/reference/cordis-primer
- Cordis tutorial: https://deepseek-harness.github.io/deepseek-harness/develop/cordis-tutorial/
- Koishi case study: https://koishi.chat
- DeepSeek Harness: https://github.com/deepseek-ai/deepseek-harness
- Cordis upstream: https://github.com/cordiverse/cordis
- npm package:
1. What is Cordis?
Cordis is a plugin meta-framework developed from the Koishi ecosystem. It combines runtime effect and coeffect tracking with a declarative component loader, configuration reconciliation, and hot module replacement.
Its documented core concepts include:
1. Plugins
A plugin may be a function, constructor, or object. The framework does not use decorators or annotation scanning. Both ctx.plugin(fn) and the YAML-based loader ultimately follow the same plugin path.
2. Proxy contexts
Context properties are resolved through a service resolver. Derived contexts preserve encapsulation:
creates a separately named service scope.
intercept(name, config) merges service-specific configuration for downstream consumers. The implementation also uses a global symbol brand rather than
instanceof, allowing recognition across realms and multiple package copies.3. Reactive injection
Injection is persistent rather than a one-time assembly step. If a required service becomes unavailable, dependent fibers unload. If the service later returns, they load again. Until then, the fiber remains
PENDING without throwing an error. Because ordering depends on the dependency topology, YAML declaration order does not determine activation order. Optional dependencies should be inspected through
ctx.get(name) instead of being declared with inject.4. Event dispatch
The API defines five dispatch modes:
emit
parallel
serial
bail
waterfall The public primer documents four modes and omits
bail, creating a documentation inconsistency. A waterfall listener receives (...args, next) and can deny continuation by not calling next().5. Effects and reversible registration
effect(execute, label?) invokes execute immediately. Cleanup functions are registered immediately and executed in last-in, first-out order when the returned disposer is called or the owning fiber unloads. An
Effect may be a single disposer, a Promise, or an asynchronous iterable. A generator effect registers a disposer at every yield. Internally, effects form a tree rather than a flat list.6. Fibers
Fibers carry the entire lifecycle mechanism. Their state progresses through:
PENDING → LOADING → ACTIVE → UNLOADING → DISPOSED with a possible
FAILED branch. They expose a UID, a service snapshot, lifecycle operations, configuration updates, and a shared plugin runtime. One plugin definition can therefore produce multiple fibers without conflating definition and instance.2. Motivation: why dynamic composition needs stronger foundations
The paper defines two orthogonal requirements.
Temporal composability
Removing a component must safely reverse every side effect it introduced, including resource allocation, state changes, and event registration.
Spatial composability
Components must declare and discover dependencies in a structured way. Their lifecycles must then adapt as the dependency environment changes.
These concerns appear in plugin systems and self-modifying agent runtimes, but their formal foundation is weaker than that of static composition through calls, imports, or inheritance.
The paper uses VSCode extensions and agent harnesses as motivating examples. In the cited VSCode sample, most extensions contain executable code, but live unloading and dependency-oriented reactivation are limited. OS-level or container-level replacement can provide coarser temporal and spatial separation, but at the cost of discarded in-process state, additional network overhead, and weaker expression of dependencies within a shared address space.
3. Formal foundation
3.1 Revertible effects
An effect transforms a context and supplies an inverse transformation. The paper represents the basic idea as:
Γ → Γ × (Γ → Γ)A forward transformation receives the current state and returns a new state together with an explicit inverse.
Key constructs include:
trackΓ: lifts ordinary effects into effect-aware contexts and accumulates their inverses.
recoverΓ: applies the accumulated inverse and resets the accumulator.
The soundness condition requires that applying an effect and then its inverse recovers the original state, subject to the paper's observational equivalence where physical state cannot literally be restored.
A key result states that inverse operations are applied in reverse order when effects are removed. Under pairwise independence, permutations of those inverses can still recover the same initial state.
> Temporal-composability criterion: loading applies transformations and accumulates their inverses; unloading applies the accumulated cleanup.
[Inference] Cordis resembles reversible-computing and inverse-arrow research conceptually, but it does not require every computation to be globally reversible. Atomic effects provide one-sided cleanup operations, while composition derives a composite inverse.
3.2 Reactive coeffects
A component declares a dependency specification. When the context changes, the runtime classifies the new state as activating, deactivating, or neutral for that specification.
The formal model treats coeffect operations as effects. Setting a dependency value is itself a reversible effect, allowing the effect and dependency mechanisms to cooperate.
A coeffect associates a key with:
Isolation introduces runtime ad-hoc polymorphism so the same key can resolve differently in separate contexts. Interception adds cross-cutting metadata and lets an outer context constrain a component without changing its implementation.
> Spatial-composability criterion: components activate only when their specifications are satisfied. Any dependency loss is detected and drives teardown.
3.3 The unified context
The paper combines current state, inverse accumulation, and dependency context into one recursive type:
Γ∞ ≔ μΓ. Γ × (Γ → Γ) × ΣNested contexts can aggregate descendant effects and express hierarchical plugins. The model also replaces exact state equality with observational equivalence when operations such as memory deallocation or generated-name recovery cannot literally restore the original physical state.
Further theorems connect operations on distinct keys, commutativity, and the independence required for global temporal composability. The context paradigm combines explicit effect passing with an ergonomic implicit context while preserving teardown as a structural result rather than a manually maintained cleanup list.
3.4 Components and dynamic composition
A component consists of:
A fiber is the component's runtime instance. The registry maintains active fibers as a tree and derives the available coeffect context from active providers, with at most one provider per key.
The calculus contains orchestration rules for insertion, retirement, and removal, as well as loading and unloading transitions. Its metatheory covers preservation, recovery exactness, ordering, resolution coherence, progress, and confluence.
The ordering result requires providers to activate before consumers and consumers to deactivate before providers withdraw required keys. Progress assumes an acyclic precedence relation, bounded transitions, and finite names. Confluence states that the resting lifecycle state matches static assembly from the final dependency-ordered configuration, regardless of intermediate activation and deactivation interleavings.
4. Cordis implementation
Cordis is organized into a core library, component loader, and application framework.
Core library
ctx.effect executes immediately, tracks cleanup, and releases it in LIFO order.
ctx.set and ctx.get model service provisioning and dependency resolution through effects and notifications.
ctx.use instantiates components and registers their fibers.
isolate and intercept construct disposable child contexts.
ctx.get remains non-throwing.Component loader
Entries may define an ID, URL, isolation, interception, configuration, and disabled state. The loader reconciles the desired configuration with the current plugin tree.
The paper associates this mechanism with confluence: because a settled state depends only on the final configuration, incremental and concurrent updates can safely coordinate toward the same result.
The
@cordisjs/hmr package classifies modules, detects stale entries, and performs transactional reloads. Failed reloads roll back cached state rather than requiring developers to mark explicit acceptance boundaries.The paper describes Cordis v4, while Koishi currently uses Cordis v3. The two versions share the core composition model, but the loader and effect/coeffect semantics have been refined in v4.
5. DeepSeek Harness integration
DeepSeek Harness vendors Cordis packages directly under
@deepseek-ai to keep the framework layer auditable, patchable, and lockable. Its Cordis copy was based on upstream package 4.0.0-rc.7 and included loader, HMR, timer, logger, group, and utility packages.At least six of the 18 recorded vendor changes addressed kernel correctness or concurrency. Notable changes include:
cordis#41.One recorded failure involved HMR initial scanning, an include refresh, rollback, and teardown becoming interleaved so that the include fiber never settled. The process exited with code 13 and no diagnostic output.
[Inference] This evidence indicates that DeepSeek performed substantial hardening work rather than merely consuming the upstream release unchanged. The reversibility guarantee is structurally present, but its production strength depends on handling reentrancy, concurrent updates, and platform-specific resource behavior.
6. Ecosystem and governance
The principal implementations and evidence bases are:
Upstream maintenance is highly concentrated: one contributor accounts for approximately 97.6% of the reported 550 commits. Cordis also lacks an independent documentation home; its upstream homepage points to DeepSeek Harness documentation, while
cordis.js.org is only a redirect placeholder.The paper repository has no license, unlike the MIT-licensed code. The paper is an active, unreviewed draft, and its single-ecosystem observations should not be treated as comparative experimental validation.
7. Competitive positioning
Cordis is best compared along three dimensions: dependency models, side-effect rollback, and configuration/HMR support.
Dependency model
Cordis is closer to OSGi Declarative Services than to Spring. Traditional IoC mainly separates object construction, while Cordis treats component existence as a function of environmental requirements. A Spring bean remains assembled once its dependencies are satisfied; a Cordis fiber can unload and reactivate as those services change.
Side-effect rollback
This is Cordis's clearest differentiator. VSCode's
context.subscriptions.push, Fastify's onClose, and similar mechanisms also encourage cleanup, but they rely on developer discipline. Cordis tracks effects automatically, associates them with the current fiber, organizes them into an ownership tree, and releases them in reverse order.Its isolation mechanism is also lighter than OSGi's JVM-oriented classloader model, but this is not a direct equivalence: OSGi offers a mature bundle lifecycle, while Cordis provides runtime dependency and disposal semantics within TypeScript applications.
Configuration and HMR
Stable IDs, disabled entries, nested groups, isolated service scopes, patch overlays, lazy expression interpolation, and transactional reconciliation give the loader substantial engineering value. OSGi Config Admin is a close analogue, while many web-oriented frameworks provide less comprehensive plugin-tree coordination.
8. Critical corrections and limitations
“Algebraic effects” is too strong
Cordis does not provide static effect rows, algebraic handlers, or continuation capture. Its
Effect is a runtime convention in which an effect can return a disposer. A more accurate description is a responsive microkernel with automatic resource tracking.Tapable's waterfall and bail hooks have similar names and semantics, but Cordis integrates those dispatch patterns with dependency resolution and fiber lifecycles.
Formal composability is not the same as production robustness
The theory claims that reversibility is enforced by the paradigm. Vendor changes in DeepSeek Harness show gaps in reentrant disposal, setup failure rollback, concurrent group updates, and Windows file handling in an earlier release candidate. The paper presents the calculus, while the implementation evidence shows that production guarantees still require maturity.
Two conditions must remain distinct:
INACTIVE because no valid activation order exists; this is not a runtime deadlock.
Governance and documentation risks
An unstable API, a bus factor of one, no independent documentation site, and heavy dependence on downstream users create sustainability concerns. The paper's broad terminology may also obscure that the central engineering ideas—resource cleanup and dependency-driven lifecycle management—were already familiar concerns. The novelty lies in elevating them into a unified runtime calculus.
Operational behavior
Silent
PENDING states can be difficult to diagnose. Missing injected services do not produce immediate errors, so a plugin may appear to do nothing. Omitting stable YAML IDs can also cause entries to be treated as deleted and re-added after every configuration change.9. Maturity assessment and recommendations
Cordis is well suited to:
It is less compelling for short-lived request/response services where runtime composition and exact resource teardown provide little benefit, or for enterprise projects that require long-term API stability.
Organizations adopting it should lock a specific commit, vendor the relevant source, maintain an explicit patch log, and test reentrant disposal, concurrent updates, rollback paths, and Windows behavior. Directly depending on
cordis@4.0.0-rc.x while expecting stable semantics carries material risk.10. Research limitations
1. The principal theory comes from an unreviewed August 13, 2026 draft and may change under active revision.
2. Koishi is the main empirical ecosystem, so validation is observational and limited to one TypeScript-based domain.
3. No controlled comparison with alternative architectures was performed, and performance and developer-productivity costs remain future work.
4. Cordis itself was not executed independently in the research workspace; implementation evidence came primarily from DeepSeek Harness's vendored copy and modification history.
5. The theoretical and engineering investigations were produced in parallel and cross-checked against the source paper, but some implementation details depend on worker summaries.
Conclusion
Cordis is not merely another IoC container. It advances a model in which reversible teardown and reactive dependencies are structural properties of a runtime. Revertible effects, reactive coeffects, unified contexts, fibers, and the dynamic-composition calculus provide a coherent formal foundation, while Koishi and DeepSeek Harness demonstrate the value of the approach in long-lived, hot-modifiable systems.
The framework nevertheless remains an early release candidate with an unstable API, concentrated upstream maintenance, dependent documentation, and evidence of concurrency defects in a previous version. DeepSeek's vendoring and hardening work illustrate both the framework's value and the work required to make that value reliable.
The most accurate short description is: Cordis is the physics of plugins—theoretically rigorous, practically useful, and architecturally distinctive, but not yet as mature or production-proven as its ambitious terminology suggests.
References
Yifan Shi, Wei Zhang, Tian Tianyi Cui, *A Programming Paradigm for Spatiotemporal Composability*, Draft of August 13, 2026. Peking University and DeepSeek-AI. https://github.com/cordiverse/paper
cordis@4.0.0-rc.8`