Introduction

The plugin ecosystem of DeepSeek-Harness supports two dispatch modes: waterfall and serial. In multi-plugin collaboration scenarios, the native Cordis hook execution order depends on the plugin registration order, which is often driven by the plugin dependency injection (inject) mechanism. For independent plugins that are unaware of each other, this is essentially nondeterministic.

This means plugins cannot reliably declare relative order, such as “auth must run before logging”. Once the dependencies of related plugins are adjusted, the execution order may flip arbitrarily, causing logic errors. The dsh-plugin-hooks-ordering plugin solves this issue by introducing a deterministic ordering algorithm.

Core Features

This plugin provides deterministic before/after ordering for Cordis hooks, supports both waterfall and serial dispatch modes, and provides DeepSeek-Harness-level support. Specifically, it includes:

  • Provides deterministic before/after ordering for Cordis hooks.
  • Supports both waterfall and serial dispatch modes.
  • Provides a pure topological sorting algorithm.
  • Supports DAG constraint graph logging.
  • Provides DeepSeek-Harness (dsh) layer support.

Installation and Dependencies

Installation requires specifying the peer dependency @deepseek-ai/cordis.

pnpm add @tengxiaohtx/dsh-plugin-hooks-ordering
pnpm add @deepseek-ai/cordis

Usage

Waterfall Hooks

Waterfall hooks use the onion model and implement pre and post stage control through prepend listeners.

  1. Import HookOrdering.
  2. Install the plugin and control the target hook.
  3. Register participants in the front and back stages.
import HookOrdering from '@tengxiaohtx/dsh-plugin-hooks-ordering'

ctx.plugin(HookOrdering)

// 控制钩子,控制多次会抛出错误
ctx.hooksOrdering.control('request/assemble')

// 注册参与者:auth 必须在 logging 之前执行
ctx.hooksOrdering.register('request/assemble', 'front', {
  name: 'auth',
  before: ['logging'],
  run: (req) => authenticate(req),
})

ctx.hooksOrdering.register('request/assemble', 'front', {
  name: 'logging',
  run: (req) => log(req),
})

// 注册参与者:metrics 必须在最后执行
ctx.hooksOrdering.register('request/assemble', 'back', {
  name: 'metrics',
  run: (req) => emitMetrics(req),
})

Serial Hooks

Serial hooks do not have a next() chain, so ordering is controlled using a front coordinator (short-circuit) and a back coordinator (best-effort).

import { SerialHookOrdering } from '@tengxiaohtx/dsh-plugin-hooks-ordering'

ctx.plugin(SerialHookOrdering)
ctx.serialHooksOrdering.control('turn/stopping')

// front 阶段:运行在原生链之前,返回非 falsy 值会短路整个分发
ctx.serialHooksOrdering.register('turn/stopping', 'front', {
  name: 'guard',
  run: (turn) => (isAllowed(turn) ? undefined : 'DENIED'),
})

// back 阶段:尽力而为地最后运行
ctx.serialHooksOrdering.register('turn/stopping', 'back', {
  name: 'audit',
  run: (turn) => recordAudit(turn),
})

DAG Logging

The plugin supports exporting the constraint graph (DAG) as JSON for debugging ordering issues.

  1. Pass the log path when installing.
  2. Retrieve the current JSON string via the dumpDag() method.
ctx.plugin(HookOrdering, { log: './hooks-ordering-dag.json' })

// 程序中获取 DAG
const dag = ctx.hooksOrdering.dumpDag()

DeepSeek-Harness Integration

The plugin provides a /dsh entry point for controlling real dsh hooks at the DeepSeek-Harness level.

  1. Add plugin configuration in cordis.patch.yml.
  2. The plugin automatically takes over hooks contributed by multiple packages, such as agent/pre-step, tools/post-execute, and others.
- insert:
    - id: hooks-ordering
      name: '@tengxiaohtx/dsh-plugin-hooks-ordering/dsh'
      config:
        # hooks: ['agent/pre-step', 'tools/post-execute', 'llm/stream', 'turn/stopping']

Layered Architecture

The plugin is divided into three layers, and you can choose the layer(s) to use as needed:

  1. Algorithm Layer: Provides a pure topological sorting algorithm and DAG renderer, with zero dependencies and no Cordis dependency.
  2. Cordis Service Layer: Provides the HookOrdering and SerialHookOrdering services, allowing hook control in any Cordis application.
  3. DeepSeek-Harness Layer: Provides the dsh plugin and cordis.patch.yml for controlling real dsh hooks.

Notes

  • This plugin does not modify or fork the Cordis framework.
  • It implements the onion model via prepend listeners.
  • The front stage short-circuits serial dispatch.
  • The back stage is best-effort.

Summary

dsh-plugin-hooks-ordering provides stable hook execution order control for Cordis plugins. Through topological sorting and a layered design, it solves the nondeterministic dependency ordering problem in multi-plugin collaboration without breaking the framework.