# 跨工具通用性:语义不变量与载体绑定
governed_by:D-020、D-040、D-055
本文效力:**已接受**(approved_by: Alan,approved_at: 2026-09-02)
> 本文规定规范条文的**写法**:什么内容可以进入正文、什么必须移出、以及"通用"如何被机械检验。它约束本仓库所有其他规范文档,包括已生效的 D-014。
## 1. 为什么"通用"不能只是一句声明
本规范的受支持宿主是 DeepSeek Harness(DSH);Claude Code 自 D-135 起不再支持。正文的写法仍按「换一种工具要不要改」判(§3),所以这一变化不改变正文该写什么,只改变能拿来做可行性证据的宿主有几个(§5)。
只写一句"正文只写通用内容"是无效的,原因有二:
1. **无法机械执行。** 写规范的人无法在写下某句话的当时判断它是否绑定了某种工具——因为他正在用那种工具。载体绑定通常不是以工具名出现的,而是以该工具的**默认假设**出现:假定有文件、假定有文件头、假定有目录、假定有版本控制、假定有会话概念。
2. **载体绑定会伪装成语义。** 一个约定用得足够久就会显得像真理。"工作区身份就是 repository/worktree/branch/HEAD"读起来像定义,实际上是把当下的工具生态当成了永久真理——正是[补偿面](https://github.com/Alan-IFT/dsh-project-std/blob/archive-pre-ts-refactor/docs/%E5%BD%92%E6%A1%A3/%E8%BE%93%E5%85%A5%E6%9D%90%E6%96%99/003-%E7%AC%AC%E4%B8%89%E8%BD%AE%E8%B5%84%E6%96%99%E7%BB%BC%E5%90%88%E8%AE%B0%E5%BD%95.md#impacts)所警告的。
因此本文给出可逐句套用的各条判据和一条硬性检验。
## 2. 判据一与判据二:这句话该不该写进规范
按信息的**源头**判定:
| 信息源头 | 处置 | 理由 |
|---|---|---|
| 公开语料 | **不写** | 模型已内化或将内化;写下来只是缩小它的搜索空间 |
| 代码、配置与运行环境 | **不写** | 工具可直接读取;写下来会制造第二个事实来源,且必然先于代码过期 |
| 人的头脑与组织结构 | **必须写** | 模型和工具都拿不到;不写就永远不存在 |
| 运行中观察提炼的经验 | **写**,须绑定它防的失败与删除条件 | 既不在公开语料也不能从代码读出 |
前两行的「不写」是默认方向,不是禁令:同一可推断事实观察到第二次失败即写,并绑定删除条件;读取成本过高时允许缓存副本,但副本须带对账。
叠加责任判据:**只有人能继承后果。** 凡涉及价值排序、风险接受、不可逆授权和最终验收的内容,无论模型多强都必须写,且必须指名责任人。这一条不因技术进步而消解。
两条判据的共同推论:规范正文应当**越写越短**,因为随着模型和工具变强,前两类内容持续退出;而后两类内容不会自己出现,只能由人补。
## 3. 判据三:这句话是语义还是载体
对已经通过判据一二的内容,用两个问题分类:
> **换一种工具,这句话要不要改?**
不用改的是**语义不变量**,进正文。要改的是**载体绑定**,移出正文。
第二个问题:
> **换一个团队,这句话会不会不一样?**
会变的内容不进正文;正文只写该类内容必须存在并有所有者。
载体绑定的常见伪装形态——出现以下任一项即应怀疑:
- 具名文件或目录(入口文件名、规则目录、状态文件路径);
- 具名格式(Markdown、JSON、YAML、frontmatter、表格列名);
- 具名机制(钩子事件名、命令名、子代理名、工具名);
- 具名产品或版本控制系统;
- 隐含的结构假设("文件头"、"目录深度"、"会话"、"分支")。
## 4. 两条轴:与 D-021 的分工
判据三第一问问的是"换工具变不变"。还有一个正交的问题:"换模型代际变不变"。两条轴构成四个象限:
| | 换工具不变 | 换工具要变 |
|---|---|---|
| **换模型代际不变** | 正文核心,最保值 | 载体实例(附录) |
| **换模型代际要变** | 补偿性语义:进正文,但必须带过期条件 | 补偿性载体:最易过期,优先删减 |
本文(D-020)管横轴。纵轴由 D-021 管——每条规则必须绑定它防御的失败与删除条件,否则无法判断它落在哪一行。两条轴都缺时,规范只会单调膨胀。
「删除条件」尾标的取值域是 `{具体的失效条件 | 起始档 | 运行类型限定 | 写不出(仅限责任结构型)}`:「起始档」写本条从哪一档起才有对象(形态见各章 §3);「运行类型限定」写本条只对某一类运行成立,取值轴见[00 总览 §3](00-总览.md#default-scope)(产出类型与起点状态)。**一条原则的适用范围由它自己的这个字段承载,不由总览或任何一处列举原则编号的清单承载**——那样做等于把作用域写成一份需要同步维护的第二副本。取"写不出"须同时写出责任结构型的理由,写不出理由的一律视为可淘汰性缺失。档位与运行类型标注只能用来解释"这条为什么此刻不适用",不能用来自我授权跳过一条本该拦住的检查;判不清的按最宽适用处理。新取值同样受 §5 的两种机制类型检验约束:说不清它在两种机制上如何被表达为条件加载的,说明这条其实是无条件的。
## 5. 硬性可行性检验:两种机制类型
**一条候选语义要求进入正文前,必须能说清它在至少两种机制类型不同的载体上如何落地;说不出两种的,不得进入正文。**
机制类型指以下互不相同的落地位置:
| 机制类型 | 说明 |
|---|---|
| 静态指令 | 会话开始即全量加载的内容 |
| 条件加载规则 | 按路径、任务类型或触发条件才加载的内容 |
| 运行时拦截 | 在动作发生前或发生后介入并可阻断 |
| 权限与隔离配置 | 决定能访问什么、能执行什么 |
| 外部状态存储 | 跨会话持久、可被重新读取的记录 |
| 检查器 | 对工件执行判定并输出结果 |
| 人工检查点 | 需要人做判断并承担后果的停止点 |
两种实例须落在**互不相同的机制类型**上;它们可以在同一宿主工具内,但不得是同一机制类型的两种写法(同一类型换个配置键、换个文件名不算两种)。本仓当前只支持一种宿主,因此这一检验由「同一宿主内机制类型是否互异」承担,**不再由「是否跨工具」承担**——这一替换使检验更弱(同宿主的两种机制可能共享同一失效模式),所以通过本检验的候选在「跨工具」一项上记**未定**,不折算为已验证跨工具。检验的目的不是穷举实现,而是**证伪**:如果一条要求只能在一种机制上表达,它多半是那种机制的特性被误当成了普遍要求。
未通过检验的候选不是"错误",而是**尚不具备进入正文的条件**,标记为待验证并留在决策记录里,不进正文。
除机制类型之外,正文的**表达形式**与它**引用的对象**同样受硬性检验约束。
**判据优先于枚举与样例。** 一条规则的本体是它的**判据**;清单、分类与例子是判据的例示,不是穷尽。正文出现枚举处(可上交给人的问题、停机条件、状态工件的类别、记忆的运营类别、检查点所在的状态转换、候选的提取触发、来源的分类、跨边界依赖的档次),其上位判据须与枚举写在同一处;遇到不在枚举内的对象,按判据判定,判不出即记未定并升级,**不得硬塞进最近的一项**。**失败驱动的修订作用于判据,不作用于样例**:一次失败之后被修订的对象是产生该失败的那条判据,不是把该样例编码进规则;上升不成判据的失败只登记 Case、不生成规则。人的更正同理——入库的是更正的**理由**(它是判据的候选),不是更正的**结果**(它是样例);承载检查点的载体须能同时装下产出、给出的理由与人对二者的评述。
**规则引用的每个对象须能指出载体、归属与失效条件。** 指不出的名词不得作为规则的对象:要么就地给出它的载体与去向,要么从正文删除,不得靠上下文让读者自行推测。本条与上一条互为条件——判据化会引入新的名词,而这一条负责让新名词落得下去。
## 6. 探测提示:规范给线索,项目做映射
语义要求本身不含路径、文件名和字段名。为了让它可落地,正文可以在语义要求之后附一行**探测提示**——描述"这个语义在具体项目中通常长什么样"的线索。
探测提示与必填字段的区别,是本文最容易被违反的一条:
| | 必填字段 | 探测提示 |
|---|---|---|
| 性质 | 语义要求的一部分 | 落地线索 |
| 缺失时 | 该要求未被满足 | 无影响,换个形态即可 |
| 举例 | "工作区身份必须可验证且带版本标识" | "版本控制项目中通常是仓库/工作树/分支/提交标识;容器化流程中可能是镜像摘要;任务系统驱动的流程中可能是快照 ID" |
探测提示必须写成**并列的多种可能**,不得只给一种。只给一种的探测提示会被读成必填字段——这正是"参考材料与规则打架"的形态:规则说载体可变,示例只给一种,执行者照示例做。
## 7. 规范不维护各工具的映射表
规范**不**维护"某语义在宿主甲里是什么、在宿主乙里是什么"的对照表。映射由使用者在自己的工具上生成一次,并由该项目自己持有和维护。
理由:工具约定的变化速度远高于本规范的复查速度。规范维护的映射表必然先于工具过期,而过期的映射表比没有映射表更危险——它成为第二个事实来源,执行者无从判断该信任哪一份。
推论:本规范**不因某个工具的约定变化而需要修订**。若某次工具变化迫使正文修改,说明该处正文本来就是载体绑定,应按判据三移出。这是本规范通用性的自检信号。
## 8. 载体实例的存放与效力
移出正文的载体绑定内容进入[附录·载体实例](附录-载体实例/README.md),其效力为**零**:不阻断、不授权、不构成落地要求。
载体实例的唯一作用是充当**可行性证据**与**反面参照**——展示同一条语义要求换一个载体就要重写。附录整体删除不影响规范。
模板目录同理:模板是语义要求在文档载体上的一种实现,其**字段集合**属于语义,其**文件形态、章节顺序与表格布局**属于载体。
## 9. 与 D-014 的关系
D-014 规定一条规则**是否生效**,D-020 规定一条规则**能否写成这样**。两者都作用于规范条文,但顺序是先 D-020 后 D-014:一条未通过可行性检验的候选,即使被批准也无法在多数工具上执行,批准它只会制造无法落地的生效规则。
D-014 §7 的标注载体(章节头声明 + 集中登记)本身是**一种载体实现**。其语义要求为:每条规则可追溯到唯一的效力声明位置,且状态值在整个规范中只有一处副本。用什么形式承载该声明,由项目决定。
## 10. 本决策的验证方式
| 反例 | 应触发的条款 |
|---|---|
| 正文写"入口文件应命名为 X" | §3 具名文件 → 移入附录,正文改为"入口必须唯一且可寻址" |
| 正文写"状态记录必须包含分支与提交标识" | §3 隐含版本控制假设 → 改为语义 + 并列探测提示 |
| 某语义要求只能用运行时拦截表达 | §5 未通过两种机制检验 → 不得进正文,退回待决策 |
| 探测提示只举了一种形态 | §6 会被读成必填字段 → 补齐并列形态或删除提示 |
| 有人提议在规范中维护各工具对照表 | §7 第二个事实来源 → 拒绝,改为探测提示 |
| 某工具改了约定,有人提议修订正文 | §7 自检信号 → 先检查该处是否本就是载体绑定 |
| 附录中的实例被引用为落地要求 | §8 附录效力为零 → 拒绝该引用 |
| 正文列出一份封闭清单("可上交给人的四类问题"),清单旁没有写出它的上位判据 | §5 判据优先于枚举 → 补上位判据,否则遇到清单外的对象只能硬塞进最近一项 |
| 一次失败之后在样例或清单里追加一条,产生该失败的判据不动 | §5 失败驱动的修订作用于判据 → 退回:改判据,或只登记 Case 不生成规则 |
| 规则引用了一个说不出载体、归属与失效条件的名词 | §5 规则引用的对象须可落地 → 就地给出它的载体与去向,或从正文删除 |
| 一条原则的「删除条件」写"写不出",括号里没有说明它为什么是责任结构而不是别的 | §4 取值域 → 视为可淘汰性缺失,按 D-021 处置,不得按已合法登记对待 |
| 有人拿"本条自某档起适用"当作跳过一条本该拦住的检查的理由 | §4 档位与运行类型只解释"为什么此刻不适用",不自我授权 → 拒绝;判不清按最宽适用 |