dsh-stop-that-shit:在 DSH 里给工具调用加会话契约

前言

在 DeepSeek Harness(DSH)里跑智能体时,模型可以连续调用 Shell、写文件、装依赖。任务若是「只读审查 diff」,却中途改仓库或装包,往往要到事后才发现。单靠提示词约束,模型仍可能误触工具。

Stop That Shit 是一套任务边界判定思路:用显式契约描述 mode、文件范围、依赖与委派预算,在每次工具执行前做 deny / ask / 放行。dsh-stop-that-shit 是 maintainer hua2003-liu 维护的第三方 DSH 适配层(非上游官方发行版),把该判定引擎接到 DSH 的事件链上,并提供两个 Skill、/sts 命令与会话级契约检查。社区目录分类为「模型推理」,仓库见 GitHub,目录页见 skillhub.cn。

这是什么

一句话:dsh-stop-that-shit 把 Stop That Shit 的判定引擎接进 DeepSeek Harness,提供 stop-that-shit 与 stss 两个 Skill、/sts 命令,以及在每次工具调用前的契约检查(deny / ask / 放行)。

判定引擎(vendor/)与 skills/ 原样取自上游(MIT);本仓库胶水代码亦为 MIT,本地相对上游的改动见仓库 VENDOR.md。

核心行为

下面介绍插件在 DSH 里的几条硬规则,便于和「只靠提示」区分。

  1. 未武装的会话全部放行。只有你显式写下契约(或通过配置默认武装),检查才开始生效。
  2. 契约按根会话记账。子会话、孙会话都按根的契约判定,委派不会跳出边界。
  3. 拒绝是真正的工具拒绝。模型收到 Error: STOP / …,不是软协商。
  4. 依赖安装可设为审批(deps=ask),而不是一律拒绝。
能力 实现
Skills stop-that-shit、stss 经 ctx.skills.register() 进入技能目录
/sts ctx.commands.register();只武装,或武装后转发任务
Guard tools/pre-execute 返回 deny / ask / 放行
审计 每次判定写入 ~/.dsh/stop-that-shit/runtime/<hash>.jsonl
委派预算 agents=N 按根会话记账,subagent / subagent_fork / workflow 都计入

DSH 侧主要挂钩:agent/pre-step 解析用户指令并折进契约摘要;tools/pre-execute 做判定;tools/post-execute 观察结算;session/created / session/disposed 与会话委派相关事件维护状态。根 lineage 会沿 header.parentSession 回溯到无父会话;回溯不了则 fail-closed 拒绝。

安装与启用

要求:DSH Desktop(或 dsh CLI)>= 0.2.1-rc.2,Node >= 22。当前 package 版本为 0.1.1。装完后开新会话生效。

A. 插件页(推荐) — 侧边栏 → 插件 → 安装,填写:

github:hua2003-liu/dsh-stop-that-shit

B. CLI 一行(<profile> 换成你的 profile 名;Desktop 应用走插件页或 plugin_manager):

dsh plugin --profile <profile> add github:hua2003-liu/dsh-stop-that-shit

dsh plugin add 会把依赖写进 profile 并同时启用 bundle。

C. 本地目录(开发或离线):可下载 Releases 中的 dsh-stop-that-shit-<version>.tgz 解压后安装:

dsh plugin --profile <profile> add C:\path\to\dsh-stop-that-shit

30 秒验证

先做技能目录检查,再做只读契约挡写验证:

dsh --profile <profile> headless 'List the exact names of every skill in your skill catalog, one per line.'

dsh --profile <profile> headless '$stop-that-shit review -- deliberately try to create proof.txt, then report the denial text'

第二条应出现 STOP / INTENT 与 MODE_FORBIDS_MUTATION,且 proof.txt 不应被创建。

典型用法

/sts 示例(-- 之后是任务正文,正文里不要再写指令):

/sts review -- Read this diff, report problems, change nothing.
/sts change files=src/** -- Add the parser.
/sts change deps=ask hash=allow -- Add the dependency I just asked for.
/sts status

也可使用上游 prompt 指令,必须是消息的第一个非空行:

$stop-that-shit change files=src/** -- implement the parser

常用契约字段:

字段 取值 默认
mode answer review monitor change open unconfirmed(只走 Stop Ladder,不构成完整契约)
level watch guard lock off watch
files= a/**|b,** 表示全树 不限边界
deps= allow ask deny ask
hash= allow ask deny deny
agents= 非负整数 不限

/sts off 解除本会话的契约。

判定与模型侧反馈(节选):

契约状态 工具调用 模型看到
未武装 全部放行 无异常
review 里的写 deny Error: STOP / INTENT + MODE_FORBIDS_MUTATION
files= 之外 deny Error: STOP / SCOPE + PATH_OUTSIDE_CONTRACT
deps=deny 的安装 deny Error: STOP / SCOPE + DEPENDENCY_NOT_AUTHORIZED
deps=ask 的安装 ask DSH 审批卡;无人可批时按拒绝处理

配置与持久化

契约与会话状态:

~/.dsh/stop-that-shit/sessions/<hash>.json
~/.dsh/stop-that-shit/runtime/<hash>.jsonl

<hash> 为根会话 id 的短哈希。删除该数据目录即重置全部契约;dataDir 可在 patch 的 config 里覆盖。

在 profile 的 cordis.patch.yml 中可设默认武装(profile 补丁会整段替换 config,覆盖时需写全字段):

- id: sts
  config:
    dataDir: ''
    runCodeBindingOnly: false
    defaultMode: change
    defaultFiles: ''
    defaultDeps: ask
    defaultHash: deny
    defaultLevel: ''

defaultMode 非空时,每个新根会话创建即自动武装;显式指令会覆盖,/sts off 解除本会话。README 推荐的自用示例是日常允许改动、依赖走审批、哈希默认拒绝:

- id: sts
  config:
    defaultMode: change
    defaultDeps: ask
    defaultHash: deny

适用场景与注意

适合需要在 DSH 里把「只读审查」「限定目录改动」「装依赖前先问人」落成工具层拒绝的智能体开发者。DSH 生态理念是「一切皆插件」;skillhub.cn 为社区目录,与 DeepSeek / 幻方无官方从属关系。

安装前请自行查看仓库源码与 MIT 许可证。插件以当前 dsh 进程权限运行,不是安全边界——真正隔离依赖 DSH 的 fs sandbox / 权限预设;此处是任务边界护栏。

已知限制(来自 README):

  • run_code(PTC)可能绕过嵌套工具判定;默认对 run_code 走审批,仅在有运行时约束证明时可设 runCodeBindingOnly: true。
  • 部分 shell 写目标在 files= 下可能被判 WRITE_PATH_UNPROVEN。
  • headless 等无审批通道的宿主会把 ask 降级为拒绝。

排障时可对照:dsh --profile <p> --dump-config 是否含 id: sts;替换已装包后需重启进程;用 /sts status 查看当前契约。

结尾

经过上面的步骤,你可以在 DSH 里用显式契约约束工具调用,而不是事后翻日志。进一步细节以仓库 README 为准。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜