三处写入侧的缺口,都是被下游"模块银行"(module_bank,把模块打包进 svfs 包 再按需导入)真实逼出来的: - add_bytes(rel_path, data, ...):从内存写文件,不经过磁盘。受保护的字节码、 密文这类绝对不能落盘的内容因此可以直接入库——先写临时文件再 add_file 会把 明文留在磁盘上,而磁盘残留是这类工具最容易被忽视的泄漏点。 - make_parents=True(默认):补齐缺失的父目录行。list_directory 是按 parent_path 过滤的,而"某个目录存在"的唯一标志就是它自己那一行——少一层 目录行,export_directory 从根就递归不下去,export_filesystem() 会静默导出 一个空目录。add_file 一并受益(内部改为读盘后调 add_bytes,行为不变, 含 created_time 取 st_ctime 这个细节)。 - commit=False + 公开的 commit():一组相关文件可以写成一个事务,中途任何一步 失败整批回滚,不会在库里留下半套数据。 - rename_snapshot(id, name):create/list/delete 都有,唯独缺改名;而"把发布名 落在快照上"是版本管理的基本动作。**定格一个版本靠的正是它**:先给当前快照 改名,再另建一个工作快照接手后续写入——直接 create_snapshot(name) 的话, 名字落在会继续被写入的那一版上,下一次改动就把这个"版本"改了。 - DEFAULT_DIR_PERMISSIONS:补出来的目录行用 0o755(表的默认值 0o644 是按文件 定的,套到目录上会让导出的目录不可进入)。 - 版本 0.3.0 → 0.4.0(add_file 开始建父目录行属于可见的行为变化)。 测试:tests/test_core_add_bytes.py(22 条:往返/空内容/bytearray/时间戳与权限/ 压缩/去重/覆盖/空路径/只读拒绝/父目录行与 export 目录树/批量提交与回滚/ add_file 委托行为)+ tests/test_snapshots.py 新增 5 条改名用例(只改名字不动 内容与摘要/空名拒绝/不存在的快照报错/允许重名/改名+派生工作快照之后 已定格的版本不被后续写入改动)。完整测试套件逐个文件跑通。
起始状态:主链路 100% 不可用,而且失败被静默吞掉——打包后库里 0 个文件、 界面仍打印"文件数量: N";解包导出 0 个文件并在磁盘上生成几百层 sub/sub/sub 垃圾目录。 缺陷修复(4 个 P0 + 12 个 P1,逐条见 BUG_REPORT.md): - 建表列名 compresse_algo 与 INSERT/read_file 用的 compress_algo 不一致 - list_directory 按 path 而非 parent_path 过滤,导致导出无限自递归 - CLI --ignore-timestamps 把 export_filesystem 赋成引用自身的 lambda - add_file 缺少 commit(直接调用 API 时静默丢数据) - LIKE 前缀误伤兄弟目录(删 doc 连带删 docs);mv_dir 二次改名 - 失败路径一律返回 exit code 0;--exclude 是子串匹配而非 glob - FolderPacker.add_file 反向调用 export_file_safe,会用库内内容覆盖源文件 存储层(schema v3,格式变更,提供 vfsmigrate 迁移): - 内容移入 blobs(hash PRIMARY KEY):相同内容只存一份,跨路径/跨快照共享 - files 的唯一约束改为 UNIQUE(snapshot_id, path):一个库存多个版本 - 完整性:每文件 sha256 + 快照级摘要 + HMAC-SHA256 签名,只读连接即可验证 - 增量打包:按 mtime+size 或 sha256 只写变化项,未变文件不重写不重压 - get_file_info 不再返回 content(元数据查询不该搬 BLOB) 新增能力: - 可选 FastAPI 静态文件插件(extras,核心仍零第三方依赖) - 内容寻址发布到对象存储 + 逐对象校验的取回客户端 - 压缩默认改回 zlib:实测比自研哈夫曼体积小 1/3~1/170、快数百倍 其它: - P2-4:时间戳显式转字符串,清掉 1240 条 DeprecationWarning(盘上格式不变) - read_file 负数 offset/size 改为报错(原先会走切片语义从末尾取) - requires-python 从 >=3.7 改为按实际 API 推导的 >=3.9 测试:0 → 343 个用例,纯标准库 unittest,有/无 FastAPI 两种环境都跑通。 证据见 docs/evidence-*.txt。