DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

MrXiongBear /

MrXiongBear/dsh-task-steward

Verified

Task steward for DSH: watches a running task for stalls, no-progress loops, forbidden commands, tainted privileged calls, budget overruns and escalation requests, then records / reminds / blocks / stops on a deterministic ladder. Shadow mode by default.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@54365d84

dsh-task-steward(任务管家)

本仓库 100% 由 AI 生成 —— 需求、代码、测试、文档都是人与 AI 对话里由 AI 写出来的,人只负责验收和拍板。 实验性 · 自用性质 · 非商业:它紧贴 DeepSeek Harness(DSH)的宿主接缝(apply / inject / client bundle / 配置解析),只在写它的那个 DSH 版本上验证过,宿主升级后可能直接失效。 安装前必读:DSH 的 profile 加载是全有或全无——一个插件 import 失败会连坐整个 profile,甚至把配置写残。装之前先备份 profile 里的 package.json 与 cordis.patch.yml。 没有发布到 npm:把本目录放进 profile 的 node_modules(或 "<包名>": "link:<本目录绝对路径>"),再在 package.json 的 dsh.profile.bundles 里登记,重启 DSH。 卸载/回滚:从 dsh.profile.bundles 摘掉 → pnpm remove <包名> 或删掉 junction → 重启;出问题就用备份的那两个文件还原。

给 DSH 的会话装一个"管家":任务跑起来之后,它盯着一件事——这个任务还在正常推进吗?

  • 卡死(真静默)、空转(同一个调用反复)、思考链复读、连续多步没有进展证据 → 提醒。
  • 禁区命令(删根、格式化磁盘、--force 强推、读凭据、往外传文件)→ 拦截。
  • 读网页/MCP/文件之后马上调特权工具 → 判定为"可能被注入" → 拦住问人。
  • 预算烧穿、要提权/换沙箱 → 停住问人,不自动放。
  • 消极怠工:连续多步只有空话没有动作、todo 一直不开 → 提醒。

M0 只记账不干预。 默认 policy: report:所有信号都算出来、都记进账本,但不会拦一次工具、不会停一次任务。跑几天看 scripts/bill.mjs 出的账单,误报低了再翻 auto。

为什么是"确定性 + 零模型调用"

管家不该比被看管的任务还贵。这里所有判断都是规则/状态机:工具名 + 参数指纹、事件时间戳、在飞计数、进展证据。默认配置下一次模型调用都不发。

内置的 dsh-experimental-auto-review(已在 profile 里、默认关)负责"单次调用的风险复核",我们负责"跨步的进程监督",两者是两条线,不重复。

四档干预(policy: auto 才生效)

档 动作 怎么落地
tier 0 record 只写账本
tier 1 nudge 往会话插一条 user/message:管家提醒(带证据 + 你可以怎么回),不唤醒模型
tier 2 block tools/pre-execute 返回 {kind:'deny'},把理由交给宿主原生审批链
tier 3 stop agent.cancel({kind:'hook', reason}),附停机交接

同一信号连续出现 tierUpAfter 次(默认 2)升一档;任何行为进展都会重新计数;resetAfterMs 后清零。 allowStop: false(默认)时 tier 3 降级为 nudge——M0/M1 阶段绝不自行杀任务。

信号

信号 判据 默认阈值
repeat.exact 同一工具 + 规范化参数在窗口内重复 3 次 / 回看 12 次调用
repeat.no-effect 同一调用且结果摘要不变 2 次
loop.thinking 思考链字面/标点变体/长块/整行复读 体量 > 80k 字符才扫
stall.silent 运行中 + 无事件 + 无在飞操作 120s
stall.thinking 只有思考文本、无工具调用、距上次进展过久 180s
progress.none 连续多步没有进展证据 8 步
forbidden.command 禁区命令规则命中 11 条规则
taint.sink 读不可信来源后调特权工具 first-taint-wins
budget.exceeded 步数/时长/(可选)token 超预算 0 = 不设限
escalation.request 要提权、要换沙箱、被 sandbox 拒绝 立即 tier 2

进展证据只有四类:写/改文件、关掉一条 todo、验证命令通过(test|build|lint|tsc|vitest 且 exitCode 0)、用户新消息。没有这四类,说得再热闹也不算进展——这就是"消极怠工"的判据。

在飞豁免:有工具调用没回来时,永不判卡死。长下载、长构建不会被误杀。

配置(cordis.patch.yml)

- insert:
    - id: task-steward
      name: 'dsh-task-steward'
      config:
        policy: report        # report | auto
        stall: { silentMs: 120000 }
        escalation: { allowStop: false }

可调项:policy、stewardName、repeat.*、thinking.*、stall.*、progress.*、budget.*、escalation.*、ledger.*(retentionDays 30 / maxBytes 20MB)。完整默认值见 lib/policy.mjs 的 DEFAULT_CONFIG。

账本与账单

  • 账本:$DSH_HOME/task-steward/events.jsonl(一行一条,坏了不会拖垮插件;超过 maxBytes 轮转成 .1)。
  • 心跳:$DSH_HOME/task-steward/boot.json —— apply 的第一件事写的自证物(at/pid/version/policy/ledger),只依赖 node:fs。装载失败时还会留 apply-error.json。
  • 观察覆盖:$DSH_HOME/task-steward/stats.json —— sessionEvents/turns/steps/toolCalls/hits/records/lastEventAt,每 statsFlushMs(默认 30s)和每个 turn/end 落一次。
  • 账单:node scripts/bill.mjs --days 7 → 先「管家存活」段(心跳/覆盖/告警),再按天/信号/动作汇总 + 最近 20 条。
  • 三种空账本要分清:没有 boot.json = 插件没被 loader 起来;有 boot.json 但 sessionEvents=0 = 影子期没跑过任务;有事件但零命中 = 判据对这段活动是干净的(通常是好事)。
  • 证据可离线复核:progress.none 的 evidence.recentTools 是最近 8 个工具名——连续 read/grep/glob 属于正常查证,连续同一 bash 空跑才是空转。stall.thinking 的 evidence.idleMs 记录当时静默了多久,用来判断阈值是不是贴太紧。
  • 三步放权:①逐条标真问题/误报 ②误报多先调阈值 ③连续几天都干净再把 policy 改成 auto,allowStop 最后放。

工程纪律(照抄本机能跑住的插件)

  • 插件契约:export const name / export const inject / export function apply(ctx);配置走 cordis.patch.yml 的 config:。
  • 所有 waterfall 监听在放行路径必须 return next(),只有真要拦才占据调用。
  • 拦截理由是给模型看的,必须放顶层 reason,不能塞进 info。
  • 审计/账本永不携带匹配原文(凭据就地脱敏)。
  • 一切上界:扫描长度、每规则一次命中、ring buffer、账本轮转。
  • 不依赖不存在的服务:ctx.get() 取不到就降级,不崩。
  • 装载是全有或全无:装之前先过 dsh-capability-ledger 的 preflight 闸门。

验证

cd <repo>
node --test test/*.test.mjs     # 纯逻辑 + 接缝形状 + 真 Cordis 装载(106 项)
node scripts/bill.mjs --help

test/materialize.test.mjs 会用锚点树里宿主自己的 Cordis 把插件真装一遍(ctx.plugin + 真实 inject 解析 + 真 effect),并断言"派生 context 上 emit 的 agent/status 收得到"和"在飞工具调用期间不误判卡死"。没解锚点(node tools\extract-anchor.mjs)的机器上它会自动 skip。

装进 profile 之后:

  1. 重启,日志里看到 [task-steward] 管家已启用(policy=report,账本=…,心跳=…)。
  2. 立刻 node scripts/bill.mjs:应该先看到心跳 ✅。看不到 boot.json 就别去调阈值——那说明插件没挂上。
  3. 跑一个真任务,再看账单里「观察覆盖」有没有涨:涨了但零命中 = 判据干净;连事件数都不涨 = 监听没接上。

装载与自证(0.1.2 起)

插件在 apply 的第一行就写 $DSH_HOME/task-steward/boot.json,之后持续写 stats.json,装载抛错留 apply-error.json。判"有没有生效"只看这三个文件 / 账单头部,不看闸门绿不绿:

node <repo>\scripts\bill.mjs --days 7
  • 心跳 ❌ + 没有账本 → 插件没被 loader 起来(看 boot.json 在不在);
  • 心跳 ✅ + sessionEvents=0 → 挂上了但影子期没跑任务;
  • 心跳 ✅ + 有事件 + 零命中 → 判据对这段活动是干净的。

教训(0.1.0 → 0.1.2):apply 里绝对不能读没在 inject 声明的 ctx 服务属性(例如 ctx.config)——cordis 的 ctx 是注入守卫,一读就抛,而 fiber 失败只写 stderr、桌面端看不见。配置只用 apply(ctx, config) 的第二个参数。test/host.test.mjs 的假 ctx 已改成"读 .config 就抛错",防止回退。

—/ 5

No ratings yet

Verified DSH bundle

Commit 54365d845d5f

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout