共享记忆同步 #504 关闭口径:迁移归属与复核条件

- decision-log 2026-09-24 条目补充:#504 以 Reviewed/Won't Fix 关闭,跟踪交回迁移侧,复核与重新打开条件见 #504 关闭评论
- pitfalls 同条目处理口径补上 #504 关闭状态与重新打开路径
This commit is contained in:
2026-09-24 12:18:34 +08:00
parent 771965ea40
commit ca53c30d01
2 changed files with 2 additions and 2 deletions
@@ -9333,7 +9333,7 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
## 2026-09-24 AGC 项目快照「换号后整项目重传」的根因与迁移约束(客户端索引修复未落地)
- 背景:AGC 客户端在项目打开期间把本地工程增量上传到 OSS,判定依据是 `<AppData>/project-snapshots/<projectId>/index.json`。该文件整份只保存一个账号的基线,同步前用 `previous.user_id == session.user_id` 判等,不等就换成空基线;而远端对象键第一段正是 `userId`,于是换号被等价成「本机没有基线」。issue #504 的真机复现(CDP attach dev 客户端 + 点「春卷冲刺」):账号 A 留下的基线与当前账号不匹配 → 一次性重传 2311 个文件,约 3 分钟、2311 次 `POST /api/agc/project-snapshots/files`,其中 2306 次服务端 HEAD 命中纯白跑;同窗口内 `/api/runtime/frontend-config``/api/llm/models``/api/profile/recharge-center` 在服务端 200 且 ≤61ms 的情况下被客户端报 15s 超时(同进程 IPC 被重传压垮),并触发 #490 的「检查失败」钉死。本机 6 个索引文件里有 4 个不同 `userId`09-23 19:47、09-23 20:47、09-24 10:57 三次同形态全量重传。
- 结论(本条目只固化根因,不定架构):客户端基线分桶的实现已完成并验证,但**未合入 master**——这条链路正被「数据与 IO 往后端挪」的架构迁移覆盖,落地在客户端本地索引上会与该迁移形成两套实现。实现保留在分支 `fix/api-timeout`commit `3be8e40bc`),对应 PR #505 已按迁移方向关闭;迁移完成后若该问题仍在,可直接复用该分支或重开 PR。
- 结论(本条目只固化根因,不定架构):客户端基线分桶的实现已完成并验证,但**未合入 master**——这条链路正被「数据与 IO 往后端挪」的架构迁移覆盖,落地在客户端本地索引上会与该迁移形成两套实现。实现保留在分支 `fix/api-timeout`commit `3be8e40bc`),对应 PR #505 已按迁移方向关闭;issue #504 随之以 `Reviewed/Won't Fix` 关闭,跟踪交回迁移侧(复核与重新打开条件写在 #504 的关闭评论里)。迁移完成后若该问题仍在,可直接复用该分支或重开 PR。
- 迁移必须保留的约束(不随实现位置改变):① 基线只能按 `(userId, projectId)` 两元组归属,远端对象键第一段就是 `userId`,换号后旧基线对新账号无效,任何新设计都不能跨账号共用或互相覆盖;② 任何一次同步只要清单/清单写入没有成功,就绝不能推进基线,否则下一轮立刻退化为整项目重发(这条已在 #504 上验证);③ 本机扫描与读文件无法上移,服务端拿不到用户磁盘,`扫描 + 读字节 + 发字节` 必须留在客户端,「差异判定」才是可上移到后端的那一层。
- 分层(回应「是否涉及协议层」):本次改动只碰本地持久化格式(`index.json` schema)与一个 native-only 诊断视图的字段(`read_local_project_snapshot_state``baselineCount` / `baselinePresent`),**没有触碰客户端↔服务端的路由 / DTO / 对象键 / 清单结构**,即不涉及协议层。若差异判定上移到后端,新增的 `manifest/diff` 交互才是协议层变更,需要按规范单独定义。
- 边界:不新增路由、不改服务端、不改公开契约;索引是 AppData 私有文件、不进项目目录;分支上的实现只影响 `project_snapshot/index.rs``mod.rs``tests.rs`,删改范围可控。
@@ -5952,7 +5952,7 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
- **现象**:打开 AGC 项目后客户端短时间无响应,`/api/runtime/frontend-config``/api/llm/models``/api/profile/recharge-center` 报「请求超时(15000 ms)」;同时本地 api-server 日志被 `POST /api/agc/project-snapshots/files` 刷屏(全是 200、`latency_ms` 58~61ms、每 60ms 一条)。紧接着项目列表还会被钉成「检查失败」(#490)。
- **原因**:本地快照索引整份只保存一个账号的基线,同步前按 `user_id` 判等,不等就换成空基线 → 换号后打开项目即整项目重传(春卷冲刺 2311 个文件、约 3 分钟)。对象键带内容摘要、服务端 HEAD 命中即 `200 + skipped`,这批请求全是白跑却完全静默,只有服务端日志量能看出来。真正超时的那一层在客户端:同一窗口服务端对三个接口都是 200、≤61ms,而客户端 webview 的 Tauri 定制协议 IPC 在重传压力下大面积失败(`IPC custom protocol failed … TypeError: Failed to fetch`,刷屏时 ≈0.7 次/秒,而空闲时段 847 行日志里只有 59 次;每次失败还写一行 ~330 字节日志),响应回不到 renderer,JS 侧 15s 计时器先到。
- **处理(现行口径)**:暂不落地客户端修复——这条链路归入「数据与 IO 往后端挪」的架构迁移,客户端再单独做基线分桶会与之形成两套实现。按账号分桶的实现在分支 `fix/api-timeout`commit `3be8e40bc`)完成并通过验证,PR #505 已按迁移方向关闭;迁移完成后若该问题仍在,可直接复用该分支或重开 PR。
- **处理(现行口径)**:暂不落地客户端修复——这条链路归入「数据与 IO 往后端挪」的架构迁移,客户端再单独做基线分桶会与之形成两套实现。按账号分桶的实现在分支 `fix/api-timeout`commit `3be8e40bc`)完成并通过验证,PR #505 已按迁移方向关闭、issue #504 已按 `Reviewed/Won't Fix` 关闭,跟踪交回迁移侧;迁移完成后若该问题仍在,可直接复用该分支或重开 PR。
- **排障口径**:遇到「后端日志刷屏 + 客户端报超时」这种组合,先把两侧对齐到同一时间窗:客户端 `diagnostics/application.log``project_snapshot.sync.*`(看 `uploaded=` 是否等于项目文件数、`skippedRemote=` 是否接近它)对 `logs/api-server/api-server-*.log` 里各 route 的 `http.response`(状态码与 `latency_ms`)。客户端报超时但服务端 200 且毫秒级返回,说明堵在客户端侧,别只盯后端。
- **验证**:分支 `fix/api-timeout``cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --bin genarrative-ai-game-creator-shell project_snapshot` 26 passed / 0 failed(含「账号切换后基线互不覆盖」「切回旧账号差异为空」);master 状态无该修复,运行态排障仍可用 `read_local_project_snapshot_state` 观察当前账号的 `fileCount` / `syncRevision`
- **关联**issue #504、issue #490、PR #505closed)、`apps/ai-game-creator-shell/src-tauri/src/project_snapshot/index.rs``docs/project-memory/shared-memory/decision-log.md`2026-09-24 条目含迁移必须保留的三条约束)。