AGENTS.md@src/host/storage · git:20260922.3481b25 · 2026-09-22 · sha256 db0e249ff9dd808d

AGENTS.md@src/host/storage git:20260922.3481b25A

Immutable. This exact content never changes and is served at /api/v1/blob/db0e249ff9dd808d.

# Storage Module Rules

## 适用范围
适用于 `src/host/storage/`。本文件定义持久化事实层特有的治理边界与修改规则;通用规范遵循根 `AGENTS.md`。

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

## 核心职责
以「单文件即单资源 + 原子发布 + 进程内/跨进程锁」保存与读取 Host 的持久化文档,并对外提供可复用的原子文件原语与崩溃恢复能力。

判断归属:该修改是否改变「什么被持久化、以什么形状持久化、并发写入如何被串行化」?只改变业务语义判断(是否合法、是否该存在、下一步做什么)应放到对应领域模块。

## 非职责
不负责:

- Workflow / 图语义决策:结构合法性、状态机推进、运行编排、结构编辑;
- 运行态内存事实:运行锁、运行快照、等待器、子代理表(归 orchestrator);
- 第二套结构事实源:不得缓存或镜像一份 Workflow 结构;
- 调用方业务规则:是否允许删除、是否会话越权判定所需的策略,由调用方表达,storage 只执行明确的读写。

## 状态所有权
- 数据目录布局、`revision`、`updatedAt`、资源归属字段(如 `sessionId`)与写入字段剥除策略由 storage 决定并对外表现为稳定语义。
- 调用方不得绕过 storage 直接写同一数据文件;需要新资源类型时在 storage 增加明确入口,而不是在别处拼路径。
- 只读方只能拿到值副本(如映射读取返回新对象),不得让调用方持有内部可变结构。
- storage 回答「存了什么」,不回答「是否该存在」。

## 读取语义(可执行)
- 单资源读取遇损坏 JSON **必须抛出带路径的可诊断错误**,不得伪装成「不存在」。
- 列表读取跳过损坏项以保证可用性,但不得吞掉权限等其他错误(避免把权限问题伪装成空列表)。
- 新增读取入口必须明确选边(单资源 / 列表),并在注释与测试中固化该选择。

## 原子性与锁(可执行)
- 所有写入必须经组合锁原语(磁盘锁在外、进程内锁在内),不得裸写文件。
- **读改写必须在同一临界区内完成**:禁止 `check → await → act` 形式的跨锁判定(会丢更新)。
- 新增写路径必须复用既有原子原语,禁止定义第二套持久化协议(临时文件命名、fsync、发布方式、锁语义都属原语职责)。
- 新增公共写方法必须能说明:其读改写位于同一临界区,且失败路径不残留临时文件或锁。

## 生命周期与跨文件边界
- 目录初始化必须幂等;新增目录必须同时进入布局常量,不得散落硬编码路径。
- 删除与创建语义必须对称:级联删除的从属文件必须显式列出并注释其归属关系。
- **跨文件事务不在保证范围内**:例如服务文档与其会话映射文件由不同锁键保护,删除服务后并发写入仍可能重建从属文件。调用方必须在写入前校验主资源存在,并保证写顺序;新增此类从属文件必须写明该不变式。

## 时间戳与版本
- `createdAt = 调用方值 ?? 既有值 ?? now`;`updatedAt` 与 `revision` 恒由 storage 生成,调用方传入值不得覆盖。
- 乐观锁只在调用方显式传入 `expectedRevision` 时生效(不得用文档内的 revision 隐式当作冲突期望)。

## 兼容与退役字段
- 旧字段只保留读取兼容语义,重新保存后被剥除;禁止新增已退役字段的写入。
- 前端临时标记与仅服务端拥有的字段必须在写入路径统一处理,不得依赖调用方自觉清理。
- 修改磁盘形状、目录布局或公共错误码时,必须同步检查读取路径的向后兼容与调用方。

## 纯函数与副作用分离
- 路径计算、字段剥除、版本记账、文档投影等确定性逻辑必须实现为纯函数,且与 IO 分离(不读时钟、不读盘、不改写入参)。
- 副作用(写盘、删除、建目录、加锁)只出现在 store 方法与原子原语中;不得藏在名称模糊的 helper 或看似纯函数中。
- 领域映射(如把一种持久化文档投影成另一种视图)保持纯函数,且不得在投影中做写入或语义决策。

## 修改前确认
1. 这是持久化事实,还是领域语义判断?
2. 是否改变磁盘形状、目录布局、公共 API 或错误码?
3. 是否改变并发/锁语义(是否仍在同一临界区完成读改写)?
4. 是否引入跨文件事务假设;若有,调用方不变式是否已写明?
5. 是否有调用方、测试与架构文档需要同步?

## 验证
验证命令遵循根 `AGENTS.md`。除标准命令外,本模块改动必须额外确认:

- 并发写同一资源无丢更新(读改写仍在同一临界区);
- 失败路径无临时文件与锁残留;
- 单资源读对损坏 JSON 仍抛可诊断错误、列表读仍保持可用;
- 无旧路径残留、无循环依赖、磁盘形状与公共错误码未被意外改变。

## 核心原则
1. 持久化事实由 storage 单独拥有。
2. 单一写入入口,状态变化经明确方法。
3. 读改写不出临界区,锁顺序固定。
4. 单资源读可诊断,列表读可用。
5. 纯函数与副作用分离。
6. 时间戳与版本由 storage 记账。
7. 跨文件一致性由调用方保证并写明不变式。
8. 磁盘形状与公共错误码属对外契约。