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;
  • --strictUNSUPPORTED 视为 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
1CLI 使用错误或内部错误
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 字段删除或类型变化。