From 9944136b0faeb321ae8d1dc724f3a4d7847d6486 Mon Sep 17 00:00:00 2001 From: kdletters <61648117+kdletters@users.noreply.github.com> Date: Mon, 28 Sep 2026 17:43:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B8=E5=AF=B9=E6=B8=B8=E6=88=8F=E5=88=86?= =?UTF-8?q?=E5=8F=91=E9=98=B6=E6=AE=B5=20A=20=E7=9A=84=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E9=AA=8C=E6=94=B6=EF=BC=9A=E5=8B=BE=E9=80=89=E4=B8=80?= =?UTF-8?q?=E6=9D=A1=E5=B9=B6=E5=88=97=E5=87=BA=E5=85=B6=E4=BD=99=E4=BA=94?= =?UTF-8?q?=E6=9D=A1=E7=BC=BA=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 阶段 A 第 2 条勾选:真实 ZIP 字节与展开清单由 module-game-distribution 13 passed 覆盖,包上限/分片/422 由 api-server package_ 6 passed 覆盖 - 未勾选五条逐条写明缺口:跨账号读写撤销缺接口级用例、额度超限与失败后旧对象/公开状态不变缺断言、并发上传不混写缺用例、响应丢失与未知结果区分缺用例、gameDistribution.ts 手写 DTO 无 Rust↔TS 一致性检查 --- ...程碑】游戏分发目录详情与在线游玩-2026-09-18.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/project-memory/plans/【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md b/docs/project-memory/plans/【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md index 3508680d1..8c900ec42 100644 --- a/docs/project-memory/plans/【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md +++ b/docs/project-memory/plans/【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md @@ -49,7 +49,7 @@ ### 行为与验收 - [ ] 登录用户创建服务端分配的游戏,owner 不能由请求伪造;其他账号不能读取私有版本、上传、提交或撤销。 -- [ ] 服务端接收真实 ZIP 字节,重算摘要/字节数并建立展开清单;只有 metadata 的请求不能获得已上传或已发布状态。 +- [x] 服务端接收真实 ZIP 字节,重算摘要/字节数并建立展开清单;只有 metadata 的请求不能获得已上传或已发布状态。 - [ ] 缺入口、越界/重复/大小写冲突路径、符号链接、压缩炸弹、敏感内容和额度超限均失败关闭,原私有对象和公开状态保持一致。 - [ ] 一份版本只接受一份已确认内容;同 key 同请求重放无重复游戏/版本,不同请求冲突;同版本并发上传不混写。 - [ ] 校验可异步恢复,响应丢失、服务进程退出和客户端重试均回到原版本;确定失败和未知结果在响应中可区分。 @@ -147,4 +147,17 @@ - 阶段 C:AGC 发布资料链路、现代游戏目录与跨端游玩路由(`games` / `games/detail` / `games/mine` / `games/play` / `games/publish` 已进 nginx SPA 白名单)、`src/components/game-distribution/gameDistributionGuards.ts` 与统一作品详情都在现役代码里。 - 阶段 D:需要实际部署资源、真实发行域名与 TLS/CDN,本轮未执行。 -阶段状态只按上面三等事实更新;**阶段验收本身仍按原门禁流程**(A 验收后才允许把依赖它的阶段标记为 accepted),因此里程碑状态改为 `implemented-awaiting-runtime-acceptance`,阶段表里的门禁关系保持不变。 \ No newline at end of file +阶段状态只按上面三等事实更新;**阶段验收本身仍按原门禁流程**(A 验收后才允许把依赖它的阶段标记为 accepted),因此里程碑状态改为 `implemented-awaiting-runtime-acceptance`,阶段表里的门禁关系保持不变。 +## 本轮核对(2026-09-28,阶段 A 服务端条目) + +本轮只处理阶段 A 里纯服务端/契约可证的条目,逐条给出证据与缺口;真机、域名与 CDN 相关的条目原样保留。 + +- 已勾选(第 2 条:服务端接收真实 ZIP 字节、重算摘要/字节数并建立展开清单;只有 metadata 的请求不能获得已上传或已发布状态) + - `cargo test -p module-game-distribution --manifest-path server-rs/Cargo.toml` → **13 passed**,其中 `accepts_root_entry_and_returns_file_manifest`(真实归档 → 展开清单)、`version_state_machine_reaches_pending_review_only_after_package_validation`(状态只在包校验通过后才前进)、`accepts_package_above_the_previous_hundred_mib_limit`、`keeps_expansion_headroom_over_package_limit`。 + - `cargo test -p api-server --manifest-path server-rs/Cargo.toml -- package_ --test-threads=1` → **6 passed**(请求体上限对齐包上限、分片大小与 `Content-Type`、上传偏移非负、校验错误按 422 下发)。 +- 仍未勾选(缺口写具体,避免"看起来做了") + - 第 1 条(owner 不能由请求伪造;其他账号不能读取私有版本、上传、提交或撤销):领域侧有 `owner_is_required_for_version_and_package_mutations`;接口侧代码在越权时返回 403/404,但**没有跨账号读/写/撤销的接口级用例**——缺的就是这一层。 + - 第 3 条(缺入口、越界/重复/大小写冲突、符号链接、压缩炸弹、敏感内容与额度超限均失败关闭,原私有对象与公开状态保持一致):`rejects_missing_entry_sensitive_and_traversal_paths`(含重复与大小写冲突路径,见 `package.rs` 的 `case_folded_paths`)、`keeps_expansion_headroom_over_package_limit`、`asset_path_rejects_traversal_and_absolute_input`、`content_type_allowlist_fails_closed_for_unknown_extensions`、`extraction_only_returns_the_exact_declared_entry` 覆盖了前半句的大部分;缺口两项——**额度超限**(game-distribution 链路没有配额用例,仓库里的配额用例只覆盖客户端项目快照)与**"原私有对象和公开状态保持一致"**(没有断言失败后旧私有对象/公开投影未变)。 + - 第 4 条(一份版本只接受一份已确认内容;同 key 同请求幂等、不同请求冲突;同版本并发上传不混写):`idempotency_replays_same_snapshot_and_rejects_digest_conflict`、`validation_failure_can_retry_same_confirmed_package` 与 api-server 的 `idempotency_key_requires_a_bounded_non_empty_header` 覆盖前两句;缺口是**并发上传不混写**没有用例。 + - 第 5 条(校验可异步恢复;响应丢失、服务进程退出与客户端重试回到原版本;确定失败与未知结果可区分):只有 api-server 的 `recovery_action_covers_every_version_status` 覆盖"状态 → 恢复动作"的映射;后两句在 game-distribution 链路没有用例。 + - 第 6 条(状态/私有查询/错误 envelope 的 Rust 与 TS DTO 一致;新增 schema、迁移、表目录与绑定一致):后半句有门禁(`npm run lint` 内的 SpacetimeDB schema guard 覆盖 85 张表、生成绑定校验通过);DTO 侧有 `public_payload_exposes_cover_and_screenshot_object_keys`、`version_detail_payload_exposes_frozen_metadata_to_owner`、`package_validation_errors_are_unprocessable`;缺口是 `packages/shared/src/contracts/gameDistribution.ts` 为手写 DTO,**没有任何 Rust↔TS 一致性检查**。