{"slug": "deepseek-harness-cordis-and-the-case-for-spatiotemporal-agent-architectures", "title": "DeepSeek Harness, Cordis, and the Case for Spatiotemporal Agent Architectures", "summary": "DeepSeek AI and Peking University published a paper formalizing spatiotemporal composability for agent architectures, introducing the Cordis micro-kernel that powers DeepSeek Harness (dsh). The Cordis kernel, an open-source TypeScript engine, treats models, tools, sandboxes, session stores, and the agent loop as hot-swappable plugins, with revertible effects ensuring clean unloads. Cordis has run in production for four years in the Koishi chatbot ecosystem with over 4,000 community plugins.", "body_md": "## On this page\n\n# DeepSeek Harness, Cordis, and the Case for Spatiotemporal Agent Architectures\n\nDeepSeek AI and Peking University formalized agent modularity in a recent paper on spatiotemporal composability. Here is an engineering look at the Cordis kernel, revertible effects, and what this pattern means for self-modifying agents.\n\nMost agent frameworks claim they are modular. In practice, they offer surface-level customization.\n\nThey give you a tool registry, a prompt template, and a model router. Then they hardcode the execution loop, the session state, the sandbox runtime, and the user interface into a fixed core. If you want to change how the loop handles retries, swap the session storage engine, or replace the sandbox environment, you end up forking the repository or hacking internal classes.\n\nWhen DeepSeek released [DeepSeek Harness](https://deepseek.com/harness/en/) (`dsh`\n\n), they took a different approach. Alongside the codebase, DeepSeek AI and Peking University published a research paper: [ A Programming Paradigm for Spatiotemporal Composability](https://github.com/cordiverse/paper/blob/main/paper.pdf).\n\nThe paper formalizes the architecture behind [Cordis](https://deepseek-harness.github.io/deepseek-harness/en/develop/cordis-tutorial/), the open-source TypeScript micro-kernel underneath DeepSeek Harness. Instead of building a monolithic agent runtime with hooks, they built an engine where models, tools, sandboxes, session stores, and even the agent loop itself are hot-swappable plugins.\n\n```\n%%{init: {\"layout\": \"dagre\"}}%%\nflowchart TD\n    subgraph Monolith[\"Typical Agent Framework (Fixed Core)\"]\n        M1[Hardcoded Agent Loop] --> M2[Built-in Session State]\n        M1 --> M3[Built-in Terminal UI]\n        M1 --> M4[Hardwired Sandbox]\n        M1 -.->|Only customizable layer| M5[Custom Tools & Prompts]\n    end\n\n    subgraph CordisHarness[\"DeepSeek Harness on Cordis (Micro-Kernel)\"]\n        K[Cordis Kernel: Context + Events + Lifecycle]\n        K --- P1[\"ctx.llm: Model Adapter\"]\n        K --- P2[\"ctx.agentLoop: Agent Driver\"]\n        K --- P3[\"ctx.sessions: Append-Only Log\"]\n        K --- P4[\"ctx.sandbox: Container / MicroVM\"]\n        K --- P5[\"ctx.tools: Tool Registry & MCP\"]\n        K --- P6[\"ctx.agents: Live Agent Registry\"]\n    end\n```\n\nThis design did not start in the AI lab. Cordis ran in production for four years powering the Koishi chatbot ecosystem across more than 4,000 community plugins before DeepSeek applied it to agent harnesses.\n\nI am still reading through the paper myself, working through the formal theory of effects and coeffects. Rather than declaring this pattern superior to simpler agent loops, let us examine how the mechanics work, what trade-offs they introduce, and what we can learn from this direction.\n\n## The Theory: Spatial and Temporal Composability\n\nThe core argument of the DeepSeek and Peking University paper is that dynamic software systems fail at composability in two distinct dimensions: time and space.\n\n```\n%%{init: {\"layout\": \"dagre\"}}%%\nflowchart LR\n    subgraph Spatial[\"Spatial Composability (Coeffects)\"]\n        A[Plugin declares required services] --> B[Cordis resolves DAG]\n        B --> C[Plugin activates only when context is ready]\n    end\n\n    subgraph Temporal[\"Temporal Composability (Revertible Effects)\"]\n        D[Plugin executes side effect] --> E[Runtime tracks inverse action]\n        E --> F[Plugin unloads: effect unwinds with zero leftovers]\n    end\n```\n\n### 1. Temporal Composability via Revertible Effects\n\nIn standard software, installing a capability is easy; removing it cleanly is hard. When you disable a plugin, it often leaves active interval timers, dangling event listeners, open network sockets, or stale prompt injections in memory.\n\nThe paper formalizes **revertible effects**: every transformation applied to the shared execution context must have a mathematically defined inverse that the runtime tracks. When a plugin unloads, the runtime executes that inverse.\n\n``` js\nimport { Context, Service } from 'cordis'\n\nexport class MonitoringService extends Service {\n  constructor(ctx: Context) {\n    super(ctx, 'monitoring', true)\n  }\n\n  protected start() {\n    // Revertible effect: the returned closure is the tracked inverse\n    this.ctx.effect(() => {\n      const timer = setInterval(() => this.collectMetrics(), 10000)\n      return () => clearInterval(timer)\n    })\n\n    // Event listener: automatically unbound on plugin unload\n    this.ctx.on('tool/execute', (event) => {\n      this.recordLatency(event)\n    })\n  }\n}\n```\n\nWhen this plugin unloads, Cordis runs the cleanup closure and unbinds the event listener. The process returns to its exact prior state.\n\n### 2. Spatial Composability via Reactive Coeffects\n\nIn type theory, **effects** describe what a program *produces* (e.g. logs, network calls, state mutations). **Coeffects** describe what a program *requires* from its environment to execute (e.g. specific services, configurations, credentials).\n\nCordis treats plugin dependencies as reactive coeffects. A plugin declares what it demands:\n\n```\nexport class ToolExecutionPlugin extends Service {\n  // Coeffect requirements: requires both ctx.tools and ctx.sandbox\n  static inject = ['tools', 'sandbox']\n\n  constructor(ctx: Context) {\n    super(ctx, 'toolExecution', true)\n  }\n}\n```\n\nCordis monitors the context tree. When `ctx.tools`\n\nand `ctx.sandbox`\n\nbecome available, the plugin activates automatically. If the sandbox plugin crashes or unloads, downstream plugins pause or deactivate until the dependency returns. There is no manual boot order to configure.\n\n## How DeepSeek Harness Implements the Model\n\nIn DeepSeek Harness, the Cordis kernel contains zero AI logic. It does not know what an LLM token is. Instead, it exposes a typed `Context`\n\nwhere packages register services and listen to events.\n\n| Package | Responsibility | Context Key |\n|---|---|---|\n`core/session` | Append-only `SessionEvent` log and store | `ctx.sessions` |\n`core/system-prompt` | Dynamic prompt-section and tool-schema assembly | `ctx.systemPrompt` |\n`core/tools` | Scoped tool registry and guarded execution pipeline | `ctx.tools` |\n`core/agent` | Live agent registry and lifecycle events | `ctx.agents` |\n`core/agent-loop` | Default execution driver implementing step turns | `ctx.agentLoop` |\n`llm/llm` | Model stream abstraction and provider adapters | `ctx.llm` |\n`core/sandbox` | Process isolation, container, and microVM boundaries | `ctx.sandbox` |\n\n### Four Typed Dispatch Modes\n\nCommunication across plugins relies on an event bus with four explicit dispatch modes:\n\n| Mode | Awaited? | Execution Order | Return Value? | Behavioral Semantic |\n|---|---|---|---|---|\n`emit` | No | Registration order | No | Fire-and-forget notifications (telemetry, background logging). |\n`waterfall` | No | Around-middleware chain | Yes | Interception middleware (`(...args, next)` ). Can mutate, delegate, or short-circuit. |\n`parallel` | Yes | Concurrent (`Promise.all` ) | No | Awaited broadcast across independent listeners. |\n`serial` | Yes | Registration order | Yes | Decisive sequential gates (e.g. `agent/turn-stopping` ). |\n\nThe **waterfall** mode allows plugins to wrap core decisions:\n\n```\n// Intercepting prompt messages before the model sees them\nctx.waterfall('agent/pre-step', async (session, messages, next) => {\n  if (violatesPolicy(messages)) {\n    // Short-circuit: stop the turn before calling the model\n    return { status: 'rejected', reason: 'Blocked by policy' }\n  }\n  const sanitized = sanitize(messages)\n  return next(session, sanitized)\n})\n```\n\n## The Turn and Step Lifecycle\n\nDeepSeek Harness defines a structured execution pipeline:\n\n```\nturn/start\n  │\n  ├─ Claim queued input from inbox\n  ├─ Assemble prompt sections + tool schemas (ctx.systemPrompt)\n  │\n  ├─► agent/pre-step (waterfall) ──► [reject / enter(messages)]\n  │     └─ If rejected: close turn immediately (0 steps spent, logged)\n  │\n  ├─► step/start\n  │     ├─ Append entered messages to session log as user/message\n  │     ├─ deriveMessages(): Project model history from the immutable log\n  │     ├─ agent/request (waterfall)\n  │     ├─ llm/stream (waterfall) ──► assistant/chunk* ──► assistant/message\n  │     ├─ tool/call* ──► tools/pre-execute ──► tools/execute ──► tools/post-execute ──► tool/result*\n  │     └─ step/end\n  │\n  ├─ Check continuation: tools owe another request OR queued input arrived?\n  │     ├─ If YES: jump back to step/start (next step)\n  │     └─ If NO: proceed\n  │\n  ├─► agent/turn-stopping (serial gate)\nturn/end\n```\n\n## Capability Seams and Append-Only Logs\n\nTwo additional engineering choices stand out in the architecture:\n\n### 1. Capability Seams\n\nA **seam** separates a Service Definition (interface), a Service Provider (implementation), and Consumers (tools).\n\nBecause file access (`ctx.fs`\n\n), subprocess execution (`ctx.subprocess`\n\n), and terminals (`ctx.terminals`\n\n) share a common seam, changing the provider from local Node.js to a remote microVM moves all tools, file reads, and language servers into the container simultaneously. Consumer code remains untouched.\n\n### 2. “Model-Visible Means Logged”\n\nThe harness enforces an invariant: **anything that reaches the LLM must be reconstructable from the append-only event log**.\n\n- The runtime does not mutate an in-memory chat array. The\n`deriveMessages()`\n\nfunction computes context directly from immutable`SessionEvent`\n\nrecords. - Sub-agents branch cleanly via\n`ctx.sessions.fork(parentSessionId, boundaryEventId)`\n\nwithout cloning process heaps. - Deterministic replay allows developers to step through historical execution runs event by event.\n\n## Why This Pattern Matters: The Self-Modifying Agent\n\nWhy go through the trouble of building formal spatiotemporal composability into an AI agent harness?\n\nThe most compelling answer is **runtime self-modification**.\n\nIn a traditional agent framework, if an agent writes a new tool or scripts an integration during a long-running task, it cannot mount that tool without restarting its process. Restarting wipes ephemeral memory, drops open network sessions, and resets execution state.\n\nUnder Cordis:\n\n- The agent writes a new TypeScript tool plugin.\n- The harness loads the plugin into the live context at runtime.\n- Cordis checks the plugin’s coeffects, mounts the tool, and automatically updates the system prompt assembly for the next step.\n- If the tool fails or finishes its purpose, the agent unloads the plugin. Cordis unwinds the effect tree with zero leftover memory or socket leaks.\n\nThe agent modifies its own runtime in-flight while preserving active session history.\n\n## Open Questions and Engineering Trade-Offs\n\nWhile the architecture is elegant on paper, it introduces real trade-offs that teams should weigh:\n\n| Dimension | Monolithic Loop (e.g. Pi / Minimalist Harness) | Spatiotemporal Micro-Kernel (Cordis / dsh) |\n|---|---|---|\n| Conceptual overhead | Low: read one linear loop file | High: understand contexts, seams, and dispatch modes |\n| Debuggability | Simple stack traces and breakpoints | Non-linear event graphs across waterfall chains |\n| Dynamic safety | Compile-time static guarantees | Runtime dependency resolution in TypeScript |\n| Extensibility | Fork or subclass internal code | Declarative plugin mounting via config patches |\n| Self-modification | Difficult without process restart | Native support for in-flight tool mounting and unwinding |\n\nThree practical questions remain as this pattern encounters production adoption:\n\n**Debugging Indirection:** When behavior is distributed across multiple waterfall listeners, tracing why a prompt was altered or a tool call was rejected requires dedicated event-graph tooling.**Language Boundaries:** Cordis is written in TypeScript. Bringing this level of dynamic effect unwinding to environments like Python or Rust requires different runtime primitives (e.g. explicit RAII guards or actor systems).**Complexity Budget:** For focused coding agents with fixed tool sets, a 200-line linear loop like HuggingFace’s Tau remains significantly easier to audit and reason about.\n\n## The Bottom Line\n\nDeepSeek Harness and the Cordis paper represent a deliberate shift in agent system design: treating agent harnesses not as static scripts around an LLM API, but as dynamic operating systems for hot-swappable capabilities.\n\nI am still working my way through the mathematical details and operational calculus in the paper. We do not need to rush to declare this architecture superior or inferior to simpler, linear agent loops. Instead, we should wait and watch where these patterns head: whether dynamic plugin trees become the standard foundation for self-modifying agents, or if linear simplicity remains the preferred choice for production stability.\n\nFor now, the paper gives us a clear vocabulary for understanding what true modularity in agent runtimes requires.\n\n*Observing how agent architectures evolve, or experimenting with plugin runtimes for autonomous systems? I would love to hear your perspective. Reach out on LinkedIn.*", "url": "https://wpnews.pro/news/deepseek-harness-cordis-and-the-case-for-spatiotemporal-agent-architectures", "canonical_source": "https://kondasamy.com/blog/2026/deepseek-harness-cordis-kernel-architecture/", "published_at": "2026-08-14 00:00:00+00:00", "updated_at": "2026-08-14 09:12:51.236739+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "ai-research", "developer-tools"], "entities": ["DeepSeek AI", "Peking University", "DeepSeek Harness", "Cordis", "Koishi"], "alternates": {"html": "https://wpnews.pro/news/deepseek-harness-cordis-and-the-case-for-spatiotemporal-agent-architectures", "markdown": "https://wpnews.pro/news/deepseek-harness-cordis-and-the-case-for-spatiotemporal-agent-architectures.md", "text": "https://wpnews.pro/news/deepseek-harness-cordis-and-the-case-for-spatiotemporal-agent-architectures.txt", "jsonld": "https://wpnews.pro/news/deepseek-harness-cordis-and-the-case-for-spatiotemporal-agent-architectures.jsonld"}}