- 来源:
v2026.07.02 -> v2026.07.03目录目标修复、元数据/封面回归修复、用户反馈与发布验证。 - 状态:已验证。
- 刷新触发器:EPUB 构建器、补丁工具、目录、元数据、封面、Release 流程发生变化时。
- 验证方式:运行脚本编译、最小 fixture、EPUB 审计、Calibre 元数据检查、远端 Release SHA 下载复验。
正文补充、实验室说明、目录修复这类“局部变更”,不得默认重建整本 EPUB。重建会改变 OPF、manifest、spine、nav、NCX、封面和内部标识,严格阅读器会把它当成另一套结构。
正确做法:
- 先定义唯一允许变化的 ZIP entry。
- 修改前后记录 OPF、NCX、封面、元数据、manifest 数量、spine 数量、XHTML 数量。
- 任一不变量变化,直接失败,不输出“修复成功”。
Calibre 目录编辑器把 EPUB3 nav.xhtml 中无 href 的父级 <span> 显示成 None / 位置不存在。即使子项存在,父级项也会被标红。
正确做法:
- 有自身页面的 TOC 节点指向自身页面。
- 无自身页面但有子页面的分组节点指向首个子页面。
- 最终发布成品里
nav_span_count必须为0,nav_target_errors必须为0。
blockquote -> p、span -> a 这类结构变更不能靠简单字符串替换。带属性、命名空间、嵌套节点、空白和序列化差异都会让正则变成隐性破坏器。
正确做法:
- 用 XML/DOM 解析节点。
- 只操作目标节点和必要属性。
- 写回后重新 parse。
- 对修改前后结构不变量做机器校验。
ZIP 可打开只是最低条件。iOS Books、Calibre、Kindle 对 OPF、nav、NCX、mimetype、manifest、spine、内部锚点和缓存标识更严格。
发布前必须检查:
mimetype是 ZIP 第一项且无压缩。- 所有 XHTML/XML 可解析。
- manifest 文件存在。
- spine idref 都在 manifest。
- XHTML 内部链接、图片、锚点都存在。
- nav 链接目标都存在。
- 封面条目存在且 SHA 未意外变化。
- 元数据与内部 identifier 没被误改。
封面、作者、出版者、日期、identifier、title sort 会影响阅读器展示和缓存命中。只为了加说明文字而改 OPF,是高风险变更。
正确做法:
- 能不改 OPF 就不改 OPF。
- 必须改 OPF 时,明确写出变更字段、原因和缓存影响。
- iOS Books 异常时,优先排查内部 identifier 和旧缓存,而不是只看文件名。
公开标题页不是项目 README,过多实验室说明会干扰阅读器首页体验。TradeCatLabs 信息只保留两行:工程职责一行,工程仓库与负责人 X 一行。
正确做法:
- OPF
dc:title保持“斯坦福哲学百科全书(中文版)”。 - 标题页
h1使用“斯坦福哲学百科全书简体中文版”。 - 标题页只显示
TradeCatLabs、tradecatlabs/SEP-editing-cn与@123olp。 - 不再单独增加“实验室负责人”段落,不再展示
@tradecatlabs。
本地审计通过后仍不够。GitHub Release 上传后必须下载远端资产重新算 SHA,证明用户下载到的就是审计过的文件。
当前门禁:
release-manifest.json写入本地成品 SHA。- Release tag 必须指向包含当前发布文档和报告的提交。
- Release 附件必须包含 EPUB、
release-manifest.json、epub-audit.json、completion-report.json、user-style-diff-report.json、resource-manifest.json、resource-scan.json、orphan-pages.json、tradecatlabs-notice-report.json和nav-targets-report.json。 - Release 上传后运行
tools/check_release_assets.py --verify-epub下载 EPUB 并复算 SHA。 - 远端下载 SHA 必须等于
release-manifest.json。
如果 README 和本地报告已经更新,但 GitHub Release tag 仍指向旧提交,用户下载到的仍可能是旧 EPUB。复用旧 tag 会让“代码最新”和“资产最新”分裂。
正确做法:
- 优先创建新的 patch release tag,例如
v2026.07.03.1。 - 不强制移动已公开 tag,避免破坏历史引用。
- 新 tag 创建在当前
HEAD上,再上传完整附件并设为 latest。 - README、
RELEASE.md和reports/epub/release-manifest.json必须同时指向同一个 tag。
用户提供的待补充资料清单可以沉淀,但未确认来源、版权、授权和项目归属前,不能加入 SEP EPUB 的公开 Release。
正确做法:
- 缺口表放入
docs/SOURCE_GAPS.md作为备忘。 - 不复制来源不明的正文实体。
- 不把其他项目资料混入 SEP 供应链。
每次处理 EPUB 成品前:
- 明确本次允许变化的 ZIP entry。
- 备份或保留输入 SHA。
- 确认是否需要重建;能补丁就不重建。
- 对 HTML/XHTML 结构修改使用 DOM/XML 操作。
- 修改后检查
mimetype、OPF、manifest、spine、nav、NCX、封面、元数据。 - 检查
nav_span_count=0、nav_target_errors=0。 - 用 Calibre 工具检查元数据。
- Release tag 指向当前发布提交。
- Release 上传后用
tools/check_release_assets.py --verify-epub复验远端资产 SHA。
tools/patch_epub_tradecatlabs_notice.py:只改标题页,不改 OPF/nav/NCX/封面。tools/patch_epub_nav_targets.py:只改OPS/nav.xhtml,修复父级目录无目标项。reports/epub/DEBUG.md:两次事故的根因、实验和回归证据。reports/epub/nav-targets-report.json:目录目标修复的机器可读证据。reports/epub/epub-audit.json:最终 EPUB 审计门禁。reports/epub/release-manifest.json:Release 资产 SHA 与元信息。tools/check_repo_health.py:仓库结构、报告一致性、发布引用和软链接约定门禁。tools/check_release_assets.py:GitHub Release 附件清单、远端 manifest 与 EPUB SHA 门禁。