mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 06:34:54 +08:00
fix(release): 完成分发证明代际绑定与质量门禁收口
This commit is contained in:
@@ -371,8 +371,8 @@ JSON-RPC 2.0 服务,是面向上层服务(Go 层)的**主要跨语言边
|
||||
- CDN path 支持 `GET` / `HEAD` / Range / 条件请求;ETag 优先使用 download
|
||||
manifest 中的 BLAKE3,响应包含 Last-Modified、Accept-Ranges 和长期缓存头。
|
||||
- 版本/清单发现优先走 RPC:先 `daemon.status`,再 `daemon.doctor`,再读取
|
||||
Rust 轻量 `release.attestation`,最后按 attested release/publication/manifest
|
||||
identity 读取 `catalog.status` / `resource.manifest`(可用 `--socket` 指定 socket
|
||||
Rust 轻量 `release.attestation`,最后按 attested release/publication/mapping/manifest
|
||||
identity 和 verification generation 读取 `catalog.status` / `resource.manifest`(可用 `--socket` 指定 socket
|
||||
文件)。Go 不重新实现 release verifier;普通 current CDN 只有在 attestation
|
||||
fresh/ready、分页快照完整且本地只读路径检查都允许时才分发。
|
||||
- `/v1/releases`、`/v1/distribution` 和受保护的 `/admin/releases/status`、
|
||||
|
||||
@@ -270,6 +270,14 @@ distribution 查询只读取该文件、当前 manifest 的内容 identity 和
|
||||
`destination_index`,再校验目标文件的 size/BLAKE3;不会为了定位一个 destination
|
||||
重做完整 mapping canonicalization 或遍历其他资源。
|
||||
|
||||
`official-distribution-attestation.json` 是 Rust full local verification 的结果。发布时
|
||||
文件先写入 `.staging/<id>`,但其中的 `resource_root` 永远记录最终的
|
||||
`versions/<id>` canonical root;随后 staging 目录原子重命名并切换 `current`,不会因为
|
||||
重命名再次增加 verification generation。周期性 current 验证、显式 verify/repair 和新
|
||||
release 发布都会写入新的 generation;失败会写入 `ready=false`、`integrity_status=invalid`
|
||||
且 `verified_at=null` 的新结果。`max_age_seconds` 由 Rust watch 的验证周期和失败重试
|
||||
周期计算,缺失或为 0 的旧结果直接视为不可用,不使用固定兼容 fallback。
|
||||
|
||||
---
|
||||
|
||||
## 5. 发现与 seed URL 规则(L2)
|
||||
|
||||
@@ -439,7 +439,7 @@ BAT_API_TRUST_PROXY_HEADERS=true
|
||||
|
||||
否则保持默认 `false`,`bat-api` 会按 TCP peer IP 做限流和日志归因。应用层访问日志只记录 path,不记录 query string,避免 query token 进入日志。动态 JSON 响应使用 `Cache-Control: no-store`;CDN 字节路径仍使用长期 immutable 缓存。
|
||||
|
||||
不要在生产 env 里设置 `BAT_API_RESOURCE_ROOT`。`bat-api` 会按 `BAT_API_REFRESH_INTERVAL` 周期通过 RPC 读取当前 official `release.attestation`,再以同一 release/publication/manifest identity 请求 `resource.manifest`,从而跟随 Rust `bat` 切换 `current -> versions/<id>`;attestation 过期或分页代际不一致时 fail closed。
|
||||
不要在生产 env 里设置 `BAT_API_RESOURCE_ROOT`。`bat-api` 会按 `BAT_API_REFRESH_INTERVAL` 周期通过 RPC 读取当前 official `release.attestation`,再以同一 release/publication/mapping/manifest identity 和 verification generation 请求 `resource.manifest`,从而跟随 Rust `bat` 切换 `current -> versions/<id>`;attestation 过期、generation 变化或分页不一致时 fail closed。
|
||||
|
||||
### 健康检查
|
||||
|
||||
|
||||
@@ -34,9 +34,15 @@ cargo --version
|
||||
rustfmt --version
|
||||
cargo clippy --version
|
||||
go version
|
||||
golangci-lint --version # 必须为 2.12.2
|
||||
```
|
||||
|
||||
该 workflow 会用 `GITHUB_SERVER_URL`、`GITHUB_REPOSITORY`、`GITHUB_REF` 和 `GITHUB_SHA` 手动 `git fetch` 当前提交,再执行 Rust workspace 的只读格式检查、检查、构建、clippy 和测试,以及 Go API 格式、测试、vet、构建、可选 lint 和文档状态门禁。这样可以避免自托管 runner 在准备阶段通过代理克隆第三方 action 仓库。
|
||||
缺少上述命令、版本不匹配或 `golangci-lint` 不是 2.12.2 都会使 required gate 失败;
|
||||
`golangci-lint 2.12.2` 是 required gate,不是可选检查。该 workflow 会用
|
||||
`GITHUB_SERVER_URL`、`GITHUB_REPOSITORY`、`GITHUB_REF` 和 `GITHUB_SHA` 手动 `git fetch`
|
||||
当前提交,再执行 Rust workspace 的只读格式检查、检查、构建、clippy 和测试,以及通过
|
||||
`make check-go-format` 执行的 Go 格式、测试、vet、构建、2.12.2 lint 和文档状态门禁。
|
||||
这样可以避免自托管 runner 在准备阶段通过代理克隆第三方 action 仓库。
|
||||
|
||||
#### Docker
|
||||
```bash
|
||||
|
||||
@@ -104,7 +104,7 @@ contract 为准,不应绕过 daemon 状态文件或扩展 `bat-ffi` 作为主
|
||||
| `resource.sync` | 已实现 | `{ "force": false }` | `{ "task_id": "...", "kind": "resource.sync" }`。 |
|
||||
| `resource.verify` | 已实现 | `null` | `{ "task_id": "...", "kind": "resource.verify" }`。 |
|
||||
| `resource.repair` | 已实现 | `null` | `{ "task_id": "...", "kind": "resource.repair" }`。 |
|
||||
| `resource.manifest` | 已实现 | `{ "release_id": "...", "expected_publication_identity": "...", "expected_manifest_identity": "...", "offset": 0, "limit": 100 }` | 绑定一个 Rust attested official generation 的 download manifest 分页。 |
|
||||
| `resource.manifest` | 已实现 | `{ "release_id": "...", "expected_publication_identity": "...", "expected_manifest_identity": "...", "expected_verification_generation": 7, "offset": 0, "limit": 100 }` | 绑定一个 Rust attested official generation 的 download manifest 分页;generation 为必需绑定条件,`0` 也不能省略或忽略。 |
|
||||
| `resource.list` | 已实现 | 同 `resource.manifest` | `resource.manifest` 的兼容别名。 |
|
||||
| `resource.index` | 已实现 | `{ "offset": 0, "limit": 100, "type": "asset_bundle", "hash": "...", "path_pattern": "*", "release_id": "...", "platform": "windows", "destination": "...", "archive_entry": "...", "parse_status": "parsed", "format": "json" }` | 当前 `ResourceRepository` 分页/过滤查询。 |
|
||||
|
||||
@@ -120,12 +120,14 @@ SQLite `ResourceRepository`,索引不存在时返回 `ok=true` 且
|
||||
`1..=1000`,非法参数返回 `BAT-ERR-700002`。
|
||||
|
||||
`resource.manifest` 的请求必须携带由 `release.attestation` 返回的
|
||||
`release_id`、`expected_publication_identity` 和 `expected_manifest_identity`。
|
||||
`release_id`、`expected_publication_identity`、`expected_manifest_identity` 和
|
||||
`expected_verification_generation`。
|
||||
每一页返回 `release_id`、`resource_root`、`manifest_version`、
|
||||
`publication_identity`、`mapping_identity`、`manifest_identity`、`generation`、
|
||||
`total_entries`、`offset`、`limit` 和 `entries`。Rust 在当前 release 切换或 identity
|
||||
不匹配时拒绝请求;Go 会逐页验证这些字段、页 offset、total 和最终 entry count,
|
||||
任何一页不一致都会丢弃整个候选快照。
|
||||
不匹配、attestation 不可用或 generation 改变时拒绝请求;Go 会逐页验证 channel、
|
||||
这些 identity、generation、manifest version、页 offset/limit、total 和最终 entry
|
||||
count,任何一页不一致都会丢弃整个候选快照。
|
||||
|
||||
`resource.index` 的 `entries[]` 是 `Resource` JSON,除 `id`、`local_path`、
|
||||
`entry` 外会包含 `metadata`:`official_release_id`、`platform`、
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
| ID | 约定 |
|
||||
|---|---|
|
||||
| F | 版本/清单经 **`bat.sock` JSON-RPC**(`--socket`);不读 daemon 内部状态文件 |
|
||||
| G | RPC 顺序:先 **`daemon.status`**,再 **`daemon.doctor`**,再轻量 **`release.attestation`**,再 catalog/manifest;manifest 请求绑定 attested release/publication/manifest identity |
|
||||
| G | RPC 顺序:先 **`daemon.status`**,再 **`daemon.doctor`**,再轻量 **`release.attestation`**,再 catalog/manifest;manifest 请求绑定 attested release/publication/mapping/manifest identity 和 verification generation |
|
||||
| H | 生产文件字节从 RPC 返回的 `resource_root` 读盘;`bat-api` 与 daemon 同服务器/同容器/共享文件系统部署;`--resource-root` 仅 fixture 或应急只读诊断 |
|
||||
| I | 生产中 Rust `bat` 与 `bat-api` 在同一主机/容器/共享文件系统;开发用 `/tmp` fixture 和真实本地 `bat.sock` smoke,不依赖远程连接 |
|
||||
| J | Go 索引以 **manifest + 磁盘 Present/size** 建立可读快照,但不将其当作 release integrity |
|
||||
@@ -95,7 +95,7 @@
|
||||
| 组件 | 路径 | 状态 | 说明 |
|
||||
|---|---|---|---|
|
||||
| Module | `go.mod` → `bat-api` | 已用 | 服务层模块名 |
|
||||
| RPC client | `internal/backendrpc` | **完成** | Unix socket JSON-RPC transport + typed helper;typed helper 覆盖 daemon 已实现控制/查询、`resource.state/sync/verify/repair/manifest/list`、`release.attestation/status/list/distribution/cleanup`、`catalog.*`、`parse.*`、`localized.status/publish/rollback`、`task.*`、`translation.tasks`、`translation.handoff`、`translation.task.update`、`translation.worker.run`、`translation.proofread`、`translation.memory.summary/query/confirm`、`translation.glossary.summary/query/diagnose/add/update/approve/deprecate/delete` 和文件级 UnityFS patch 调用;`resource.manifest` typed params 固定 release/publication/manifest identity;`localized.publish` 的 typed params 支持 `translation_file`、`from_worker` 或 `patch_manifest` 三选一;`resource.index`、`patch.apply` 仍通过通用 `Call` 走同一 contract;fake transport 单测和 `internal/api/testdata/contract/` mirror test 固化 Rust 输出字段 |
|
||||
| RPC client | `internal/backendrpc` | **完成** | Unix socket JSON-RPC transport + typed helper;typed helper 覆盖 daemon 已实现控制/查询、`resource.state/sync/verify/repair/manifest/list`、`release.attestation/status/list/distribution/cleanup`、`catalog.*`、`parse.*`、`localized.status/publish/rollback`、`task.*`、`translation.tasks`、`translation.handoff`、`translation.task.update`、`translation.worker.run`、`translation.proofread`、`translation.memory.summary/query/confirm`、`translation.glossary.summary/query/diagnose/add/update/approve/deprecate/delete` 和文件级 UnityFS patch 调用;`resource.manifest` typed params 固定 release/publication/manifest identity 和 verification generation;`localized.publish` 的 typed params 支持 `translation_file`、`from_worker` 或 `patch_manifest` 三选一;`resource.index`、`patch.apply` 仍通过通用 `Call` 走同一 contract;fake transport 单测和 `internal/api/testdata/contract/` mirror test 固化 Rust 输出字段 |
|
||||
| 资源 bootstrap/分发 | `cmd/bat-api` + `internal/api` | **MVP+生产控制面** | RPC 发现 + 周期刷新/诊断 + `/v1/bootstrap` + `/v1/launcher/bootstrap` + `/v1/releases` + `/v1/distribution` + launcher 资源 metadata 兼容 + `/readyz` + CDN Range/缓存头 + 鉴权/限流/访问日志/反代适配 + OpenAPI + 管理控制白名单 + release/localized/TM/Glossary admin forwarding + 内嵌 dashboard + `.env` |
|
||||
| 试验 CLI | `cmd/bat` | **试验** | doctor 固定 ok;manifest/sync 走 FFI |
|
||||
| FFI | `internal/ffi` | **可选** | 需 `build-ffi` |
|
||||
|
||||
Reference in New Issue
Block a user