Files
BlueArchiveToolkit/docs/reports/CURRENT_GAPS.md
T
nyaKazuha 43e1a33b88
bat-rust / Build and test Rust (push) Failing after 1s
fix(ci): 移除 Gitea workflow 外部 action 依赖
改为在 linux runner 中手动 fetch 当前提交,避免自托管 runner 准备阶段通过 gh-proxy 克隆 actions/checkout 和 dtolnay/rust-toolchain 时被 403 拦截,并同步开发文档与缺口说明。
2026-07-21 11:53:39 +08:00

481 lines
18 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-07-20
- **用途**:集中跟踪当前代码中的占位实现、设计缺口和下一步验收项。
- **权威计划**`../../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 引擎解析器仍未完成
现象:
- `crates/bat-assetbundle/src/parser.rs` 只有 `Parser::name`
- `types.rs` 只有 `AssetType::TextAsset`
- `adapters/src/unity/unity_2021_3.rs` 已能解析 UnityFS header、block info、directory,并校验 directory `offset+size` 不越界;这属于 adapter 层基础摘要能力,不等于 `bat-assetbundle` 引擎已完成。
- 仍没有对象表、TypeTree、TextAsset、MonoBehaviour、ScriptableObject 或可扩展提取入口。
影响:
- 可以对部分 UnityFS 样本做基础结构校验,但无法完成真实资源对象解析和文本提取。
- 无法提取 TextAsset 或配置文本。
验收:
- `crates/bat-assetbundle` 能解析结构化测试样本和隔离真实样本。
- 支持 UnityFS header、blocks、directory、metadata、object table。
- 错误包含偏移和字段上下文。
### G-006Patch 引擎仍是占位
现象:
- `binary::apply_patch` 明确返回 `PatchError::ApplyFailed`,提示 Binary patch 尚未实现。
- `json::apply_json_patch` 明确返回 `PatchError::ApplyFailed`,提示 JSON patch 尚未实现。
影响:
- 无法生成或应用补丁。
- 回滚和完整性校验无法落地。
验收:
- Binary patch 能完成 diff/apply 往返。
- JSON patch 能应用 RFC 6902 patch。
- Patch manifest 包含 hash、版本和回滚信息。
### G-007Addressables Catalog 解析不完整
状态:**部分关闭**
现象:
- `AddressablesCatalogDriver` 已能解析当前真实形态 JSON catalog fixture/golden。
- 已输出 path、hash、size、resource_type、address、dependencies、metadata,并已提取 `m_Crc``crc` 字段。
- `bat-core` 已提供 `crc32_ieee``ResourceEntry::verify_downloaded_bytes`SQLite `ResourceRepository` 已有 `crc` 列迁移。
- 仍需覆盖更多官方 catalog 结构变体、二进制/压缩字段组合和更明确的失败诊断。
影响:
- 当前解析能力可以服务 Manifest inspect 和部分资源索引,但还不能宣称完整兼容所有 Unity Addressables/SBP catalog 形态。
验收:
- 能解析项目目标版本的真实 Catalog 样本集合。
- 解析结果包含资源 key、provider、dependency、hash、size、path、CRC。
- 对不支持的 catalog 结构返回明确错误,而不是静默丢字段。
---
## 3. 应用层缺口
### G-008Go CLI 产品入口尚未完成
状态:**未完成(此前“并入 G-009”只是短期跟踪调整,不代表能力完成)**
现象:
- 当前可用的用户同步/运维入口是 Rust `bat` binary。
- `cmd/bat` 已存在,但仅有 `doctor``manifest inspect``sync plan` 试验能力;`doctor` 只输出固定 `ok``manifest`/`sync` 依赖可选 CGO/FFI helper。
- Go 侧尚未实现通过 Rust `bat --json` 或 daemon RPC 包装官方同步命令、稳定 human/json 输出、真实 doctor 检查和端到端测试。
- 如果项目决策改为“用户 CLI 永久由 Rust `bat` 承担,Go 只做 `bat-api`/服务层”,必须同步更新 `AGENTS.md``PROJECT_PLAN.md` 和 issue 跟踪;在完成该决策前,不能把 Go CLI 写成已完成。
验收:
- `cmd/bat doctor` 做真实环境诊断,而不是固定字符串。
- `cmd/bat sync` 能通过 Rust `bat --json` 或 RPC 触发/查询官方同步,不走 FFI 控制下载器或 daemon。
- human/json 输出、退出码和错误码与 Rust `bat` 契约一致。
- `go test ./...``go vet ./...` 覆盖命令解析、错误输出和至少一个 mocked Rust 边界。
### G-009API Server`bat-api`,仿官方 API)尚未实现
现象:
- `api/` 只有目录结构,无 handler、service、路由。
- Go 侧尚无对接 daemon RPC / `current/` 发布布局的服务端入口。
目标(对应 issue #19):
- 新建 `cmd/bat-api`**完全仿照 BlueArchive 官方 API** 的 Go HTTP 服务,把 Rust `bat` 后端发布的 `current/` release 按官方接口形态对外提供,使真实客户端/工具可将其当作官方服务端。
- 仿真面:资源 CDN 面(TableCatalog/MediaCatalog/BundlePackingInfo、bundle、seed `.hash`)、server-info 面、launcher API 面。
- 鉴权/签名**完全仿照**官方实现,服务端做验签(对齐 `adapters/src/official/launcher.rs` 的签名逻辑)。
- 版本/状态经 daemon RPC`catalog.*` / `resource.manifest`)发现,资源字节从 `current/` 读取;不读写 daemon 状态文件内部。
影响:
- 客户端、工具和第三方集成无服务端入口。
验收:
- Go 单测覆盖路由、签名验签、错误响应形态。
- 真机 e2edaemon 发布 fixture release → 启动 `bat-api` → 按官方 URL 与鉴权头请求 server-info / catalog / bundle / launcher 链,断言字节与形态正确、验签生效(缺签/错签被拒)。
- 统一错误结构与官方响应 envelope 对齐;Makefile 增加 Go 构建/测试目标。
排期:P2,排在 issue #17 验收收口以及 issue #2 / #3 的解析能力继续推进之后启动;可与 G-008 的 Go 产品入口边界收敛并行。
### G-010Web 管理后台尚未实现
现象:
- `web/` 只有目录结构。
影响:
- 翻译审核、术语管理、Dashboard 无 UI。
验收:
- 登录、权限、翻译审核、术语管理基础流程可用。
---
## 4. 数据与翻译缺口
### G-011Resource Repository 未持久化
状态:**部分关闭**
影响:
- `SqliteResourceRepository` 已存在,可按领域 repository 接口保存资源元数据。
- `ResourceImportService` 已能把 manifest 中有数据的资源写入 CAS + `ResourceRepository`AssetBundle 会记录 UnityFS 摘要,TextAsset/Table/Media 会分类索引。
- 官方同步下载结果尚未作为用户级流程自动触发导入 CAS + ResourceRepository。
- 迁移、版本化 schema 和 CLI 查询入口仍需补齐。
验收:
- schema 和迁移可重复执行。
- 可按版本、类型、hash、路径查询资源。
- 官方同步后的资源可通过 CLI 查询并能追溯到 CAS 对象。
### 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-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 的构建和测试,不改变“不引入托管 CI”的决策。
- workflow 不使用外部 GitHub Action;它通过 runner 环境变量手动 `git fetch` 当前提交,并要求 runner 预装 `git`、Rust stable、rustfmt 和 clippy,避免准备阶段因第三方 action 仓库代理或网络限制失败。
- 质量门禁由本地默认验证命令和自托管 workflow 共同承担:提交前执行 `cargo fmt` / `cargo clippy --workspace --all-targets -- -D warnings` / `cargo test --workspace`(见 `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 #17 验收并关闭或更新范围:多线程下载与指数退避实现已合入,但 GitHub issue 仍 open。
2. issue #2 / G-007:继续扩大 Addressables 可校验字段和结构变体覆盖。
3. issue #3 / G-005:把 UnityFS 基础摘要推进到 `bat-assetbundle` 引擎级解析。
4. G-011:官方同步结果接入 CAS + ResourceRepository 用户级工作流。
5. G-008 / G-009:收敛 Go 产品入口边界,并实现 `bat-api`issue #19)。
6. G-012 / G-006:翻译系统、Patch 引擎。
这个顺序优先把 Rust `bat` 后端做扎实(解析能力 + 下载性能),再把官方同步结果进入可查询资源库,之后收敛 Go 入口和仿官方 API 服务端,最后推进翻译和补丁。G-018 已固化为可重复 smoke 命令并关闭;G-017 已按“不引入托管 CI”决策关闭。