6abe13abb1
一个 encode 对七个 decode_*。编码不需要知道目标类型(对象自己知道),解码需要 (一个字典什么都不知道),不对称是这个原因。 载荷就是记录类的字段,没有任何元信息键——没有类型标签、没有时间戳。哪一行是哪种记录由 存储实现自己解决,库不替它定文件布局;多塞一个键会让步记录的载荷不再和迁移前那份逐行 轨迹同形,而那边的验收标准是逐字段可比。 解码三条:带版本的三种记录(运行开始、步记录、运行结果)版本必须在场且认得,缺了或者 认不得都失败;记录类上的每个字段都必须在载荷里,有默认值的也一样(默认值补齐会把 「这件事没发生过」改写成「发生了但值为空」);多余键忽略(存储常要在同一个字典里塞 自己的东西,把它整个递回来解码是最自然的写法)。 第二条的直接后果写进了模块 docstring:往持久化结构里加字段必须同时抬 schema 版本。 CLAUDE.md §1.3 那条「新增字段必带默认值」管的是 Python 构造器,持久化这一侧由 §1.4 管。 SchemaVersionError 与 DecodeError 分开:一个说去升级库,一个说去查数据。压成一个的话, 一次例行升级漏做会被读成数据损坏,然后有人去修数据。