# Shared Module Rules

## 适用范围
适用于 `src/host/shared/`。本文件定义 Host / Client 共享契约层特有的治理边界与修改规则；通用规范遵循根 `AGENTS.md`。

本文件描述稳定治理原则，不是当前源码结构说明。除非契约边界变化，否则不因文件移动、重命名或内部重构而修改。

## 核心职责
为 Host 半区与 Client 半区提供**同一份**契约来源：

- 共享的形状（图模型、持久化文档、模板、元参数）；
- 共享的跨层常量（端点名、工具名与可见性、状态枚举、口径常量）。

判断归属：该修改是否同时约束 Host 与 Client 两端的契约？只影响一端的实现细节，应放到对应半区，而不是共享层。

## 非职责
不负责：

- 业务逻辑与运行时行为：校验、归一化、判定、编排、持久化；
- 任何运行时实现细节：具体模块路径、类、函数；
- 单向契约：只被一侧使用的类型不得放进共享层。

## 纯度契约
共享层必须保持「可被两端零风险引用」：

- **禁止运行时 import**：不得引入任何模块的运行时值（避免双 tsconfig 的 Context augmentation 相互污染）；
- **允许 `import type`**：类型引用编译期完全擦除，不构成运行时依赖；
- **形状文件不得定义运行时值**：运行时值只允许出现在协议常量文件中，并必须是无运行时依赖的字面量常量；
- 不得在共享层定义全局可变状态、单例、副作用或环境依赖。

## 契约一致性
- 协议层枚举/取值域与类型层联合必须**双向穷尽**：任一侧增删取值时两侧同步，并由编译期断言锁定（类型 ⊆ 常量 ∧ 常量 ⊆ 类型）。
- **禁止用固定长度或固定列表断言代替穷尽断言**：固定列表会把漂移锁死，而不是发现漂移。
- 同一语义只允许一处本体。需要跨文件引用时用 `import type` 直接引用本体，不得使用「结构镜像 + 键集合断言」这类双份维护的替代方案。
- 形状必须与真实写入/读取对齐：持久化层或客户端实际写入的字段（如时间戳）必须在本层声明，不得依赖调用方 `as` 断言补形状。

## 契约路径稳定
- 对外契约的 import 说明符属于公共契约：内部按职责拆分时，必须保留既有路径（通过 type-only barrel 再导出），不得要求调用方改 import。
- 新增契约优先落在语义最贴近的现有职责文件；仅为「文件数好看」新增聚合文件是被禁止的。

## 兼容性
- 字段增删必须说明旧数据与旧客户端的读取行为：新增字段默认可选，删除/改义必须给出兼容路径。
- 已退役字段只保留**读取兼容**语义，禁止新增写入，也必须说明何时被剥除。
- 修改公共契约（端点名、工具名、可见性、状态枚举、bundle 格式）必须同步检查调用方、测试、Tool Schema 与相关文档。

## 修改前确认
1. 这是 Host/Client 双方共用的契约，还是单侧实现细节？
2. 是否引入运行时依赖或运行时值？
3. 是否改变端点名 / 工具名 / 可见性 / 状态枚举 / bundle 格式？
4. 是否与类型层、磁盘事实或客户端行为产生漂移？
5. 是否有调用方、测试、架构文档需要同步？
6. 是否保持了既有契约路径（import 说明符）？

## 核心原则
1. 契约单一来源，禁止双份维护。
2. 形状与逻辑分离，共享层不含行为。
3. 零运行时依赖；`import type` 优先。
4. 枚举双向穷尽，禁止固定列表断言。
5. 契约路径稳定，内部拆分不外溢。
6. 兼容优先于整洁，退役字段只读。
