修复 #599:首页建项不再等待 AI 项目命名,改为后台条件改名 #606
Reference in New Issue
Block a user
Delete Branch "fix/home-project-naming-async"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
关联 issue
Closes #599(Kind/Enhancement、Priority/Low)
改了什么
1. 建项不再等 AI 命名
create_automatic_local_game_project固定传name: null(宿主兜底名GameAgent 项目 <8 位短 id>/策划项目 <8 位短 id>),不再等待suggest_automatic_project_name返回。命名慢、超时、失败或返回非法内容都不影响建项、附件导入与首轮创作。rename_local_game_project_if_unchanged(projectPath, expectedProjectId, expectedName, name):只有「项目 ID 相同」且「当前名称仍是本次创建的兜底名」才落盘改名,用户已手动改名 / 项目 ID 不符 / 名称未变一律跳过;空expectedProjectId/expectedName/ 空名 / 控制字符 / 超长失败关闭。与既有rename_local_game_project同口径:簿记写入,不推进项目 revision。2. 自动命名是「生成任务」体系里的一条后台任务(不是页面里的 promise)
taskType(asset-generation/project-naming,缺省asset-generation),kind改为可选(命名任务为null);schema 升agc-asset-generation-task.v2,读取同时接受 v1 与 v2(v1 记录按素材任务读回)。game-creator-asset-generation-task-changed)与同一套卡片样式;展示名固定「AI 项目命名」,不渲染缩略图 / 提示词 / 派发与「定位到素材」,结论只在终态显示。enqueue_local_project_naming_task(排队中)→update_local_project_naming_task(命名中)→ 已完成(已应用 AI 名称 / 建议名与现状一致 / 用户已手动改名,已跳过 AI 命名)或 失败(无可用名称、自动改名失败,均保留兜底名)。命名任务由命名链路推进,因此 enqueue 登记 live、终态写盘后摘除,否则任何一次账本读取都会按「上次运行中断」把它误收口为失败(中断残留仍按命名口径收口为失败)。packages/shared/**)、server-rs/**、任何 SpacetimeDB schema 或 HTTP 路由。测试
tests/homeProjectNamingAsync.test.tsx(12 例,promise 闸门控时序,不用 sleep):命名请求永不返回仍进工作区、AI 结果先于进项目落定仍不被兜底名覆盖、手动改名不被覆盖且任务按「已完成 + 已跳过」收口、空/非法响应 → 任务 failed 且保留兜底名、条件改名失败不影响已建工作区、做方案不发起命名、切到别的工作区不被劫持、卸载/pagehide后不写上下文;并断言账本推进序列入队 → running → 终态。tests/projectNamingGenerationTaskRow.test.tsx(3 例):固定展示名、进行中不渲染阶段文案与缩略图/定位动作、终态才显示结论、失败徽章与原因、在途计数。tests/appSurface/home.suite.ts:建项后「生成任务」里出现这条「AI 项目命名」(进行中可见),账本变更事件 → 一次受控快照读取 → 终态结论出现在同一行;窗口标题与最近项目行同步 AI 名。asset_generation_task27 例(含naming_task_stays_in_flight_across_ledger_reads_until_terminal、naming_task_update_requires_the_project_rename_permission、naming_task_update_rejects_a_record_from_another_project、naming_task_terminal_state_rejects_a_different_status_but_allows_the_same_one、ledger_with_an_unsupported_schema_version_fails_closed、ledger_without_a_schema_version_is_accepted_as_v1、legacy_v1_ledger_reads_back_with_the_default_asset_generation_task_type)、conditional_project_rename_tests7 例(含超长名失败关闭)。await entrySettled→ 顺序用例红;去掉上下文写入的项目路径守卫 → 劫持用例红;去掉生命周期守卫 → 卸载/隐藏两条用例红;去掉命名任务的 live 登记 → 在途记录被误收口为失败(Rust 用例红)。验证(实跑)
独立评审修复(0 P0/P1,4 P2 + 1 P3 全部处理)
recovers the naming row when the terminal event lands before the subscription is ready、re-reads the naming ledger when the generation tasks panel opens),并做了「改前红」验证:把实现退回「先读后订阅 / 面板打开不补读」,两条即红。update_local_project_naming_task门禁不对称 + 终态可被覆盖:补enforce_project_permission_policy(root, "project.rename")(与 enqueue 同口径)、校验记录project_id与该项目一致、终态只接受同状态幂等重放(completed → failed一律 Err 且不写盘)。新增 3 条 Rust 用例(权限拒绝、跨项目记录拒绝、终态不同状态拒绝 + 同状态重放通过)。schemaVersion→ Err、缺schemaVersion按 v1 接受,共 3 条 Rust 用例。兼容性边界(单向,已知并记录)
"kind": null,而旧构建的AssetGenerationTaskRecord.kind必填、read_ledger也不校验 schema,解析含命名记录的账本会整份失败 → 「生成任务」面板报「生成任务列表读取失败」,同一批读里在途的素材任务会被按「上次运行中断」收口为失败。触发条件:同一项目先被新构建写过命名任务,之后又被旧构建(降级 / 新旧混跑)打开。kind(例如unknown),只靠taskType区分——旧构建会把它渲染成一张名为「AI 项目命名」的素材任务卡,但账本能解析、不会误伤在途素材任务。涉及是否允许命名记录借用素材 kind 词表,留给用户定。合并与剩余风险
origin/mastertipccd271572(mergeeeac2c759)、origin/fix/ci-master-redtip8b11dc4e7(merge459fe5b43,PR #609 修掉共享红)、origin/mastertip33552d2ed(merge3dcfbb1d1,仅decision-log.md/pitfalls.md两处文档冲突,两边条目全部保留)、origin/mastertipa2f250364(merge160b7e6cf)与origin/mastertip76cd1f057(mergef47a8f305,含 #608 Direct 交付合同重构,与本文档 hunk 不相交、零冲突),全部用 merge、未 rebase。check:tests:types)把直接赋值window.__TAURI__迁到installTauriRuntime/resetTauriRuntime;命名任务的账本推进命令名写成字面量,满足check-config.mjs的静态枚举门禁。Repository checks红在lint:eslint(simple-import-sort/imports:view/project-development/index.tsx的 type 导入与值导入混排),已用eslint --fix归位并实跑npm run lint:eslint(0 problems);该修复见提交cd07b7375。/pay/<checkoutToken>的前缀路由(Nginx 三模板 + Pingora + 门禁) ad0430fcd2Close #599
suzmii referenced this pull request2026-10-05 17:06:23 +08:00