DSHA://DOCS

三个宿主上的真实实例

DSHA 在 Codex、Antigravity、WorkBuddy 里到底跑到哪一步,留下了什么证据。

这一篇只写本机能查到证据的部分。查不到的,直接写"没有",不编。

每条实例都附证据路径,你可以自己打开看。

先说结论

宿主装了吗真跑过吗拦截生效吗
Codex是(适配器 2.3.0)是,有完整留痕是——环境激活 + 门禁都在
Antigravity(Anty)是(47 个文件)安装器跑过否——钩子注册了,但 enabled: false
WorkBuddy否否否(只有配置契约)

三行摆在一起,本身就是一条教训:装了不等于生效。

实例一:Codex —— 最完整的一个

它长在哪

~/.codex/tools/dsha/
  host.json                 宿主描述:版本、源码快照、解析出的解释器、激活的变量
  source/                   vendored 源码(VERSION 1.3.0,40 个文件)
  sources/<commit>/         按 commit 缓存的源码快照
  python-env/               自带 Python 环境
  jdk/                      自带 JDK(host.json 里带 sha256)
  verification/             每次运行的证据文件

外加 ~/.codex/config.toml 里的一段:

[mcp_servers.rea]
command = "node"
args = [".../rea-agents/scripts/rea.mjs", "mcp"]

[mcp_servers.rea.env]
GHIDRA_INSTALL_DIR = "..."
JAVA_HOME = "~/.codex/tools/dsha/jdk/jdk-21.0.12.1+1"
REA_ANALYSIS_PROVIDER = "ghidra"
REA_GHIDRA_STARTUP_TIMEOUT_MS = "5400000"

注意最后两行的位置:变量是挂在 MCP 服务器的 env 块上,只注入那个子进程,不改系统环境。这就是协议里说的"单向封套"。

一次真实的环境探测

verification/environment-20261019T142903.local.json 记录了这一轮:

项值
scopewhitelisted tool version probes; absence means not discovered, not proven uninstalled
探测项27 项
结果19 PASS / 8 NOT_DISCOVERED
已解析python, node, npm, npx, git, gh, pwsh, bash, sh, rustc, cargo, rustup, dotnet, cmake, ninja, java, javac, msbuild, cl
未发现Go、GCC、Clang、GNU Make、Docker CLI、SQLite CLI、uv、ADB

那份报告里有一句话值得抄下来:

未发现:仅表示本轮配置、PATH 及 SDK 候选未发现,不证明未安装。

一次真实的 EnvFeel 运行

verification/envfeel-20261019T144705.local.json:

段值
statusCOMPLETE
contextPASS / Windows / runtime-reported facts, not hardware attestation
toolspython 3.12.14、node 24.14.1,均 PASS
health两项都跑自制最小程序并 PASS
activationPREPARED,scope = child mapping only
注入变量PATH、PYTHONUTF8、PYTHONIOENCODING、DSHA_PYTHON、DSHA_NODE
taskPASS,stdout = ENVFEEL_EXEC_OK

这里有两个细节,别的宿主上不一定看得到:

  1. scope: child mapping only——它明说了注入只作用于子进程,不动宿主。想改系统环境?不在能力范围。
  2. 只在有自定义样本通过后才叫 PASS。版本号对得上不算数,得真跑通一段自己的代码。

教训

Codex 这一侧把"证据"做成了文件,不是屏幕上的输出。所以你三天后再来看,还能查到当时探测了什么、结果是什么、注入了哪些变量。

实例二:Antigravity(Anty)—— 装了,但门没关

它长在哪

~/.gemini/config/plugins/dsh-permissions/     47 个文件
  hooks.json          PreToolUse 钩子注册
  tier.json           当前挡位
  rules/AGENTS.md     注入给模型的规则(6,257 B,纯 ASCII)
  scripts/gate.py     门禁本体(20,861 B)
  scripts/englock.py  词表校验器(24,411 B)
  lexicon.json        词表(7,421 B)
~/.gemini/config/_rollback/DSHA_*/            安装时的回滚点(3 个)

拦截链路是:

模型要动工具
   ↓
Antigravity 触发 PreToolUse
   ↓
hooks.json → scripts/run-gate.cmd
   ↓
scripts/gate.py 读 tier.json + lexicon.json 判一次
   ↓
allow / deny

实际状态

hooks.json 里是这么写的:

"dsh-permissions": {
  "enabled": false,
  "PreToolUse": [ ... ]
}

enabled: false。

钩子注册了,命令路径是对的,脚本都在——但开关是关的。所以此刻 Anty 里的这条门禁不拦任何东西。

tier.json 同时显示挡位是 danger-full-access:

{ "tier": "danger-full-access", "auto_reviewer": "local", "audit_logging": true, "log_allow": false }

这是最容易误判的一条。

看到 ~/.gemini/config/plugins/dsh-permissions/ 有 47 个文件,很容易得出"已经装好了、在起作用"的结论。

不是。 开关在 hooks.json 的 enabled 字段里。装完不等于启用,启用不等于生效——这三件事得分开验。

正确的确认方式是:在只读挡位下让模型去写一个文件,看它会不会被拒。拒了才算生效。

教训

安装器会备份、会写回滚点、会注册钩子——这些都对。但它不会替你把开关打开。

这是设计选择,不是缺陷:门禁装上了应当默认不改变现有行为,让人自己决定什么时候启用。代价是"装了没开"这个状态很容易被忽略。

实例三:WorkBuddy —— 本机没有

它是什么

WorkBuddy 是 REA 支持的 MCP 客户端之一。REA 的 supportedClients 列表里有:

claude_code / claude_desktop / codex / cursor / gemini_cli /
windsurf / devin / opencode / antigravity / copilot_cli / workbuddy

它的配置位置按 REA 的约定是:

~/.workbuddy/mcp.json      (跨平台一致)

本机状态

~/.workbuddy 不存在。

所以这一条没有运行实例——只有配置契约。能写的只有"如果装了,会接在哪儿",写了也不是实测。

为什么不编一个?

因为这一页开头说了:查不到的写"没有"。给你一段看着很真的假日志,比告诉你"这里缺一个实例"更糟——前者会让你以为验证过了。

如果你装了 WorkBuddy,运行一次:

dsha envfeel

再把 ~/.workbuddy/mcp.json 发出来,这一节就能补成真实例。

三个实例对照:同一套东西,三种成熟度

CodexAntyWorkBuddy
规则注入AGENTS.md → 提示词rules/AGENTS.md 6,257 B未装
强制位点MCP 服务器 env + 适配器PreToolUse → run-gate.cmd未装
环境探测有留痕(27 项 / 19 PASS)未单独留痕未装
单向封套明写 child mapping only由 run-gate.cmd 承担未装
当前生效是否(enabled: false)—

结论不是"哪家做得好",而是:同一套协议落到不同宿主上,成熟度可以差很远。 所以协议里那些 scope、NOT_RUN、未发现不等于未安装 的措辞不是啰嗦——它们就是用来防"看起来装了"的。