dsh-compat Compatibility Contract v1
August 14, 2026 · View on GitHub
1. CLI Contract
Inspect
dsh-compat inspect <source> \
[--target-dsh package:<version>|commit:<sha>] \
--format text|json \
[--strict]
- 只读;
- 不启动 package manager、MCP、LSP、hook 或 binary;
- 默认输出摘要到 stdout;JSON 模式输出稳定 schema;
--strict将UNSUPPORTED视为 policy failure。
Convert
dsh-compat convert <source> \
--out ./generated-plugin \
[--target-dsh package:<version>|commit:<sha>]
- 先完成 inspect;存在
BLOCKED时不生成; - 不覆盖未知文件;
- 只写
--out与显式--report; - 不执行生成产物或源插件代码。
Test
dsh-compat test ./generated-plugin \
[--format text|json]
- 当前实现只执行确定性静态校验,不启动 DSH、MCP、LSP 或源插件;
- DSH
--dump-config与 headless behavior 属于独立 M3 验证流程; - CI 可非交互运行。
2. Exit Codes
| Code | 含义 |
|---|---|
| 0 | 命令完成,满足当前 policy |
| 1 | CLI 使用错误或内部错误 |
| 2 | 兼容 policy 未通过,例如 strict 模式出现 UNSUPPORTED |
| 3 | 安全阻塞,例如路径逃逸、凭据或权限放宽 |
| 4 | 保留给未来的来源 ref 或目标 DSH revision 解析失败 |
同一错误类别不得在小版本中改变 exit code。
3. Report Schema
顶层:
{
"schemaVersion": "1",
"tool": {
"name": "dsh-compat",
"version": "0.1.0",
"ruleSetVersion": "2026-08-14.1"
},
"source": {
"kind": "local|git",
"displayLocator": "<source-root>",
"ref": "optional",
"resolvedCommit": "optional",
"contentDigest": "sha256:...",
"license": "optional"
},
"target": {
"kind": "dsh",
"requested": "commit:<sha>",
"resolvedRevision": "commit:<full-sha>",
"resolvedAdapter": "dsh-developer-preview-2026-08",
"capabilityFingerprint": "sha256:..."
},
"summary": {
"overall": "DIRECT|ADAPTED|UNSUPPORTED|BLOCKED",
"counts": {
"direct": 0,
"adapted": 0,
"unsupported": 0,
"blocked": 0
}
},
"components": [],
"diagnostics": [],
"generatedFiles": []
}
4. Component Decision
{
"id": "hook:hooks/hooks.json#PreToolUse[0]",
"kind": "hook",
"name": "security-check",
"sourceRef": {
"path": "hooks/hooks.json",
"pointer": "/hooks/PreToolUse/0"
},
"state": "ADAPTED",
"ruleId": "hook.claude.pre-tool-use.bridge.v1",
"reason": "Target DSH adapter supports this event through the official bridge.",
"transformations": [],
"risks": [],
"manualActions": [],
"targetArtifacts": []
}
5. 状态规则
DIRECT
- 目标语义与安全边界可证明等价;
- 允许路径和格式层面的无语义变化 normalization;
- 有官方契约或行为 fixture。
ADAPTED
- 需要生成 wrapper、改写字段或改变调用形式;
- 报告必须列出 transformation 和已知差异;
- 不得扩大权限。
UNSUPPORTED
- DSH 无等价能力,或产品明确不支持;
- 不生成伪行为;
- 非 strict inspect 可完成,convert 跳过该组件并保留报告。
BLOCKED
- 安全风险、未知可执行语义、冲突或缺少必要版本信息;
- 默认阻止整个 convert;
- 不提供
--force绕过安全 blocker。
6. Overall State
严重度:BLOCKED > UNSUPPORTED > ADAPTED > DIRECT。
顶层 overall 等于所有组件中最严重状态。空插件或无法发现任何组件为 BLOCKED,并附 source diagnostic。
7. 稳定 ID 与 Source Map
- 组件 ID 由
kind + normalized relative path + logical pointer生成; - 文件改名会改变 ID,内容变化不改变同路径组件 ID;
- 生成文件必须反向列出一个或多个 source component IDs;
- diagnostics 必须包含 path 和 JSON Pointer/行号之一;
- 不在输出中泄露用户绝对路径。
8. Lockfile
dsh-compat.lock.json 至少包含:
- source resolved ref / content digest;
- source adapter 和版本;
- IR schema、report schema、rule set;
- target DSH revision、capability fingerprint 和 emitter;
- 每个 generated file 的 SHA-256;
- acknowledged manual actions;
- 生成时间仅进入 lock metadata,不参与产物内容摘要。
9. Determinism Contract
确定性输入:
- source content digest;
- CLI major/minor;
- rule set version;
- target DSH adapter;
- policy file。
这些值相同时,除报告中的明确 non-reproducible metadata 外,所有生成文件必须字节一致。
10. Ownership Contract
- 每个生成文件带 machine-readable ownership manifest,不要求在文件中插入注释;
- 已存在但不属于当前 lockfile 的文件不覆盖;
convert可更新自己生成且摘要匹配旧 lock 的文件;- 用户修改过的生成文件报告 conflict,不静默覆盖;
- 删除 source component 时,只删除 lockfile 明确拥有且未被用户修改的产物。
11. 兼容性变更
以下变更必须升级 schema/rule 或发布 breaking note:
- 状态从 DIRECT/ADAPTED 变成 UNSUPPORTED/BLOCKED;
- transformation 或权限结果变化;
- 同一输入产生不同 target artifact;
- exit code 变化;
- report 字段删除或类型变化。