Files
BlueArchiveToolkit/docs/reports/CURRENT_GAPS.md
T
nyaKazuha 72c1a879a3
bat-rust / Build and test Rust (push) Canceled after 0s
bat-rust / Build and test Go API (push) Canceled after 0s
feat(bat): 补全工作流命令与人工校对状态
Refs #43
2026-08-19 21:33:33 +08:00

576 lines
35 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 当前实现缺口清单
- **更新时间**2026-08-03
- **Go 进度权威**`GO_STATUS.md`
- **资源布局 / 逆向契约**`../architecture/resource-release-layout.md`
- **用途**:集中跟踪当前代码中的占位实现、设计缺口和下一步验收项。
- **权威计划**`../../PROJECT_PLAN.md`
---
## 1. 基线缺口
### G-001Git 元数据不可用
状态:**已关闭,采用新初始化基线**
原现象:
- `.git/` 是空目录。
- `git status``not a git repository`
处理结果:
- 已执行 `git init`
- 已将初始分支调整为 `main`
- 已配置当前路径为 Git safe directory。
- `git status --short --branch` 已可用。
- 本轮创建首次基线提交。
限制:
- 原项目历史未恢复。
- 后续历史从当前基线提交开始。
验收:
- `git log --oneline -1` 能看到基线提交。
### G-002CAS 有两套实现边界
状态:**已关闭**
原现象:
- `crates/bat-cas-engine/src/storage.rs` 有文件系统存储。
- `infrastructure/src/cas/filesystem.rs` 也实现了文件系统 CAS repository。
处理结果:
- `crates/bat-cas-engine` 新增 `repository` 组合层,成为 CAS 核心实现。
- `infrastructure/src/cas/filesystem.rs` 已改为 `bat-core::CasRepository` 适配层。
- infrastructure 不再直接写对象文件,不再维护自己的引用计数逻辑。
验收证据:
- `bat-cas-engine::repository::FileSystemCasRepository`
- `bat_infrastructure::FileSystemCasRepository`
- `cargo test --workspace`
### G-003CAS 引用计数和 GC 未实现
状态:**已关闭**
原现象:
- `FileSystemCasRepository::add_reference` 返回固定 `1`
- `remove_reference` 返回固定 `0`
- `get_reference_count` 返回固定 `1`
- `gc` 返回固定 `0`
- `crates/bat-cas-engine/src/refcount.rs` 是占位。
处理结果:
- `crates/bat-cas-engine/src/refcount.rs` 使用 SQLite 保存对象元数据和引用计数。
- `store()` 会存储对象并增加引用计数。
- `add_reference()``remove_reference()``get_reference_count()` 已持久化。
- `gc()` 删除引用计数为 0 的对象和元数据。
- `gc_candidates()` 提供 dry-run 能力。
验收证据:
- 引用计数增减有持久化测试。
- GC 不删除仍被引用对象。
- 并发引用更新测试通过。
---
## 2. 核心功能缺口
### G-004:CAS 写入不是生产级原子流程
状态:**已关闭**
原现象:
- 当前写入直接写目标路径。
- 缺少临时文件、fsync、原子 rename、并发冲突处理。
处理结果:
- `FileSystemStorage::put()` 使用临时文件写入、文件 sync、原子 rename、目录 sync。
- 读取对象时强制 Hash 校验。
- 并发写入相同内容只保留一个对象,引用计数按调用次数递增。
- 损坏对象读取返回 `HashMismatch`
验收证据:
- 写入失败不会留下可见半成品对象。
- 并发写入相同内容只产生一个对象。
- 读取时 Hash 不匹配会返回明确错误。
### G-005AssetBundle 引擎解析器仍未完成
状态:**部分完成**
冻结状态:自 2026-07-30 起,G-005 不再作为默认推进项。解析层只接受维护冻结规则允许的稳定性修复、诊断修复、真实回归修复和文档校正;新增 TypeTree 语义类型、扩大解析覆盖和新增写入型解析入口全部暂停。冻结细则见 `docs/reports/PARSER_FREEZE.md`
现象:
- `crates/bat-assetbundle` 已接管 UnityFS 解析,提供 `UnityFsParser``UnityFsBundle`、header、block info、directory、压缩模式、block info at end、LZ4/LZMA block info 解压、数据 block 解压、directory 文件提取和边界诊断。
- `crates/bat-assetbundle::serialized` 已提供 Unity serialized file header、type table、TypeTree node 元数据、object table、TextAsset bytes 和基础 TypeTree field reader。
- `adapters/src/unity/unity_2021_3.rs` 已降为 Unity 版本选择薄层,复用 `bat-assetbundle`,不再维护第二套 UnityFS parser。
- `ResourceImportService` 的 UnityFS 摘要已经能暴露解包文件数、serialized file 数、TextAsset 名称、TextUnit 数量/格式和字段诊断。
- `MonoBehaviour``ScriptableObject` 已有基础 TypeTree 字段级反序列化和字符串提取入口;array/vector/staticvector/`List<T>`/`HashSet<T>`/map 元素与 TypeTree-covered managed reference registry payload 已保留独立 field path、offset 和 byte sizeenum `value__` backing field 会暴露为语义化 `{type_name, storage_type, value}``LayerMask` / `BitField``m_Bits` backing field 会暴露为语义化 `{type_name, storage_type, bits}`managed-reference full typename 可拆为 assembly/namespace/class,常见 `m_ManagedReferences` / `RefIds` / `m_RefIds` / verbose type 字段命名、`managedReference*` / `serializedReference*` prefixed metadata、`SerializedReference` 节点 alias 和 `data` / `value` / `payload` / `object` / `managedReferencePayload` / `referencePayload` / `serializedReferencePayload` / `managedReferenceValue` / `referenceValue` / `serializedReferenceValue` / `managedReferenceObject` / `referenceObject` / `serializedReferenceObject` / `managedReferenceData` / `referenceData` / `serializedData` / `serializedReferenceData` payload 命名已有回归覆盖,多记录 registry 聚合已有单元回归,TextUnit 提取会跳过 registry 元数据字符串并把它们作为 payload 文本上下文,fallback 字段遍历也会跳过常见 managed-reference 元数据别名,并按 `RefIds[n]` 等记录前缀或子字段推导 metadata 写入 payload TextUnit context;当前可对 string、bool、integer、float raw bits、bytes、enum、bit_field、常见固定 Unity float/int/hash 值类型的 leaf/direct-child 形态、unknown fixed-size raw bytes 同长度替换、PPtr、object 字段组合和 TypeTree schema 支撑的 array/vector/List/HashSet/map 整体替换执行文件级 patchmap entry 的 `first/second``key/value` 字段命名已有 serialized 和 UnityFS 重建回归,ScriptableObject `key/value` map 解析、变长替换和 UnityFS 重建已有专门回归;真实版本差异、未见样本驱动的复杂 managed reference registry / map entry 变体、unknown 字段结构语义和发布级重打包入口仍未完成。
issue 43 例外说明:新增的 `parse repack` 只编排已有 TextAsset、TypeTree string 和受支持语义 field patch 实现;它不新增解析器类型、字段族或 catalog 覆盖。人工翻译工作台和有限 TextAsset 发布也只消费已有 TextUnit 输出。
影响:
- 可以对 UnityFS 容器做结构校验、解包 directory 文件,并提取 serialized file 中的 TextAsset 原始 bytes。
- 对日语汉化最关键的 TextAsset 索引、bytes、JSONL TextUnit、MonoBehaviour/ScriptableObject 基础字符串字段、array/vector/List/HashSet/map 字符串元素和 TypeTree-covered managed reference payload 提取已有入口;managed-reference 类型元数据作为上下文保留,不进入翻译文本队列,fallback registry 字段遍历也会过滤常见元数据别名,并按记录前缀或子字段保留可推导 metadata。文件级 UnityFS 重建可覆盖 TextAsset、TypeTree string 字段、managed-reference registry payload 字符串、基础语义字段、enum、bit_field、unknown fixed-size raw bytes、object 字段组合和 TypeTree schema 支撑的 array/vector/List/HashSet/map 整体替换,但还不能完成发布级复杂对象重打包。
当前验收证据:
- `crates/bat-assetbundle` 能解析结构化测试样本和隔离真实样本。
- 支持 UnityFS header、blocks、directory、metadata 摘要、directory 文件提取。
- 支持 Unity serialized file object table、TypeTree node 元数据和 TextAsset 提取的合成 fixture。
- 错误包含偏移和字段上下文。
关闭前仍需:
- 冻结解除前不继续扩大 TypeTree 字段 reader 覆盖。当前 TypeTree-covered managed reference 字段与 registry 记录已可结构化解码,`m_ManagedReferences``RefIds` / `m_RefIds`、verbose type 字段、`managedReference*` / `serializedReference*` metadata、payload/value/object 家族、`managedReferenceData` / `referenceData` / `serializedData` / `serializedReferenceData` payload、多记录 registry 聚合、enum `value__` backing field、`LayerMask` / `BitField``m_Bits` backing field、固定 Unity float/int/hash 值类型 leaf/direct-child 形态、unknown fixed-size raw bytes 同长度替换、嵌套 vector `Array` 形态、`List<T>` / `HashSet<T>` 集合 alias、`first/second``key/value` map entry schema、空 array/vector/List/HashSet/map 扩容已有合成 fixture 覆盖;剩余真实版本差异、unknown 字段结构语义、更多 nested collection、managed reference registry / map entry 变体只记录为冻结后的工作。
- 用真实 fixture 继续覆盖 MonoBehaviour、ScriptableObject 字段级遍历和字符串策略。
- 输出可追溯文本定位:bundle path、archive entry、serialized file、path id、class id、field path、字段 offset/byte size。
- 用真实资源 fixture 覆盖对象级解析、TextAsset 提取和字段级文本提取。
- 将解析结果作为 Patch 输入;真正的重打包、Patch 生成和 `localized` 发布切换归 G-006/G-011D。
解析补全路线图:
-`docs/architecture/assetbundle.md` 的 P2/P3/P5。
### G-006:Patch 引擎基础已落地,发布入口仍未完成
状态:**部分关闭**
已完成:
- `bat-patch::binary` 已提供确定性 Binary hunk diff/apply,应用前校验 source size/BLAKE3,应用后校验 target size/BLAKE3。
- `bat-patch::json` 已提供 RFC 6902 JSON Patch apply,覆盖 add/remove/replace/move/copy/test 和 JSON Pointer escape。
- `bat-patch::text` 已提供 UTF-8 Text Patch,按 source-relative byte range 替换,支持 expected 文本校验、UTF-8 边界校验、source/target BLAKE3 和 size 校验。
- `bat-patch::manifest` 已定义通用 Patch manifest、文件级 patch kind、source/target BLAKE3、size、rollback 元数据和 manifest 文件完整性校验。
- `LocalizedPatchManifest` 可转换为通用 `bat_patch::PatchManifest`UnityFS TextAsset 发布链路和通用 Patch manifest 已有类型对齐点。
- `infrastructure::patch_ops``patch.apply` RPC 和 `patch-apply` CLI 已开放文件级 Binary/JSON/Text patch apply;输入/输出为显式文件路径,输出原子写入并返回 size/BLAKE3。
- `unityfs.patch_text_asset` / `unityfs.patch_string_field` / `unityfs.patch_field` RPC 和 `unityfs-patch-text-asset` / `unityfs-patch-string-field` / `unityfs-patch-field` CLI 已开放显式 UnityFS bundle 文件写入;TextAsset、TypeTree string 字段、managed-reference registry `data` / `managedReferenceData` payload 字符串、基础语义字段、enum、bit_field、固定 Unity 值类型 leaf/direct-child 形态、unknown fixed-size raw bytes、object 字段组合和 TypeTree schema 支撑的 array/vector/List/HashSet/map 整体替换会在重建后重新解析校验。
影响:
- 通用 Binary/JSON/Text Patch crate 能力可作为后续发布流程输入。
- 文件级写入入口可用于隔离测试和上层工具显式产物生成。
- 发布级通用 `patch build` / `patch rollback`、复杂 AssetBundle 重打包和完整翻译文件集合的正式使用仍未完成;issue 43 的 `parse repack``parse clear-cache``i18n validate``i18n publish` 仅覆盖已有 patch 实现支持的安全子集。
验收:
- Binary patch 能完成 diff/apply 往返。
- JSON patch 能应用 RFC 6902 patch。
- Patch manifest 包含 hash、版本和回滚信息。
- Patch 构建/应用必须写 staging,完整性校验通过后才能发布。
- `patch.apply` / `patch-apply` 对显式文件执行 apply 时必须原子写目标文件,并返回 source/patch/target hash 与 size。
- 失败时不得影响 `bat-resources/current` 或已发布 `bat-localized/current`
### G-007Addressables Catalog 解析不完整
状态:**部分关闭**
现象:
- `AddressablesCatalogDriver` 已能解析当前真实形态 JSON catalog fixture/golden。
- 已输出 path、hash、size、resource_type、address、dependencies、metadata,并已提取 `m_Crc``crc` 字段。
- compact catalog 解析已补充 hash/size/CRC 的非 0 回归、资源计数 metadata,以及 blob 解码失败时的明确错误;不再在 compact 字段损坏时静默退回低保真 `m_InternalIds`
- `bat-core` 已提供 `crc32_ieee``ResourceEntry::verify_downloaded_bytes`SQLite `ResourceRepository` 已有 `crc` 列迁移。
- 仍需覆盖更多官方 catalog 结构变体、provider/bundle name 持久化字段,以及真实 Windows/Android catalog 样本集合。
影响:
- 当前解析能力可以服务 Manifest inspect 和部分资源索引,但还不能宣称完整兼容所有 Unity Addressables/SBP catalog 形态。
验收:
- 能解析项目目标版本的真实 Catalog 样本集合。
- 解析结果包含资源 key、provider、dependency、hash、size、path、CRC。
- 对不支持的 catalog 结构返回明确错误,而不是静默丢字段。
- 解析结果能反查 bundle 文件、依赖链和本地下载 manifest 条目。
- Windows/Android 样本集合需要覆盖 JSON、compact JSON 和后续二进制 catalog 入口。
解析补全路线图:
-`docs/architecture/assetbundle.md` 的 P1。
---
## 3. 应用层缺口
### G-008Go 同步/运维 CLI 产品入口
状态:**已决策关闭(wontfix**
决策(2026-07-24,见 `GO_STATUS.md`):
- **正式同步/运维命令行 = Rust `bat`**(近乎全自动:auto-discover + watch/daemon,无需持久手操维护)。
- **不另做**产品级 Go 同步 CLI,避免与 Rust `bat` 双轨。
- Go 试验入口 `cmd/bat` 可保留为 experimental,产物必须为 `bin/bat-go`**禁止**再构建为 `bin/bat`
- Go 正式产品入口集中在 **`bat-api` 资源 bootstrap/分发服务** + `internal/backendrpc`G-009)。
原验收(真实 doctor / Go sync 包装)**不再作为当前里程碑**。
### G-009API Server`bat-api`,资源 bootstrap/分发)部分完成
状态:**资源 bootstrap + CDN MVP 已落地;非完整官方游戏 API**
目标(对应 issue #19**按资源面收窄**):
- `cmd/bat-api`:组织 Rust `bat` 已发布 release 的启动前资源入口,并只读分发官方 CDN host/path 形态资源。
- **拉取归属 Rust `bat`**`bat-api` 不做下载器。
- 发现经 `bat.sock`:先 `daemon.status`,再 `daemon.doctor`,再 `catalog.status` / `resource.manifest`
- Rust RPC 的 `resource.state``catalog.status``parse.status``localized.status` 会返回短状态 `status` 与稳定生命周期状态码 `status_code``backendrpc` 已提供对应 client 能力,当前 `bat-api` 发现流程只消费 `resource.state``catalog.status``resource.manifest`parse/localized 不由 HTTP surface 暴露;错误原因仍以 `BAT-ERR-*` 为准。
- `bat-api` 可通过受限 Web 控制面转发 `reload` / `refresh` / `restart` / `sync` / `verify` / `repair` / `catalog-refresh`,这些控制动作均走 Rust live RPC`parse.*``localized.status` 和文件级 `unityfs.patch_*` 属于 `backendrpc` 能力,但当前不由 HTTP surface 暴露;`daemon.clean-stable` 等危险或离线生命周期命令不经 Web 转发。
- 生产与 Rust `bat` 同环境运行,资源根来自 RPC 返回的 `resource_root``--resource-root` 仅用于 fixture 或应急只读诊断。
- `.env` 配置端口 / public base / RPC socket / RPC 刷新周期;预留 database/redis。
- `/v1/bootstrap` 返回 RPC 健康、release 摘要、server-info URL、client-patch base 和改写后的 Addressables root。
- `/v1/launcher/bootstrap``/api/launcher/...` 形状端点返回资源引导兼容信息,当前来源是 Rust `bat` 已发布 snapshot/RPC 中的 launcher metadata 与 GameMainConfig 摘要;Rust 侧已新增 release 内 `official-launcher-bootstrap.json` 版本化产物,后续 bat-api 字段统一和联调应以该产物加 RPC contract fixture 为准。
- `/healthz` 暴露最近一次 RPC refresh 诊断;`/readyz` 在无可分发 release 时返回 `503`
- 玩家-facing HTTP 控制面必须支持 token 鉴权、限流、访问日志、反代 IP 适配、动态 JSON `no-store``/v1/resources` 分页上限。
- CDN path 支持 `GET` / `HEAD` / `Range`、ETag、Last-Modified、Accept-Ranges 和长期缓存头。
- launcher 完整安装包更新链、账号、登录、网关、游戏业务 API 和鉴权全链 **非关闭条件**;USERGUIDE 已补基础章节,联调后补生产排障样例。
已完成:
- `cmd/bat-api``internal/api``/v1/bootstrap``/v1/launcher/bootstrap`、launcher 资源 metadata 兼容端点、HTTP token 鉴权、限流、访问日志、反代 IP 适配、动态 JSON `no-store``/v1/resources` 分页上限、OpenAPI、`/admin/` 管理控制白名单、RPC 周期刷新/诊断、`/readyz`、CDN Range/缓存头、fixture 单测、USERGUIDE 基础章节、systemd bat-api 模板、`make build-go-api` / `test-go-api`
- 进度权威:`docs/reports/GO_STATUS.md`
- Rust snapshot schema 与 Go mirror struct 的仓库内 contract fixture 已完成,文件位于
`internal/api/testdata/contract/`;剩余是 live daemon socket 和完整 release 切换联调。
验收(剩余):
- 与远程长期运行的 `bat` / 全量 release 联调(覆盖 bootstrap、server-info、CDN pathSSH 实勘可后置)
- refresh 中 manifest 磁盘校验的 mtime/size 增量缓存优化(真实全量 release 观测后决定)
- 文档与 GO_STATUS 持续一致
排期:P2 主体可联调;持久化 API 层与完整 launcher/业务链另议。
### G-010Web 管理后台尚未实现
现象:
- `web/` 只有目录结构。
影响:
- 翻译审核、术语管理、Dashboard 无 UI。
验收:
- 登录、权限、翻译审核、术语管理基础流程可用。
---
## 4. 数据与翻译缺口
### G-011Resource Repository 查询面仍不完整
状态:**部分关闭**
影响:
- `SqliteResourceRepository` 已存在,可按领域 repository 接口保存资源元数据。
- `ResourceImportService` 已能把 manifest 中有数据的资源写入 CAS + `ResourceRepository`AssetBundle 会记录 UnityFS 摘要,TextAsset/Table/Media 会分类索引。
- 官方同步下载结果可用 `--import-repository` / `BAT_IMPORT_REPOSITORY=1` 在已校验 release 发布后自动导入 CAS + ResourceRepository;默认 CAS 为 `<output>/.cas`,默认 SQLite 索引为 `<output>/resources.sqlite`,也可通过 `--import-cas-root``--import-resource-db``BAT_IMPORT_CAS_ROOT``BAT_IMPORT_RESOURCE_DB` 覆盖。
- `resource.index` RPC/CLI 已能按资源类型、hash、路径模式、官方 release ID、平台、destination、bundle path、archive entry、parse status 和 TextUnit format 分页查询现有 SQLite 索引;数据库不存在时返回 `available=false`,不会因查询创建空库。
- 官方 release 发布后会写出 `official-resource-changes.json``crowdin-translation-handoff.json`,新增+变更资源进入解析/翻译 handoff,删除资源只进入差异记录。
- `Resource` metadata 已通过 SQLite `metadata_json` 兼容迁移保存 release、平台、bundle path、parse status、TextAsset 名称和 TextUnit 数量/格式;`resource.index` 会返回这些 metadata。
- 官方 release 发布后会持久化 `official-textunit-index.json`,记录单条 TextUnit 和解析错误;`parse.text_units` / `parse.errors` RPC 和 `parse-text-units` / `parse-errors` CLI 可按 destination、archive entry、path id、class id、field path 和 format 分页过滤。
- 官方 release 发布后会从 Added/Modified 资源、parse cache 和 TextUnit 明细索引派生 `official-textunit-tasks.json``crowdin-textunit-queue.json``translation-tasks.sqlite`;删除资源不会进入队列。
- 官方 release 发布后还会写入版本化 `translation-handoff.json``translation.handoff` RPC/CLI 动态合并该快照与 SQLite worker 状态,暴露 job、unit、provider run、attempt 和 failure reason。
- `translation-tasks.sqlite``schema_migrations` 管理 durable task state、attempt count、provider run ID 和 failure reason;重复同步会保留已有 worker 状态。
- `translation.tasks` RPC/CLI 优先查询 `translation-tasks.sqlite`,旧 release 没有状态库时回退到 `official-textunit-tasks.json`;返回队列 `status`、worker `task_status`、failure reason 和时间/尝试次数。
- `translation.task.update` 已提供 queued/running/failed/completed/skipped 状态回写契约,并已通过 `bat i18n task update`、Go typed helper 和 bat-api 鉴权控制面暴露;`translation.proofread` 已提供人工校对状态标记契约,provider worker 可在消费 handoff 后按 task_id 更新并由同一查询接口反查。
- `i18n get/set/unset` 可查看、修改或清空单条工作台译文,`i18n validate` 可在发布前校验工作台 release、source text、重复 patch 目标,并区分可直接发布的 TextAsset 与必须进入 `parse repack` 的条目;`i18n proofread` 可把当前汉化 workflow 标记为人工校对中,且不会遮蔽已发布汉化 release;`parse clear-cache` 只删除可再生解析/队列 JSON,保留 `translation-tasks.sqlite` 的 worker 状态。
- 真实 Crowdin 网络 worker、翻译记忆和完整 localized repack 仍属于后续翻译系统工作,不在当前 Rust 离线状态仓储范围内。
验收:
- schema 和迁移可重复执行。
- 可按版本、平台、类型、hash、路径、destination、archive entry、parse status 和 TextUnit format 查询资源,且能明确区分索引缺失、版本缺失和空结果。
- 官方同步后的资源可通过 CLI/RPC 查询并能追溯到 CAS 对象。
- `official-parse-cache.json` 的 bundle、zip entry、TextAsset 和 TextUnit 摘要能进入 ResourceRepository 查询面。
- `parse.status` 能报告 TextUnit 索引、TextUnit 队列路径与摘要。
- `parse.text_units` / `parse.errors` 能分页查询当前 release 的 TextUnit 明细和解析错误。
- 离线 TextUnit 翻译任务状态和跳过/失败 reason 可反查到对应官方 release、资源 destination 和 archive entry。
- Crowdin handoff 被后续翻译 worker 消费后,worker 状态、远端失败原因和完成结果能反查到对应官方 release 与资源 destination。
解析补全路线图:
-`docs/architecture/assetbundle.md` 的 P4。
### G-011A:资源导入链路基础能力不足
状态:**已关闭**
历史现象:
- 资源导入链路只导入 AssetBundle。
- 非 AssetBundle manifest 条目只会被跳过。
- 导入报告只包含 UnityFS 基础摘要,不包含稳定分类统计。
处理结果:
- `ResourceImportService` 会把有数据的 manifest 条目导入 CAS 并写入 `ResourceRepository`
- AssetBundle 仍执行 UnityFS header/block/directory 摘要解析。
- TextAsset、TableBundle、Media 会按资源类型分类,缺少数据时记录为 skipped,便于渐进导入。
- `ResourceImportReport` 增加 `category_counts``ImportedResource` 增加 `resource_type``category` 和可选 UnityFS 摘要。
验收:
- `cargo test -p bat-infrastructure import::tests::`
- `cargo test -p bat-infrastructure --test synthetic_phase2_import`
### G-011B:官方版本状态管理不明确
状态:**已关闭**
历史现象:
- 当前可用版本主要靠 `current` symlink 和 release 内 snapshot 推断。
- 未显式保存“正在拉取版本”和“失败版本”。
- 上一个可用版本需要从目录状态间接判断。
处理结果:
- 新增 `<output>/official-version-state.json`
- 开始下载后写入 `in_progress_version`
- 发布成功后写入 `current_completed_version``previous_available_version`
- 失败或中断后写入 `failed_versions` 并清空 in-progress。
- `bat status` 会读取并展示版本状态摘要。
验收:
- `cargo test -p bat-infrastructure version_state`
- `cargo test -p bat-infrastructure --test official_game_main_config_bootstrap`
### G-011D:汉化发布状态与 Patch 发布流程未完成
状态:**部分关闭**
当前已完成:
- 官方原版资源发布根为 `./bat-resources`,汉化产物发布根为 `./bat-localized`
- CLI 支持 `--localized-output` / `BAT_LOCALIZED_OUTPUT`,并拒绝官方目录和汉化目录相同或互相嵌套。
- 官方同步报告新增 `localized_release_status=not_localized`,明确表示原版资源已发布、汉化资源未发布;`translation.proofread` 只写 workflow 标记,不会把 `localized_release_status``localized` 回退成 `not_localized`
- `LocalizedPatchService` 已具备将给定汉化文件按官方相对路径发布到 `--localized-output` / `BAT_LOCALIZED_OUTPUT` 指定目录下的 `.staging/<id>`、校验后移动到 `versions/<id>`、原子切换 `current` 并写入 `localized-version-state.json` 的基础能力。
- `LocalizedPatchService` 已写入结构化 `localized-patch-manifest.json`,记录 TextAsset 操作、原始/汉化 hash、size、byte delta 和 rollback 信息;发布前后会校验 manifest hash/size 与 current symlink,失败时清理 staging / 未完成 version。
- `localized.status` RPC 会读取 `.env` / daemon 配置中的汉化输出目录,校验汉化状态是否匹配当前官方 release,且要求 patch manifest 存在并匹配 release,避免写死 `./bat-localized` 或误报手工状态;其中 `status` / `status_code` 返回生命周期状态,`localized_release_status` 保留 `localized` / `not_localized` 发布标签,`translation_workflow_status=manual_proofreading` 仅描述人工校对流程,不影响已发布汉化资源继续正常发布。
仍未完成:
- 真实 Patch/翻译构建阶段尚未从 `crowdin-textunit-queue.json`、翻译记忆和 Crowdin 结果生成完整汉化文件集合。
- 通用 Binary/JSON/Text Patch crate 基础和文件级 `patch.apply` / UnityFS 写入入口已经实现;复杂 AssetBundle 重打包、发布级 patch build/rollback 和与汉化发布流程的统一仍未完成。
- 尚未实现原版资源与汉化资源双发布后的查询、分发和清理策略。
验收:
- 原版资源同步成功后保持 `not_localized`,不发布半成品汉化资源。
- Patch 构建和校验成功后,汉化产物按官方相对路径写入配置化汉化发布根下的 `versions/<id>`
- 汉化发布必须原子切换配置化汉化发布根下的 `current`,失败时不影响已发布原版资源。
- `localized` 状态能证明原版和汉化两套资源都可发布,并能被 CLI/RPC/API 查询;缺 patch manifest 或 release 不匹配时不得返回 `localized`
### G-011C:真实 fixture 与回归样本不足
状态:**已关闭当前阶段**
历史现象:
- 已有 Addressables real-shape fixture/golden,但缺少按问题类型命名的当前/上一版本/结构变化样本。
- 403/404 和 hash mismatch 主要依赖单测内联构造,不便于后续回归扩展。
处理结果:
- 新增 `adapters/tests/fixtures/addressables_regression/current_catalog.json`
- 新增 `adapters/tests/fixtures/addressables_regression/previous_catalog.json`
- 新增 `adapters/tests/fixtures/addressables_regression/structure_changed_catalog.json`
- 新增 `infrastructure/tests/fixtures/official_regression/http_403.json`
- 新增 `infrastructure/tests/fixtures/official_regression/http_404.json`
- 新增 `infrastructure/tests/fixtures/official_regression/hash_mismatch_catalog.json`
- 对应测试会解析这些 fixture,防止样本只存在但不参与验证。
验收:
- `cargo test -p bat-adapters --test addressables_regression`
- `cargo test -p bat-infrastructure regression_fixture`
### G-012Translation Memory 未实现
影响:
- 无法复用人工翻译和 AI 翻译历史。
验收:
- 精确匹配、模糊匹配、上下文匹配可用。
- 记录 Provider、模型、审核状态和历史版本。
### G-013Glossary 未实现
影响:
- 无法保证术语一致性。
- AI 翻译无法强制遵守术语。
验收:
- 术语优先级高于 AI。
- 支持别名、分类、冲突检测、审核。
### G-014AI Provider 抽象未实现
影响:
- 无法接入 DeepL/OpenAI/Anthropic/Google/Azure。
验收:
- Provider 可替换。
- 支持批处理、限流、重试、成本统计和质量检查。
---
## 5. 文档与发布缺口
### G-015README 与当前真实状态不完全一致
状态:**已关闭**
现象:
- 旧 README 描述了最终架构,但部分功能尚未实现。
验收:
- README 明确区分已实现、开发中、规划中。
处理结果:
- README 已明确区分当前可用能力、未完成模块、官方同步运行命令和近期优先级。
### G-016:架构文档需要更新为当前路线图
状态:**已关闭当前阶段**
现象:
-`docs/architecture/README.md` 偏目标架构,容易让读者误以为 Go 同步器和 API/Web 已经可用。
验收:
- 增加 ADR 或架构决策记录。
- 明确 Rust/Go/DB/Plugin 边界。
处理结果:
- 架构 README 已明确当前 Rust 官方同步入口、Go 计划边界和目标架构差异。
- 官方资源后端说明由 `docs/architecture/official-resource-backend.md` 承载。
- `bat-ffi` 已降级为可选无状态兼容层,主集成边界明确为 `bat --json` 进程边界或未来稳定 SDK。
### G-017CI 未落地
状态:**已关闭(决策:不引入托管 CI)**
原现象:
- 仓库没有 GitHub Workflows 或等价托管 CI,质量门槛无自动远端执行。
处理结果:
- 明确决策:本项目不加入 GitHub Workflows,也不引入其他托管 CI。
- 目前补充了自托管 Gitea linux-runner workflow`.gitea/workflows/bat.yml`),覆盖 Rust workspace 构建/测试、Go API 门禁和文档状态门禁,不改变“不引入托管 CI”的决策。
- workflow 不使用外部 GitHub Action;它通过 runner 环境变量手动 `git fetch` 当前提交,并要求 runner 预装 `git`、Rust stable、rustfmt、clippy 和 Go,避免准备阶段因第三方 action 仓库代理或网络限制失败。
- 质量门禁由本地默认验证命令和自托管 workflow 共同承担:提交前执行 `cargo fmt` / `cargo clippy --workspace --all-targets -- -D warnings` / `cargo test --workspace`、Go API 门禁和 `make check-docs`(见 `docs/guides/development.md``docs/guides/baseline.md`)。
- 发布类检查(build、smoke)由 `Makefile``scripts/` 下的可重复脚本承担(如 `make official-smoke`)。
限制:
- 门禁执行依赖提交者本地自觉,无远端强制拦截;若未来出现多人协作或外部贡献需求,可重新评估本决策。
### G-018:真实官方网络全量下载 smoke test 已固化为可重复命令
状态:**已关闭(已固化可重复 smoke 命令;真实下载产物不纳入 Git)**
历史现象:
- 本地测试覆盖 mock、fixture、synthetic import 和 CLI 参数。
- 曾缺少真实官方网络全量下载的固定 runbook 和可重复命令。
处理结果:
- 新增 `scripts/official-full-pull-smoke.sh`,默认在 `/tmp/bat-official-smoke-<UTC timestamp>/` 下创建隔离资源目录、状态目录和报告目录。
- 新增 `make official-smoke` 统一入口。
- 新增 `docs/guides/official-full-pull-smoke.md`,记录目标、命令、输出结构、环境变量、安全边界和成功判定。
- smoke 流程覆盖 dry-run plan、首次全量拉取、二次 `up_to_date`、人工破坏 active release 文件后的 `repair`、repair 后 `verify`
- 脚本会检查二次 `up_to_date`、repair 完成、verify `healthy=true`,并检查首次拉取和 repair 的 stderr log 中存在下载已完成计数、单文件进度和校验结果日志。
- 运行报告 `SMOKE_REPORT.md` 记录实际输出目录、active release、文件数量、release 大小和被破坏文件;大型官方资源文件保留在隔离输出目录,不纳入 Git。
验收:
- 使用 `scripts/official-full-pull-smoke.sh``make official-smoke`
- 默认输出目录必须是独立 `/tmp` 目录;非 `/tmp` 路径需要显式设置 `BAT_SMOKE_ALLOW_NON_TMP=1`,且输出目录必须为空。
- 脚本退出码为 0 即表示 runbook 验收通过。
- 真实网络执行需要外部网络和足够磁盘空间;本仓库只保存 runbook、脚本和测试,不保存官方大文件。
后续跟踪(非阻塞):
- 官方同步长期运行测试正在进行,运行报告将在后续提供。
### G-019:下载失败重试策略不够精细
状态:**已关闭**
历史现象:
- curl 失败只按固定次数重试,错误信息主要保留最后一次 stderr。
- 403/404 和 5xx 没有不同处理。
- 单个 URL 长期失败时缺少可查询的 quarantine 诊断状态。
- 旧 launcher 包下载虽然有 primary/backup CDN 路径,但失败信息没有统一分类。
处理结果:
- 新增统一 curl 失败分类:`http_forbidden``http_not_found``http_client_error``http_too_many_requests``http_server_error``dns``connect``timeout``tls``interrupted``network` 等。
- 403/404/普通 4xx 视为不可重试并提前停止;5xx、429、DNS、连接、超时、中断和网络类错误按尝试次数重试。
- 单个资源 URL 最终失败会写入 `official-download-quarantine.json`,记录失败类型、HTTP 状态、是否可重试、尝试次数和最后错误。
- 失败 URL 会发出 Failed progressdaemon status 和 `bat-events.jsonl` 暴露失败类型、HTTP 状态、重试属性和 quarantine 状态。
- quarantine 会中断同步并阻止发布不完整 staging;下一轮成功下载或复用后清理对应 quarantine 条目。
- 旧 launcher 包或 `resources.assets` 下载在 primary CDN 失败后会切换官方 backup CDN。
验收:
- HTTP 404 不重试,写入 quarantinemanifest 不写失败项。
- HTTP 5xx 重试到上限后写入 quarantine。
- launcher primary CDN 失败后会尝试官方 backup CDN。
---
## 6. 当前关闭顺序建议
1. issue #24:失败 staging 复用回归已补;核对残余场景。
2. issue #1RPC 主体、文件级 `patch.apply` / `unityfs.patch_text_asset` / `unityfs.patch_string_field` / `unityfs.patch_field` 已落地;剩余发布级 patch build/rollback、复杂 UnityFS 语义编辑与设计边界确认。
3. issue #17 的历史顺序/重试契约仍保留;当前 issue #33/#35 已补有界 downloader
scheduler 和默认并发 8,范围 `1..=256`,worker 完成后立即领取下一个任务,
进度即时按完成数上报,最终 report 保持 plan 顺序。
4. **G-008:已决策关闭**(同步 CLI = Rust `bat`;见 `GO_STATUS.md`)。
5. **G-009 / issue #19**:资源 bootstrap/分发 MVP 已编码;优先服务器联调与索引实勘,非「从零实现」。
6. issue #2 / G-007P1):Addressables 可校验字段。
7. issue #3 / G-005P1):UnityFS 容器基础解析已落地;对象级引擎解析继续跟踪 G-005。
8. G-011:翻译任务状态、CAS 诊断和 ResourceRepository 查询面扩展。
9. G-012 / G-006Crowdin/翻译系统、复杂 AssetBundle 重打包和 Patch 发布流程统一。
10. G-011D:原版/汉化双发布后的查询、分发和清理策略。
Go 进度以 `docs/reports/GO_STATUS.md` 为准。G-018 / G-017 已关闭。