Merge remote-tracking branch 'origin/master' into fix/test-concurrent-problem
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m41s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m14s
Project CI / Backend tests (pull_request) Successful in 4m28s
Project CI / Native shell tests (pull_request) Successful in 6m4s
Project CI / Frontend tests (pull_request) Successful in 2m13s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m53s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 10m23s
Project CI / Repository checks (pull_request) Successful in 2m24s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 10m57s

# Conflicts:
#	docs/project-memory/shared-memory/pitfalls.md
This commit is contained in:
2026-10-02 01:35:26 +08:00
52 changed files with 2310 additions and 589 deletions
@@ -2,6 +2,12 @@
这里只记录对当前开发仍有用的症状、根因、排查方法和风险边界。同一事实保留一个当前口径;退役对象的专属过程与单轮测试结果由 Git 历史追溯。遇到旧路径或版本时,以现行代码和专题文档为准。
## 2026-10-01 Rust 分片编译失败只剩汇总错误
- **原因**:`--message-format=json` 把编译诊断写到 stdout;只读取 `compiler-artifact` 的运行器会丢弃 `compiler-message`,CI 只能看到「due to 1 previous error」。
- **处理**:使用 `json-render-diagnostics` 保留 JSON artifact,同时让 Cargo 将诊断渲染到 stderr;运行器继承 stderr。既有分片 fixture 同时覆盖编译失败详情、测试 panic 和成功摘要,见开发运维文档的 Rust lane 口径。
- **排查边界**:函数签名变更与另一分支新增测试可能在无文本冲突的合并后产生参数不匹配;合并后必须检查测试目标,不能只验证普通二进制。
## 2026-10-01 线上 Nginx 手工维护漂移:`/profile` 刷新 404、发行包请求体仍限 64m
- **现象**:登录后刷新 `https://www.genarrative.world/profile` 直接 404,返回 Nginx 默认 404 页(162 字节);应用内点击进入正常。`curl` 复现:`/`、`/project`、`/creation`、`/components`、`/design-system`、`/games*`、`/editor/canvas` 全部 200 且正文与 `/` 同一份 SPA 外壳,只有 `/profile`(含 `/PROFILE`、`/profile/`)404。
@@ -9,6 +15,14 @@
- **处理**:线上只收敛 SPA allowlist(12 条,含 `/profile`)并补 `error_page 404 /404.html`;host-only 块收进 `deploy/nginx/snippets/genarrative-host-extras.conf`,由主模板 include、由 `Genarrative-Server-Provision` 安装。退役路由不进白名单,也不需要显式 404 配置,落 `location /` 即得品牌 404(非 HTML 客户端保持纯 404)。
- **判据/取证**:改前 `grep -c profile /etc/nginx/conf.d/genarrative.conf` 为 0;改后 `curl -s -o /dev/null -w '%{http_code}' https://www.genarrative.world/profile` 为 200(正文 sha 与 `/` 一致),`sudo nginx -T | grep -c 'editor/canvas|profile|project'` 为 1,`match3d` 计数为 0。
- **长期口径**:任何 SPA/路由白名单改动都要同时核对**生效配置**(`sudo nginx -T`)与仓库模板;线上主站 vhost 只由模板 + `genarrative-host-extras.conf` 生成,不再手工追加路由。snippet 内的 location 不在 Pingora 路由矩阵覆盖范围,Pingora 接公网 443 前要单独确认这些 host-only 路径。
## 2026-10-01 AGC 账户总量门槛会阻断单项查询与导入
- 账户素材库接口当前返回全量快照;客户端不能以全库条数代替单次查询、返回或导入的资源边界。原先在解析阶段拒绝超过 500 项,会让 `limit=1` 和指定 ID 导入一起失效,且检查发生在下载和 JSON 解析之后,不能保护这两步开销。
- 账户查询允许偏移超过 500,仍按单页最多 100 项返回安全元数据。修改时同步 MCP schema/校验、Direct 工具桥、Runtime 执行层及 `agent_native_tools.rs` 下发的 strict 原生函数 schema;仅直接调用 observation 会绕过模型侧参数约束,无法证明后续页可达,必须验证实际生成的函数参数 schema。共享分页函数的项目文件调用方仍保留自己的范围,画布资源数量边界独立维护。
- 实际平台会话导入还需避免在身份租约内再次调用会话读取/校验:租约持有非重入互斥锁,提交 helper 重复校验会等待自身释放。下载后校验并取得租约,持有至本地提交完成即可;不能用无平台会话的提交夹具替代完整导入链路验证。
- 后端有界分页与按 ID 读取由 #574 跟进,不作为 #549 客户端恢复可用的前置条件。当前合同与验证入口见 [AGC 实施计划](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md) 的“账户 / 项目画布 / 本地素材导入”。
## 2026-09-30 构建期 staging 撞上不装 npm 依赖的 Linux 门禁:AGC 壳 Rust lane 全红
- **现象**:`Project CI` 的 AGC 壳 Rust 三条 lane(`npm run check:native-shells:agc-rust-shard-*`)在 `fb130d184` 之后全部失败,日志只有 `error: failed to run custom build command for genarrative-ai-game-creator-shell` 与 `thread 'main' panicked at build.rs:65:28: Claude Agent SDK 缺失;请先执行 npm ci`(run 3083 / job 17521 实测,1 分钟即失败)。
@@ -6191,6 +6205,14 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
- **验证**:真机尺寸下用 `document.elementFromPoint(按钮中心)` 断言命中的是按钮自身而不是底部菜单(`overlay.parentElement === document.body`);顶栏断点矩阵(320–768)断言单行且无横向溢出。
- **关联**:`src/components/common/SquareImageCropModal.tsx`、`src/components/platform-entry/PlatformProfileModalShell.tsx`、`src/components/platform-entry/PlatformEntryActiveFlowShell.tsx`、`src/index.css`。
## 2026-10-01 cc/Anthropic 必须走平台网关,客户端不得直连 Router
- **现象**:目录里把 `claude-opus-5-5` 标成 `agentMode=cc` 后,选它发消息必然失败:先是 Claude CLI 自己打印 `Not logged in · Please run <path>`,后来卡满 `requestTimeoutMs=180000`。
- **根因**:`claude_code_cli.rs` 用配置里残留的 `llm.baseUrl`(`https://router.genarrative.world/v1`)当 `ANTHROPIC_BASE_URL`,再把平台会话 token 塞成 `ANTHROPIC_AUTH_TOKEN`。平台凭据边界是「客户端只出示平台 access token,账号的 Router key 由 api-server 解析、绝不下发」(见 `api-server/src/llm/mod.rs`)。实测 `POST https://router.genarrative.world/v1/messages` 用平台 token 返回 `401 Invalid token (new_api_error)`。
- **现行口径**:baseUrl 不带路由与版本段,统一由协议自己拼 `v1/<op>`(服务端 `router_protocol_url` 会先把历史凭据末尾的 `/v1` 归一化掉)。平台侧 Anthropic 是独立路由 `/api/llm/anthropic/{*path}`,客户端 `ANTHROPIC_BASE_URL` 设成 `{apiBaseUrl}/api/llm/anthropic`;OpenAI 侧是 `/api/llm/v1/responses` 与 `/api/llm/v1/chat/completions`,旧的无 `v1` 路径保留为已发布客户端的兼容别名。
- **注意**:Claude Agent SDK 固定请求 `{ANTHROPIC_BASE_URL}/v1/messages?beta=true`(外加一次 `HEAD /api/hello` 探测),网关不要自己再补 `v1`,用通配段承接客户端协议路径。
- **后台协议选项**:`AgcAgentMode` 增加 `anthropic`(显式 Anthropic 协议),`cc` 保留为同一执行器的历史别名;新增目录项应直接写 `anthropic`。
## 2026-10-01 AGC 壳 Rust 单测片内 `--test-threads=1` 不等于没有并发:宿主后台回合会跨用例发通知
- **现象**:`agent::thread_manager::tests::active_turn_changes_publish_one_notification_per_real_change` 在 CI 偶发红,`进度内容变化必须通知一次` 拿到 6 而非 5(也见过入队断言就多 1);本地要跑 3–5 次才复现。这条用例靠一个进程级计数器数「运行中的项目」通知。